ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/include/object.h
Revision: 1.112
Committed: Mon Apr 30 04:25:30 2007 UTC (17 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.111: +1 -1 lines
Log Message:
This is the first rough cut of the skill use system (use the STABLE tag).

Details will likely change, and combat skills do not work very well, but
it works quite well.

Players no longer have a shoottype or range slots, instead, each player
has these members:

   combat_skill/combat_ob  the currently selected skill (and weapon)
                           for direct attacks.
   ranged_skill/ranged_ob  the currently selected ranged skill (and
                           bow/spell/item)
   golem                   the currently-controlled golem, if any.

File Contents

# Content
1 /*
2 * CrossFire, A Multiplayer Online RPG
3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * The authors can be reached via e-mail at crossfire@schmorp.de
23 */
24
25 #ifndef OBJECT_H
26 #define OBJECT_H
27
28 #include <bitset>
29
30 #include "cfperl.h"
31 #include "shstr.h"
32
33 typedef int tag_t;
34
35 #define NUM_BODY_LOCATIONS 12
36 #define BODY_ARMS 1
37
38 /* See common/item.c */
39
40 typedef struct Body_Locations
41 {
42 const char *save_name; /* Name used to load/save it to disk */
43 const char *use_name; /* Name used when describing an item we can use */
44 const char *nonuse_name; /* Name to describe objects we can't use */
45 } Body_Locations;
46
47 extern Body_Locations body_locations[NUM_BODY_LOCATIONS];
48
49 /*
50 * Each object (this also means archetypes!) could have a few of these
51 * "dangling" from it; this could also end up containing 'parse errors'.
52 *
53 * key and value are shared-strings.
54 *
55 * Please use get_ob_key_value(), set_ob_key_value() from object.c rather than
56 * accessing the list directly.
57 * Exception is if you want to walk this list for some reason.
58 */
59 struct key_value
60 {
61 key_value *next;
62 shstr key, value;
63 };
64
65 struct UUID
66 {
67 uint64 seq;
68
69 UUID () { }
70 UUID (uint64 seq) : seq(seq) { }
71 operator uint64() { return seq; }
72 void operator =(uint64 seq) { this->seq = seq; }
73 };
74
75 extern void init_uuid ();
76 extern UUID gen_uuid ();
77 extern const uint64 UUID_SKIP;
78
79 /* Definition for WILL_APPLY values. Replaces having harcoded values
80 * sprinkled in the code. Note that some of these also replace fields
81 * that were in the can_apply area. What is the point of having both
82 * can_apply and will_apply?
83 */
84 #define WILL_APPLY_HANDLE 0x01
85 #define WILL_APPLY_TREASURE 0x02
86 #define WILL_APPLY_EARTHWALL 0x04
87 #define WILL_APPLY_DOOR 0x08
88 #define WILL_APPLY_FOOD 0x10
89
90 /* However, if you're keeping a pointer of some sort, you probably
91 * don't just want it copied, so you'll need to add to common/object.C,
92 * e.g. ->copy_to ()
93 */
94
95 INTERFACE_CLASS (object)
96 // these are being copied
97 struct object_copy : attachable
98 {
99 typedef bitset<NUM_FLAGS> flags_t;
100
101 sint16 ACC (RW, x), ACC (RW, y); /* Position in the map for this object */
102 sint8 ACC (RW, direction); /* Means the object is moving that way. */
103 sint8 ACC (RW, facing); /* Object is oriented/facing that way. */
104 shstr ACC (RW, name); /* The name of the object, obviously... */
105 shstr ACC (RW, name_pl); /* The plural name of the object */
106 shstr ACC (RW, title); /* Of foo, etc */
107 shstr ACC (RW, race); /* human, goblin, dragon, etc */
108 shstr ACC (RW, slaying); /* Which race to do double damage to */
109 /* If this is an exit, this is the filename */
110 shstr ACC (RW, skill); /* Name of the skill this object uses/grants */
111 shstr ACC (RW, msg); /* If this is a book/sign/magic mouth/etc */
112 shstr ACC (RW, lore); /* Obscure information about this object, */
113 /* To get put into books and the like. */
114 shstr ACC (RW, materialname); /* specific material name */
115 shstr ACC (RW, custom_name); /* Custom name assigned by player */
116 // materialtype_t *ACC (RW, material); /* What material this object consists of */
117 object_ptr ACC (RW, owner); /* Pointer to the object which controls this one */
118 object_ptr ACC (RW, enemy); /* Monster/player to follow even if not closest */
119 object_ptr ACC (RW, attacked_by); /* This object start to attack us! only player & monster */
120 object_ptr ACC (RW, chosen_skill); /* the skill chosen to use */
121 object_ptr ACC (RW, spellitem); /* Spell ability monster is choosing to use */
122 object_ptr ACC (RW, spell); /* Spell that was being cast */
123 object_ptr ACC (RW, current_weapon); /* Pointer to the weapon currently used */
124 arch_ptr ACC (RW, arch); /* Pointer to archetype */
125 arch_ptr ACC (RW, other_arch);/* Pointer used for various things - mostly used for what */
126
127 float ACC (RW, speed); /* The overall speed of this object */
128 float ACC (RW, speed_left); /* How much speed is left to spend this round */
129 uint32 ACC (RW, nrof); /* How many of the objects */
130
131 /* This next big block are basically used for monsters and equipment */
132 uint8 ACC (RW, type); /* PLAYER, BULLET, etc. See define.h */
133 uint8 ACC (RW, subtype); /* subtype of object */
134 uint16 ACC (RW, client_type); /* Public type information. see doc/Developers/objects */
135 sint16 ACC (RW, resist[NROFATTACKS]); /* Resistance adjustments for attacks */
136 uint32 ACC (RW, attacktype); /* Bitmask of attacks this object does */
137 uint32 ACC (RW, path_attuned);/* Paths the object is attuned to */
138 uint32 ACC (RW, path_repelled); /* Paths the object is repelled from */
139 uint32 ACC (RW, path_denied); /* Paths the object is denied access to */
140 uint16 ACC (RW, materials); /* What materials this object consists of */
141 sint8 ACC (RW, magic); /* Any magical bonuses to this item */
142 uint8 ACC (RW, state); /* How the object was last drawn (animation) */
143 sint32 ACC (RW, value); /* How much money it is worth (or contains) */
144 /* Note that the last_.. values are sometimes used for non obvious
145 * meanings by some objects, eg, sp penalty, permanent exp.
146 */
147 sint32 ACC (RW, last_heal); /* Last healed. Depends on constitution */
148 sint32 ACC (RW, last_sp); /* As last_heal, but for spell points */
149 sint16 ACC (RW, last_grace); /* as last_sp, except for grace */
150 sint16 ACC (RW, last_eat); /* How long since we last ate */
151 sint16 ACC (RW, invisible); /* How much longer the object will be invis */
152 sint16 ACC (RW, level); /* Level of creature or object */
153 uint8 ACC (RW, pick_up); /* See crossfire.doc */
154 sint8 ACC (RW, item_power); /* power rating of the object */
155 sint8 ACC (RW, gen_sp_armour);/* sp regen penalty this object has (was last_heal) */
156 sint8 ACC (RW, glow_radius); /* indicates the glow radius of the object */
157 sint32 ACC (RW, weight); /* Attributes of the object */
158 sint32 ACC (RW, weight_limit);/* Weight-limit of object */
159 sint32 ACC (RW, carrying); /* How much weight this object contains */
160 sint64 ACC (RW, perm_exp); /* Permanent exp */
161 uint32 ACC (RW, weapontype); /* type of weapon */
162 uint32 ACC (RW, tooltype); /* type of tool or build facility */
163 sint8 ACC (RW, body_info[NUM_BODY_LOCATIONS]); /* body info as loaded from the file */
164 sint8 ACC (RW, body_used[NUM_BODY_LOCATIONS]); /* Calculated value based on items equipped */
165 faceidx ACC (RW, face); /* Face with colors */
166 living ACC (RO, stats); /* Str, Con, Dex, etc */
167 /* See the pod/objects.pod for more info about body locations */
168
169 /* Following mostly refers to fields only used for monsters */
170 uint32 ACC (RW, hide); /* The object is hidden, not invisible */
171
172 /* allows different movement patterns for attackers */
173 sint32 ACC (RW, move_status); /* What stage in attack mode */
174 uint16 ACC (RW, attack_movement); /* What kind of attack movement */
175 uint16 ACC (RW, run_away); /* Monster runs away if it's hp goes below this percentage. */
176 float ACC (RW, expmul); /* needed experience = (calc_exp*expmul) - means some */
177 /* races/classes can need less/more exp to gain levels */
178
179 /* Spell related information, may be useful elsewhere
180 * Note that other fields are used - these files are basically
181 * only used in spells.
182 */
183 sint16 ACC (RW, duration); /* How long the spell lasts */
184 sint16 ACC (RW, casting_time);/* time left before spell goes off */
185 uint16 ACC (RW, start_holding);
186 uint8 ACC (RW, duration_modifier); /* how level modifies duration */
187 uint8 ACC (RW, dam_modifier); /* How going up in level effects damage */
188 sint8 ACC (RW, range); /* Range of the spell */
189 uint8 ACC (RW, range_modifier); /* How going up in level effects range */
190
191 MoveType ACC (RW, move_type); /* Type of movement this object uses */
192 MoveType ACC (RW, move_block);/* What movement types this blocks */
193 MoveType ACC (RW, move_allow);/* What movement types explicitly allowd */
194 MoveType ACC (RW, move_on); /* Move types affected moving on to this space */
195 MoveType ACC (RW, move_off); /* Move types affected moving off this space */
196 MoveType ACC (RW, move_slow); /* Movement types this slows down */
197 float ACC (RW, move_slow_penalty); /* How much this slows down the object */
198
199 char *ACC (RW, spellarg);
200
201 /* Following are values used by any object */
202 /* this objects turns into or what this object creates */
203 treasurelist *ACC (RW, randomitems); /* Items to be generated */
204 flags_t flag; /* various flags */
205 #if FOR_PERL
206 bool ACC (RW, flag[NUM_FLAGS]);
207 #endif
208 uint16 ACC (RW, animation_id);/* An index into the animation array */
209 uint8 ACC (RW, anim_speed); /* ticks between animation-frames */
210 uint8 ACC (RW, last_anim); /* last sequence used to draw face */
211 sint16 ACC (RW, elevation); /* elevation of this terrain - not currently used */
212 uint8 ACC (RW, smoothlevel); /* how to smooth this square around */
213 uint8 ACC (RW, will_apply); /* See crossfire.doc */
214 };
215
216 struct object : zero_initialised, object_copy
217 {
218 // These variables are not changed by ->copy_to
219 maptile_ptr ACC (RW, map); /* Pointer to the map in which this object is present */
220
221 UUID ACC (RW, uuid); // Unique Identifier, survives saves etc.
222 int ACC (RO, count);
223 int ACC (RO, index); // index into objects
224 int ACC (RO, active); // index into actives
225
226 player_ptr ACC (RW, contr); /* Pointer to the player which control this object */
227
228 object *ACC (RW, below); /* Pointer to the object stacked below this one */
229 object *ACC (RW, above); /* Pointer to the object stacked above this one */
230 /* Note: stacked in the *same* environment */
231 object *inv; /* Pointer to the first object in the inventory */
232
233 //TODO: container must move into client
234 object_ptr ACC (RW, container); /* Current container being used. I think this
235 * is only used by the player right now.
236 */
237 object *ACC (RW, env); /* Pointer to the object which is the environment.
238 * This is typically the container that the object is in.
239 */
240 object *ACC (RW, more); /* Pointer to the rest of a large body of objects */
241 object *head; /* Points to the main object of a large body */ // NO ACC, perl semantics are different
242 client_container *seen_by; // seen by which player/container currently?
243 key_value *key_values; /* Fields not explictly known by the loader. */
244
245 bool parse_kv (object_thawer &f); // parse kv pairs, (ab-)used by archetypes, which should not exist at all
246 static object *read (object_thawer &f, maptile *map = 0); // map argument due to toal design bogosity, must go.
247 bool write (object_freezer &f);
248
249 MTH static object *create ();
250 object &operator =(const object &src);
251 MTH void copy_to (object *dst);
252 MTH object *clone (); // create + copy_to
253 void do_destroy ();
254 void gather_callbacks (AV *&callbacks, event_type event) const;
255 MTH void destroy (bool destroy_inventory = false);
256
257 // recursively destroy all objects in inventory, optionally dropping them to the ground instead
258 MTH void destroy_inv (bool drop_to_ground = false);
259 MTH object *insert (object *item); // insert into inventory
260 void do_remove ();
261 MTH void remove ()
262 {
263 if (!flag [FLAG_REMOVED])
264 do_remove ();
265 }
266
267 static bool can_merge_slow (object *op1, object *op2);
268
269 // this is often used in time-critical code, so optimise
270 MTH static bool can_merge (object *op1, object *op2)
271 {
272 return op1->value == op2->value
273 && op1->name == op2->name
274 && can_merge_slow (op1, op2);
275 }
276
277 MTH void set_owner (object *owner);
278 MTH void set_speed (float speed);
279
280 MTH void open_container (object *new_container);
281 MTH void close_container ()
282 {
283 open_container (0);
284 }
285
286 MTH void instantiate ();
287
288 // recalculate all stats
289 MTH void update_stats ();
290 MTH void roll_stats ();
291 MTH void swap_stats (int a, int b);
292 MTH void add_statbonus ();
293 MTH void remove_statbonus ();
294 MTH void drain_stat ();
295 MTH void drain_specific_stat (int deplete_stats);
296 MTH void change_luck (int value);
297
298 // info must hold 256 * 3 bytes currently
299 const char *debug_desc (char *info) const;
300 MTH const char *debug_desc () const;
301 const char *debug_desc2 () const; // another debug_desc, pure convinience function
302 const char *flag_desc (char *desc, int len) const;
303
304 int number_of () const
305 {
306 return nrof ? nrof : 1;
307 }
308
309 uint64 total_weight () const
310 {
311 return weight * number_of ();
312 }
313
314 // return the dominant material of this item, always return something
315 const materialtype_t *dominant_material () const;
316
317 // return the volume of this object in cm³
318 uint64 volume () const
319 {
320 return total_weight ()
321 * 1000
322 * (type == CONTAINER ? 1000 : 1)
323 / dominant_material ()->density;
324 }
325
326 MTH bool is_weapon () const { return type == ARROW || type == BOW || type == WEAPON; }
327 MTH bool is_armor () const { return type == ARMOUR || type == SHIELD || type == HELMET
328 || type == CLOAK || type == BOOTS || type == GLOVES
329 || type == BRACERS || type == GIRDLE; }
330 MTH bool is_alive () const { return (type == PLAYER
331 || flag [FLAG_MONSTER]
332 || (flag [FLAG_ALIVE] && !flag [FLAG_GENERATOR] && type != DOOR))
333 && !flag [FLAG_IS_A_TEMPLATE]; }
334 MTH bool is_arrow () const { return type == ARROW
335 || (type == SPELL_EFFECT
336 && (subtype == SP_BULLET || subtype == SP_MAGIC_MISSILE)); }
337
338 MTH bool has_active_speed () const { return FABS(speed) >= MIN_ACTIVE_SPEED; }
339
340 // temporary: wether the object can be saved in a map file
341 // contr => is a player
342 // head => only save head of a multitile object
343 // owner => can not reference owner yet
344 MTH bool can_map_save () const { return !contr && !head && !owner && !flag [FLAG_NO_MAP_SAVE]; }
345
346 /* This return true if object has still randomitems which
347 * could be expanded.
348 */
349 MTH bool has_random_items () const { return randomitems && !flag [FLAG_IS_A_TEMPLATE]; }
350
351 // returns the player that has this object in his inventory, or 0
352 MTH object *in_player () const
353 {
354 for (object *op = env; op; op = op->env)
355 if (op->type == PLAYER)
356 return op;
357
358 return 0;
359 }
360
361 // "temporary" helper function
362 MTH object *head_ ()
363 {
364 return head ? head : this;
365 }
366
367 MTH std::string long_desc (object *who = 0);
368 MTH std::string describe_monster (object *who = 0);
369 MTH std::string describe_item (object *who = 0);
370 MTH std::string describe (object *who = 0);
371
372 // If this object has no extra parts but should have them,
373 // add them, effectively expanding heads into multipart
374 // objects. This method only works on objects not inserted
375 // anywhere.
376 MTH void expand_tail ();
377
378 MTH void create_treasure (treasurelist *tl, int flags = 0);
379
380 // insert object at same map position as 'where'
381 // handles both inventory and map "positions"
382 MTH object *insert_at (object *where, object *originator = 0, int flags = 0);
383
384 MTH void activate ();
385 MTH void deactivate ();
386 MTH void activate_recursive ();
387 MTH void deactivate_recursive ();
388
389 // set the givne flag on all objects in the inventory recursively
390 MTH void set_flag_inv (int flag, int value = 1);
391
392 void enter_exit (object *exit);//Perl
393 MTH void enter_map (maptile *newmap, int x, int y);
394
395 // returns the mapspace this object is in
396 mapspace &ms () const;
397
398 // fully recursive iterator
399 struct iterator_base
400 {
401 object *item;
402
403 iterator_base (object *container)
404 : item (container)
405 {
406 }
407
408 operator object *() const { return item; }
409
410 object *operator ->() const { return item; }
411 object &operator * () const { return *item; }
412 };
413
414 MTH unsigned int random_seed () const
415 {
416 return (unsigned int)uuid.seq;
417 }
418
419 // depth-first recursive iterator
420 struct depth_iterator : iterator_base
421 {
422 depth_iterator (object *container);
423 void next ();
424 object *operator ++( ) { next (); return item; }
425 object *operator ++(int) { object *i = item; next (); return i; }
426 };
427
428 object *begin ()
429 {
430 return this;
431 }
432
433 object *end ()
434 {
435 return this;
436 }
437
438 /* This returns TRUE if the object is something that
439 * should be displayed in the floorbox/inventory window
440 */
441 MTH bool client_visible () const
442 {
443 return !invisible && type != PLAYER;
444 }
445
446 MTH struct region *region () const;
447
448 protected:
449 friend struct archetype;
450
451 void link ();
452 void unlink ();
453
454 object ();
455 ~object ();
456 };
457
458 typedef object_vector<object, &object::index > objectvec;
459 typedef object_vector<object, &object::active> activevec;
460
461 extern objectvec objects;
462 extern activevec actives;
463
464 #define for_all_objects(var) \
465 for (unsigned _i = 0; _i < objects.size (); ++_i) \
466 declvar (object *, var, objects [_i])
467
468 #define for_all_actives(var) \
469 for (unsigned _i = 0; _i < actives.size (); ++_i) \
470 declvar (object *, var, actives [_i])
471
472 typedef struct oblnk
473 { /* Used to link together several objects */
474 object_ptr ob;
475 struct oblnk *next;
476 } objectlink;
477
478 typedef struct oblinkpt
479 { /* Used to link together several object links */
480 struct oblnk *link;
481 long value; /* Used as connected value in buttons/gates */
482 struct oblinkpt *next;
483 } oblinkpt;
484
485 /*
486 * The archetype structure is a set of rules on how to generate and manipulate
487 * objects which point to archetypes.
488 * This probably belongs in arch.h, but there really doesn't appear to
489 * be much left in the archetype - all it really is is a holder for the
490 * object and pointers. This structure should get removed, and just replaced
491 * by the object structure
492 */
493
494 INTERFACE_CLASS (archetype)
495 struct archetype : zero_initialised, attachable
496 {
497 archetype ();
498 ~archetype ();
499 void gather_callbacks (AV *&callbacks, event_type event) const;
500
501 static archetype *read (object_thawer &f);
502 static archetype *get (const char *name); // find or create
503 static archetype *find (const char *name);
504
505 void hash_add (); // add to hashtable
506 void hash_del (); // remove from hashtable
507
508 shstr ACC (RW, name); /* More definite name, like "generate_kobold" */
509 struct archetype *ACC (RW, next); /* Next archetype in a linked list */
510 struct archetype *ACC (RW, head); /* The main part of a linked object */
511 struct archetype *ACC (RW, more); /* Next part of a linked object */
512 object ACC (RO, clone); /* An object from which to do ->copy_to () */
513 uint32 ACC (RW, editable); /* editable flags (mainly for editor) */
514 bool ACC (RW, linked); // linked into list of heads
515 sint8 ACC (RW, tail_x), ACC (RW, tail_y); /* Where the lower right most portion of the object is
516 * in comparison to the head.
517 */
518 };
519
520 /* Used by update_object to know if the object being passed is
521 * being added or removed.
522 */
523 #define UP_OBJ_INSERT 1
524 #define UP_OBJ_REMOVE 2
525 #define UP_OBJ_CHANGE 3
526 #define UP_OBJ_FACE 4 /* Only thing that changed was the face */
527
528 /* These are flags passed to insert_ob_in_map and
529 * insert_ob_in_ob. Note that all flags may not be meaningful
530 * for both functions.
531 * Most are fairly explanatory:
532 * INS_NO_MERGE: don't try to merge inserted object with ones alrady
533 * on space.
534 * INS_ABOVE_FLOOR_ONLY: Put object immediatly above the floor.
535 * INS_NO_WALK_ON: Don't call check_walk_on against the
536 * originator - saves cpu time if you know the inserted object
537 * is not meaningful in terms of having an effect.
538 * INS_ON_TOP: Always put object on top. Generally only needed when loading
539 * files from disk and ordering needs to be preserved.
540 * INS_BELOW_ORIGINATOR: Insert new object immediately below originator -
541 * Use for treasure chests so the new object is the highest thing
542 * beneath the player, but not actually above it. Note - the
543 * map and x,y coordinates for the object to be inserted must
544 * match the originator.
545 * INS_MAP_LOAD: disable lots of checkings done at insertion to
546 * speed up map loading process, as we assume the ordering in
547 * loaded map is correct.
548 *
549 * Note that INS_BELOW_ORIGINATOR, INS_ON_TOP, INS_ABOVE_FLOOR_ONLY
550 * are mutually exclusive. The behaviour for passing more than one
551 * should be considered undefined - while you may notice what happens
552 * right now if you pass more than one, that could very well change
553 * in future revisions of the code.
554 */
555 #define INS_NO_MERGE 0x0001
556 #define INS_ABOVE_FLOOR_ONLY 0x0002
557 #define INS_NO_WALK_ON 0x0004
558 #define INS_ON_TOP 0x0008
559 #define INS_BELOW_ORIGINATOR 0x0010
560 #define INS_MAP_LOAD 0x0020
561
562 #define ARCH_SINGULARITY "singularity"
563 #define ARCH_DETECT_MAGIC "detect_magic"
564 #define ARCH_DEPLETION "depletion"
565 #define ARCH_SYMPTOM "symptom"
566
567 #endif
568