--- deliantra/server/include/object.h 2010/01/30 23:30:26 1.225 +++ deliantra/server/include/object.h 2011/05/03 11:23:48 1.260 @@ -1,9 +1,9 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team - * Copyright (©) 1992,2007 Frank Tore Johansen + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2001 Mark Wedel & Crossfire Development Team + * Copyright (©) 1992 Frank Tore Johansen * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the @@ -25,8 +25,6 @@ #ifndef OBJECT_H #define OBJECT_H -#include - #include "cfperl.h" #include "shstr.h" @@ -34,45 +32,37 @@ typedef int tag_t; -enum { - body_skill, - body_combat, - body_range, - body_shield, - body_arm, - body_torso, - body_head, - body_neck, - body_finger, - body_shoulder, - body_foot, - body_hand, - body_wrist, - body_waist, - NUM_BODY_LOCATIONS -}; - -enum slottype_t +// also see common/item.C +enum { - slot_none, - slot_combat, - slot_ranged, +# define def(name, use, nonuse) body_ ## name, +# include "slotinc.h" +# undef def + NUM_BODY_LOCATIONS }; /* See common/item.c */ -typedef struct Body_Locations +struct Body_Locations { - keyword save_name; /* Name used to load/save it to disk */ + const char *name; /* Short name/identifier */ + keyword kw; /* Name used to load/save it to disk */ const char *use_name; /* Name used when describing an item we can use */ const char *nonuse_name; /* Name to describe objects we can't use */ -} Body_Locations; +}; extern Body_Locations body_locations[NUM_BODY_LOCATIONS]; +// for each set of directions (1 == up, 2 == right, 4 == down, 8 == left) +// contains the wall suffix (0, 1_3, 1_4 and so on). +extern const char *wall_suffix[16]; + #define NUM_COINS 4 /* number of coin types */ extern const char *const coins[NUM_COINS + 1]; +// restart server when object_count reaches this value +#define RESTART_COUNT 0xe0000000 + /* * Each object (this also means archetypes!) could have a few of these * "dangling" from it; this could also end up containing 'parse errors'. @@ -85,10 +75,59 @@ */ struct key_value : slice_allocated { - key_value *next; + key_value *next; // must be first element shstr key, value; }; +// "crossfires version of a perl hash." +struct key_values +{ + key_value *first; // must be first element + + bool empty() const + { + return !first; + } + + void clear (); + shstr_tmp get (shstr_tmp key) const; + void del (shstr_tmp key); + void set (shstr_tmp key, shstr_tmp value); + + void add (shstr_tmp key, shstr_tmp value); // liek set, but doesn't check for duplicates + void reverse (); // reverses the ordering, to be used after loading an object + key_values &operator =(const key_values &kv); + + // custom extra fields management + struct access_proxy + { + key_values &kv; + shstr_tmp key; + + access_proxy (key_values &kv, shstr_tmp key) + : kv (kv), key (key) + { + } + + const access_proxy &operator =(shstr_tmp value) const + { + kv.set (key, value); + return *this; + } + + operator const shstr_tmp () const { return kv.get (key); } + operator const char *() const { return kv.get (key); } + + private: + void operator =(int); + }; + + const access_proxy operator [](shstr_tmp key) + { + return access_proxy (*this, key); + } +}; + //-GPL struct UUID @@ -291,14 +330,30 @@ const_utf8_string query_short_name (const object *op); const_utf8_string query_name (const object *op); const_utf8_string query_base_name (const object *op, int plural); +sint64 query_cost (const object *tmp, object *who, int flag); +const char *query_cost_string (const object *tmp, object *who, int flag); + +int change_ability_duration (object *spell, object *caster); +int min_casting_level (object *caster, object *spell); +int casting_level (object *caster, object *spell); +sint16 SP_level_spellpoint_cost (object *caster, object *spell, int flags); +int SP_level_dam_adjust (object *caster, object *spob); +int SP_level_duration_adjust (object *caster, object *spob); +int SP_level_range_adjust (object *caster, object *spob); -struct object : zero_initialised, object_copy +struct freelist_item +{ + freelist_item *next; + uint32_t count; +}; + +struct object : object_copy { // These variables are not changed by ->copy_to maptile *ACC (RW, map); /* Pointer to the map in which this object is present */ UUID ACC (RW, uuid); // Unique Identifier, survives saves etc. - int ACC (RO, count); + uint32_t ACC (RO, count); object_vector_index ACC (RO, index); // index into objects object_vector_index ACC (RO, active); // index into actives @@ -318,51 +373,27 @@ */ object *ACC (RW, more); /* Pointer to the rest of a large body of objects */ object *head; /* Points to the main object of a large body */ // NO ACC, perl semantics are different - key_value *key_values; /* Fields not explictly known by the loader. */ - // privates / perl - shstr_tmp kv_get (shstr_tmp key) const; - void kv_del (shstr_tmp key); - void kv_set (shstr_tmp key, shstr_tmp value); - -//-GPL - - // custom extra fields management - struct key_value_access_proxy + MTH void set_flag (int flagnum) { - object &ob; - shstr_tmp key; - - key_value_access_proxy (object &ob, shstr_tmp key) - : ob (ob), key (key) - { - } - - const key_value_access_proxy &operator =(shstr_tmp value) const - { - ob.kv_set (key, value); - return *this; - } - - operator const shstr_tmp () const { return ob.kv_get (key); } - operator const char *() const { return ob.kv_get (key); } - - private: - void operator =(int); - }; + flag [flagnum] = true; + } - // operator [] is too annoying to use - const key_value_access_proxy kv (shstr_tmp key) + MTH void clr_flag (int flagnum) { - return key_value_access_proxy (*this, key); + flag [flagnum] = false; } + // extra key value pairs + key_values kv; + +//-GPL + bool parse_kv (object_thawer &f); // parse kv pairs, (ab-)used by archetypes, which should not exist at all MTH void post_load_check (); // do some adjustments after parsing static object *read (object_thawer &f, maptile *map = 0); // map argument due to toal design bogosity, must go. bool write (object_freezer &f); - MTH int slottype () const; MTH static object *create (); const mapxy &operator =(const mapxy &pos); MTH void copy_to (object *dst); @@ -379,6 +410,7 @@ // recursively destroy all objects in inventory, optionally dropping them to the ground instead MTH void destroy_inv (bool drop_to_ground = false); + MTH void destroy_inv_fast (); // like destroy_inv (false), but only works when *this is destroyed, too MTH object *insert (object *item); // insert into inventory MTH void play_sound (faceidx sound) const; MTH void say_msg (const_utf8_string msg) const; @@ -399,7 +431,15 @@ insert_at (this, this); } - // high-level move functions, return true if successful + // high-level move method. + // object op is trying to move in direction dir. + // originator is typically the same as op, but + // can be different if originator is causing op to + // move (originator is pushing op) + // returns 0 if the object is not able to move to the + // desired space, 1 otherwise (in which case we also + // move the object accordingly. This function is + // very similiar to move_object. int move (int dir, object *originator); int move (int dir) @@ -407,6 +447,9 @@ return move (dir, this); } + // changes move_type to a new value - handles move_on/move_off effects + MTH void change_move_type (MoveType mt); + static bool can_merge_slow (object *op1, object *op2); // this is often used in time-critical code, so optimise @@ -420,8 +463,6 @@ MTH void set_owner (object *owner); MTH void set_speed (float speed); MTH void set_glow_radius (sint8 rad); - MTH bool change_weapon (object *ob); - MTH bool change_skill (object *ob); MTH void open_container (object *new_container); MTH void close_container () @@ -522,6 +563,8 @@ MTH bool is_dragon () const; + MTH bool is_immunity () const { return invisible && type == SIGN; } + MTH bool has_active_speed () const { return speed >= MIN_ACTIVE_SPEED; } // temporary: wether the object can be saved in a map file @@ -539,6 +582,12 @@ MTH bool has_dialogue () const { return msg_has_dialogue (&msg); } + /* need_identify returns true if the item should be identified. This + * function really should not exist - by default, any item not identified + * should need it. + */ + MTH bool need_identify () const; + // returns the outermost owner, never returns 0 MTH object *outer_owner () { @@ -602,6 +651,9 @@ return !!contr; } + /* elmex: this method checks whether the object is in a shop */ + MTH bool is_in_shop () const; + MTH bool affects_los () const { return glow_radius || flag [FLAG_BLOCKSVIEW]; @@ -612,7 +664,7 @@ return glow_radius; } - // returns the player that cna see this object, if any + // returns the player that can see this object, if any MTH object *visible_to () const; MTH std::string long_desc (object *who = 0); // query_name . " " . describe @@ -633,6 +685,12 @@ MTH void create_treasure (treasurelist *tl, int flags = 0); + // makes sure the player has the named skill, + // and also makes it innate if can_use is true. + // returns the new skill or 0 if no such skill exists. + MTH object *give_skill (shstr_cmp name, bool can_use = false); + MTH void become_follower (object *new_god); + // insert object at same map position as 'where' // handles both inventory and map "positions" MTH object *insert_at (object *where, object *originator = 0, int flags = 0); @@ -645,12 +703,19 @@ MTH void activate_recursive (); MTH void deactivate_recursive (); + // prefetch and activate the surrounding area + MTH void prefetch_surrounding_maps (); + // set the given flag on all objects in the inventory recursively MTH void set_flag_inv (int flag, int value = 1); - void enter_exit (object *exit);//Perl - MTH void enter_map (maptile *newmap, int x, int y); + void enter_exit (object *exit); // perl + MTH bool enter_map (maptile *newmap, int x, int y); void player_goto (const_utf8_string path, int x, int y); // only for players + MTH bool apply (object *ob, int aflags = AP_APPLY); // ob may be 0 + + MTH object *mark () const; + MTH void splay_marked (); // returns the mapspace this object is in mapspace &ms () const; @@ -711,13 +776,14 @@ MTH struct region *region () const; - void statusmsg (const_utf8_string msg, int color = NDI_BLACK); - void failmsg (const_utf8_string msg, int color = NDI_RED); + MTH void statusmsg (const_utf8_string msg, int color = NDI_BLACK); + MTH void failmsg (const_utf8_string msg, int color = NDI_RED); + void failmsgf (const_utf8_string format, ...); // always NDI_RED... - const_utf8_string query_inventory (object *who = 0, const_utf8_string indent = ""); + MTH const_utf8_string query_inventory (object *who = 0, const_utf8_string indent = ""); MTH const_octet_string ref () const; // creates and returns a consistent persistent object reference - static object *deref (const_octet_string ref); // returns the object from the generated refreence, if possible + static object *deref (const_octet_string ref); // returns the object from the generated reference, if possible // make some noise with given item into direction dir, // currently only used for players to make them temporarily visible @@ -739,10 +805,20 @@ MTH utf8_string as_string (); + // low-level management, statistics, ... + static uint32_t ACC (RW, object_count); + static uint32_t ACC (RW, free_count); + static uint32_t ACC (RW, create_count); + static uint32_t ACC (RW, destroy_count); + static freelist_item *freelist; + MTH static void freelist_free (int count); + protected: void link (); void unlink (); + void do_delete (); + object (); ~object (); @@ -788,7 +864,7 @@ //-GPL INTERFACE_CLASS (archetype) -struct archetype : object +struct archetype : object, zero_initialised { static arch_ptr empty; // the empty_archetype MTH static void gc (); @@ -810,16 +886,18 @@ object_vector_index ACC (RW, archid); // index in archvector shstr ACC (RW, archname); /* More definite name, like "generate_kobold" */ - sint8 ACC (RW, min_x), ACC (RW, min_y); /* extents, compared to the head (min_x, min_y should be zero, but aren't...) */ - sint8 ACC (RW, max_x), ACC (RW, max_y); + sint8 ACC (RW, max_x); /* extents, compared to the head (min_x, min_y should be zero, but aren't...) */ // support for archetype loading static archetype *read (object_thawer &f); MTH static void commit_load (); // commit any objects loaded, resolves cyclic dependencies and more static void postpone_arch_ref (arch_ptr &ref, const_utf8_string other_arch); /* postpone other_arch reference */ + +protected: + void do_delete (); }; -// returns whether the objetc is a dragon player, which are often specialcased +// returns whether the object is a dragon player, which are often specialcased inline bool object::is_dragon () const { @@ -899,6 +977,7 @@ #define INS_NO_WALK_ON 0x0004 #define INS_ON_TOP 0x0008 #define INS_BELOW_ORIGINATOR 0x0010 +#define INS_NO_AUTO_EXIT 0x0020 // temporary, fix exits instead //-GPL