1 /*
2 This file is part of "Avanor, the Land of Mystery" roguelike game
3 Home page: http://www.avanor.com/
4 Copyright (C) 2000-2003 Vadim Gaidukevich
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #ifndef __XOBJECT_H
22 #define __XOBJECT_H
23
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include "defs.h"
29 #include "xfile.h"
30
31
32 enum ITEM_MASK {
33 IM_UNKNOWN = 0x00000000,
34 IM_HERO = 0x00000001, //let it's be
35 IM_CREATURE = 0x00000002,
36 IM_MONSTER = IM_HERO | IM_CREATURE,
37 IM_WAY = 0x00000004,
38 IM_DOOR = 0x00000008,
39 IM_TRAP = 0x00000010,
40 IM_TELEPORT = 0x00000020,
41 IM_ALTAR = 0x00000040,
42 IM_MISC = 0x00000080,
43
44 IM_HAT = 0x00000100,
45 IM_NECK = 0x00000200,
46 IM_BODY = 0x00000400,
47 IM_CLOAK = 0x00000800,
48 IM_WEAPON = 0x00001000,
49 IM_SHIELD = 0x00002000,
50 IM_HAND = IM_WEAPON | IM_SHIELD, //for a bodyparts
51 IM_GLOVES = 0x00004000,
52 IM_RING = 0x00008000,
53 IM_BOOTS = 0x00010000,
54 IM_MISSILEW = 0x00020000,
55 IM_MISSILE = 0x00040000,
56 IM_POTION = 0x00100000,
57 IM_SCROLL = 0x00200000,
58 IM_BOOK = 0x00400000,
59 IM_WAND = 0x00800000,
60 IM_FOOD = 0x01000000,
61 IM_HERB = 0x02000000,
62 IM_LIGHTSOURCE = 0x04000000,
63 IM_TOOL = 0x08000000,
64 IM_GEM = 0x10000000,
65 IM_MONEY = 0x20000000,
66 IM_STACKABLE = 0x40000000, //for spells
67 IM_CHEST = 0x80000000,
68 IM_ITEM = 0x2FFFFF00, //all items!
69
70 IM_OTHER = 0x80000000,
71 IM_TOHIT = IM_HAT | IM_NECK | IM_BODY | IM_CLOAK | IM_GLOVES | IM_SHIELD | IM_BOOTS | IM_RING | IM_WEAPON,
72 IM_ARMOUR = IM_HAT | IM_BODY | IM_CLOAK | IM_GLOVES | IM_SHIELD | IM_BOOTS,
73 IM_VALUEDICE = IM_WEAPON | IM_MISSILEW | IM_MISSILE,
74 IM_VALUEDVPV = IM_HAT | IM_BODY | IM_CLOAK | IM_GLOVES | IM_SHIELD | IM_BOOTS | IM_WEAPON,
75 IM_VALUEHITDMG = IM_HAT | IM_BODY | IM_CLOAK | IM_GLOVES | IM_BOOTS | IM_WEAPON,
76 IM_ALL = 0xFFFFFFFF
77 };
78
79
80 class XObject;
81 //next code is for creating class by it name
82 typedef XObject * (*CLASS_CREATOR)();
83
84 #define REGISTER_CLASS(__xClass) \
85 XClassFactory reg##__xClass(#__xClass, (CLASS_CREATOR)__xClass::Creator)
86
87 struct DUMMY_STRUCT
88 {
89 };
90
91 #define DECLARE_CREATOR(__xClass, __xBaseClass) \
92 __xClass(DUMMY_STRUCT * ds) : __xBaseClass(ds) {} \
93 static __xClass * Creator() {DUMMY_STRUCT ds; return new __xClass(&ds);} \
94 virtual const char * GetClassName() {return #__xClass;}
95 // void InvalidateLeave() {__xBaseClass::Invalidate();}
96
97 //#define INVALIDATE_ENTER() static int inside = 0; assert(!inside); if (!isValid()) return; inside = 1;
98 //#define INVALIDATE_LEAVE() InvalidateLeave(); inside = 0;
99
100 //virtual XObject * MakeCopy() {return new __xClass(this);}
101
102 class XClassInfo
103 {
104 public:
XClassInfo(char * _name,CLASS_CREATOR p)105 XClassInfo(char * _name, CLASS_CREATOR p) {name = _name; pClassCreator = p; next = NULL;}
106 char * name;
107 CLASS_CREATOR pClassCreator;
108 XClassInfo * next;
109 };
110
111 class XClassFactory
112 {
113 public:
114 static XClassInfo * first_class;
115 static int counter;
116 XClassFactory(char * name, CLASS_CREATOR pClass);
117 ~XClassFactory();
118 static XObject * Create(char * name);
119 };
120
121 #define DYNCREATE(x) XClassFactory::Create(x)
122 // end
123
124
125
126 typedef unsigned long XGUID;
127 extern XGUID guid;
128
129 //this class is a base class for most important part's of cernel
130 class XObject
131 {
132 public:
133 static long invalid_count;
134 static XObject ** table;
135 static long count;
136 static XObject * root;
137
138 XObject * prev;
139 XObject * next;
140
141 bool bAlreadyStored;
142
AddToList()143 void AddToList()
144 {
145 assert(table == 0);
146 if (root != 0) root->prev = this;
147 prev = 0;
148 next = root;
149 root = this;
150 count++;
151 }
152
RemoveFromList()153 void RemoveFromList()
154 {
155 assert(table == 0);
156 if (this == root) root = next;
157 if (prev != 0) prev->next = next;
158 if (next != 0) next->prev = prev;
159 count--;
160 invalid_count++;
161 }
162
163 int reference; //objects can't be deleted till reference > 0
164 int is_valid;
165
Create()166 void Create()
167 {
168 reference = 0;
169 AddToList();
170 }
171
172 public:
173 static void StorePointer(XFile * f, XObject * p);
174 static XObject * RestorePointer(XFile * f, void * owner);
175 static void StoreAllObjects(XFile * f);
176 static void RestoreAllObjects(XFile * f);
177 static void InvalidateAllObjects();
178 static void FreeTable();
179
180 // DECLARE_CREATOR(XObject);
181
XObject(DUMMY_STRUCT * ds)182 XObject(DUMMY_STRUCT * ds) : is_valid(1)
183 {
184 Create();
185 }
186
XObject()187 XObject() : xguid(::guid++), quantity(1), im(IM_UNKNOWN), is_valid(1)
188 {
189 Create();
190 }
191
XObject(XObject * o)192 XObject(XObject * o) : xguid(::guid++), quantity(o->quantity), im(o->im), is_valid(1), ttm(o->ttm), ttmb(o->ttmb)
193
194 {
195 Create();
196 }
197
~XObject()198 virtual ~XObject()
199 {
200 assert(!is_valid && reference == 0);
201 invalid_count--;
202 }
203
AddRef()204 void AddRef()
205 {
206 reference++;
207 }
208
Release()209 void Release()
210 {
211 assert(reference > 0);
212 if(--reference == 0 && !is_valid)
213 {
214 delete this;
215 }
216 }
217
GetRef()218 int GetRef()
219 {
220 return reference;
221 }
222
Invalidate()223 virtual void Invalidate()
224 {
225 // assert(is_valid);
226 if (!is_valid) return;
227 is_valid = 0;
228 RemoveFromList();
229 if (reference == 0)
230 {
231 delete this;
232 }
233 }
234
Compare(XObject * o)235 virtual int Compare(XObject * o) { return 1; }
Concat(XObject * o)236 virtual void Concat(XObject * o)
237 {
238 assert(o->reference == 0);
239 quantity += o->quantity;
240 o->Invalidate();
241 }
242
GetClassName()243 virtual const char * GetClassName() { return "XObject"; }
244
245 virtual void Dump(XFile * f);
246 static void DumpAll();
247
248 int quantity; //some objects can stacked to a bundle: "bundle of 23 arrow (1d4)"
249 XGUID xguid; //all objects has global unique inditifer
250 //(it has no sense to store pointers)
251 ITEM_MASK im; //many years ago it was item mask, now it is mask for all!
252
isValid()253 int isValid() { return is_valid; }
254
255 // interface for store/restore functions
256 virtual void Store(XFile * f);// = 0;
257 virtual void Restore(XFile * f);// = 0;
258
259 // Runable object...
260 // If It returns zero, than object must be removed from scheduler
Run()261 virtual int Run() { return 1; }
262 int ttm; //time to move
263 int ttmb; //basis of time to move
264
265 };
266
267 template<class TYPE> class XPtr
268 {
269 mutable XObject * p;
270 void operator=(const XPtr<TYPE> &);
271 XPtr(const XPtr<TYPE> &);
272 TYPE * get_with_check() const;
273 public:
XPtr()274 XPtr() : p(NULL) { }
XPtr(TYPE * _p)275 XPtr(TYPE * _p) : p(_p) { if(p != NULL) p->AddRef(); }
276 ~XPtr();
277
278 bool operator==(XPtr<TYPE> & x) const { return operator TYPE * () == x.operator TYPE * (); }
279
280 void operator=(TYPE * _p);
281
282 operator TYPE * () const { return (p == NULL) ? NULL : get_with_check(); }
283
get()284 TYPE * get() const { return static_cast<TYPE *>(p); }
285 TYPE * operator->() const { return static_cast<TYPE *>(p); }
286
287 void Store(XFile * f) const;
288 void Restore(XFile * f);
289 };
290
~XPtr()291 template<class TYPE> XPtr<TYPE>::~XPtr()
292 {
293 if(p != NULL) p->Release();
294 }
295
296 template<class TYPE> void XPtr<TYPE>::operator=(TYPE * _p)
297 {
298 if(p == (XObject *)_p) return;
299 if(p != NULL) p->Release();
300 p = (XObject *)_p;
301 if(p != NULL) p->AddRef();
302 }
303
get_with_check()304 template<class TYPE> TYPE * XPtr<TYPE>::get_with_check() const
305 {
306 if(p->isValid()) return static_cast<TYPE *>(p);
307 p->Release();
308 p = NULL;
309 return NULL;
310 }
311
Store(XFile * f)312 template<class TYPE> void XPtr<TYPE>::Store(XFile * f) const
313 {
314 XObject::StorePointer(f, operator TYPE * ());
315 }
316
Restore(XFile * f)317 template<class TYPE> void XPtr<TYPE>::Restore(XFile * f)
318 {
319 assert(p == NULL);
320 p = XObject::RestorePointer(f, this);
321 if (p != NULL) p->AddRef();
322 assert(p == NULL || dynamic_cast<TYPE *>(p));
323 }
324
325 #endif
326