#include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "mud.h" AFFECT_DATA *affect_free = NULL; RESET_DATA *reset_free = NULL; int total_fgt = 0; void affect_modify (CHAR_DATA * ch, AFFECT_DATA * paf, bool fAdd, short flaggy); extern char *ans_uppercase (const char *txt); FGT * new_fgt (void) { FGT *f; int i; total_fgt++; f = mem_alloc (sizeof (*f)); f->ears = 2; f->combat_delay_count = -1; for (i = 0; i < 4; i++) f->attackers[i] = 0; f->compliance = 25; f->master = NULL; f->leader = NULL; f->pulling = NULL; f->riding = NULL; f->mounted_by = NULL; f->hunting = NULL; f->attackers[0] = NULL; f->attackers[1] = NULL; f->attackers[2] = NULL; f->attackers[3] = NULL; f->fighting = NULL; return f; } void clear_fgt (CHAR_DATA * ch) { if (ch->fgt) { if (ch->fgt->hunting) free_string (ch->fgt->hunting); } if (ch->fgt) { free (ch->fgt); total_fgt--; } ch->fgt = NULL; return; } void check_fgt (CHAR_DATA * ch) { if (!ch->fgt) ch->fgt = new_fgt (); return; } void do_coins (CHAR_DATA * ch, char *argy) { int coinage; DEFINE_COMMAND ("coins", do_coins, POSITION_DEAD, IMM_LEVEL, LOG_ALWAYS, "Creates the specified amount of coins.") if (!is_number (argy) || argy[0] == '\0') { return; } coinage = atoi (argy); if (coinage > 0 && coinage < 1000000) create_amount (coinage, ch, NULL, NULL); return; } void no_spam (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("nospam", no_spam, POSITION_DEAD, 0, LOG_NORMAL, "Toggles between levels of spam.") if (IS_PLAYER (ch)) { ch->pcdata->no_spam = 1; send_to_char ("NoSpam mode ENABLED.\n\r", ch); send_to_char ("NOTE: You can toggle through the modes using the SPAM command.\n\r", ch); } return; } void add_to_aggro_list (CHAR_DATA * ch) { CHAR_DATA *c; if (IS_SET (ch->special, IS_IN_AGGRO_LIST) || !IS_SET(ch->act, ACT_AGGRESSIVE | ACT_ANGRY) || ch->in_room->pcs == 0) return; for (c = aggro_check; c != NULL; c = c->gen_next) { if (c == ch) return; } ch->gen_next = aggro_check; aggro_check = ch; SET_BIT (ch->special, IS_IN_AGGRO_LIST); return; } void spam (CHAR_DATA * ch, char *argy) { DEFINE_COMMAND ("spam", spam, POSITION_DEAD, 0, LOG_NORMAL, "Turns on nospam mode.") if (IS_MOB (ch)) return; if (ch->pcdata->no_spam == 0) { send_to_char ("Moderate SPAM mode enabled.\n\r", ch); ch->pcdata->no_spam = 2; return; } else if (ch->pcdata->no_spam == 1) { send_to_char ("FULL SPAM mode enabled.\n\r", ch); ch->pcdata->no_spam = 0; return; } else send_to_char ("NO SPAM mode enabled.\n\r", ch); ch->pcdata->no_spam = 1; return; } int get_race_look (char *argy) { int i; if (!str_cmp(argy, "enemy")) return 100; for (i = 0; i < RACE_COUNT; i++) { if (!str_prefix (argy, race_info[i].name)) return i; } for (i = 0; i <NUM_ALIGN; i++) { if (!str_prefix(argy, align_info[i].name)) return i+50; } return -1; } /* * Retrieve a character's age. */ int get_age (CHAR_DATA * ch) { return 18 + (((ch->pcdata->played / 2) + (((int) (current_time - ch->pcdata->logon)) / 2)) / 7200) / 4; } /* These 5 functions return the character's current stats. */ int get_stat (CHAR_DATA *ch, int num) { if (IS_MOB(ch)) return 32; return URANGE (3, (ch->pcdata->stat[num] + UMIN(2, ch->pcdata->stat_mod[num])), 32); } int get_curr_str (CHAR_DATA * ch) { return get_stat (ch, STR); } int get_curr_int (CHAR_DATA * ch) { return get_stat (ch, INT); } int get_curr_dex (CHAR_DATA * ch) { return get_stat (ch, DEX); } int get_curr_wis (CHAR_DATA * ch) { return get_stat (ch, WIS); } int get_curr_con (CHAR_DATA * ch) { return get_stat (ch, CON); } bool is_name (const char *str, char *namelist) { char name[SML_LENGTH]; if (!str_cmp (str, namelist)) return TRUE; for (;;) { if (namelist == NULL) return FALSE; if (!str_cmp(str,namelist)) return TRUE; namelist = one_argy (namelist, name); if (name[0] == '\0') return FALSE; if (!str_cmp (str, name)) return TRUE; } return FALSE; } bool is_approx_name (const char *str, char *namelist) { char name[SML_LENGTH]; if (!str_cmp (str, namelist)) return TRUE; for (;;) { if (namelist == NULL) return FALSE; namelist = one_argy (namelist, name); if (name[0] == '\0') return FALSE; if (!str_cmp (str, name)) return TRUE; if (strlen (str) > 1 && !str_prefix (str, name)) return TRUE; } return FALSE; } void affect_modify (CHAR_DATA * ch, AFFECT_DATA * paf, bool fAdd, short flagg) { int mod, i; mod = paf->modifier; if (fAdd) { for (i = 0; i < 4; i++) SET_BIT(ch->aff[i], paf->aff[i]); } else { for (i = 0; i < 4; i++) REMOVE_BIT(ch->aff[i], paf->aff[i]); mod = 0 - mod; } if(IS_PLAYER(ch)) { switch (paf->location) { default: bug ("Affect_modify: unknown location %d.", paf->location); return; case APPLY_NONE: break; case APPLY_STR: if (flagg != 1) ch->pcdata->stat_mod[STR] += mod; break; case APPLY_DEX: if (flagg != 1) ch->pcdata->stat_mod[DEX] += mod; break; case APPLY_INT: if (flagg != 1) ch->pcdata->stat_mod[INT] += mod; break; case APPLY_WIS: if (flagg != 1) ch->pcdata->stat_mod[WIS] += mod; break; case APPLY_CON: if (flagg != 1) ch->pcdata->stat_mod[CON] += mod; break; case APPLY_LCK: if (flagg != 1) ch->pcdata->stat_mod[LCK] += mod; break; case APPLY_WIL: if (flagg != 1) ch->pcdata->stat_mod[WIL] += mod; break; case APPLY_CHA: if (flagg != 1) ch->pcdata->stat_mod[CHA] += mod; break; case APPLY_RANDOM_STAT: if (flagg != 1) { paf->location = number_range(1,NUM_STATS); ch->pcdata->stat_mod[paf->location-1] += mod; } break; case APPLY_MANA: ch->pcdata->n_max_mana += mod; break; case APPLY_HIT: if (flagg != 1) ch->max_hit += mod; break; case APPLY_MOVE: if (flagg != 1) ch->max_move += mod; break; case APPLY_AC: ch->armor += mod; break; case APPLY_HITROLL: ch->hitroll += mod; break; case APPLY_DAMROLL: ch->damroll += mod; break; case APPLY_SAVING_THROW: ch->pcdata->saving_throw += mod; break; case APPLY_KICK_DAMAGE: ch->pcdata->plus_kick += mod; break; case APPLY_SNEAK: ch->pcdata->plus_sneak += mod; break; case APPLY_WARMTH: ch->pcdata->warmth += mod; break; case APPLY_HIDE: ch->pcdata->plus_hide += mod; break; } } if (IS_PLAYER (ch)) { int i; for (i = 0; i < 4; i++) { ch->aff[i] |= ch->pcdata->nat_aff[i]; ch->aff[i] |= race_info[ch->pcdata->race].aff[i]; ch->aff[i] |= align_info[ch->pcdata->alignment].aff[i]; } } return; } void affect_to_char (CHAR_DATA * ch, AFFECT_DATA * paf) { AFFECT_DATA *paf_new; long hurts = (paf->aff[HURT] &~(ch->aff[PROT])); /* In other words, hurts is all of the affect bits which are on the affect, and which the character does not have a resistance to. This seems to bea lot cleaner than the old stuff. If the character is resistant to all the affects and there were harmful affects, then the spell does not take affect. This is different than the old style where if you resist any part of the spell then you resist it all. This seems to make more sense. */ if (IS_MOB(ch)) /* Guarding mobs cannot be blinded to stop twinks :) */ { if(ch->pIndexData->guard != NULL && (IS_SET(paf->aff[HURT], BLIND))) return; } /* This says if the spell had bad affects and you resisted them all, the spell does not take affect. It also requires the other affects to not take place...so if you make a powerful affect have a bad side affect (like TP and maybe poison or something) you can still get the TP even if you resist the poison. */ if (paf->aff[HURT] && !hurts && !paf->aff[PROT] && !paf->aff[AFF] && !paf->aff[DET]) { send_to_char("You are immune! you resist the effect!\n\r", ch); return; } if (affect_free == NULL) paf_new = mem_alloc (sizeof (*paf_new)); else { paf_new = affect_free; affect_free = affect_free->next; } *paf_new = *paf; /* You change paf_new->aff[HURT] to remove the resisted bits. People will not like this. */ paf_new->aff[HURT] = hurts; paf_new->next = ch->affected; ch->affected = paf_new; affect_modify (ch, paf_new, TRUE, 0); return; } void affect_remove (CHAR_DATA * ch, AFFECT_DATA * paf) { if (ch->affected == NULL) { bug ("Affect_remove: no affect.", 0); return; } affect_modify (ch, paf, FALSE, 0); if (paf == ch->affected) { ch->affected = paf->next; } else { AFFECT_DATA *prev; for (prev = ch->affected; prev != NULL; prev = (!prev->next ? NULL : prev->next)) { if (prev->next == paf) { prev->next = paf->next; break; } } if (prev == NULL) { bug ("Affect_remove: can't find paf.", 0); return; } } paf->next = affect_free; affect_free = paf->next; return; } void strip_all_affects (CHAR_DATA * ch) { AFFECT_DATA *paf; AFFECT_DATA *paf_next; int i; for (paf = ch->affected; paf != NULL; paf = paf_next) { paf_next = paf->next; affect_remove (ch, paf); } for (i = 0; i < 4; i++) ch->aff[i] = 0; if (IS_PLAYER (ch)) { for (i = 0; i < 4; i++) { ch->aff[i] |= ch->pcdata->nat_aff[i]; ch->aff[i] |= race_info[ch->pcdata->race].aff[i]; ch->aff[i] |= align_info[ch->pcdata->alignment].aff[i]; } FIXIT (ch) } return; } void affect_strip_bits (CHAR_DATA * ch, int type, int bits) { AFFECT_DATA *paf; AFFECT_DATA *paf_next; int i; /* Two types of affect removes...first is for removing all affects from a spell that removes bits. when type == -1 the bits are the spell->gsn instead of the bits..otherwise you send the type of affect: HURT PROT AFF DET and then remove the bits. */ if (type == -1) { SPELL_DATA *spl; if ((spl = skill_lookup(NULL, bits)) == NULL) return; for (paf = ch->affected; paf != NULL; paf = paf_next) { if (!paf->next) paf_next = NULL; else paf_next = paf->next; for (i = 0; i < 4; i ++) { if (IS_SET(paf->aff[i], spl->aff[i])) { affect_remove(ch, paf); break; } } } } else if (type >= 0 && type < 4) { for (paf = ch->affected; paf != NULL; paf = paf_next) { if (!paf->next) paf_next = NULL; else paf_next = paf->next; if (IS_SET (paf->aff[type], bits)) affect_remove (ch, paf); } } if (IS_PLAYER (ch)) { for (i = 0; i < 4; i++) { ch->aff[i] |= ch->pcdata->nat_aff[i]; ch->aff[i] |= race_info[ch->pcdata->race].aff[i]; ch->aff[i] |= align_info[ch->pcdata->alignment].aff[i]; } FIXIT(ch) } return; } void affect_strip (CHAR_DATA * ch, int sn) { AFFECT_DATA *paf; AFFECT_DATA *paf_next; if (sn < 0) return; for (paf = ch->affected; paf != NULL; paf = paf_next) { if (!paf->next) paf_next = NULL; else paf_next = paf->next; if (paf->type == sn) affect_remove (ch, paf); } if (IS_PLAYER (ch)) { int i; for (i = 0; i < 4; i++) { ch->aff[i] |= ch->pcdata->nat_aff[i]; ch->aff[i] |= race_info[ch->pcdata->race].aff[i]; ch->aff[i] |= align_info[ch->pcdata->alignment].aff[i]; } FIXIT(ch) } return; } void affect_join (CHAR_DATA * ch, AFFECT_DATA * paf) { AFFECT_DATA *paf_old; bool found; if (paf->type < 0) return; if (IS_PLAYER (ch) && (IN_BATTLE (ch) || CHALLENGE (ch) == ARENA_FIGHTING)) return; found = FALSE; for (paf_old = ch->affected; paf_old != NULL; paf_old = paf_old->next) { if (paf_old->type == paf->type && paf_old->location == paf->location) { paf->duration += paf_old->duration; paf->modifier += paf_old->modifier; affect_remove (ch, paf_old); } } affect_to_char (ch, paf); return; } void remove_from_fighting_list (CHAR_DATA * ch) { CHAR_DATA *c; if (IS_SET (ch->special, IS_IN_FIGHTING_LIST)) REMOVE_BIT (ch->special, IS_IN_FIGHTING_LIST); if (ch == f_first) { f_first = ch->next_fighting; ch->next_fighting = NULL; return; } for (c = f_first; c != NULL; c = c->next_fighting) { if (c->next_fighting == ch) { c->next_fighting = ch->next_fighting; ch->next_fighting = NULL; return; } } return; } void add_to_fighting_list (CHAR_DATA * ch) { CHAR_DATA *c; CHAR_DATA *cn; if (IS_SET (ch->special, IS_IN_FIGHTING_LIST)) return; for (c = f_first; c != NULL; c = cn) { cn = c->next_fighting; if (c == ch) { fprintf (stderr, "Found %s already in fighting list without bit set!\n", NAME (c)); return; } } ch->next_fighting = f_first; f_first = ch; SET_BIT (ch->special, IS_IN_FIGHTING_LIST); return; } void remove_from_aggro_list (CHAR_DATA * ch) { CHAR_DATA *c; if (IS_SET (ch->special, IS_IN_AGGRO_LIST)) { REMOVE_BIT (ch->special, IS_IN_AGGRO_LIST); } if (ch == aggro_check) { aggro_check = ch->gen_next; ch->gen_next = NULL; } else for (c = aggro_check; c != NULL; c = c->gen_next) { if (ch == c->gen_next) { c->gen_next = ch->gen_next; ch->gen_next = NULL; return; } } return; } void char_from_room (CHAR_DATA * ch) { CHAR_DATA *pir; int kk = 0; if (!ch || ch->in_room == NULL) { return; } if (ch->fgt && ch->fgt->pulling) { send_to_char ("You stop pulling your load.\n\r", ch); ch->fgt->pulling = NULL; } if (IS_PLAYER(ch)) { ch->in_room->light -= ch->pcdata->light; ch->in_room->area->nplayer--; ch->in_room->pcs--; } else { if (IS_SET(ch->pIndexData->act4, ACT4_COMMANDSCRIPT)) ch->in_room->command_objs--; if (ch->in_room->command_objs < 0) ch->in_room->command_objs = 0; } if (ch == ch->in_room->people) { ch->in_room->people = ch->next_in_room; } else { CHAR_DATA *prev; for (prev = ch->in_room->people; prev; prev = prev->next_in_room) { if (prev->next_in_room == ch) { prev->next_in_room = ch->next_in_room; break; } } if (prev == NULL) { bug( "Char_from_room: ch not found.", 0 ); ch->in_room = NULL; ch->next_in_room = NULL; return; } } if (IS_MOB (ch) && ch->in_room->pcs == 0) remove_from_aggro_list (ch); if (IS_PLAYER (ch)) { for (pir = ch->in_room->people; pir != NULL; pir = pir->next_in_room) { if (ch->in_room->pcs == 0) { remove_from_aggro_list (pir); } if (IS_MOB (pir) && IS_HURT (pir,CHARM) && MASTER (pir) == ch) { while (ch->pcdata->pet_temp[kk] != 0) kk++; ch->pcdata->pet_temp[kk] = pir->pIndexData->vnum; ch->pcdata->pet_hps[kk] = pir->hit; ch->pcdata->pet_move[kk] = pir->move; } } } if (FIGHTING(ch)) { CHAR_DATA *vch; int i; for (i = 0; i < TOTAL_LIST; i++) { for (vch=char_list[i]; vch!=NULL; vch=vch->next) { if (FIGHTING(vch)==ch) { vch->fgt->fighting=NULL; vch->position=POSITION_STANDING; } } ch->fgt->fighting=NULL; ch->position=POSITION_STANDING; } } ch->in_room = NULL; ch->next_in_room = NULL; return; } void check_stats (CHAR_DATA * ch) { int i; if (IS_MOB(ch)) return; for (i = 0; i < NUM_STATS; i++) { if (ch->pcdata->stat[i] > race_info[ch->pcdata->race].limits[i]) ch->pcdata->stat[i] = race_info[ch->pcdata->race].limits[i]; } return; } void remove_char_from_list (CHAR_DATA *ch) { if (!ch || ch->list == TOTAL_LIST + 1) return; if (ch == char_list[ch->list]) { char_list[ch->list] = ch->next; if (char_list[ch->list]) char_list[ch->list]->prev = NULL; } else { if (ch->prev && ch->next) { ch->prev->next = ch->next; ch->next->prev = ch->prev; } else if (ch->prev) { ch->prev->next = ch->next; } else if (ch->next) { fprintf (stderr, "Error removing mob from list with no prev!\n"); } } ch->next = NULL; ch->prev = NULL; ch->list = TOTAL_LIST + 1; return; } void add_char_to_list (CHAR_DATA *ch) { if (!ch) return; if (ch->list != TOTAL_LIST + 1) { remove_char_from_list (ch); } ch->list = (IS_PLAYER (ch) ? PLAYER_LIST : (ch->in_room ? (ch->in_room->area->nplayer > 0 ? (ch->pIndexData->vnum % MOB_LIST) : MOB_LIST) : TOTAL_LIST)); ch->prev = NULL; if (char_list[ch->list]) char_list[ch->list]->prev = ch; ch->next = char_list[ch->list]; char_list[ch->list] = ch; return; } void char_to_room (CHAR_DATA * ch, ROOM_DATA * oneroom) { bool neww; neww = FALSE; if (!oneroom) oneroom = get_room_index(2); if ((IS_SET(oneroom->room_flags,ROOM_INDOORS | ROOM_UNDERGROUND) || (oneroom->sector_type >= SECT_CAVE)) && IS_AFF(ch, FLYING) && (ch->height > INDOOR_FLY_HEIGHT)) { send_to_char("You cannot fly while indoors.\n\r",ch); do_land(ch,""); } if (ch->in_room) { char_from_room (ch); } if (oneroom->area && IS_PLAYER (ch) && IS_OPEN (oneroom->area) && (ch->pcdata->level > 100 && ch->pcdata->level < 105)) { send_to_char ("You have no reasons to be in an open area...\n\r", ch); send_to_char ("If you are a god, you may check out characters using the snoop\n\r", ch); send_to_char ("command. Please stay in your zone or another closed area.\n\r", ch); if (LEVEL(ch)<100) oneroom = get_room_index (3); else oneroom = get_room_index (2); } else { if (oneroom->area && !IS_OPEN (oneroom->area) && IS_PLAYER (ch) && ch->pcdata->level < 101) { send_to_char ("You may not go to unopened areas. Sorry!\n\r", ch); oneroom = get_room_index (3); } } if (IS_PLAYER (ch) && !IS_SET (ch->act, PLR_HOLYWALK)) { if (oneroom->vnum >= 100 && oneroom->vnum < (NUM_ALIGN-1+100)) { DESCRIPTION_DATA *ded; char *cp; char kw[500]; char argo[SML_LENGTH]; FIXIT(ch); fix_char(ch); natural_mana (ch); for (ded = oneroom->extra_descr; ded != NULL; ded = ded->next) { if (!ded->keyword || ded->keyword[0] == '\0') continue; strcpy (kw, ded->keyword); cp = one_argy (kw, argo); if (is_number (argo) && is_number (cp)) { int racenum; int roomvn; ROOM_DATA *nr; racenum = atoi (argo); roomvn = atoi (cp); if (racenum >= 0 && racenum <= RACE_COUNT && racenum == ch->pcdata->race && (nr = get_room_index (roomvn)) != NULL && (nr->vnum < 100 && nr->vnum > (100+NUM_ALIGN-1))) { char_to_room (ch, nr); return; } } } } } if (IS_PLAYER (ch) && ch->in_room) { CHAR_DATA *d; for (d = ch->in_room->people; d != NULL; d = d->next_in_room) { if (IS_MOB (d)) { add_to_aggro_list (d); } if (d == ch) { ch->in_room = oneroom; return; } } } if (IS_PLAYER (ch) && oneroom) { CHAR_DATA *d; for (d = oneroom->people; d != NULL; d = d->next_in_room) { if (IS_MOB (d)) add_to_aggro_list (d); if (d == ch) { fprintf (stderr, "UGH!\n"); ch->in_room = oneroom; return; } } } if (oneroom == NULL) { bug ("Char_to_room: NULL.", 0); return; } ch->in_room = oneroom; if (IS_PLAYER (ch)) { int kk; if (pet_flag) for (kk = 0; kk < 20; kk++) ch->pcdata->pet_temp[kk] = 0; ch->in_room->area->nplayer++; ch->in_room->pcs++; } if (IS_MOB (ch) && ch->in_room->pcs > 0) add_to_aggro_list (ch); if (oneroom->people != ch) { ch->next_in_room = oneroom->people; oneroom->people = ch; } if (IS_PLAYER(ch)) { if (oneroom->vnum >= BATTLEGROUND_START_VNUM && oneroom->vnum <= BATTLEGROUND_END_VNUM) { ch->pcdata->battleground = BATTLE_FIGHTING; } else { ch->pcdata->battleground = 0; ch->pcdata->wasroom = oneroom->vnum; } oneroom->light +=ch->pcdata->light; } else { if (IS_SET(ch->pIndexData->act4, ACT4_COMMANDSCRIPT)) ch->in_room->command_objs++; add_char_to_list (ch); } if (IS_PLAYER(ch) && IS_SET(ch->pcdata->act2, PLR_MAPPING)) { small_map(ch); } return; } SINGLE_OBJECT * get_item_held (CHAR_DATA * ch, int itype) { int i; int num_hands = UMIN(MAX_HOLD,(IS_MOB(ch) ? 1 : race_info[ch->pcdata->race].parts[3])*2); for (i = 0; i < num_hands; i++) { if (ch->hold[i] != NULL && ch->hold[i]->pIndexData->item_type == itype) return ch->hold[i]; } return NULL; } SINGLE_OBJECT * get_eq_char (CHAR_DATA * ch, int wear_loc, int wear_num) { SINGLE_OBJECT *obj; for (obj = ch->carrying; obj != NULL; obj = obj->next_content) { if (worn_flags[obj->wear_loc].flagname == wear_loc && (obj->wear_num == wear_num)) return obj; } return NULL; } /* * Equip a char with an obj. */ void equip_char (CHAR_DATA * ch, SINGLE_OBJECT * obj, int wear_loc, int wear_num) { AFFECT_DATA *paf; SINGLE_OBJECT *prev; int bitty; if (obj->pIndexData->item_type == ITEM_ARMOR) { if (obj->size < 1) SET_OBJ_SIZE (ch, obj); if (!OBJ_FITS (obj, ch)) { char tmpb[1000]; bool plural; plural = (obj->pIndexData->short_descr[strlen (obj->pIndexData->short_descr) - 1] == 's'); if (OBJ_TOO_BIG (obj, ch)) { sprintf (tmpb, "%s\x1B[37;0m %s too big and just fall%s off!\n\r", capitalize (obj->pIndexData->short_descr), (plural ? "are" : "is"), (plural ? "" : "s")); send_to_char (tmpb, ch); } else { sprintf (tmpb, "%s\x1B[37;0m %s too small for you to wear!\n\r", capitalize (obj->pIndexData->short_descr), (plural ? "are" : "is")); send_to_char (tmpb, ch); } return; } } obj->wear_loc = wear_loc; obj->wear_num = wear_num; /* Remove the object from the carrying list. */ if(obj == ch->carrying) { ch->carrying = obj->next_content; obj->next_content = NULL; prev = NULL; } else { for (prev = ch->carrying; prev != NULL; prev = prev->next_content) { if (prev->next_content == obj) { prev->next_content = obj->next_content; obj->next_content = NULL; break; } } } /* If ch was not carrying anything, or the first item is not worn or the first item is worn but a greater number...we put the new item first. */ if (!ch->carrying || (ch->carrying && (ch->carrying->wear_loc == WEAR_NONE || ch->carrying->wear_loc > wear_loc))) { obj->next_content = ch->carrying; ch->carrying = obj; } else /* Otherwise the top item exists and is worn and its wearing number is <= that of the new obj. */ { for (prev = ch->carrying; prev != NULL; prev = prev->next_content) { /* Now we look for an object that either has nothing following or if it does have something following, then the object following is not worn or its wear_loc is >= that of obj. */ if (!prev->next_content || (prev->next_content && (prev->next_content->wear_loc == WEAR_NONE || prev->next_content->wear_loc > wear_loc))) { obj->next_content = prev->next_content; prev->next_content = obj; break; } } } if (worn_flags[wear_loc].flagname == ITEM_WIELD) { ch->hold[wear_num] = obj; } if (IS_PLAYER(ch)) { if(obj->pIndexData->item_type == ITEM_ARMOR) { I_ARMOR *r = (I_ARMOR *) obj->more; if (r->max_condition == 0) { ch->pcdata->armor[0] += (r->protects_body); ch->pcdata->armor[1] += (r->protects_head); ch->pcdata->armor[2] += (r->protects_legs); ch->pcdata->armor[3] += (r->protects_arms); } else { ch->pcdata->armor[2] += (r->protects_legs * r->condition_now) / (r->max_condition); ch->pcdata->armor[0] += (r->protects_body * r->condition_now) / (r->max_condition); ch->pcdata->armor[1] += (r->protects_head * r->condition_now) / (r->max_condition); ch->pcdata->armor[3] += (r->protects_arms * r->condition_now) / (r->max_condition); } ch->pcdata->warmth += r->warmth; if (ch->pcdata->warmth < 0) ch->pcdata->warmth = 0; } if (worn_flags[wear_loc].flagname == ITEM_WEAR_FEET) SET_BIT(ch->act, PLR_HAS_SHOES); if (worn_flags[wear_loc].flagname == ITEM_WEAR_SHIELD) SET_BIT(ch->act, PLR_HAS_SHIELD); if (obj->pIndexData->item_type == ITEM_VEHICLE && obj->wear_loc > WEAR_NONE) { I_VEHICLE *veh = (I_VEHICLE *) obj->more; if (veh->sector_use == SECT_SNOW) SET_BIT(ch->act, PLR_HAS_SNOWSHOES); if (veh->sector_use == SECT_UNDERWATER) SET_BIT(ch->act, PLR_HAS_SCUBA); if (veh->sector_use == SECT_MOUNTAIN) SET_BIT(ch->act, PLR_HAS_MTN_BOOTS); } if (obj->pIndexData->item_type == ITEM_GEM && worn_flags[wear_loc].flagname == ITEM_WIELD ) { act ("As you hold $p in your hand, its energy drains.", ch, obj, NULL, TO_CHAR); act ("...You slowly start to feel the gem get used to your hand and it begins", ch, obj, NULL, TO_CHAR); act ("to power up for use. Use the examine command to check it's power.", ch, obj, NULL, TO_CHAR); ((I_GEM *) obj->more)->mana_now = 0; ch->pcdata->n_mana = 0; } if (obj->pIndexData->item_type == ITEM_SHIELD) { send_to_char("As the powershield floats about your head, all power drains from it...\n\r", ch); ((I_SHIELD *)obj->more)->current_power = 0; } bitty = 0; if (!IS_AFF (ch, FLYING)) bitty = 1; for (paf = obj->pIndexData->affected; paf != NULL; paf = ((!paf->next) ? NULL : paf->next)) affect_modify (ch, paf, TRUE, 0); if (obj->affected != NULL) for (paf = obj->affected; paf != NULL; paf = ((!paf->next) ? NULL : paf->next)) affect_modify (ch, paf, TRUE, 0); if (IS_AFF (ch, FLYING) && bitty == 1) REMOVE_BIT (ch->aff[AFF], FLYING); ++ch->pcdata->light; if (ch->move > ch->max_move) ch->move = ch->max_move; } return; } int hand_empty (CHAR_DATA * ch) { int i; int arm_pairs = (IS_MOB(ch) ? 1 : race_info[ch->pcdata->race].parts[3]); for (i = 0; i < arm_pairs*2; i++) { if (ch->hold[i] == NULL) return i; } return WEAR_NONE; } bool unequip_char (CHAR_DATA * ch, SINGLE_OBJECT * obj) { AFFECT_DATA *paf; int amt; SINGLE_OBJECT *objs; if (worn_flags[obj->wear_loc].flagname != ITEM_WEAR_BELT && obj->wear_loc != WEAR_NONE) { for (paf = obj->pIndexData->affected; paf != NULL; paf = ((!paf->next) ? NULL : paf->next)) affect_modify (ch, paf, FALSE, 0); for (paf = obj->affected; paf != NULL; paf = ((!paf->next) ? NULL : paf->next)) affect_modify (ch, paf, FALSE, 0); } if (worn_flags[obj->wear_loc].flagname == ITEM_WIELD) ch->hold[obj->wear_num] = NULL; if (IS_PLAYER(ch)) { if (worn_flags[obj->wear_loc].flagname == ITEM_WEAR_FEET) REMOVE_BIT(ch->act, PLR_HAS_SHOES); if (worn_flags[obj->wear_loc].flagname == ITEM_WEAR_SHIELD) REMOVE_BIT(ch->act, PLR_HAS_SHIELD); if (obj->pIndexData->item_type == ITEM_VEHICLE) { I_VEHICLE *veh = (I_VEHICLE *) obj->more; if (veh->sector_use == SECT_SNOW) REMOVE_BIT(ch->act, PLR_HAS_SNOWSHOES); if (veh->sector_use == SECT_UNDERWATER) REMOVE_BIT(ch->act, PLR_HAS_SCUBA); if (veh->sector_use == SECT_MOUNTAIN) REMOVE_BIT(ch->act, PLR_HAS_MTN_BOOTS); } if (obj->pIndexData->item_type == ITEM_GEM) { if (((I_GEM *) obj->more)->mana_now < 0) { amt=UMIN((0-((I_GEM *) obj->more)->mana_now),ch->pcdata->n_mana); ((I_GEM *) obj->more)->mana_now+=amt; ch->pcdata->n_mana-=amt; } } if (obj->pIndexData->item_type == ITEM_LIGHT && IS_LIT (obj)) { if (ch->in_room != NULL) { ch->in_room->light--; if (IS_PLAYER(ch)) ch->pcdata->light--; } } if(obj->pIndexData->item_type == ITEM_ARMOR) { I_ARMOR *r = (I_ARMOR *) obj->more; if (r->max_condition == 0) { ch->pcdata->armor[0] -= (r->protects_body); ch->pcdata->armor[1] -= (r->protects_head); ch->pcdata->armor[2] -= (r->protects_legs); ch->pcdata->armor[3] -= (r->protects_arms); } else { ch->pcdata->armor[2] -= (r->protects_legs * r->condition_now) / (r->max_condition); ch->pcdata->armor[0] -= (r->protects_body * r->condition_now) / (r->max_condition); ch->pcdata->armor[1] -= (r->protects_head * r->condition_now) / (r->max_condition); ch->pcdata->armor[3] -= (r->protects_arms * r->condition_now) / (r->max_condition); } ch->pcdata->warmth -= r->warmth; if (ch->pcdata->warmth < 0) ch->pcdata->warmth = 0; } } /* If the object we unequip is the first, remove it and make the obj_list start at 2nd object. */ if(obj == ch->carrying) { ch->carrying = obj->next_content; obj->next_content = NULL; } if (ch->carrying == NULL) { ch->carrying = obj; obj->next_content = NULL; } else { for (objs = ch->carrying; objs != NULL; objs = objs->next_content) { /* Pop obj from the linked list... */ if (objs->next_content == obj) { objs->next_content = obj->next_content; obj->next_content = NULL; } } for(objs = ch->carrying; objs != NULL; objs = objs->next_content) { if (objs->wear_loc > WEAR_NONE) { if (objs->pIndexData->item_type == ITEM_ARMOR) { if (worn_flags[objs->wear_loc].flagname == ITEM_WEAR_FEET) SET_BIT(ch->act, PLR_HAS_SHOES); if (worn_flags[objs->wear_loc].flagname == ITEM_WEAR_SHIELD) SET_BIT(ch->act, PLR_HAS_SHIELD); } else if (obj->pIndexData->item_type == ITEM_VEHICLE) { I_VEHICLE *veh = (I_VEHICLE *) obj->more; if (veh->sector_use == SECT_SNOW) SET_BIT(ch->act, PLR_HAS_SNOWSHOES); if (veh->sector_use == SECT_UNDERWATER) SET_BIT(ch->act, PLR_HAS_SCUBA); if (veh->sector_use == SECT_MOUNTAIN) SET_BIT(ch->act, PLR_HAS_MTN_BOOTS); } } /* If we are at the end of the linked list, slap obj back in. */ if (objs->next_content == NULL) { objs->next_content = obj; obj->next_content = NULL; break; } } } obj->wear_loc = WEAR_NONE; obj->wear_num = WEAR_NONE; return TRUE; } int count_obj_list (OBJ_PROTOTYPE * pObjIndex, SINGLE_OBJECT * list) { SINGLE_OBJECT *obj; int nMatch; nMatch = 0; for (obj = list; obj != NULL; obj = obj->next_content) { if (obj->next_content && obj == obj->next_content) { fprintf (stderr, "Endless object pointers called in count_obj_list\n"); exit (15); } if (obj->pIndexData == pObjIndex) nMatch++; } return nMatch; } void extract_char (CHAR_DATA * ch, bool fPull) { CHAR_DATA *wch; SINGLE_OBJECT *obj; SINGLE_OBJECT *obj_next; ROOM_DATA *ir; DESCRIPTOR_DATA *d; int i; if (IS_MOB(ch)) clear_tracks (ch); if (fPull) die_follower (ch); ir = ch->in_room; if (ch->in_room) stop_fighting (ch, TRUE); if (ch->in_room) char_from_room (ch); if (IS_PLAYER(ch)) { if(ch->pcdata->guarding != NULL) { for(i = 0; i < 4; i++) { if(IS_PLAYER(ch->pcdata->guarding)) if (ch->pcdata->guarding->pcdata->guarded_by[i] == ch) ch->pcdata->guarding->pcdata->guarded_by[i] = NULL; } ch->pcdata->guarding = NULL; } for (i = 0; i < 4; i++) { if(ch->pcdata->guarded_by[i] != NULL) { if (IS_PLAYER(ch->pcdata->guarded_by[i])) ch->pcdata->guarded_by[i]->pcdata->guarding = NULL; ch->pcdata->guarded_by[i] = NULL; } } } else { remove_from_aggro_list(ch); } if (RIDING (ch) != NULL) { check_fgt (ch->fgt->riding); ch->fgt->riding->fgt->mounted_by = NULL; ch->fgt->riding = NULL; } if (MOUNTED_BY (ch) != NULL) { check_fgt (ch->fgt->mounted_by); ch->fgt->mounted_by->fgt->riding = NULL; ch->fgt->mounted_by = NULL; } if (IS_MOB (ch) && ch->society) { SOCIETY_DATA *soc; int jj, rank; if ((soc = society_lookup (NULL, ch->society)) != NULL) { for (jj = 0; jj < NUM_CASTES; jj++) { if (soc->caste[jj] && ((rank = (ch->pIndexData->vnum - soc->caste[jj]->mob_start_vnum)) >= 0) && rank < soc->caste[jj]->num_ranks) { soc->caste[jj]->curr_pop[rank]--; if (soc->caste[jj]->curr_pop[rank] < 0) soc->caste[jj]->curr_pop[rank] = 0; break; } } } ch->society = 0; } if (IS_PLAYER (ch) && ch->desc != NULL && ch->desc->original != NULL) do_return (ch, ""); if (fPull) { SCRIPT_INFO *si; SCRIPT_INFO *si_next; for (si = info_list; si != NULL; si = si_next) { si_next = si->next; if (si->current == ch || si->mob == ch) { end_script (si); } } for (i = 0; i < TOTAL_LIST; i++) { for (wch = char_list[i]; wch != NULL; wch = wch->next) { if (wch->fgt) { if (MASTER (wch) == ch) wch->fgt->master = NULL; if (LEADER (wch) == ch) wch->fgt->leader = NULL; if (RIDING (wch) == ch) wch->fgt->riding = NULL; if (MOUNTED_BY (wch) == ch) wch->fgt->mounted_by = NULL; } if (wch->pcdata && wch->pcdata->reply == ch) wch->pcdata->reply = NULL; } } remove_char_from_list (ch); if (IS_PLAYER (ch)) { for (d = descriptor_list; d != NULL; d = d->next) { if (d->character && d->connected == CON_PEDITOR && ch == (CHAR_DATA *) d->pEdit) { ch->in_room = ir; return; } } } if (ch == debugger) debugger = NULL; for (obj = ch->carrying; obj != NULL; obj = obj_next) { obj_next = obj->next_content; free_it (obj); } } if (IS_PLAYER (ch) && !fPull) { ch->pcdata->condition[COND_FULL] = 55; ch->pcdata->condition[COND_THIRST] = 55; ch->pcdata->condition[COND_DRUNK] = 0; } if (!fPull) { strip_all_affects (ch); char_to_room(ch, get_room_index(ch->pcdata->alignment+100)); WAIT_STATE(ch, 5*PULSE_VIOLENCE); return; } if (IS_MOB (ch)) { --ch->pIndexData->count; } if (IS_PLAYER (ch) && ch->desc) ch->desc->character = NULL; free_it (ch); return; } CHAR_DATA * get_char_room (CHAR_DATA * ch, char *argy) { static char arg[500]; CHAR_DATA *rch; int RCLOOK; int number; /*char buf[50]; */ int count; RCLOOK = 0; if (ch == NULL || !ch->in_room) return NULL; arg[0] = '\0'; number = number_argy (argy, arg); count = 0; if (!ch->in_room) return NULL; if (!str_cmp (arg, "self")) return ch; if (!str_cmp (arg, "me")) return ch; RCLOOK = get_race_look(arg); /*Mobs FIRST */ for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room) { if (!rch->in_room) continue; if (IS_PLAYER (rch)) continue; if (!can_see (ch, rch) || (!is_approx_name (arg, RNAME (rch)) && str_prefix (arg, RNAME (rch)))) continue; if (++count == number) return rch; } if (RCLOOK != -1) { for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room) { if (!rch->in_room) continue; if (LEVEL(rch) == MAX_LEVEL) continue; if (!can_see (ch, rch) || IS_MOB (rch) || IS_MOB (ch)) continue; if (LEVEL(rch) == MAX_LEVEL) continue; if (rch == ch) continue; if (!DIFF_ALIGN(ch, rch)) continue; if (RCLOOK < 100) { if (RCLOOK >= 50) { if (ALIGN(rch) != (RCLOOK - 50)) continue; } else { if (rch->pcdata->race != RCLOOK) continue; } } if (++count == number) return rch; } } { for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room) { if (!rch->in_room) continue; if (!can_see (ch, rch) || (!is_name (arg, RNAME (rch)) && str_prefix (arg, RNAME (rch)))) continue; if (IS_MOB (rch) && !IS_SET (ch->act, PLR_HOLYLIGHT) && IS_SET (rch->pIndexData->act3, ACT3_MIMIC)) continue; if (arg[0] == '\0' && IS_PLAYER(rch)) continue; if (++count == number) return rch; } } return NULL; } CHAR_DATA * get_char_room_near (CHAR_DATA *ch, ROOM_DATA *in_room, int range, char * argy) { if (!ch || !in_room) return NULL; return get_char_room_near2 (ch, in_room, range,argy, 9999); } CHAR_DATA * get_char_room_near2 (CHAR_DATA * ch, ROOM_DATA *in_room, int range, char *argy, int direction) { static char arg[500]; char argg[SML_LENGTH]; CHAR_DATA *rch = NULL; int RCLOOK = 0; int number; int count; int door; ROOM_DATA *troom; EXIT_DATA *pexit; bool people = FALSE; if(in_room == NULL) return NULL; if (ch == NULL) return NULL; if (range < 0) return NULL; else range--; arg[0] = '\0'; strcpy(argg, argy); number = number_argy (argy, arg); count = 0; if (!str_cmp (arg, "self")) { return ch; } if (!str_cmp (arg, "me")) { return ch; } RCLOOK = get_race_look(arg); /*Mobs FIRST */ if (!in_room) { return NULL; } for (rch = in_room->people; rch != NULL; rch = rch->next_in_room) { people = TRUE; if (IS_PLAYER (rch)) continue; if (!can_see (ch, rch) || (!is_approx_name (arg, RNAME (rch)) && str_prefix (arg, RNAME (rch)))) continue; if (++count == number) { return rch; } } if (RCLOOK != -1) { for (rch = in_room->people; rch != NULL; rch = rch->next_in_room) { if (!can_see (ch, rch) || IS_MOB (rch)) continue; if (LEVEL(rch) == MAX_LEVEL) continue; if (rch == ch) continue; if (!DIFF_ALIGN(ch, rch)) continue; if (RCLOOK < 100) { if (RCLOOK >= 50) { if (ALIGN(rch) != (RCLOOK - 50)) continue; } else { if (rch->pcdata->race != RCLOOK) continue; } } if (++count == number) { return rch; } } } for (rch = in_room->people; rch != NULL; rch = rch->next_in_room) { if (!can_see (ch, rch) || (!is_name (arg, RNAME (rch)) && str_prefix (arg, RNAME (rch)))) continue; if (arg[0] == '\0' && IS_PLAYER(rch)) continue; if (++count == number) { return rch; } } if (direction == 9999) { for (door = 0; ((door < MAX_DIR)); door++) { if ((pexit = in_room->exit[door]) != NULL && (troom = in_room->exit[door]->to_room) != NULL && (!pexit->d_info || !IS_SET(pexit->d_info->exit_info, EX_CLOSED))) { if ((rch = get_char_room_near2 (ch, troom, range, argg, door)) != NULL) return rch; } else rch = NULL; } } if (direction >= 0 && direction < MAX_DIR) { if (!people && (pexit = in_room->exit[direction]) != NULL && (troom = in_room->exit[direction]->to_room) != NULL && (!pexit->d_info || !IS_SET(pexit->d_info->exit_info, EX_CLOSED))) { if (( rch = get_char_room_near2 (ch, troom, range, argg, direction)) != NULL) return rch; } else rch = NULL; } return NULL; } /* Find a player in the world */ CHAR_DATA * get_player_world (CHAR_DATA * ch, char *argy, bool need_see) { char arg[SML_LENGTH]; CHAR_DATA *wch; DESCRIPTOR_DATA *dd; int number; int count; if (!ch || !ch->in_room) return NULL; if ((wch = get_char_room (ch, argy)) != NULL) return wch; number = number_argy (argy, arg); count = 0; for (dd = descriptor_list; dd != NULL; dd = dd->next) { if (dd->character == NULL) continue; if (dd->connected > 0) continue; wch = dd->character; if (!wch->in_room) continue; if ((need_see && !can_see (ch, wch)) || !is_approx_name (arg, RNAME (wch)) || (ch->in_room && wch->in_room && wch->in_room->area != ch->in_room->area)) continue; if (++count == number) return wch; } number = number_argy (argy, arg); count = 0; for (dd = descriptor_list; dd != NULL; dd = dd->next) { if (dd->character == NULL) continue; if (dd->connected > 0) continue; wch = dd->character; if (!wch->in_room) continue; if ((need_see && !can_see (ch, wch)) || !is_name (arg, RNAME (wch))) continue; if (++count == number) return wch; } return NULL; } ONLINE * /* JRAJRA - stuff to check the online list for people */ check_online (ONLINE *victim, char* argy) { bool found = FALSE; ONLINE *online; ONLINE *onlinenx; int ll = 0; for (online = been_online; onlinenx != NULL && !found ; online = onlinenx) { onlinenx = online->next; ll++; if (!str_cmp(online->name,argy)) { return online; } if (ll > 1000) break; } return NULL; } CHAR_DATA * get_char_world (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *wch; int number, i, count; if (!ch->in_room) return NULL; if ((wch = get_char_room (ch, argy)) != NULL) return wch; if ((wch = get_player_world (ch, argy, TRUE)) != NULL) return wch; number = number_argy (argy, arg); count = 0; number = number_argy (argy, arg); count = 0; for (i = 0; i < TOTAL_LIST; i++) { for (wch = char_list[i]; wch != NULL; wch = wch->next) { if (!wch->in_room) continue; if (wch->desc && wch->desc > 0) continue; if (!can_see (ch, wch) || !is_name (arg, RNAME (wch))) continue; if (++count == number) return wch; } } return NULL; } CHAR_DATA * get_char_world_2 (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; CHAR_DATA *wch; int number, i, count; if (!ch->in_room) return NULL; if ((wch = get_char_room (ch, argy)) != NULL) return wch; if ((wch = get_player_world (ch, argy, FALSE)) != NULL) return wch; number = number_argy (argy, arg); count = 0; for (i = 0; i < TOTAL_LIST; i++) { for (wch = char_list[i]; wch != NULL; wch = wch->next) { if (!wch->in_room) continue; if (!is_name (arg, RNAME (wch)) && str_cmp (arg, NAME (wch))) continue; if (++count == number) return wch; } } return NULL; } SINGLE_OBJECT * get_obj_type (OBJ_PROTOTYPE * pObjIndex) { SINGLE_OBJECT *obj; int i; for (i = 0; i < 2; i++) { for (obj = object_list[i]; obj != NULL; obj = obj->next) { if (obj->pIndexData == pObjIndex) return obj; } } return NULL; } SINGLE_OBJECT * get_obj_list (CHAR_DATA * ch, char *argy, SINGLE_OBJECT * list) { char arg[SML_LENGTH]; SINGLE_OBJECT *obj; int number; int count; number = number_argy (argy, arg); count = 0; for (obj = list; obj != NULL; obj = obj->next_content) { if (can_see_obj (ch, obj) && is_name (arg, obj->pIndexData->name)) { if (++count == number) return obj; } } return NULL; } SINGLE_OBJECT * get_obj_carry (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; SINGLE_OBJECT *obj; int number; int count; number = number_argy (argy, arg); count = 0; for (obj = ch->carrying; obj != NULL; obj = obj->next_content) { if ((obj->wear_loc == WEAR_NONE) && (obj->pIndexData->item_type == ITEM_FOOD || obj->pIndexData->item_type == ITEM_PILL || can_see_obj (ch, obj)) && is_name (arg, obj->pIndexData->name)) { if (++count == number) return obj; } } for (obj = ch->carrying; obj != NULL; obj = obj->next_content) { if ((obj->wear_loc == WEAR_NONE) && (obj->pIndexData->item_type == ITEM_FOOD || obj->pIndexData->item_type == ITEM_PILL || can_see_obj (ch, obj)) && is_approx_name (arg, obj->pIndexData->name)) { if (++count == number) return obj; } } return NULL; } SINGLE_OBJECT * get_obj_wear (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; SINGLE_OBJECT *obj; int number; int count; number = number_argy (argy, arg); count = 0; for (obj = ch->carrying; obj != NULL; obj = obj->next_content) { if (obj->wear_loc != WEAR_NONE && can_see_obj (ch, obj) && is_name (arg, obj->pIndexData->name)) { if (++count == number) return obj; } } for (obj = ch->carrying; obj != NULL; obj = obj->next_content) { if (obj->wear_loc != WEAR_NONE && can_see_obj (ch, obj) && is_approx_name (arg, obj->pIndexData->name)) { if (++count == number) return obj; } } return NULL; } SINGLE_OBJECT * get_obj_inv (CHAR_DATA * ch, char *argy) { SINGLE_OBJECT *obj; if ((obj = get_obj_carry (ch, argy)) != NULL) return obj; if ((obj = get_obj_wear (ch, argy)) != NULL) return obj; return NULL; } SINGLE_OBJECT * get_obj_here (CHAR_DATA * ch, char *argy, int lookfirst) { SINGLE_OBJECT *obj; if (lookfirst == SEARCH_ROOM_FIRST) { obj = get_obj_list (ch, argy, ch->in_room->contents); if (obj != NULL) return obj; if ((obj = get_obj_inv (ch, argy)) != NULL) return obj; return NULL; } else if (lookfirst == SEARCH_INV_FIRST) { if ((obj = get_obj_inv (ch, argy)) != NULL) return obj; obj = get_obj_list (ch, argy, ch->in_room->contents); if (obj != NULL) return obj; return NULL; } else return NULL; } SINGLE_OBJECT * get_obj_world (CHAR_DATA * ch, char *argy) { char arg[SML_LENGTH]; SINGLE_OBJECT *obj; int number, i; int count; if ((obj = get_obj_here (ch, argy, SEARCH_ROOM_FIRST)) != NULL) return obj; number = number_argy (argy, arg); count = 0; for (i = 1; i >= 0; i--) { for (obj = object_list[i]; obj != NULL; obj = obj->next) { if (can_see_obj (ch, obj) && is_name (arg, obj->pIndexData->name)) { if (++count == number) return obj; } } } return NULL; } void create_amount (int amount, CHAR_DATA * pMob, ROOM_DATA * pRoom, SINGLE_OBJECT * pObj) { I_CONTAINER *c = NULL; if (pObj && pObj->pIndexData->item_type != ITEM_CONTAINER && pObj->pIndexData->item_type != ITEM_CORPSE_NPC && pObj->pIndexData->item_type != ITEM_CORPSE_PC) return; if (pObj) c = (I_CONTAINER *) pObj->more; if (amount <= 0) { bug ("Create_amount: zero or negative money %d.", amount); return; } if (amount == 1) { if (pMob) pMob->coins[COPPER]++; if (pObj) c->money++; if (pRoom) { pRoom->coins[COPPER]++; } } else { if (pMob) { int i; for (i = MAX_COINS -1; i >= 0; i--) { if (amount >= coin_mult[i]) { pMob->coins[i] += amount/coin_mult[i]; amount %= coin_mult[i]; } } } else if (pRoom) { int i; for (i = MAX_COINS -1; i >= 0; i--) { if (amount >= coin_mult[i]) { pRoom->coins[i] += amount/coin_mult[i]; amount %= coin_mult[i]; } } } else if (pObj) c->money += amount; } return; } int tally_coins (CHAR_DATA * ch) { int total = 0; int i; for (i = 0; i < MAX_COINS; i++) { if(ch->coins[i] < 0) ch->coins[i] = 0; total += coin_mult[i] * ch->coins[i]; } return total; } char * name_amount (int amount) { static char buf[STD_LENGTH]; char buf2[500]; int amt_left = amount; int coin_types = 0; int coins_used = 0; int i; buf[0] = '\0'; buf2[0] = '\0'; if (amount == 0) { sprintf(buf, "nothing"); return buf; } /* First figure out what kinds of coins we need to use... start with biggest and subtract off those kinds of coins first. */ for (i = MAX_COINS-1; i >= 0; i--) { if (amt_left >= coin_mult[i]) { amt_left = amt_left % coin_mult[i]; coin_types++; } } amt_left = amount; if (coin_types == 1) { for (i = MAX_COINS-1; i >=0; i--) if (amt_left >= coin_mult[i]) break; sprintf(buf2, "%d %s", amt_left/ coin_mult[i], coin_name[i]); sprintf(buf, buf2); } else { buf[0] = '\0'; for (i = MAX_COINS -1; i >= 0; i--) { if (amt_left >= coin_mult[i]) { coins_used++; if (coins_used < coin_types) { sprintf(buf2, " %d %s,", amt_left/ coin_mult[i], coin_color[i]); strcat(buf, buf2); } else { sprintf(buf2, " and %d %s", amt_left/coin_mult[i], coin_color[i]); strcat(buf, buf2); } amt_left = amt_left % coin_mult[i]; } } } if (buf[0] == '\0') sprintf (buf, "nothing"); return buf; } /* Ch is totally rewritten to handle any number of different coin types... even with different ratios between coin types ! */ char * sub_coins (int amount, CHAR_DATA * ch) { static char ret_val[500]; int money = 0; int i; if (tally_coins (ch) < amount) { sprintf (ret_val, "nothing"); bug ("Sub_coins: ch doesn't have enough money (%d)", amount); return ret_val; } if (tally_coins (ch) == amount) { for (i = 0; i < MAX_COINS; i++) ch->coins[i] = 0; sprintf (ret_val, "nothing"); return ret_val; } /* First do a cascading making of change to make sure we can always make change for the above amounts. We basically check to make sure that at each level we have enough coins to fully split the next level up. This does assume that the coin denominations are ALL divisible by each other in order. So be careful if you change that fact :) */ for (i = MAX_COINS-1; i > 0; i--) { if (ch->coins[i-1] < coin_mult[i]/coin_mult[i-1] && ch->coins[i] > 0) { /* THE FOLLOWING LINE REQUIRES!!!! THAT THE AMOUNTS IN coin_mult ARE ALL DIVISIBLE!!!! LOOK AT IT...IF THESE ARE NOT DIVISIBLE, YOU WILL BE MAKING PLAYERS LOSE MONEY AND THEY WILL COME AND BITCH AT YOU!!!! */ ch->coins[i-1] += coin_mult[i]/coin_mult[i-1]; ch->coins[i]--; } } money = 0; /* The idea of making this sort of change is.. money starts at 0, then we start from the BIGGEST coins the person has. We then see if we have collected too little money, we start subtracting coins until we have at least enough money. */ /* Then if the money was too great we collected, we go down a level in coins and start to give some of the change back. Then that should take us to below the amount possibly, so we go and keep going back and forth until we reach the lowest denomination coins and there should be enough of those because we changed a bigger value for one of them. */ for (i = MAX_COINS-1; i >= 0; i--) { if (money < amount) { if (ch->coins[i] > 0) { while(ch->coins[i] > 0 && money < amount) { ch->coins[i]--; money += coin_mult[i]; } } } else if (money > amount) { while(money > amount) { ch->coins[i]++; money -= coin_mult[i]; } } else break; } money = amount; sprintf (ret_val, "%s", name_amount (money)); return ret_val; } int get_obj_number (SINGLE_OBJECT * obj) { int number; if (obj->pIndexData->item_type == ITEM_CONTAINER) number = 0; else number = 1; for (obj = obj->contains; obj != NULL; obj = obj->next_content) { number += get_obj_number (obj); } return number; } int get_obj_weight (SINGLE_OBJECT * obj) { int weight; weight = obj->pIndexData->weight; for (obj = obj->contains; obj != NULL; obj = obj->next_content) { weight += get_obj_weight (obj); } return weight; } int room_is_dark (ROOM_DATA * oneroom) { if (oneroom == NULL || oneroom->light > 0) return FALSE; if (oneroom->sector_type >= SECT_CAVE || (oneroom->room_flags & (ROOM_UNDERGROUND | ROOM_DARK))) return TRUE; if (IS_SET (oneroom->room_flags, ROOM_INDOORS) || oneroom->sector_type == SECT_INSIDE) return FALSE; if (oneroom->sector_type >= SECT_WOODS && oneroom->sector_type <= SECT_CANYON && weather_info.sky > SKY_RAINING) return TRUE; if (weather_info.sunlight > SUN_DARK) return FALSE; return TRUE; } bool can_see (CHAR_DATA * ch, CHAR_DATA * victim) { if (!ch || !victim) return FALSE; if (ch == victim) return TRUE; if (IS_PLAYER (victim) && victim->pcdata->wizinvis > LEVEL (ch) && LEVEL (ch) < LEVEL (victim)) return FALSE; if (IS_PLAYER (ch) && IS_SET (ch->act, PLR_HOLYLIGHT)) return TRUE; if (IS_HURT (ch, BLIND)) return FALSE; if ((victim->aff[AFF] % COLD) & ~ (victim->aff[DET] % COLD)) return FALSE; if (weather_info.sky == SKY_FOGGY && number_range(1,4) != 0 && !IS_DET(ch, FOGGY)) return FALSE; if (room_is_dark (ch->in_room) && (!IS_DET(ch, DARK) || (IS_AFF(victim, COLD) && !IS_DET(ch, COLD)))) return FALSE; return TRUE; } bool can_see_nextdoor (CHAR_DATA * ch, CHAR_DATA * victim) { if (!ch || !victim) return FALSE; if (ch == victim) return TRUE; if (IS_PLAYER (victim) && victim->pcdata->wizinvis > ch->pcdata->level) return FALSE; if (IS_PLAYER (ch) && IS_SET (ch->act, PLR_HOLYLIGHT)) return TRUE; if (IS_HURT (ch, BLIND)) return FALSE; if ((victim->aff[AFF] % COLD) & ~ (victim->aff[DET] % COLD)) return FALSE; if (weather_info.sky == SKY_FOGGY && number_bits (2) != 0 && !IS_DET(ch, FOGGY)) return FALSE; if (room_is_dark (victim->in_room) && (!IS_DET(ch, DARK) || (IS_AFF(victim, COLD) && !IS_DET(ch, COLD)))) return FALSE; return TRUE; } bool can_see_obj (CHAR_DATA * ch, SINGLE_OBJECT * obj) { if (IS_PLAYER (ch) && IS_SET (ch->act, PLR_HOLYLIGHT)) return TRUE; if (IS_HURT (ch, BLIND)) return FALSE; if (IS_SET (obj->pIndexData->extra_flags, ITEM_UNSEEN) && (IS_SET (obj->pIndexData->wear_flags, ITEM_TAKE))) return FALSE; if (obj->pIndexData->item_type == ITEM_LIGHT && IS_LIT (obj)) return TRUE; if (obj->carried_by == ch) return TRUE; if (room_is_dark (ch->in_room) && !IS_DET (ch,DARK )) return FALSE; if (IS_SET (obj->pIndexData->extra_flags, ITEM_INVIS) && !IS_DET (ch, INVIS)) return FALSE; return TRUE; } /* * True if char can drop obj. */ bool can_drop_obj (CHAR_DATA * ch, SINGLE_OBJECT * obj) { if (!obj) return TRUE; if (!IS_SET (obj->pIndexData->extra_flags, ITEM_NODROP)) return TRUE; if (IS_PLAYER (ch) && ch->pcdata->level >= LEVEL_IMMORTAL) return TRUE; return FALSE; } /* * Return ascii name of a mob type. */ char * mob_type_name (int mob_num) { static char retv[30]; if (mob_num >= 0 && mob_num < MAX_MOB_TYPE) strcpy(retv, mob_info[mob_num].name); else strcpy(retv, "unknown"); return retv; } /* * Return ascii attack of a mob type. */ char * mob_type_attack (int mob_type) { static char retv[30]; if (mob_type >= 0 && mob_type < MAX_MOB_TYPE) strcpy(retv, mob_info[mob_type].attackname); else strcpy(retv, "punch"); return retv; } /* * Return ascii name of an item type. */ char * item_type_name (int itemtype) { static char retv[30]; if(itemtype < 1 || itemtype > ITEM_MAX) itemtype = ITEM_MAX; strcpy (retv, item_types[itemtype-1].name); return retv; } int mob_name_type (char *name) { int i; for (i = 0; i < MAX_MOB_TYPE; i++) { if (!str_cmp(name, mob_info[i].name)) return i; } return -1; } int item_name_type (char *name) { int i; for (i = 0; i < ITEM_MAX; i ++) { if (!str_cmp(name, item_types[i].name)) return item_types[i].number; } return 0; } /* * Return ascii name of an affect location. */ char * affect_loc_name (int location) { static char retv[30]; if (location >= 0 && location < MAX_APPLY) strcpy(retv, apply_loc_names[location]); else strcpy(retv, "unknown"); return retv; } int affect_name_loc (char *name) { int i; if (!str_cmp(name, "none")) return APPLY_NONE; for (i = 1; i < MAX_APPLY; i++) if (!str_cmp(name, apply_loc_names[i])) return i; return -99; } /* * Return ascii name of an affect bit vector. */ char * affect_bit_name (int vector0, int vector1, int vector2, int vector3) { static char buf[STD_LENGTH]; int i, k; int vector[4]; bool found; buf[0] = '\0'; vector[0] = vector0; vector[1] = vector1; vector[2] = vector2; vector[3] = vector3; for (k = 0; k < 2; k++) { found = FALSE; for (i = 0; affect_flags1[i].flagname > 0; i++) { if (vector[k] & affect_flags1[i].flagname) { if (!found) strcat(buf, (k == 0 ? " Hurt:" : " Prot:")); found = TRUE; strcat (buf, affect_flags1[i].how_it_appears); } } } for (k = 2; k < 4; k++) { found = FALSE; for (i = 0; affect_flags2[i].flagname > 0; i++) { if (vector[k] & affect_flags2[i].flagname) { if (!found) strcat(buf, (k == 2 ? " Aff:" : " Det:")); found = TRUE; strcat (buf, affect_flags2[i].how_it_appears); } } } strcat(buf, "\x1b[0;37m"); return buf; } /* * Return bit vector */ int affect_name_bit (int type, char *buf) { int i; if (type < 2) { for (i = 0; affect_flags1[i].flagname > 0; i++) if (!str_cmp (buf, affect_flags1[i].what_you_type)) return affect_flags1[i].flagname; } else { for (i = 0; affect_flags2[i].flagname > 0; i++) if (!str_cmp (buf, affect_flags2[i].what_you_type)) return affect_flags2[i].flagname; } return 0; } char * augment_bit_name (int vector) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; augment_flagss[i].flagname > 0; i++) if (vector & augment_flagss[i].flagname) strcat (buf, augment_flagss[i].how_it_appears); return (buf[0] != '\0') ? buf + 1 : " "; } char * tactics_bit_name (int vector) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; tactics_flags[i].flagname > 0; i++) if (vector & tactics_flags[i].flagname) strcat (buf, tactics_flags[i].how_it_appears); return (buf[0] != '\0') ? buf + 1 : " "; } /* * Return bit vector */ int augment_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; augment_flagss[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", augment_flagss[i].what_you_type); } } for (i = 0; augment_flagss[i].flagname > 0; i++) if (!str_cmp (buf, augment_flagss[i].what_you_type)) return augment_flagss[i].flagname; return 0; } int tactics_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; tactics_flags[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", tactics_flags[i].what_you_type); } } for (i = 0; tactics_flags[i].flagname > 0; i++) if (!str_cmp (buf, tactics_flags[i].what_you_type)) return tactics_flags[i].flagname; return 0; } /* * Return ascii name of extra flags vector. */ char * extra_bit_name (int extra_flags) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; extra_flagss[i].flagname > 0; i++) if (extra_flags & extra_flagss[i].flagname) strcat (buf, extra_flagss[i].how_it_appears); return (buf[0] != '\0') ? buf + 1 : "none"; } int extra_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; extra_flagss[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", extra_flagss[i].what_you_type); } } for (i = 0; extra_flagss[i].flagname > 0; i++) if (!str_cmp (buf, extra_flagss[i].what_you_type)) return extra_flagss[i].flagname; return 0; } /* * Return ascii name of room flags vector. */ char * room_bit_name (int room_flags) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; room_flagss[i].flagname > 0; i++) { if (room_flags & room_flagss[i].flagname) { strcat (buf, room_flagss[i].how_it_appears); } } return (buf[0] != 0 ? buf + 1 : " "); } int room_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; room_flagss[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", room_flagss[i].what_you_type); } } for (i = 0; room_flagss[i].flagname > 0; i++) if (!str_cmp (buf, room_flagss[i].what_you_type)) return room_flagss[i].flagname; return 0; } int society_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; society_flagss[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", society_flagss[i].what_you_type); } } for (i = 0; society_flagss[i].flagname > 0; i++) if (!str_cmp (buf, society_flagss[i].what_you_type)) return society_flagss[i].flagname; return 0; } int caste_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; caste_flagss[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", caste_flagss[i].what_you_type); } } for (i = 0; caste_flagss[i].flagname > 0; i++) if (!str_cmp (buf, caste_flagss[i].what_you_type)) return caste_flagss[i].flagname; return 0; } int exit_name_bit (char *buf) { int i; for (i = 0; exit_flagss[i].flagname > 0; i++) if (!str_cmp (buf, exit_flagss[i].what_you_type)) return exit_flagss[i].flagname; return 0; } char * room_bit_name2 (int room_flags) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; room_flags2[i].flagname > 0; i++) { if (room_flags & room_flags2[i].flagname) { strcat (buf, room_flags2[i].how_it_appears); } } return (buf[0] != 0 ? buf + 1 : " "); } int room_name_bit2 (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; room_flags2[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", room_flags2[i].what_you_type); } } for (i = 0; room_flags2[i].flagname > 0; i++) if (!str_cmp (buf, room_flags2[i].what_you_type)) return room_flags2[i].flagname; return 0; } char * race_bit_name (int rc) { static char buf[512]; char t[30]; int i; buf[0] = '\0'; for (i = 0; i < RACE_COUNT; i++) if (rc & (1 << i)) { sprintf (t, " k%s", race_info[i].name); strcat (buf, t); } return (buf[0] != '\0') ? buf + 1 : " "; } char * act_bit_name (int act) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; act_1[i].flagname > 0; i++) if (act & act_1[i].flagname) strcat (buf, act_1[i].how_it_appears); return (buf[0] != '\0') ? buf + 1 : " "; } char * act3_bit_name (int act) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; act_3[i].flagname > 0; i++) if (act & act_3[i].flagname) strcat (buf, act_3[i].how_it_appears); return (buf[0] != '\0') ? buf + 1 : " "; } char *exit_bit_name (int bits) { static char buf[500]; int i; buf[0] = '\0'; for (i = 0; exit_flagss[i].flagname > 0; i++) if (bits & exit_flagss[i].flagname) strcat(buf, exit_flagss[i].how_it_appears); return ((buf[0] != '\0') ? buf + 1: " "); } char * act4_bit_name (int act) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; act_4[i].flagname > 0; i++) if (act & act_4[i].flagname) strcat (buf, act_4[i].how_it_appears); return ((buf[0] != '\0') ? buf + 1 : " "); } char * society_bit_name (int act) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; society_flagss[i].flagname > 0; i++) if (act & society_flagss[i].flagname) strcat (buf, society_flagss[i].how_it_appears); return ((buf[0] != '\0') ? buf + 1 : " "); } char * caste_bit_name (int act) { static char buf[512]; int i; buf[0] = '\0'; for (i = 0; caste_flagss[i].flagname > 0; i++) if (act & caste_flagss[i].flagname) strcat (buf, caste_flagss[i].how_it_appears); return ((buf[0] != '\0') ? buf + 1 : " "); } char * plr_bit_name (int act) { static char buf[512]; buf[0] = '\0'; if (act & PLR_HOLYLIGHT) strcat (buf, " holylight"); if (act & PLR_HOLYPEACE) strcat (buf, " holypeace"); if (act & PLR_LOG) strcat (buf, " log"); if (act & PLR_DENY) strcat (buf, " deny"); if (act & PLR_FREEZE) strcat (buf, " freeze"); if (act & WIZ_NOTIFY) strcat (buf, " notify"); return (buf[0] != '\0') ? buf + 1 : "none"; } int race_name_bit (char *buf) { int i; buf++; for (i = 0; i < RACE_COUNT; i++) if (!str_cmp (buf, race_info[i].name)) return (1 << i); if (!str_cmp (buf, "all")) return 0xFFFFFFFF; if (!str_cmp (buf, "none")) return 0; return 0; } int act_name_bit (char *buf) { int i; if (!str_cmp(buf,"flaglist")) { for (i = 0; act_1[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", act_1[i].what_you_type); } } for (i = 0; act_1[i].flagname > 0; i++) if (!str_cmp (buf, act_1[i].what_you_type)) return act_1[i].flagname; if (!str_cmp(buf,"flaglist")) { for (i = 0; act_3[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", act_3[i].what_you_type); } } for (i = 0; act_3[i].flagname > 0; i++) if (!str_cmp (buf, act_3[i].what_you_type)) return act_3[i].flagname; if (!str_cmp(buf,"flaglist")) { for (i = 0; act_4[i].flagname > 0; i++) { sprintf(hugebuf_o+strlen(hugebuf_o),"%-10s: ", act_4[i].what_you_type); } } for (i = 0; act_4[i].flagname > 0; i++) if (!str_cmp (buf, act_4[i].what_you_type)) return act_4[i].flagname; return 0; } /* * Returns the name of a wear bit. */ char * wear_bit_name (int wear) { int i; static char buf[512]; buf[0] = '\0'; for (i = 0; worn_flags[i].flagname != 0; i++) { if (wear & worn_flags[i].flagname) { strcat(buf, " "); strcat(buf, worn_flags[i].what_you_type); } } return (buf[0] != '\0') ? buf + 1 : "none"; } /* * Returns the bit, given a certain name. */ int wear_name_bit (char *buf) { int i; for (i = 0; worn_flags[i].flagname > 0; i++) { if (!str_cmp(buf, worn_flags[i].what_you_type)) return worn_flags[i].flagname; } return 0; } char * area_bit_name (int areaflags) { int i; static char buf[512]; buf[0] = '\0'; for (i = 0; area_flagss[i].flagname != 0; i++) { if (areaflags & area_flagss[i].flagname) { strcat(buf, " "); strcat(buf, area_flagss[i].what_you_type); } } return (buf[0] != '\0') ? buf + 1 : "none"; } int area_name_bit (char *buf) { int i; for (i = 0; area_flagss[i].flagname > 0; i++) { if (!str_cmp(buf, area_flagss[i].what_you_type)) return area_flagss[i].flagname; } return 0; } /* * Return ascii name of wear location. */ char * wear_loc_name (int wearloc) { static char retv[35]; int i; for (i = 1; worn_flags[i].flagname > 0; i++) if (IS_SET(worn_flags[i].flagname, wearloc)) { strcpy(retv, worn_flags[i].what_you_type); return retv; break; } strcpy(retv, "unknown"); return retv; } int wear_name_loc (char *buf) { int i; if (is_number (buf)) { return atoi (buf); } for (i = 0; worn_flags[i].flagname > 0; i++) { if(!str_cmp(buf, worn_flags[i].what_you_type)) return worn_flags[i].flagname; } return WEAR_NONE; } /* * Sees if last char is 's' and returns 'is' or 'are' pending. */ char * is_are (char *text) { while (*text != '\0') { text++; } text--; if (*text == 's' || *text == 'S') return "are"; else return "is"; } /* * Get an extra description from a list. */ char * get_extra_descr (const char *name, DESCRIPTION_DATA * ed) { for (; ed != NULL; ed = ed->next) { if (is_name (name, ed->keyword)) return ed->description; } return NULL; } bool use_tool (SINGLE_OBJECT * obj, int bit) { I_TOOL *t; if (obj == NULL || obj->pIndexData->item_type != ITEM_TOOL) return FALSE; t = (I_TOOL *) obj->more; if (!IS_SET (t->tool_type, bit)) return FALSE; if (t->uses <= 0) return FALSE; t->uses--; return TRUE; } int PERCENTAGE (int amount, int max) { if (max > 0) return ((100 * amount)/max); return 100; } bool find_str (char *str1, char *str2) { bool found; int length; char *str; length = strlen (str2); str = str2; found = 0; while (*str1 != '\0' && *str2 != '\0') { if (*str2 == *str1) { found++; str2++; } else { found = 0; str2 = str; } str1++; } if (found != length) found = 0; return found; }