Adding obj level variable

Posted by Zeno on Mon 29 Nov 2004 11:07 PM — 18 posts, 72,312 views.

USA #0
I need to have the object level variable written to the object, but when I tested it on my old server, it would be set back to 0. I'm not sure if I have to use the AREA_VERSION idea again, or just code it in. It seems simple, but is getting annoying.

In obj_index_data struct:
    sh_int              level;



In obj_data struct:
    sh_int              level;


In fwrite_obj function:
    if ( obj->level )
      fprintf( fp, "Level        %d\n", obj->level                  );


In fread_obj function:
        case 'L':
            KEY( "Level",       obj->level,             fread_number( fp ) );
            break;



reset.c:
      if ( mob->pIndexData->pShop )
      {
        //int olevel = generate_itemlevel( pArea, pObjIndex );;
        obj = create_object(pObjIndex, 1);
        xSET_BIT(obj->extra_flags, ITEM_INVENTORY);
      }
      else
        obj = create_object(pObjIndex, number_fuzzy(level));
      obj->level = URANGE(0, obj->level, LEVEL_AVATAR);


Now, either it's not saving, or it's not loading it. This is my nearly unchanged code, not the old server test.
USA #1
Does the object level work on the new server, but not the old server that doesn't have the level code in it? I'm not sure exactly what the problem is.
USA #2
If you didn't know, stock Smaug never saved item levels. It simply generated one. So I disabled the random generation, and set to 1 on the new server. On the old server, I attempted to fix that, and have obj levels save, but they are loading at level 0 after I tried.
USA #3
if ( mob->pIndexData->pShop )
      {
        //int olevel = generate_itemlevel( pArea, pObjIndex );;
        obj = create_object(pObjIndex, 1);
        xSET_BIT(obj->extra_flags, ITEM_INVENTORY);
      }
      else
        obj = create_object(pObjIndex, number_fuzzy(level));
      obj->level = URANGE(0, obj->level, LEVEL_AVATAR);
Well, if number_fuzzy(level) yields a negative number, then the URANGE will put it between 0 and LEVEL_AVATAR, hence 0.

I've never played with object levels in SMAUG, mainly because the other people who run the MUD have a very strong objection to them. :)
USA #4
Oh, I don't feel object level restrictions are too bad. If FFXI uses them, then I feel they aren't that bad. Let me get my old server up and I will see what I did.

[EDIT] Ugh, what a bad pair of sentences. Tch. You get what I mean. ;)
Amended on Mon 29 Nov 2004 11:46 PM by Zeno
USA #5
I don't particularly mind them myself, but when you're not the only admin you don't get to make that kind of decision all by yourself. :P
USA #6
Right, might as well discuss this with my other admins first. I say keep the levels, and I know some others will too. But hopefully some will bring up some good points. I'll hold off posting my code until I get some responses.
USA #7
Err, just found something out after I asked about everyone's opinion. Apparently objects that are placed on a mob via a reset are set to that mobs level, and save at that level. So objects DO save, just not through oset? I killed a lvl 64 mob, it dropped a worn item, the item level was 64. I hotbooted, stayed saved. Then I did a reboot. Stayed. Any idea..? Doesn't make much sense.

[EDIT] Hmm, so levels are saved. I checked this in my pfile:
#OBJECT
Vnum         2180
Level        64
Values       12 12 84 3 0 0
End

Amended on Tue 30 Nov 2004 12:28 AM by Zeno
USA #8
I've never looked into object levels at all so I really can't tell you what saves and what doesn't. It doesn't really surprise me that at least something saves. :-)

So what exactly is the problem, then?
USA #9
The problem is, after osetting the object's level, it won't stay. I'm going to have search for this problem. I'm guessing it's in reset.c
USA #10
The obj->level does save, but it is reset somewhere. I have yet to find where. Does anyone know?
Australia #11
I would take a look in this function, seems its totaly resoncible for levels.

int generate_itemlevel( AREA_DATA *pArea, OBJ_INDEX_DATA *pObjIndex )

Hope that helps some,

Peace.
USA #12
Nope, that doesn't have anything to do with it being set to 0.

A dragon arm:
Cost: 0  Rent: 0  Timer: 0  Level: 115 (0)

The last number is obj->pIndexData->level.
I oset it to prototype, oset it to level 64, oset it back to non-proto:
Cost: 0  Rent: 0  Timer: 0  Level: 64 (0)


As you can tell the index isn't being set.
USA #13
Hrmm. I suspect this has a large part to do with your problem of the index value not being set.

Build.c, in function do_oset:


   if( !str_cmp( arg2, "level" ) )
   {
      if( !can_omodify( ch, obj ) )
         return;
      obj->level = value;
      return;
   }


I compared this to the other cases (arguments I mean), where it checks for prototype flags and then sets the index value, and it became obvious that oset <obj> <level> never touches the index value.

I don't know if this answers your question at all about why it's reseting the index to zero, maybe that's an artifact of something else you've changed, but as far as oset'ing it and not having the index change, this appears to be the problem.

Hopefully that helps?

USA #14
This is semi-pseudo code, so you may need to change a word or two.


if( !str_cmp( arg2, "level" ) )
{
if( !can_omodify( ch, obj ) )
return;
if (xIS_SET(obj->flags, ITEM_PROTOTYPE))
obj->pIndexData->level = value;
else
obj->level = value;
return;
}

The problem with this, is all objects will be like this, i'll go look at my code and check how it is done, been a while since I had to mess with this.

--------EDIT---------
int
generate_itemlevel (AREA_DATA * pArea, OBJ_INDEX_DATA * pObjIndex)
{
int olevel;
int min = UMAX (pArea->low_soft_range, 1);
int max = UMIN (pArea->hi_soft_range, min + 15);

if (pObjIndex->level > 0)
olevel = UMIN (pObjIndex->level, MAX_LEVEL);




I believe if you change that pointer to OBJ_INDEX_DATA to OBJ_DATA and than have it check the obj->level than UMIN(obj->level, MAX_LEVEL), than change the other parts to obj->pIndexData that need to point to it, it should generate fine.
Amended on Fri 06 May 2005 10:55 AM by Txzeenath
USA #15
Yes it turns out mset wasn't setting the index var. But now if I set the index variable, save/foldarea, and hotboot, it'll reset to 0.

Level: 7 (7)
(foldarea, hotboot)
Level: 7 (0)

Does anyone know why?
USA #16
As was mentioned to me before when working out the hotboot / rare items issues, it's probably one of two broad possibilities. Either it's not saving properly and thus not being read properly back in (the level I mean) OR it is saving properly but just not reading back in properly and therefore taking the default / initial value of zero.

I realize that's no exact solution but that's all I can suggest, that maybe something is off in fread_obj or fwrite_obj somehow?

USA #17
I don't even see where it saves index data. Looking at item_type (since this saves the index):

fwrite obj:
    if ( obj->item_type != obj->pIndexData->item_type )
        fprintf( fp, "ItemType     %d\n",       obj->item_type       );


fread_obj:
            KEY( "ItemType",    obj->item_type,         fread_number( fp ) );

...
                    obj->item_type = obj->pIndexData->item_type;


Now the last line... that wouldn't be it would it? I doubt it, since each obj level is unique. (IE, if spawned off a mob its that mobs level)

Here's object level:

fwrite_obj:
    if ( obj->level )
      fprintf( fp, "Level        %d\n", obj->level                   );


fread_obj:
            KEY( "Level",       obj->level,             fread_number( fp ) );


That's it.