/* ************************************************************************ * file: handler.c , Handler module. Part of DIKUMUD * * Usage: Various routines for moving about objects/players * * Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * ************************************************************************* */ #include CONFIG #if HAVE_STRINGS_H #include <strings.h> #endif #if HAVE_STRING_H #include <string.h> #endif #include <ctype.h> #include "structs.h" #include "utils.h" #include "comm.h" #include "db.h" #include "skills.h" #include "error.h" #include "proto.h" extern struct room_data *world; extern struct zone_data *zone_table; extern struct obj_data *object_list; extern struct char_data *character_list; extern struct mob_index_data *mob_index; extern struct obj_index_data *obj_index; extern struct descriptor_data *descriptor_list; extern char *menu; extern int rev_dir[]; extern int max_dir[]; extern char log_buf[]; /* External procedures */ int str_cmp(char *arg1, char *arg2); void free_char(struct char_data *ch); void stop_fighting(struct char_data *ch); void remove_follower(struct char_data *ch); extern char *index(); void clearMemory(struct char_data *ch); void update_crash(struct char_data *ch); char *fname(char *namelist) { static char holder[30]; register char *point; if(!namelist) { log("BUG: null pointer into fname!"); *point='\0'; return(point); } for (point = holder; isalpha(*namelist); namelist++, point++) *point = *namelist; *point = '\0'; return(holder); } int isname(char *str, char *namelist) { register char *curname, *curstr; if(!str || !namelist) return NULL; curname = namelist; for (;;) { for (curstr = str;; curstr++, curname++) { if (!*curstr && !isalpha(*curname)) return(1); if (!*curname) return(0); if (!*curstr || *curname == ' ') break; if (LOWER(*curstr) != LOWER(*curname)) break; } /* skip to next name */ for (; isalpha(*curname); curname++); if (!*curname) return(0); curname++; /* first char of new name */ } } void affect_modify(struct char_data *ch,byte loc, byte mod, long bitv, bool add) { int maxabil; if (!add) { mod = -mod; } maxabil = (IS_NPC(ch) ? 25:18); switch(loc) { case APPLY_NONE: break; case APPLY_STR: GET_STR(ch) += mod; break; case APPLY_DEX: GET_DEX(ch) += mod; break; case APPLY_INT: GET_INT(ch) += mod; break; case APPLY_WIS: GET_WIS(ch) += mod; break; case APPLY_CON: GET_CON(ch) += mod; break; case APPLY_SEX: /* ??? GET_SEX(ch) += mod; */ break; case APPLY_CLASS: /* ??? GET_CLASS(ch) += mod; */ break; case APPLY_LEVEL: /* ??? GET_LEVEL(ch) += mod; */ break; case APPLY_AGE: /* ch->player.time.birth += mod; */ break; case APPLY_CHAR_WEIGHT: GET_WEIGHT(ch) += mod; break; case APPLY_CHAR_HEIGHT: GET_HEIGHT(ch) += mod; break; case APPLY_MANA: ch->physical->max_mana += mod; if(GET_MANA(ch)>mana_limit(ch)) GET_MANA(ch)=mana_limit(ch); break; case APPLY_HIT: ch->physical->max_hit += mod; if(GET_HIT(ch)>hit_limit(ch)) GET_HIT(ch)=hit_limit(ch); break; case APPLY_MOVE: ch->physical->max_move += mod; break; case APPLY_GOLD: break; case APPLY_EXP: break; case APPLY_AC: GET_AC(ch) += mod; break; case APPLY_HITROLL: GET_HITROLL(ch) += mod; break; case APPLY_DAMROLL: GET_DAMROLL(ch) += mod; break; case APPLY_SAVING_PARA: ch->specials.apply_saving_throw[0] += mod; break; case APPLY_SAVING_ROD: ch->specials.apply_saving_throw[1] += mod; break; case APPLY_SAVING_PETRI: ch->specials.apply_saving_throw[2] += mod; break; case APPLY_SAVING_BREATH: ch->specials.apply_saving_throw[3] += mod; break; case APPLY_SAVING_SPELL: ch->specials.apply_saving_throw[4] += mod; break; default: log("BUG: Unknown apply adjust attempt (handler.c, affect_modify)"); break; } /* switch */ } /* This updates a character by subtracting everything he is affected by */ /* restoring original abilities, and then affecting all again */ void affect_total(struct char_data *ch) { struct affected_type *af; struct obj_affect *oa; struct obj_data *i; int j; for(i=ch->carrying; i; i=i->next_content) { if(i->equipped_as != UNEQUIPPED) for(oa=i->affected;oa;oa=oa->next) affect_modify(ch, oa->location, oa->modifier, i->obj_flags.bitvector, FALSE); } for(af = ch->affected; af; af=af->next) affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE); ch->tmpabilities = ch->physical->abilities; for(i=ch->carrying; i; i=i->next_content) { if(i->equipped_as != UNEQUIPPED) for(oa=i->affected;oa;oa=oa->next) affect_modify(ch, oa->location, oa->modifier, i->obj_flags.bitvector, TRUE); } for(af = ch->affected; af; af=af->next) affect_modify(ch, af->location, af->modifier, af->bitvector, TRUE); /* Make certain values are between 0..25, not < 0 and not > 25! */ j = (IS_NPC(ch) ? 25 :18); GET_DEX(ch) = MAX(0,MIN(GET_DEX(ch), j)); GET_INT(ch) = MAX(0,MIN(GET_INT(ch), j)); GET_WIS(ch) = MAX(0,MIN(GET_WIS(ch), j)); GET_CON(ch) = MAX(0,MIN(GET_CON(ch), j)); GET_STR(ch) = MAX(0,MIN(GET_STR(ch), j)); } /* Insert an affect_type in a char_data structure Automatically sets apropriate bits and apply's */ void affect_to_char( struct char_data *ch, struct affected_type *af ) { struct affected_type *affected_alloc; CREATE(affected_alloc, struct affected_type, 1); *affected_alloc = *af; affected_alloc->next = ch->affected; ch->affected = affected_alloc; affect_modify(ch, af->location, af->modifier, af->bitvector, TRUE); affect_total(ch); } /* Remove an affected_type structure from a char (called when duration reaches zero). Pointer *af must never be NIL! Frees mem and calls affect_location_apply */ void affect_remove( struct char_data *ch, struct affected_type *af ) { struct affected_type *hjp; affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE); /* remove structure *af from linked list */ if (ch->affected == af) { /* remove head of list */ ch->affected = af->next; } else { for(hjp = ch->affected; (hjp->next) && (hjp->next != af); hjp = hjp->next); if (hjp->next != af) { log("BUG: Could not locate affected_type in ch->affected. (affect_remove)"); return; } hjp->next = af->next; /* skip the af element */ } free ( af ); affect_total(ch); } /* Call affect_remove with every spell of spelltype "skill" */ void affect_from_char( struct char_data *ch, byte skill) { struct affected_type *hjp; for(hjp = ch->affected; hjp; hjp = hjp->next) if (hjp->type == skill) affect_remove( ch, hjp ); } /* Return if a char is affected by a spell (SPELL_XXX), NULL indicates not affected */ bool affected_by_spell( struct char_data *ch, byte skill ) { struct affected_type *hjp; for (hjp = ch->affected; hjp; hjp = hjp->next) if ( hjp->type == skill ) return( TRUE ); return( FALSE ); } void affect_join( struct char_data *ch, struct affected_type *af, bool avg_dur, bool avg_mod ) { struct affected_type *hjp; bool found = FALSE; for (hjp = ch->affected; !found && hjp; hjp = hjp->next) { if ( hjp->type == af->type ) { af->duration += hjp->duration; if (avg_dur) af->duration /= 2; af->modifier += hjp->modifier; if (avg_mod) af->modifier /= 2; affect_remove(ch, hjp); affect_to_char(ch, af); found = TRUE; } } if (!found) affect_to_char(ch, af); } /* move a player out of a room */ void char_from_room(struct char_data *ch) { struct char_data *i; if (ch->in_room == NOWHERE) { log("BUG: NOWHERE extracting char from room (char_from_room)"); return; } world[ch->in_room].light -= ch->specials.lights_carried; if (ch == world[ch->in_room].people) /* head of list */ world[ch->in_room].people = ch->next_in_room; else /* locate the previous element */ { for (i = world[ch->in_room].people; i->next_in_room != ch; i = i->next_in_room); i->next_in_room = ch->next_in_room; } ch->in_room = NOWHERE; ch->next_in_room = 0; } /* place a character in a room */ void char_to_room(struct char_data *ch, int room,int dir) { int t_dir,j,other_exit=-1; struct char_data *k; if(!(world[room].room_flags & SINGLE_FILE)) { /* Don't care about order*/ ch->next_in_room = world[room].people; world[room].people = ch; } else { t_dir=rev_dir[dir]; for(j=0;j<max_dir[zone_table[world[room].zone].dir_system];j++) if(get_exit(room,j) && j!=t_dir) other_exit=j; if(other_exit==-1 || other_exit > t_dir) { ch->next_in_room = world[room].people; world[room].people = ch; } else { if(!(k=world[room].people)) world[room].people=ch; else { while(k->next_in_room) k=k->next_in_room; k->next_in_room=ch; } } } ch->in_room = room; world[room].light += ch->specials.lights_carried; } /* give an object to a char */ void obj_to_char(struct obj_data *object, struct char_data *ch) { struct obj_info_light *light; if(!object) log("BUG: No object in obj_to_char!"); if(!ch) log("BUG: No character in obj_to_char!"); if(!object || !ch) return; object->next_content = ch->carrying; ch->carrying = object; object->carried_by = ch; object->in_room = NOWHERE; IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(object); IS_CARRYING_N(ch)++; if((light = (struct obj_info_light *)get_obj_info(object,ITEM_LIGHT))) { ch->specials.lights_carried+=light->brightness; if(ch->in_room!=NOWHERE) world[ch->in_room].light+=light->brightness; } } /* take an object from a char */ void obj_from_char(struct obj_data *object) { struct obj_data *tmp; struct obj_info_light *light; if(!object->carried_by) { log("BUG: obj_from_char when obj not carried"); return; } if((light = (struct obj_info_light *)get_obj_info(object,ITEM_LIGHT))) { object->carried_by->specials.lights_carried-=light->brightness; if(object->carried_by->in_room!=NOWHERE) world[object->carried_by->in_room].light-=light->brightness; } if (object->carried_by->carrying == object) /* head of list */ object->carried_by->carrying = object->next_content; else { for (tmp = object->carried_by->carrying; tmp && (tmp->next_content != object); tmp = tmp->next_content); /* locate previous */ tmp->next_content = object->next_content; } IS_CARRYING_W(object->carried_by) -= GET_OBJ_WEIGHT(object); IS_CARRYING_N(object->carried_by)--; object->carried_by = 0; object->next_content = 0; } /* Return the effect of a piece of armor in position eq_pos */ int apply_ac(struct char_data *ch, struct obj_data *obj) { struct obj_info_wear *ow; if(!obj) { log("BUG: Null obj in apply_ac"); return 0; } if (!(ow = (struct obj_info_wear *)get_obj_info(obj,ITEM_WORN))) return 0; switch (obj->equipped_as) { case WEAR_BODY: return (3*ow->ac); /* 30% */ case WEAR_HEAD: return (2*ow->ac); /* 20% */ case WEAR_LEGS: return (2*ow->ac); /* 20% */ case WEAR_FEET: return (ow->ac); /* 10% */ case WEAR_HANDS: return (ow->ac); /* 10% */ case WEAR_ARMS: return (ow->ac); /* 10% */ case HOLD_HAND1: case HOLD_HAND2: return (ow->ac); /* 10% */ case WEAR_WAIST: return (ow->ac); /* 10% */ } return 0; } void equip_char(struct char_data *ch, struct obj_data *obj, int pos) { struct obj_affect *oa; struct obj_info_wear *ow; if (obj->in_room!=NOWHERE) { log("BUG: Obj is in_room when equip."); return; } if(obj->carried_by && obj->carried_by != ch) { log("BUG: Obj is carried by someone else when equip."); return; } if(obj->equipped_as!=UNEQUIPPED) { log("BUG: Obj is already equipped."); return; } if(!obj->carried_by) obj_to_char(obj,ch); if ((IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch))) { if (ch->in_room != NOWHERE) { act("You are zapped by $p and instantly drop it.", FALSE, ch, obj, 0, TO_CHAR); act("$n is zapped by $p and instantly drops it.", FALSE, ch, obj, 0, TO_ROOM); obj_from_char(obj); obj_to_room(obj, ch->in_room); return; } else { log("BUG: ch->in_room = NOWHERE when equipping char."); } } obj->equipped_as = pos; GET_AC(ch) -= apply_ac(ch, obj); if((ow = (struct obj_info_wear *)get_obj_info(obj,ITEM_WORN))) ch->specials.warmth += ow->warmth; for(oa=obj->affected;oa;oa=oa->next) affect_modify(ch, oa->location, oa->modifier, obj->obj_flags.bitvector, TRUE); affect_total(ch); } struct obj_data *unequip_char(struct char_data *ch, struct obj_data *obj) { struct obj_affect *oa; struct obj_info_wear *ow; GET_AC(ch) += apply_ac(ch, obj); if((ow = (struct obj_info_wear *)get_obj_info(obj,ITEM_WORN))) ch->specials.warmth -= ow->warmth; for(oa=obj->affected;oa;oa=oa->next) affect_modify(ch, oa->location, oa->modifier, obj->obj_flags.bitvector, FALSE); obj->equipped_as = UNEQUIPPED; affect_total(ch); return(obj); } int get_number(char **name) { int i; char *ppos; char number[MAX_INPUT_LENGTH+30] = ""; if(strlen(*name)>30) return(0); if ((ppos = index(*name, '.'))) { *ppos++ = '\0'; strcpy(number,*name); strcpy(*name, ppos); for(i=0; *(number+i); i++) if (!isdigit(*(number+i))) return(0); return(atoi(number)); } return(1); } struct obj_data *get_equip_used(struct char_data *ch,int use) { struct obj_data *obj; for(obj=ch->carrying;obj;obj=obj->next_content) { if(obj->equipped_as != UNEQUIPPED) { if(use >=0) { if(obj->equipped_as==use) return(obj); } else { switch(use) { } } } } return(NULL); } /* Search a given list for an object, and return a pointer to that object */ struct obj_data *get_obj_in_list(char *name, struct obj_data *list) { struct obj_data *i; int j, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp; strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); for (i = list, j = 1; i && (j <= number); i = i->next_content) if (isname(tmp, i->name)) { if (j == number) return(i); j++; } return(0); } /* Search a given list for an object number, and return a ptr to that obj */ struct obj_data *get_obj_in_list_num(int num, struct obj_data *list) { struct obj_data *i; for (i = list; i; i = i->next_content) if (i->item_number == num) return(i); return(0); } /*search the entire world for an object number, and return a pointer */ struct obj_data *get_obj_num(int nr) { struct obj_data *i; for (i = object_list; i; i = i->next) if (i->item_number == nr) return(i); return(0); } /* return a char_data structure for an id number */ struct char_data *get_char_from_id(CHAR_ID id) { struct char_data *i; for(i=character_list;i;i=i->next) if(i->id == id) return(i); /* We didn't find it in the game */ /* Doesn't exist at all */ return(NULL); } /* search a room for a char, and return a pointer if found.. */ struct char_data *get_char_room(char *name, int room) { struct char_data *i; int j, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp; if(!*name) return(NULL); strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); for (i = world[room].people, j = 1; i && (j <= number); i = i->next_in_room) if (isname(tmp, GET_NAME(i))) { if (j == number) return(i); j++; } return(0); } /* search all over the world for a char num, and return a pointer if found */ struct char_data *get_char_num(int nr) { struct char_data *i; for (i = character_list; i; i = i->next) if (i->nr == nr) return(i); return(0); } /* put an object in a room */ void obj_to_room(struct obj_data *object, int room) { struct char_data *i; struct obj_info_exit *exit; struct obj_info_light *light; if(!object) { log("BUG: Null object in obj_to_room!"); return; } object->next_content = world[room].contents; world[room].contents = object; object->in_room = room; object->carried_by = 0; /* Is it lit? */ if((light = (struct obj_info_light *)get_obj_info(object,ITEM_LIGHT))) world[room].light+=light->brightness; if(object->obj_flags.extra_flags & ITEM_IGNORE) return; if((world[room].sector_type==SECT_WATER_SWIM || world[room].sector_type==SECT_WATER_NOSWIM) && !IS_SET(object->obj_flags.extra_flags,ITEM_FLOAT)) { for(i=world[room].people;i;i=i->next_in_room) if(CAN_SEE_OBJ(i,object)) act("$p sinks into the water.",TRUE,i,object,0,TO_CHAR); extract_obj(object); } else if(world[room].sector_type==SECT_NO_GROUND) { for(i=world[room].people;i;i=i->next_in_room) if(CAN_SEE_OBJ(i,object)) act("$p falls downward.",TRUE,i,object,0,TO_CHAR); exit = get_exit(room,5); if(exit && exit->to_room!=room){ obj_from_room(object); /* Need to do this before obj_to_room so that */ /* when the falling obj goes through more than */ /* one room, it doesn't fall out before it arrives */ for(i=world[exit->to_room].people; i;i=i->next_in_room) if(CAN_SEE_OBJ(i,object)) act("$p falls here from above.",TRUE,i,object,0,TO_CHAR); obj_to_room(object,exit->to_room); } else extract_obj(object); } } /* Take an object from a room */ void obj_from_room(struct obj_data *object) { struct obj_data *i; struct obj_info_light *light; /* Is it lit? */ if((light = (struct obj_info_light *)get_obj_info(object,ITEM_LIGHT))) world[object->in_room].light-=light->brightness; /* remove object from room */ if (object == world[object->in_room].contents) /* head of list */ world[object->in_room].contents = object->next_content; else /* locate previous element in list */ { for (i = world[object->in_room].contents; i && (i->next_content != object); i = i->next_content); i->next_content = object->next_content; } object->in_room = NOWHERE; object->next_content = 0; } /* put an object in an object (quaint) */ void obj_to_obj(struct obj_data *obj, struct obj_data *obj_to) { struct obj_data *tmp_obj; obj->next_content = obj_to->contains; obj_to->contains = obj; obj->in_obj = obj_to; for(tmp_obj = obj->in_obj; tmp_obj; tmp_obj = tmp_obj->in_obj) { GET_OBJ_WEIGHT(tmp_obj) += GET_OBJ_WEIGHT(obj); if(!tmp_obj->in_obj && tmp_obj->carried_by) IS_CARRYING_W(tmp_obj->carried_by) += GET_OBJ_WEIGHT(obj); } } /* remove an object from an object */ void obj_from_obj(struct obj_data *obj) { struct obj_data *tmp, *obj_from; if (obj->in_obj) { obj_from = obj->in_obj; if (obj == obj_from->contains) /* head of list */ obj_from->contains = obj->next_content; else { for (tmp = obj_from->contains; tmp && (tmp->next_content != obj); tmp = tmp->next_content); /* locate previous */ if (!tmp) { perror("Fatal error in object structures."); abort(); } tmp->next_content = obj->next_content; } /* Subtract weight from containers container */ for(tmp = obj->in_obj; tmp->in_obj; tmp = tmp->in_obj) GET_OBJ_WEIGHT(tmp) -= GET_OBJ_WEIGHT(obj); GET_OBJ_WEIGHT(tmp) -= GET_OBJ_WEIGHT(obj); /* Subtract weight from char that carries the object */ if (tmp->carried_by) IS_CARRYING_W(tmp->carried_by) -= GET_OBJ_WEIGHT(obj); obj->in_obj = 0; obj->next_content = 0; } else { perror("Trying to object from object when in no object."); abort(); } } /* Extract an object from the world */ void extract_obj(struct obj_data *obj) { struct obj_data *temp1; if(obj->in_room != NOWHERE) obj_from_room(obj); else if(obj->carried_by) obj_from_char(obj); else if(obj->in_obj) obj_from_obj(obj); /* else if(obj->in_obj) What sense does this make? * * * * * * { temp1 = obj->in_obj; if(temp1->contains == obj) * head of list * temp1->contains = obj->next_content; else { for( temp2 = temp1->contains ; temp2 && (temp2->next_content != obj); temp2 = temp2->next_content ); if(temp2) { temp2->next_content = obj->next_content; } } } */ for( ; obj->contains; extract_obj(obj->contains)); /* leaves nothing ! */ if (object_list == obj ) /* head of list */ object_list = obj->next; else { for(temp1 = object_list; temp1 && (temp1->next != obj); temp1 = temp1->next); if(temp1) temp1->next = obj->next; } if(obj->item_number>=0) (obj_index[obj->item_number].number)--; free_obj(obj); } /* Remove a char's "belongings" completely from the world, without saving */ void extract_char_eq(struct char_data *ch) { while(ch->carrying) { if(ch->carrying->equipped_as != UNEQUIPPED) unequip_char(ch,ch->carrying); extract_obj(ch->carrying); } } /* Extract a ch completely from the world, and leave his stuff behind */ void extract_char(struct char_data *ch) { struct char_data *k, *next_char; struct descriptor_data *t_desc; int was_in; extern struct char_data *combat_list; void do_return(struct char_data *ch, char *argument, int cmd); void die_follower(struct char_data *ch); if(!ch) { log("BUG: extract_char(*NULL*)"); return; } if(!IS_NPC(ch) && !ch->desc) { for(t_desc = descriptor_list; t_desc; t_desc = t_desc->next) if(t_desc->original==ch) do_return(t_desc->character, "", 0); } if (ch->in_room == NOWHERE) { log("BUG: NOWHERE extracting char. (extract_char)"); /* exit(1); */ return; /* Must we really crash here? */ } if (ch->followers || ch->master) die_follower(ch); /*** This shouldn't be necessary while(ch->carrying) { i=ch->carrying; obj_from_char(i); obj_to_room(i,ch->in_room); } ***/ if (ch->specials.fighting) stop_fighting(ch); for (k = combat_list; k ; k = next_char) { next_char = k->next_fighting; if (k->specials.fighting == ch) stop_fighting(k); } /* Get rid of arrest information */ if(ch->specials.arrest_by) { if(ch->specials.arrest_by->specials.arrest_link==ch) ch->specials.arrest_by->specials.arrest_link=ch->specials.arrest_link; else for(k=ch->specials.arrest_by->specials.arrest_link;k;k=k->specials.arrest_link) if(k->specials.arrest_link==ch) { k->specials.arrest_link=ch->specials.arrest_link; break; } } if(ch->in_room!=NOWHERE) { /* Must remove from room before removing the equipment! */ was_in = ch->in_room; char_from_room(ch); char_to_room(ch,0,0); } GET_AC(ch) = 100; if (affected_by_spell(ch, SKILL_ARMOR)) GET_AC(ch) -= 20; if (affected_by_spell(ch, SKILL_BLINDNESS)) GET_AC(ch) += 40; if (ch->desc) if (ch->desc->original) do_return(ch, "", 0); if (IS_NPC(ch)) { if (ch->nr > -1) /* if mobile */ mob_index[ch->nr].number--; /* clearMemory(ch); Only NPC's can have memory */ SET_BIT(ch->specials.act,ACT_CLEANUP); return; } if (ch->desc) { ch->desc->connected = CON_SLCT; SEND_TO_Q(menu, ch->desc); remove_char(ch); } else SET_BIT(ch->specials.act,ACT_CLEANUP); } void remove_char(struct char_data *ch) { struct char_data *i; if(ch->in_room!=NOWHERE) char_from_room(ch); if(character_list==ch) character_list=ch->next; else for(i=character_list;i->next;i=i->next) if(i->next==ch) { i->next=ch->next; break; } ch->next=NULL; reset_char(ch); } /* *********************************************************************** Here follows high-level versions of some earlier routines, ie functions which incorporate the actual player-data. *********************************************************************** */ struct char_data *get_char_room_vis(struct char_data *ch, char *name) { struct char_data *i; int j, number; char tmpname[MAX_INPUT_LENGTH+50]; char *tmp; strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); if(!str_cmp(name,"me") || !str_cmp(name,"self")) return(ch); for (i = world[ch->in_room].people, j = 1; i && (j <= number); i = i->next_in_room) if (isname(tmp, GET_NAME(i))) if (CAN_SEE(ch, i)) { if (j == number) return(i); j++; } return(0); } struct char_data *get_char_vis(struct char_data *ch, char *name) { struct char_data *i; int j, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp; /* check location */ if ((i = get_char_room_vis(ch, name))) return(i); strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); for (i = character_list, j = 1; i && (j <= number); i = i->next) if (isname(tmp, GET_NAME(i))) if (CAN_SEE(ch, i)) { if (j == number) return(i); j++; } return(0); } struct obj_data *get_obj_in_list_vis(struct char_data *ch, char *name, struct obj_data *list) { struct obj_data *i; int j, number; char tmpname[MAX_INPUT_LENGTH+50]; char *tmp; strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); for (i = list, j = 1; i && (j <= number); i = i->next_content) if (isname(tmp, i->name)) if (CAN_SEE_OBJ(ch, i)) { if (j == number) return(i); j++; } return(0); } /*search the entire world for an object, and return a pointer */ struct obj_data *get_obj_vis(struct char_data *ch, char *name) { struct obj_data *i; int j, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp; /* scan items carried */ if ((i = get_obj_in_list_vis(ch, name, ch->carrying))) return(i); /* scan room */ if ((i = get_obj_in_list_vis(ch, name, world[ch->in_room].contents))) return(i); strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); /* ok.. no luck yet. scan the entire obj list */ for (i = object_list, j = 1; i && (j <= number); i = i->next) if (isname(tmp, i->name)) if (CAN_SEE_OBJ(ch, i)) { if (j == number) return(i); j++; } return(0); } struct room_data *get_room_vis(struct char_data *ch, char *name) { return NULL; } /* NOTE WARNING HEY HI THERE - this function isn't being called REMOVE later if no good reason is found to keep it */ struct obj_data *create_money( int amount ) { struct obj_data *obj; struct obj_info_money *money; struct extra_descr_data *new_descr; char buf[80]; char *strdup(char *str); if(amount<=0) { log("BUG: Try to create negative money."); exit(1); } CREATE(obj, struct obj_data, 1); CREATE(new_descr, struct extra_descr_data, 1); clear_object(obj); if(amount==1) { obj->name = strdup("coin gold"); obj->short_description = strdup("a gold coin"); obj->description = strdup("One miserable gold coin."); new_descr->keyword = strdup("coin gold"); new_descr->description = strdup("One miserable gold coin."); } else { obj->name = strdup("coins gold"); obj->short_description = strdup("gold coins"); obj->description = strdup("A pile of gold coins."); new_descr->keyword = strdup("coins gold"); if(amount<10) { sprintf(buf,"There are %d coins.",amount); new_descr->description = strdup(buf); } else if (amount<100) { sprintf(buf,"There are about %d coins",10*(amount/10)); new_descr->description = strdup(buf); } else if (amount<1000) { sprintf(buf,"It looks like something around %d coins",100*(amount/100)); new_descr->description = strdup(buf); } else if (amount<100000) { sprintf(buf,"You guess there are %d coins",1000*(amount/1000)); new_descr->description = strdup(buf); } else new_descr->description = strdup("There are A LOT of coins"); } new_descr->next = 0; obj->ex_description = new_descr; obj->obj_flags.extra_flags = ITEM_TAKE; money = (struct obj_info_money *)new_obj_info(ITEM_MONEY,obj); money->amount = amount; money->money_type = MONEY_GOLD_HUMAN; /* default? value */ obj->obj_flags.cost = amount; obj->item_number = -1; obj->next = object_list; object_list = obj; return(obj); } /* Generic Find, designed to find any object/character */ /* Calling : */ /* *arg is the sting containing the string to be searched for. */ /* This string doesn't have to be a single word, the routine */ /* extracts the next word itself. */ /* bitv.. All those bits that you want to "search through". */ /* Bit found will be result of the function */ /* *ch This is the person that is trying to "find" */ /* **tar Will be NULL if nothing was found, otherwise points */ /* */ /* The routine returns a pointer to the next word in *arg (just like the */ /* one_argument routine). */ int generic_find(char *arg, int bitvector, struct char_data *ch, void **tar) { static char *ignore[] = { "the", "in", "on", "at", "\n" }; int i; char name[256]; bool found; found = FALSE; /* Eliminate spaces and "ignore" words */ while (*arg && !found) { for(; *arg == ' '; arg++) ; for(i=0; (name[i] = *(arg+i)) && (name[i]!=' '); i++) ; name[i] = 0; arg+=i; if (search_block(name, ignore, TRUE) > -1) found = TRUE; } if (!name[0]) return(0); *tar = 0; if (IS_SET(bitvector, FIND_CHAR_ROOM)) { /* Find person in room */ if ((*tar = (void *) get_char_room_vis(ch, name))) { return(FIND_CHAR_ROOM); } } if (IS_SET(bitvector, FIND_CHAR_WORLD)) { if ((*tar = (void *) get_char_vis(ch, name))) { return(FIND_CHAR_WORLD); } } if (IS_SET(bitvector, FIND_OBJ_INV)) { if ((*tar = (void *) get_obj_in_list_vis(ch, name, ch->carrying))) { return(FIND_OBJ_INV); } } if (IS_SET(bitvector, FIND_OBJ_ROOM)) { if ((*tar = (void *) get_obj_in_list_vis(ch, name, world[ch->in_room].contents))) { return(FIND_OBJ_ROOM); } } if (IS_SET(bitvector, FIND_OBJ_WORLD)) { if ((*tar = (void *) get_obj_vis(ch, name))) { return(FIND_OBJ_WORLD); } } if (IS_SET(bitvector, FIND_ROOM)) { if ((*tar = (void *) get_room_vis(ch, name))) { return(FIND_ROOM); } } return(0); }