Real Time Crossfire Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CF: object structure layout.



Kjetil Torgrim Homme wrote:
> 
> [Mark Wedel]
> 
> >    Correct.  As of now, I believe monsters don't use most rings (or
> >   at least not the stat rings).  But the meaning of fields is
> >   currently confusing (int has some meanings in some areas, but I
> >   think it also has a general awareness of the monster
> 
> Well, removing ambiguity from the fields is one of the goals of
> redoing the structures, isn't it?  Overlapping uses should be given
> separate fields.  Things have changed since the original Crossfire
> design, we can afford 16 bytes extra in each object today.

 Yes - one of the goals is to remove the extra meanings.  After the change, if
something says 'sp', you can be sure it means sp, and not
a destination coordinate or bonus regen rate or something else.


> Using objects in the inventory scales better with new features, I
> think.  For efficiency reasons, perhaps a separate list should be used
> for non-physical objects.

 I was thinking something similar - at least for players.  A list for visible
object, and a list for invisible objects.  This makes searching for something
easier (you can know attributes or skills or whatever would be in the invis
list), and also makes logic for things like drop or client updates easier (don't
have to deal with going over invisible objects and how that syncs up)


> I think it sounds like a good idea in its own right to have that
> mechanism, so yes.  The actual meaning of having each stat set to 0
> should be discussed, though.  Does wisdom 0 mean reading spells never
> fail?

 0 stats would only be for monsters as a first note.  Player stats could not go
below 1 (which would be high failure rate of course.)

 Now the meaning of 0 stats for monsters could be tricky.  Should 0 pow mean the
monster is a non spellcaster (simply so you don't have to update all the
monsters to have a pow of 1), or does it mean there is no default, so it should
be a good spell caster?

 For some, it is easier.  A dex or con of 0 basically means no adjustment.  But
for spellcasting related stuff, it is more difficult.

Christian Stieber wrote:
>
> Make it a class hierarchy. It probably needs some thinking to put it
> into a single-inheritance hierarchy (multiple inheritance probably is
> too ugly in C).

 Without going to C++, doing to many classes/subtypes actually makes things more
complicated.

 The basically layout as I have now (from top to bottom):

 Object (includes map, x, y, face - stuff that all objects have)
Object subtypes (equipment, monster, connected - stuff from the previous
message)
Further subdivisions for a few specific objects.

 Simply put, I don't want to break things up very much - keeping them more
generic means it is easier to extend it in the future.  But the other advantage
is that the functions that then deal with the items don't have to know about the
further subdivisions (for example, the attack function only has to know how to
deal with the weapon, and not edged weapon, blunt, linked, etc)  At some point,
the subdivision would start making this more complicated (as you then have code
to check for subtype, and deal with the subtype structures)

 That said, the limited subtyping method does have some disadvantages - for some
objects, there will be unused fields (for example, the scroll vs rod - if we
assume there will be a recharge_time and a charges field, the scroll only uses
the charges and cares less about recharge_time, while the rod is opposite)

 One thing that I see immediately under your heirarchy system is how to deal
with subjects.

 for example, you have the item as a structure that includes the top level
object.  But for stuff like inventory, you need to have a pointer to what the
object is.  If you point directly to the item, then someplace you still need to
store what you are pointing to.

 So from my perspective, it is easier to have a top level object with a union of
the necessary sub item types - things like maps, inventory lists, and so on use
the top level object which then contains the type.  For example, here is the
definition as I have it:

/* To see better details about this, look at doc/objects */
typedef struct obj {
    struct obj *next;       /* Pointer to the next object in the free/used */
                            /* list */
    struct obj *prev;       /* Pointer to the previous object in the */
                            /* free/used list*/
    struct obj *active_next;    /* Next & previous object in the 'active' */
    struct obj *active_prev;    /* List.  This is used in process_events */
                                /* so that the entire object list does not */
                                /* need to be gone through. */
    struct obj *below;      /* Pointer to the object stacked below this one */
    struct obj *above;      /* Pointer to the object stacked above this one */

    struct obj *env;        /* Pointer to the object which is the environment.
                             * This is typically the container that the 
                             * object is in. */

    struct mapdef *map;     /* Pointer to the map in which this object is 
                             * present */

    struct obj *head;       /* Points to the main object of a large body */
    struct obj *more;       /* Pointer to the rest of a large body of objects */

    struct obj *arch;       /* Archetype for this */

    uint32 tag;             /* Which object unique number this is */

    char *arch_name;        /* Canonical name of the object - used internally */

    sint16 x,y;             /* Position in the map for this object */

    float speed;            /* The overall speed of this object */
    float speed_left;       /* How much speed is left to spend this round */

    /* Drawing related information */
    New_Face *face;         /* Face with colors */
    uint16 animation_id;    /* An index into the animation array */
    uint8 anim_speed;       /* ticks between animation-frames */
    uint8 last_anim; 

    uint32 direction:4;     /* Means the object is moving that way. */
    uint32 flags[4];        /* various flags */
    Object_Type type;       /* Specific item type */
    /* Make the element number lower case */
    union {
        Background  background;
        Monster     monster;
        Exit        exit;
        Effect      effect;
        Consumer    consumer;
        Container   container;
        Weapon      weapon;
        Equipment   equipment;
        SpellCaster spellcaster;
        Generator   generator;
        Player      player;
        Treasure    treasure;
        Connected   connected
    } it;
} object;

 So in a sense, things like background, monster, etc and children of the top
level object.  But this model allows things like the lists to track objects to
remain unchanged - what does change is how to interpert the values of the
subobjects.

 The disadvantage with the above method is that the object structure size is
determined by the largest subitem size.  So while there may be tons of
backgrounds, since the monster object is likely to be the biggest, you waste
space there.  But that is how things are currently done, and hopefully the
overall object size can still be kept small enough this is not a big problem
(the other solution would be to dynamically allocate the sub item information
and have pointers instead - that may be a better way to go in the long term, but
is likely to also cause more bugs - at least in the above model, if something
things it is dealing with a weapon and writes into the subitem when the object
is really a background, things may get messed up, but only for that one
background)


> Things like this. Thatīs just how I would probably do it --- but then, I
> this is just a "first idea without any thinking", so please donīt shoot
> me if it sucks :-)

 Its not an easy solution.  There are probably half a dozen ways to organize it,
and all might have advantages/disadvantages.  I'm probably going a little to
generic (disadvantage = more memory used), but the advntage is the functions
that deal with the objects need to be less specific (load/save, as well as
figuring out what abilities/bonuses specific items give out.)
-
[you can put yourself on the announcement list only or unsubscribe altogether
by sending an email stating your wishes to crossfire-request@ifi.uio.no]