Identify

Login to reply  Page: « < 1 of 1 > »
14 Mar 2009 - 07:511252
Identify
I am again wondering about the use of identify. When I asked about this as an offshoot of a different question, Fizban said:
Quote:
Hmm, I believe identify scrolls used to be makeable but just not castable by mortals but seems at the moment that they can't be made either.


Rumble said:
Quote:
I did remove a few spells that were implemented like you said. But identify is still stock Circle behavior. Most MUDS move it from the 200 range into the player castable/scroll usable range. Since we have done very few changes to the player aspect of CircleMUD this may be one we can look into. I know most MUDs expect to have it.


In spell_parser.c line 268 its shown in MAG_MANUAL and its shown as a non-castable spell at line 920.
In spells.c line 279, I see the command and information.
In spells.h line 111, it points out that it can only be used in scrolls or possibly by NPCs.
Shop.c line 832 seems to have an identify command along with the buy and other commands.

Is it missing somewhere else? Possibly magic.c?

Also, how hard would it be for me to make it a useable spell rather than spells and scrolls? It seems to me that it would need to be moved in spells.h from 201 to 52 and added to the total number of defined spells. It would also need to be put into class.c and the min/max mana/position in spell_parser.c would need to be changed. Would much more be needed?


14 Mar 2009 - 11:411253
As a personal choice, I've always made an identify command, and removed the spell code altogether.
Quote Parnassus:

Is it missing somewhere else? Possibly magic.c?

To answer this question, yes, you need to add a spello line in mag_assign_spells (spell_parser.c).
You will also need to 'assign' the spell to a class/level in the init_spell_levels function (class.c), if you want players to access it, although Imms should have access to all spells - just restore self (which sets all spell levels for an imm to 100%)
Finally, you should put the SPELL_IDENTIFY define (spells.h) a lower number than MAX_SPELLS. That should be it...


__________________
15 Mar 2009 - 04:281258
Perfect! Thanks.

Would making it a skill be similar? Except I guess it could go into skill 136 in spells.h since that one's currently undefined. And spell_parser.c would be skillo. Would the part that's in spells.c as ASPELL(spell_identify) go into act.other.c as ACMD(do_identify)?


23 Mar 2009 - 15:031266
Quote Parnassus:
Perfect! Thanks.

Would making it a skill be similar? Except I guess it could go into skill 136 in spells.h since that one's currently undefined. And spell_parser.c would be skillo. Would the part that's in spells.c as ASPELL(spell_identify) go into act.other.c as ACMD(do_identify)?

Yep, all of the above is correct ;)


__________________
26 Mar 2009 - 01:431276
Cool! and, well, one more question...is it hard to start up the identify code in shop.c (line 832 in my copy)? It seems to be a choice like list and buy but I don't think it's implemented but I can't see where or why it stops.


26 Mar 2009 - 09:131279
Identify in shops isn't stock behaviour, but it is very useful for players, and I have implemented this several times, although I created my own code, and am not sure whether I've shared it before, so it may be very different to your code.

My method is to add the command in SPECIAL(shopkeeper) (shop.c):
   } else if (CMD_IS("list")) {
     shopping_list(argument, ch, keeper, shop_nr);
     return (TRUE);
+  } else if (CMD_IS("identify")) {
+    return (shopping_identify(argument, ch, keeper, shop_nr));
   }
   return (FALSE);
and then to add a new shopping_identify function, which may vary from MUD to MUD, but will look something like:
bool shopping_identify(char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr)
{
  char buf[MAX_STRING_LENGTH];
  struct obj_data *obj;
  int i, found;

  if (!is_ok(keeper, ch, shop_nr))
    return FALSE;

  if (SHOP_SORT(shop_nr) < IS_CARRYING_N(keeper))
    sort_keeper_objs(keeper, shop_nr);

  if (!*arg) {
    snprintf(buf, sizeof(buf), "%s What do you want to identify??", GET_NAME(ch));
    do_tell(keeper, buf, cmd_tell, 0);
    return TRUE;
  }
  if (!(obj = get_purchase_obj(ch, arg, keeper, shop_nr, TRUE)))
    return FALSE;

  send_to_char(ch, "Name: %s\r\n", (obj->short_description) ? obj->short_description : "<None>");
  sprinttype(GET_OBJ_TYPE(obj), item_types, buf, sizeof(buf));
  send_to_char(ch, "Type: %s\r\n", buf);
  send_to_char(ch, "Weight: %d, Cost to Buy: @Y%d@n\r\n", GET_OBJ_WEIGHT(obj), sell_price(obj, shop_nr, keeper, ch));

      sprintbitarray(GET_OBJ_WEAR(obj), wear_bits, TW_ARRAY_MAX, buf);
      send_to_char(ch, "Can be worn on: %s\r\n", buf);

      switch (GET_OBJ_TYPE(obj)) {
        case ITEM_LIGHT:
          if (GET_OBJ_VAL(obj, 2) == -1)
            send_to_char(ch, "Hours Remaining: (Infinite)\r\n");
          else if (GET_OBJ_VAL(obj, 2) == 0)
            send_to_char(ch, "Hours Remaining: None!\r\n");
          else
            send_to_char(ch, "Hours Remaining: %d\r\n", GET_OBJ_VAL(obj, 2));
          break;
        case ITEM_SCROLL:
        case ITEM_POTION:
          send_to_char(ch, "Spells: %s, %s, %s\r\n",
                  skill_name(GET_OBJ_VAL(obj, 1)),
                  skill_name(GET_OBJ_VAL(obj, 2)),
                  skill_name(GET_OBJ_VAL(obj, 3)));
          break;
        case ITEM_WAND:
        case ITEM_STAFF:
          send_to_char(ch, "Spell: %s\r\n", skill_name(GET_OBJ_VAL(obj, 3)));
          send_to_char(ch, "Charges: %d/%d\r\n", GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 1));
          break;
        case ITEM_WEAPON:
            send_to_char(ch, "Damage Dice is '%dD%d' for an average per-round damage of %.1f.\r\n",
                        GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2),
                        ((GET_OBJ_VAL(obj, 2) + 1) / 2.0) * GET_OBJ_VAL(obj, 1));
		    send_to_char(ch, "Weapon Skill: %s\r\n", wskill_bits[(GET_OBJ_VAL(obj, 3))]);
            break;
        case ITEM_ARMOR:
          if(GET_OBJ_VAL(obj,1) == 0)
          {
            send_to_char(ch, "AC-apply: [%d]\r\n", GET_OBJ_VAL(obj, 0));
          }
          else
          {
            send_to_char(ch, "AC-apply: [%d] - This item has magical affects.\r\n", GET_OBJ_VAL(obj, 0));
          }
          break;
        case ITEM_CONTAINER:
          send_to_char(ch, "Capacity: %d/%d\r\n", GET_OBJ_WEIGHT(obj), GET_OBJ_VAL(obj, 0));
          break;
        case ITEM_DRINKCON:
        case ITEM_FOUNTAIN:
          send_to_char(ch, "Drinks: %d/%d\r\n", GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 0));
          break;
        case ITEM_NOTE:
          send_to_char(ch, "\r\n");
          break;
        case ITEM_KEY:
          send_to_char(ch, "\r\n");
          break;
        case ITEM_FOOD:
          send_to_char(ch, "\r\n");
          break;
        case ITEM_MONEY:
          send_to_char(ch, "\r\n");
          break;
        case ITEM_WORN:
          if(GET_OBJ_VAL(obj,1) > 0)
            send_to_char(ch, "This item has magical affects.\r\n");
          else
            send_to_char(ch, "\r\n");
          break;
        default:
          send_to_char(ch, "\r\n");
          break;
      }

      found = 0;
      send_to_char(ch, "Affections:");
      for (i = 0; i < MAX_OBJ_AFFECT; i++)
        if (obj->affected[i].modifier) {
          sprinttype(obj->affected[i].location, apply_types, buf, sizeof(buf));
          send_to_char(ch, "%s %+d to %s", found++ ? "," : "", obj->affected[i].modifier, buf);
        }
      if (!found)
        send_to_char(ch, " None");

      send_to_char(ch, "\r\nExtra Flags: ");
      sprintbitarray(GET_OBJ_EXTRA(obj), extra_bits, EF_ARRAY_MAX, buf);
      send_to_char(ch, "%s\r\n", buf);

  return TRUE;
}


__________________
27 Mar 2009 - 03:031281
Oddly, this seems to be just what I'm seeing in shop.c.

1107 } else if (CMD_IS("identify")) {
1108 return (shopping_identify(argument, ch, keeper, shop_nr));

Line 837 says this:
int i, found, atk;
while your version doesn't have the ", atk".

Your version counts hours remaining on light sources, which is much better. Yours also has more info on containers and fountains.

Stock version treats "GET_OBJ_VAL(obj, 3)" a little different but seems to come out to the same thing.

Stock version has " case ITEM_CLANARMOR:" which my reader shows as commented out although I can see the end */ but no /* at the beginning. However, if my reader recognizes it, I figure the comment must be in there somewhere. Yours doesn't have this, which seems reasonable to me.

Should I post the entire section? Considering the basics are the same, I'd think it should work unless its been removed somewhere else. Is there another section that it would need to be in?


27 Mar 2009 - 05:261282
One thing I guess you will also need is to check, is that you have an 'identify' command in the command list (interpreter.c), even if it's just a do_not_here command, like:
  { "identify" , "id"      , POS_STANDING, do_not_here , 1, 0 },

Also, I managed to find my original post here on CWG forums, which has the ITEM_CLANARMOR still intact...


__________________
27 Mar 2009 - 23:111283
That must be it then.

165 { "idea" , "id" , POS_DEAD , do_gen_write, 0, SCMD_IDEA },
166 { "imotd" , "imo" , POS_DEAD , do_gen_ps , LVL_IMMORT, SCMD_IMOTD },

so it should look like this?

165 { "idea" , "idea" , POS_DEAD , do_gen_write, 0, SCMD_IDEA },
166 { "identify" , "id" , POS_STANDING, do_not_here , 1, 0 },
167 { "imotd" , "imo" , POS_DEAD , do_gen_ps , LVL_IMMORT, SCMD_IMOTD },

Since id is often used for identify, I prefer to modify idea if that would work.
Looking at this file, I'm also thinking, if I were to make identify into a skill rather than a spell, it would need to be in here also? Since I would have needed to put ASPELL(spell_identify) into act.other.c as ACMD(do_identify), the 166 line would then be:

166 { "identify" , "id" , POS_STANDING, do_identify , 1, 0 },

I was thinking the list was alphabetical but it seems as if its actually order of "priority". Therefore:

165 { "identify" , "id" , POS_STANDING, do_identify , 1, 0 },
166 { "idea" , "idea" , POS_DEAD , do_gen_write, 0, SCMD_IDEA },
167 { "imotd" , "imo" , POS_DEAD , do_gen_ps , LVL_IMMORT, SCMD_IMOTD },

?


27 Mar 2009 - 23:441285
Yes, if you want a skill, rather than a spell, you need to add the command to the command list. The shop's identify command will override the normal one if the player is in a shop.

You are also correct about the command list. It is mostly alphabetical, but if two command begin with the same few letters, then you need to choose which command should have priority if the player types those few letters. The command that comes first in the list will have priority. I agree that identify should come before idea. This is the reason that direction commands are always right at the top of the command list, so that 's' for example, doesn't become something different, other than 'south'.


__________________
28 Mar 2009 - 02:171286
Quote Jamdog:
Quote Parnassus:
Would the part that's in spells.c as ASPELL(spell_identify) go into act.other.c as ACMD(do_identify)?

Yep, all of the above is correct ;)


It doesn't go in cleanly. Is this something easy or something hard? I copied over the ASPELL(spell_identify) renamed to ACMD(do_identify) with no other changes.

act.other.c: In function `do_identify':
act.other.c:133: error: `obj' undeclared (first use in this function)
act.other.c:133: error: (Each undeclared identifier is reported only once
act.other.c:133: error: for each function it appears in.)
act.other.c:201: error: `victim' undeclared (first use in this function)
make[1]: *** [act.other.o] Error 1


28 Mar 2009 - 15:001287
Unlike the ASPELL functions, ACMDs need to find their own targets, etc.

Look at a command like ACMD(do_open) and similar ACMDs for examples on how to get the wanted object from the "argument" string.


__________________
You know who I am.
Login to reply  Page: « < 1 of 1 > »