/** * \file handler.c * Mainupulates objects and characters * * This module deals with effects in room or on objects, transfer of objects, * transfers of characters, sets up and reads registries, and updates delays. * * Copyright 2005, Mary C. Huston, All rights reserved. * Copyright (C) 2004, Shadows of Isildur: Traithe * * The program(s) may be used and/or copied only with written * permission or in accordance with the terms and conditions * stipulated in the license from DIKU GAMMA (0.0) and SOI. * * \author Mary Huston * \author Email: auroness@gmail.com * ****************************************************************************** */ #include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include "structs.h" #include "protos.h" #include "utils.h" #include "decl.h" extern NAME_SWITCH_DATA *clan_name_switch_list; int is_hooded (CHAR_DATA *ch) { OBJ_DATA *obj; if ( (obj = get_equip (ch, WEAR_ABOUT)) && IS_SET (obj->obj_flags.extra_flags, ITEM_MASK) && IS_SET (ch->affected_by, AFF_HOODED) ) return 1; if ( ((obj = get_equip (ch, WEAR_HEAD)) || (obj = get_equip (ch, WEAR_FACE))) && IS_SET(obj->obj_flags.extra_flags, ITEM_MASK) ) { if ( obj->obj_flags.type_flag == ITEM_WORN || obj->obj_flags.type_flag == ITEM_ARMOR ) return 1; } return 0; } char *char_names (CHAR_DATA *ch) { OBJ_DATA *obj = NULL; if ( (obj = get_equip (ch, WEAR_ABOUT)) && IS_SET (obj->obj_flags.extra_flags, ITEM_MASK) && IS_SET (ch->affected_by, AFF_HOODED) ) return obj->desc_keys; if ( ((obj = get_equip (ch, WEAR_HEAD)) || (obj = get_equip (ch, WEAR_FACE))) && IS_SET(obj->obj_flags.extra_flags, ITEM_MASK)) { if ( obj->obj_flags.type_flag == ITEM_WORN ) { if ( !obj->desc_keys ) return "obscured"; return obj->desc_keys; } if ( obj->obj_flags.type_flag == ITEM_ARMOR ) { if ( !obj->desc_keys ) return "obscured"; return obj->desc_keys; } } return ch->name; } char *fname (char *namelist) { static char holder[30]; char *point = NULL; if ( !namelist ) return ""; for (point = holder; isalpha(*namelist); namelist++, point++) *point = *namelist; *point = '\0'; return(holder); } char *fname_hyphen (char *namelist) { static char holder [30]; char *point = NULL; if ( !namelist ) return "obscured"; for ( point = holder; isalpha (*namelist) || *namelist == '-' || *namelist == ' '; namelist++, point++ ) *point = *namelist; *point = '\0'; return holder; } int name_is (char *str, char *namelist) { char *curname = NULL; char *curstr = NULL; if ( !str ) return 0; if ( !namelist ) return 0; curname = namelist; for (;;) { for (curstr = str;; curstr++, curname++) { if ((!*curstr && !isalpha(*curname)) || is_abbrev(curstr,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 */ } return(0); } int real_skill (CHAR_DATA *ch, int skill) { if ( !IS_NPC (ch) ) return ch->skills [skill]; else return vtom (ch->mob->virtual)->skills [skill]; } /** sn is the spell number. not used right now, but it will be in the future **/ void affect_modify (CHAR_DATA *ch, int type, int loc, int mod, int bitv, int add, int sn) { if ( type >= JOB_1 && type <= JOB_3 ) return; if ( type >= CRAFT_FIRST && type <= CRAFT_LAST ) return; if ( type >= MAGIC_SMELL_FIRST && type <= MAGIC_SMELL_LAST ) return; if ( type >= MAGIC_FIRST_SOMA && type <= MAGIC_LAST_SOMA ) return; if ( type == MAGIC_GUARD ) return; if ( type == AFFECT_SHADOW ) return; if (type == MUTE_EAVESDROP ) return; if ( add && bitv ) SET_BIT (ch->affected_by, bitv); else if ( bitv ) { REMOVE_BIT (ch->affected_by, bitv); mod = -mod; } /* switch (type) { case SPELL_STRENGTH: GET_STR (ch) += mod; return; case SPELL_DEXTERITY: GET_DEX (ch) += mod; return; case SPELL_INTELLIGENCE: GET_INT (ch) += mod; return; case SPELL_AURA: GET_AUR (ch) += mod; return; case SPELL_WILL: GET_WIL (ch) += mod; return; case SPELL_CONSTITUTION: GET_CON (ch) += mod; return; case SPELL_AGILITY: GET_AGI (ch) += mod; return; default: break; } */ if ( loc >= (SKILL_BRAWLING+10000) && loc <= (LAST_SKILL+10000) ) { if ( add ) ch->skills [loc-10000] += mod; else { if ( ch->pc && ch->pc->skills [loc-10000] < ch->skills [loc-10000] ) ch->skills [loc-10000] -= mod; else if ( !ch->pc ) ch->skills [loc-10000] -= mod; } return; } else switch (loc) { case APPLY_NONE: case APPLY_CASH: case APPLY_SAVING_BREATH: case APPLY_SAVING_SPELL: case APPLY_AC: 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_AUR: GET_AUR (ch) += mod; break; case APPLY_WIL: GET_WIL (ch) += mod; ch->max_move = calc_lookup (ch, REG_MISC, MISC_MAX_MOVE); break; case APPLY_CON: GET_CON (ch) += mod; if ( !IS_NPC (ch) ){ ch->max_hit = 10 + 6 * GET_CON (ch); } else { ch->max_hit += mod * 6; if ( GET_HIT (ch) > ch->max_hit ){ GET_HIT (ch) = ch->max_hit; } } ch->max_move = calc_lookup (ch, REG_MISC, MISC_MAX_MOVE); break; case APPLY_AGI: GET_AGI (ch) += mod; break; case APPLY_AGE: ch->time.birth += mod; break; case APPLY_HIT: ch->max_hit += mod; break; case APPLY_MOVE: ch->max_move += mod; break; case APPLY_DAMROLL: if ( IS_NPC (ch) ){ GET_DAMROLL (ch) += mod; } break; default: break; } /* switch */ return; } void nullify_affects (CHAR_DATA *ch) { AFFECTED_TYPE *af = NULL; OBJ_DATA *eq = NULL; int i = 0; /* Remove affects caused by equipment */ for ( i = 0; i < MAX_WEAR; i++ ) { if ( !(eq = get_equip (ch, i)) || i == WEAR_BELT_1 || i == WEAR_BELT_2 || i == WEAR_BACK ) continue; for ( af = eq->xaffected; af; af = af->next ) { if ( (af->a.spell.location != APPLY_OFFENSE && af->a.spell.location != APPLY_DEFENSE) ) affect_modify (ch, af->type, af->a.spell.location, af->a.spell.modifier, eq->obj_flags.bitvector, FALSE, 0); } } /* Remove affects caused by spells */ for (af = ch->hour_affects; af; af = af->next ) affect_modify (ch, af->type, af->a.spell.location, af->a.spell.modifier, af->a.spell.bitvector, FALSE, af->a.spell.sn); /* Restore base capabilities */ ch->tmp_str = ch->str; ch->tmp_dex = ch->dex; ch->tmp_intel = ch->intel; ch->tmp_aur = ch->aur; ch->tmp_con = ch->con; ch->tmp_wil = ch->wil; return; } void reapply_affects (CHAR_DATA *ch) { AFFECTED_TYPE *af = NULL; OBJ_DATA *eq = NULL; int i = 0; /* Add equipment affects back */ for ( i = 0; i < MAX_WEAR; i++ ) { if ( !(eq = get_equip (ch, i)) || i == WEAR_BELT_1 || i == WEAR_BELT_2 || i == WEAR_BACK ) continue; for ( af = eq->xaffected; af; af = af->next ) if ( af->a.spell.location != APPLY_OFFENSE && af->a.spell.location != APPLY_DEFENSE ) affect_modify (ch, af->type, af->a.spell.location, af->a.spell.modifier, eq->obj_flags.bitvector, TRUE, 0); } /* Add spell affects back */ for ( af = ch->hour_affects; af; af = af->next ) affect_modify (ch, af->type, af->a.spell.location, af->a.spell.modifier, af->a.spell.bitvector, TRUE, af->a.spell.sn); /* Make certain values are between 0..25, not < 0 and not > 25! */ GET_DEX (ch) = MAX (0, MIN (GET_DEX (ch), 25)); GET_INT (ch) = MAX (0, MIN (GET_INT (ch), 25)); GET_WIL (ch) = MAX (0, MIN (GET_WIL (ch), 25)); GET_AUR (ch) = MAX (0, MIN (GET_AUR (ch), 25)); GET_CON (ch) = MAX (0, MIN (GET_CON (ch), 25)); GET_STR (ch) = MAX (0, MIN (GET_STR (ch), 25)); return; } AFFECTED_TYPE *get_obj_affect_location (OBJ_DATA *obj, int location) { AFFECTED_TYPE *af = NULL; if ( !obj->xaffected ) return NULL; for ( af = obj->xaffected; af; af = af->next ) if ( af->a.spell.location == location ) return af; return NULL; } void remove_obj_affect_location (OBJ_DATA *obj, int location) { AFFECTED_TYPE *af = NULL; AFFECTED_TYPE *taf = NULL; if ( !obj->xaffected ) return; if ( obj->xaffected->a.spell.location == location ) { af = obj->xaffected; obj->xaffected = obj->xaffected->next; mem_free (af); return; } for ( af = obj->xaffected; af->next; af = af->next ){ if ( af->next->a.spell.location == location ) { taf = af->next; af->next = taf->next; mem_free (taf); return; } } return; } void affect_to_obj (OBJ_DATA *obj, AFFECTED_TYPE *af) { AFFECTED_TYPE *taf = NULL; if ( !obj->xaffected ) { obj->xaffected = af; return; } for ( taf = obj->xaffected; taf->next; taf = taf->next ) ; /* cycles through taf */ taf->next = af; return; } void remove_obj_affect (OBJ_DATA *obj, int type) { AFFECTED_TYPE *af = NULL; AFFECTED_TYPE *free_af = NULL; if ( !obj->xaffected ) return; if ( obj->xaffected->type == type ) { af = obj->xaffected; obj->xaffected = af->next; mem_free (af); return; } for ( af = obj->xaffected; af->next; af = af->next ) { if ( af->next->type == type ) { free_af = af->next; af->next = free_af->next; mem_free (free_af); return; } } return; } AFFECTED_TYPE *get_obj_affect (OBJ_DATA *obj, int type) { AFFECTED_TYPE *af = NULL; if ( !obj->xaffected ) return NULL; for ( af = obj->xaffected; af; af = af->next ) if ( af->type == type ) return af; return NULL; } AFFECTED_TYPE *get_affect (CHAR_DATA *ch, int affect_type) { AFFECTED_TYPE *af = NULL; for ( af = ch->hour_affects; af && af->type != affect_type; af = af->next); return af; } /* Insert an affect_type in a char_data structure Automatically sets apropriate bits and apply's. */ void affect_to_char (CHAR_DATA *ch, AFFECTED_TYPE *af) { af->next = ch->hour_affects; ch->hour_affects = af; affect_modify (ch, af->type, af->a.spell.location, af->a.spell.modifier, af->a.spell.bitvector, TRUE, af->a.spell.sn); return; } void remove_affect_type (CHAR_DATA *ch, int type) { AFFECTED_TYPE *af = NULL; if ( (af = get_affect (ch, type)) ) affect_remove (ch, af); return; } /* 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 (CHAR_DATA *ch, AFFECTED_TYPE *af) { AFFECTED_TYPE *taf = NULL; affect_modify (ch, af->type, af->a.spell.location, af->a.spell.modifier, af->a.spell.bitvector, FALSE, af->a.spell.sn); /* remove structure *af from linked list */ if (ch->hour_affects == af) ch->hour_affects = af->next; else { for (taf = ch->hour_affects; taf && taf->next != af; taf = taf->next ) ; if ( !taf ) { return; } taf->next = af->next; } if ( af->type >= CRAFT_FIRST && af->type <= CRAFT_LAST ) mem_free (af->a.craft); mem_free (af); return; } void char_from_room (CHAR_DATA *ch) { CHAR_DATA *i = NULL; ROOM_DATA *room = NULL; AFFECTED_TYPE *af = NULL; if (ch->in_room == NOWHERE) { system_log("NOWHERE extracting char from room (handler.c, char_from_room)", TRUE); abort(); } if ( ch->room == NULL ) return; room = ch->room; if ( room && room->sector_type == SECT_LEANTO && IS_MORTAL(ch)) room->deity--; if ( ch == room->people ) /* head of list */ room->people = ch->next_in_room; else { /* locate the previous element */ for (i = room->people; i; i = i->next_in_room) { if ( i->next_in_room == ch ) { i->next_in_room = ch->next_in_room; break; } } } ch->in_room = NOWHERE; ch->room = NULL; ch->next_in_room = NULL; if ( (af = get_affect (ch, MAGIC_SIT_TABLE)) ) remove_affect_type (ch, MAGIC_SIT_TABLE); if ( room ) room_light (room); return; } /* place a character in a room */ void char_to_room (CHAR_DATA *ch, int room_num) { OBJ_DATA *obj = NULL; ROOM_DATA *room = NULL; ROOM_DATA *troom = NULL; char buf [MAX_STRING_LENGTH] = {'\0'}; int curr = 0; char *temp_arg = NULL; if ( ch->in_room > 100000 && vtor(ch->was_in_room) ) { troom = vtor(ch->was_in_room); load_save_room (troom); for ( obj = troom->contents; obj; obj = obj->next_content ) { if ( obj->deleted ) continue; if ( obj->o.od.value[0] == ch->in_room ) { if ( !(room = vtor (obj->o.od.value[0])) ){ room = generate_dwelling_room (obj); } temp_arg = obj_short_desc(obj); snprintf (buf, MAX_STRING_LENGTH, "#2%s#0 rustles as its occupants stir.", temp_arg); buf[2] = toupper(buf[2]); send_to_room (buf, obj->in_room); REMOVE_BIT (obj->obj_flags.extra_flags, ITEM_VNPC); room->occupants++; break; } } if ( !room ){ room = vtor(ch->was_in_room); } if ( !room ){ room = vtor (0); } } else if ( !(room = vtor (room_num)) ) { snprintf (buf, MAX_STRING_LENGTH, "Room %d doesn't exist in char_to_room()! (%s)", room_num, ch->tname); system_log (buf, TRUE); room = vtor (0); } if ( room->people && room->people != ch ) ch->next_in_room = room->people; else ch->next_in_room = NULL; room->people = ch; ch->in_room = room->virtual; ch->room = room; if ( !IS_NPC (ch) ) SET_BIT (room->room_flags, PC_ENTERED); if ( room->sector_type == SECT_UNDERWATER && !get_affect (ch, AFFECT_HOLDING_BREATH) ) { if ( IS_MORTAL(ch) ) { act ("You take a deep breath just before plunging into the water. . .", FALSE, ch, 0, 0, TO_CHAR); send_to_char ("\n", ch); curr = MAX(ch->skills [SKILL_SWIMMING] * number(1,3), 25); magic_add_affect (ch, AFFECT_HOLDING_BREATH, curr, 0, 0, 0, curr); } } else if ( room->sector_type != SECT_UNDERWATER && get_affect (ch, AFFECT_HOLDING_BREATH) ) { if ( IS_MORTAL(ch) ) { send_to_char ("\n", ch); act ("You inhale deeply, filling your lungs with much-needed air.", FALSE, ch, 0, 0, TO_CHAR); send_to_char ("\n", ch); } remove_affect_type (ch, AFFECT_HOLDING_BREATH); } room_light (ch->room); if ( !room->psave_loaded ) load_save_room (room); return; } void obj_to_char (OBJ_DATA *obj, CHAR_DATA *ch) /* STACKing */ { OBJ_DATA *tobj = NULL; bool stacked_obj = FALSE; /* Do object stacking */ if ( IS_SET (obj->obj_flags.extra_flags, ITEM_STACK) && !(GET_ITEM_TYPE (obj) == ITEM_FOOD && obj->o.food.food_value != obj->o.food.bites) ) { if ( ch->right_hand && ch->right_hand->virtual == obj->virtual ) { tobj = ch->right_hand; obj->count += tobj->count; extract_obj (tobj); stacked_obj = TRUE; ch->right_hand = obj; obj->carried_by = ch; obj->location = -1; obj->in_room = NOWHERE; obj->in_obj = NULL; return; } else if ( ch->left_hand && ch->left_hand->virtual == obj->virtual ) { tobj = ch->left_hand; obj->count += tobj->count; extract_obj (tobj); stacked_obj = TRUE; ch->left_hand = obj; obj->carried_by = ch; obj->location = -1; obj->in_room = NOWHERE; obj->in_obj = NULL; return; } } if ( ((ch->right_hand && ch->left_hand) && !stacked_obj) || get_equip (ch, WEAR_BOTH) ) { send_to_char ("Since your hands are full, you set the object on the ground.\n", ch); obj_to_room (obj, ch->in_room); obj->in_obj = NULL; return; } if ( !ch->right_hand ) ch->right_hand = obj; else ch->left_hand = obj; obj->carried_by = ch; obj->next_content = NULL; obj->location = -1; obj->in_room = NOWHERE; obj->in_obj = NULL; room_light (ch->room); return; } OBJ_DATA *split_obj (OBJ_DATA *obj, int count) { OBJ_DATA *new_obj = NULL; if ( obj->count < 1 || count >= obj->count ) return obj; obj->count -= count; new_obj = load_object (obj->virtual); new_obj->count = count; if ( obj->carried_by ) { new_obj->location = -1; new_obj->carried_by = obj->carried_by; new_obj->in_room = NOWHERE; IS_CARRYING_N (obj->carried_by)++; } else if ( obj->in_obj ) { new_obj->next_content = obj->in_obj->contains; obj->in_obj->contains = new_obj; } return new_obj; } void obj_from_char (OBJ_DATA **obj, int count) /* STACKing */ { int fluid = 0; int volume = 0; CHAR_DATA *ch = NULL; ch = (*obj)->carried_by; if ( ch == NULL ) { return; } if ( GET_ITEM_TYPE (*obj) == ITEM_DRINKCON ) { fluid = (*obj)->o.drinkcon.liquid; volume = (*obj)->o.drinkcon.volume; } /* Take a partial number of objs? */ if ( count != 0 && count < (*obj)->count ) { (*obj)->count -= count; if ( IS_SET ((*obj)->obj_flags.extra_flags, ITEM_VARIABLE) ) *obj = load_colored_object ((*obj)->virtual, (*obj)->var_color); else *obj = load_object ((*obj)->virtual); (*obj)->count = count; (*obj)->carried_by = NULL; if ( GET_ITEM_TYPE (*obj) == ITEM_DRINKCON ) { (*obj)->o.drinkcon.liquid = fluid; (*obj)->o.drinkcon.volume = volume; } return; } /* Remove object from inventory */ if ( ch->right_hand == *obj ) ch->right_hand = NULL; else if ( ch->left_hand == *obj ) ch->left_hand = NULL; IS_CARRYING_N (ch)--; (*obj)->carried_by = NULL; (*obj)->next_content = NULL; (*obj)->equiped_by = NULL; (*obj)->in_room = NOWHERE; (*obj)->in_obj = NULL; room_light (ch->room); return; } void equip_char (CHAR_DATA *ch, OBJ_DATA *obj, int pos) { char buf [MAX_STRING_LENGTH] = {'\0'}; if ( ch == 0 ) { snprintf (buf, MAX_STRING_LENGTH, "#1OBJECT MORPHING BUG! NULL ch pointer. Crash averted. Object vnum %d.#0\n", obj->virtual); send_to_gods (buf); system_log(buf, TRUE); return; } if ( pos < 0 ) { snprintf (buf, MAX_STRING_LENGTH, "#1OBJECT MORPHING BUG! Crash averted. Position %d, vnum %d, character %s.#0\n", pos, obj->virtual, ch->tname); send_to_gods (buf); system_log(buf, TRUE); return; } if ( get_equip (ch, pos) ) return; if ( obj->in_room != NOWHERE ) { system_log("EQUIP: Obj is in_room when equip.", TRUE); return; } obj->location = pos; if ( pos != WEAR_PRIM && pos != WEAR_SEC && pos != WEAR_BOTH && pos != WEAR_SHIELD ) { obj->next_content = ch->equip; ch->equip = obj; } if ( pos == WEAR_PRIM || pos == WEAR_SEC || pos == WEAR_BOTH || pos == WEAR_SHIELD ){ obj->carried_by = ch; } obj->equiped_by = ch; return; } OBJ_DATA *unequip_char (CHAR_DATA *ch, int pos) { OBJ_DATA *obj = NULL; OBJ_DATA *tobj = NULL; obj = get_equip (ch, pos); if ( !obj ) return NULL; if ( IS_SET (obj->obj_flags.extra_flags, ITEM_MASK) && is_hooded(ch) ) REMOVE_BIT (ch->affected_by, AFF_HOODED); if ( ch->equip == obj ) ch->equip = ch->equip->next_content; else { for ( tobj = ch->equip; tobj; tobj = tobj->next_content ) if ( tobj->next_content && obj == tobj->next_content ) { tobj->next_content = obj->next_content; break; } } obj->location = -1; obj->equiped_by = NULL; obj->next_content = NULL; if ( ch->aiming_at ) { ch->aiming_at->targeted_by = NULL; ch->aiming_at = NULL; ch->aim = 0; ch->delay_info1 = 0; ch->delay_who = NULL; send_to_char ("You stop aiming your weapon.\n", ch); } return (obj); } int get_number(char **name) { int i = 0; char *ppos = NULL; char number [MAX_INPUT_LENGTH] = { '\0' }; if ((ppos = (char *) strchr(*name, '.'))) { /* find a decimal point */ *ppos++ = '\0'; /* move past the decimal */ strcpy(number,*name); /* copy all of name to number */ strcpy(*name, ppos); /* name now starts past the decimal */ for(i=0; *(number+i); i++) if (!isdigit(*(number+i))) return(0); return(strtol(number, NULL, 10)); } return(1); } OBJ_DATA *get_carried_item (CHAR_DATA *ch, int item_type) { if ( !ch ) return NULL; if ( ch->right_hand && GET_ITEM_TYPE (ch->right_hand) == item_type ) return ch->right_hand; if ( ch->left_hand && GET_ITEM_TYPE (ch->left_hand) == item_type ) return ch->left_hand; return NULL; } /* Search a given list for an object, and return a pointer to that object */ OBJ_DATA *get_obj_in_list(char *name, OBJ_DATA *list) { OBJ_DATA *i = NULL; int j = 0; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; 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 (name_is(tmp, i->name) || (GET_ITEM_TYPE(i) == ITEM_BOOK && i->book_title && name_is(tmp, i->book_title)) ) { if (j == number) return(i); j++; } } return(0); } OBJ_DATA *get_obj_in_list_num(int num, OBJ_DATA *list) { OBJ_DATA *obj = NULL; for ( obj = list; obj; obj = obj->next_content) if ( obj->virtual == num ) return obj; return NULL; } /*search the entire world for an object, and return a pointer */ OBJ_DATA *get_obj(char *name) { OBJ_DATA *i = NULL; int j = 0; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(NULL); for (i = object_list, j = 1; i && (j <= number); i = i->next) { if ( i->deleted ) continue; if (name_is(tmp, i->name) || (GET_ITEM_TYPE(i) == ITEM_BOOK && i->book_title && name_is(tmp, i->book_title)) ) { if (j == number) return(i); j++; } } return(NULL); } CHAR_DATA *get_char_id (int coldload_id) { CHAR_DATA *ch = NULL; for ( ch = character_list; ch; ch = ch->next ) { if ( ch->deleted ) continue; if ( ch->coldload_id == coldload_id ) return ch; } return NULL; } OBJ_DATA *get_obj_in_list_id (int coldload_id, OBJ_DATA *list) { OBJ_DATA *obj = NULL; for ( obj = list; obj; obj = obj->next_content ) { if ( obj->deleted ) continue; if ( obj->coldload_id == coldload_id ) return obj; } return NULL; } OBJ_DATA *get_obj_id (int coldload_id) { OBJ_DATA *obj = NULL; for ( obj = object_list; obj; obj = obj->next ) { if ( obj->deleted ) continue; if ( obj->coldload_id == coldload_id ) return obj; } return NULL; } /* search a room for a char, and return a pointer if found.. */ CHAR_DATA *get_char_room (char *name, int room) { CHAR_DATA *i = NULL; int j = 0; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; char *temp_arg = NULL; strcpy(tmpname,name); tmp = tmpname; if(!(number = get_number(&tmp))) return(0); for (i = vtor (room)->people,j = 1; i && (j <= number); i = i->next_in_room){ temp_arg = char_names(i); if (name_is(tmp, temp_arg)) { if (j == number) return(i); j++; } } return(0); } /* search all over the world for a char, and return a pointer if found */ CHAR_DATA *get_char (char *name) { CHAR_DATA *i = NULL; int j = 0; int number = 0; char tmpname [MAX_INPUT_LENGTH]; char *tmp = NULL; char *temp_arg = NULL; strcpy (tmpname, name); tmp = tmpname; if ( !(number = get_number (&tmp)) ) return NULL; for (i = character_list, j = 1; i && (j <= number); i = i->next) { if ( i->deleted ) continue; temp_arg = char_names(i); if (name_is(tmp, temp_arg)) { if (j == number) return(i); j++; } } return NULL; } /* search all over the world for a char, and return a pointer if found */ CHAR_DATA *get_mob_vnum (int virtual) { CHAR_DATA *i = NULL; for (i = character_list; i; i = i->next) { if ( i->deleted ) continue; if ( !IS_NPC (i) ) continue; if ( i->mob->virtual == virtual ) return i; } return 0; } /* search all over the world for a char, and return a pointer if found */ CHAR_DATA *get_char_nomask (char *name) { CHAR_DATA *i = NULL; int j = 0; int number = 0; char tmpname [MAX_INPUT_LENGTH]; char *tmp = NULL; 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 ( i->deleted ) continue; if ( name_is (tmp, GET_NAMES (i)) ) { if (j == number) return(i); j++; } } return 0; } void obj_to_room (OBJ_DATA *object, int room) /* STACKing */ { int add_at_top = 0; ROOM_DIRECTION_DATA *exit_room = NULL; ROOM_DATA *r = NULL; ROOM_DATA *troom = NULL; OBJ_DATA *tobj = NULL; char buf [MAX_STRING_LENGTH] = {'\0'}; char *temp_arg = NULL; if ( !object ) return; r = vtor (room); if ( !r ) return; if ( r->contents && IS_SET (object->obj_flags.extra_flags, ITEM_STACK) ) { if ( r->contents->virtual == object->virtual ) { r->contents->count += object->count; extract_obj (object); room_light (r); return; } for ( tobj = r->contents; tobj; tobj = tobj->next_content ) { if ( tobj->virtual != object->virtual ) continue; tobj->count += object->count; extract_obj (object); room_light (r); return; } } if ( add_at_top ) { object->next_content = r->contents; r->contents = object; } else { if ( !r->contents ) { r->contents = object; object->next_content = NULL; } else for ( tobj = r->contents; tobj; tobj = tobj->next_content ) { if ( !tobj->next_content ) { tobj->next_content = object; object->next_content = NULL; break; } } } object->in_room = room; object->carried_by = 0; object->equiped_by = NULL; object->in_obj = NULL; object->location = -1; room_light (r); exit_room = r->dir_option[DIR_DOWN]; if ( exit_room ) { troom = vtor (exit_room->to_room); if ( troom && troom->sector_type != SECT_UNDERWATER ){ troom = NULL; } } if ( troom && (object->obj_flags.weight/100 >= 1 || GET_ITEM_TYPE (object) == ITEM_MONEY) ) { temp_arg = obj_short_desc(object); snprintf (buf, MAX_STRING_LENGTH, "#2%s#0 slowly sinks from sight down into the water.", temp_arg); buf[2] = toupper(buf[2]); send_to_room (buf, r->virtual); obj_from_room (&object, 0); obj_to_room (object, troom->virtual); temp_arg = obj_short_desc(object); snprintf (buf, MAX_STRING_LENGTH, "#2%s#0 slowly sinks into view from above.", temp_arg); buf[2] = toupper(buf[2]); send_to_room (buf, object->in_room); } } /* Take an object from a room */ void obj_from_room (OBJ_DATA **obj, int count) /* STACKing */ { int fluid = 0; int volume = 0; OBJ_DATA *tobj = NULL; ROOM_DATA *room = NULL; room = vtor ((*obj)->in_room); if ( !room ) return; if ( GET_ITEM_TYPE (*obj) == ITEM_DRINKCON ) { fluid = (*obj)->o.drinkcon.liquid; volume = (*obj)->o.drinkcon.volume; } /* NPC jailbags disappear, unless they are taken */ if ( (*obj)->virtual == VNUM_JAILBAG ) (*obj)->obj_timer = 0; /* Take a partial number of objs? */ if ( count != 0 && count < (*obj)->count ) { (*obj)->count -= count; if ( IS_SET ((*obj)->obj_flags.extra_flags, ITEM_VARIABLE) ) *obj = load_colored_object ((*obj)->virtual, (*obj)->var_color); else *obj = load_object ((*obj)->virtual); (*obj)->count = count; if ( GET_ITEM_TYPE (*obj) == ITEM_DRINKCON ) { (*obj)->o.drinkcon.liquid = fluid; (*obj)->o.drinkcon.volume = volume; } room_light (room); (*obj)->in_room = NOWHERE; (*obj)->next_content = NULL; return; } /* Remove object from the room */ if ( room->contents == *obj ) room->contents = (*obj)->next_content; else { for ( tobj = room->contents; tobj->next_content; tobj = tobj->next_content ){ if ( tobj->next_content == *obj ) { tobj->next_content = (*obj)->next_content; break; } } } (*obj)->in_room = NOWHERE; (*obj)->next_content = NULL; room_light (room); remove_obj_affect (*obj, MAGIC_HIDDEN); return; } void obj_to_obj (OBJ_DATA *obj, OBJ_DATA *container) { OBJ_DATA *tobj = NULL; if ( !obj || !container ) return; if ( IS_SET (obj->obj_flags.extra_flags, ITEM_STACK) && (tobj = get_obj_in_list_num (obj->virtual, container->contains)) ) { obj->count += tobj->count; extract_obj (tobj); } obj->in_obj = container; obj->equiped_by = NULL; obj->carried_by = NULL; if ( container->contains && !is_obj_in_list (obj, container->contains) ) obj->next_content = container->contains; else if ( !container->contains ) container->contains = obj; else { extract_obj (obj); return; } container->contains = obj; obj->location = -1; for ( tobj = container; tobj; tobj = tobj->in_obj ) tobj->contained_wt += OBJ_MASS (obj); return; } void obj_from_obj (OBJ_DATA **obj, int count) { int adjust_wt = 0; int fluid = 0; int volume = 0; OBJ_DATA *tobj = NULL; if ( !(*obj) ) return; if ( count < 0 ) count = 0; if ( !count ) count = (*obj)->count; if ( GET_ITEM_TYPE (*obj) == ITEM_DRINKCON ) { fluid = (*obj)->o.drinkcon.liquid; volume = (*obj)->o.drinkcon.volume; } /* Removing only part of obj from container */ if ( count < (*obj)->count ) { tobj = *obj; if ( IS_SET (tobj->obj_flags.extra_flags, ITEM_VARIABLE) ) *obj = load_colored_object (tobj->virtual, tobj->var_color); else *obj = load_object (tobj->virtual); tobj->count -= count; (*obj)->count = count; (*obj)->in_obj = tobj->in_obj; if ( GET_ITEM_TYPE (*obj) == ITEM_DRINKCON ) { (*obj)->o.drinkcon.liquid = fluid; (*obj)->o.drinkcon.volume = volume; } adjust_wt = (*obj)->count * (*obj)->obj_flags.weight; } else { /* Removing obj completely from container */ adjust_wt = OBJ_MASS (*obj); if ( (*obj)->in_obj->contains == *obj ) (*obj)->in_obj->contains = (*obj)->next_content; else { for ( tobj = (*obj)->in_obj->contains; tobj->next_content; tobj = tobj->next_content ){ if ( tobj->next_content == *obj ) { tobj->next_content = (*obj)->next_content; break; } } } } for ( tobj = (*obj)->in_obj; tobj; tobj = tobj->in_obj ) tobj->contained_wt -= adjust_wt; (*obj)->next_content = NULL; (*obj)->in_obj = NULL; return; } void object_list_new_owner(OBJ_DATA *list, CHAR_DATA *ch) { if (list) { object_list_new_owner(list->contains, ch); object_list_new_owner(list->next_content, ch); list->carried_by = ch; } return; } void remove_object_affect (OBJ_DATA *obj, AFFECTED_TYPE *af) { AFFECTED_TYPE *taf = NULL; if ( af == obj->xaffected ) { obj->xaffected = af->next; mem_free (af); return; } for ( taf = obj->xaffected; taf->next; taf = taf->next ) { if ( af == taf->next ) { taf->next = af->next; mem_free (af); return; } } return; } void destroy_dwelling (OBJ_DATA *obj) { OBJ_DATA *tobj = NULL; OBJ_DATA *tobj_next = NULL; CHAR_DATA *tch = NULL; CHAR_DATA *tch_next = NULL; ROOM_DATA *troom = NULL; char buf [MAX_STRING_LENGTH] = {'\0'}; char *temp_arg = NULL; if ( !(troom = vtor (obj->o.od.value[0])) ) return; temp_arg = obj_short_desc(obj); snprintf (buf, MAX_STRING_LENGTH, "#2%s#0 is suddenly torn down around your ears!", temp_arg); buf[2] = toupper(buf[2]); send_to_room (buf, troom->virtual); for ( tobj = troom->contents; tobj; tobj = tobj_next ) { tobj_next = tobj->next_content; obj_from_room (&tobj, 0); obj_to_room (tobj, obj->in_room); } for ( tch = troom->people; tch; tch = tch_next ) { tch_next = tch->next_in_room; char_from_room (tch); char_to_room (tch, obj->in_room); } } void extract_obj (OBJ_DATA *obj) { if ( GET_ITEM_TYPE (obj) == ITEM_DWELLING || GET_ITEM_TYPE (obj) == ITEM_TENT ) destroy_dwelling (obj); while ( obj->contains ) extract_obj (obj->contains); if ( obj->equiped_by != NULL ) (void)unequip_char (obj->equiped_by, obj->location); if ( obj->carried_by != NULL ) obj_from_char (&obj, 0); else if ( obj->in_obj != NULL ) obj_from_obj (&obj, 0); else if ( obj->in_room != NOWHERE ) obj_from_room (&obj, 0); while ( obj->xaffected ) remove_object_affect (obj, obj->xaffected); obj->carried_by = NULL; obj->equiped_by = NULL; obj->in_obj = NULL; obj->deleted = 1; knockout = 1; /* Get obj out of object_list ASAP */ return; } void morph_obj (OBJ_DATA *obj) { CHAR_DATA *ch = NULL; OBJ_DATA *container = NULL; char buf [MAX_STRING_LENGTH] = {'\0'}; OBJ_DATA *newObj = NULL; int room = 0; /** has the object been deleted? **/ if(obj->deleted){ return; } /** Is the object in a storage room? **/ if (obj->in_room && vtor(obj->in_room) && IS_SET (vtor(obj->in_room)->room_flags, STORAGE) ){ return; } /** If the object is supposed to morph, does it have soemthing to morph into, and if it does, will the object dissaper after the morph? or is it replaced**/ if(obj->morphto) { if(obj->morphto == 86){ extract_obj(obj); return; } else{ newObj = load_object(obj->morphto); } } else { snprintf (buf, MAX_STRING_LENGTH, "Object %d has a morph clock, but no morph Objnum\n", obj->virtual); system_log (buf, TRUE); return; } /** does the new object exist?**/ if (!newObj) { snprintf (buf, MAX_STRING_LENGTH, "Attempt to load morph obj %d for object %d failed\n", obj->morphto, obj->virtual); system_log (buf, TRUE); return; } /** Is the old item equipped**/ if(obj->equiped_by) { (void)unequip_char (obj->equiped_by, obj->location); equip_char(obj->equiped_by, newObj, obj->location); } /** is the old item carried?**/ if ( obj->carried_by ) { ch = obj->carried_by; obj_from_char (&obj, 0); obj_to_char(newObj, ch); } /** Is the old object in a container? **/ if ( obj->in_obj ) { container = obj->in_obj; obj_from_obj (&obj, 0); obj_to_obj(newObj, container); } /** Is the old object in the room? **/ if ( obj->in_room != NOWHERE ) { room = obj->in_room; obj_from_room (&obj, 0); obj_to_room(newObj, room); } /** Remove any effects from the object **/ while ( obj->xaffected ){ remove_object_affect (obj, obj->xaffected); } /** Delete the old object **/ obj->deleted = 1; return; } void remove_sighting (CHAR_DATA *ch, CHAR_DATA *target) { VIEWED_DATA *sighted = NULL; if ( !ch || !target ) return; if ( ch->sighted && ch->sighted->target == target ) ch->sighted = ch->sighted->next; for ( sighted = ch->sighted; sighted; sighted = sighted->next ) { if ( sighted->next && sighted->next->target == target ) sighted->next = sighted->next->next; } return; } void extract_char (CHAR_DATA *ch) { CHAR_DATA *k = NULL; CHAR_DATA *next_char = NULL; CHAR_DATA *tch = NULL; ROOM_DATA *troom = NULL; OBJ_DATA *tobj = NULL; DESCRIPTOR_DATA *td = NULL; AFFECTED_TYPE *af = NULL; int was_in = 0; char buf [MAX_STRING_LENGTH] = {'\0'}; char *temp_arg = NULL; if ( port == PLAYER_PORT && IS_NPC(ch) && IS_SET (ch->act, ACT_STAYPUT) ) { mysql_safe_query ("DELETE FROM stayput_mobiles WHERE coldload_id = %d", ch->coldload_id); snprintf (buf, MAX_STRING_LENGTH, "save/mobiles/%d", ch->coldload_id); unlink (buf); } if ( port == PLAYER_PORT && IS_NPC(ch) ) { mysql_safe_query ("DELETE FROM reboot_mobiles WHERE coldload_id = %d", ch->coldload_id); snprintf (buf, MAX_STRING_LENGTH, "save/reboot/%d", ch->coldload_id); unlink (buf); } if ( port == PLAYER_PORT && IS_NPC (ch) && ch->mob->reset_cmd ) { zone_table [ch->room->zone].cmd [ch->mob->reset_cmd].enabled = 1; mysql_safe_query ("INSERT INTO mob_resets VALUES (%d, %d)", ch->room->zone, ch->mob->reset_cmd); } if ( ch->mob && IS_SET (ch->act, ACT_VEHICLE) && (troom = vtor (ch->mob->virtual)) ) { /* By mistake, the vehicle might be in the same room as its entrance room. In that case, n/pcs and mobs don't need to be moved. */ if ( troom == ch->room ) { act ("$n is destroyed and some people fall out.", FALSE, ch, 0, 0, TO_ROOM); for ( tch = troom->people; tch; tch = tch->next ) tch->vehicle = NULL; } else { while ( troom->people ) { tch = troom->people; char_from_room (tch); char_to_room (tch, ch->in_room); tch->vehicle = NULL; act ("$N falls out of $n.", FALSE, ch, 0, tch, TO_NOTVICT); act ("You fall out of $N as it is destroyed!", FALSE, tch, 0, ch, TO_CHAR); } while ( troom->contents ) { tobj = troom->contents; obj_from_room (&tobj, 0); obj_to_room (tobj, ch->in_room); } } } if ( ch->desc && ch->desc->original ) do_return (ch, "", 0); if ( !IS_NPC (ch) && ch->room ) save_attached_mobiles (ch, 1); if ( !IS_NPC (ch) ) clear_watch (ch); /* Clear out guarders */ for ( k = character_list; k; k = k->next ) { if ( k->deleted ) continue; if ( (af = get_affect (k, MAGIC_GUARD)) && (CHAR_DATA *) af->a.spell.t == ch ) affect_remove (k, af); } for ( k = character_list; k; k = k->next ) { if ( k->deleted ) continue; if ( k->ranged_enemy == ch ) { k->ranged_enemy = NULL; k->enemy_direction = NULL; } if ( k->aiming_at == ch ) { k->aiming_at->targeted_by = NULL; k->aiming_at = NULL; k->aim = 0; } else if ( k->targeted_by == ch ) { k->targeted_by->aiming_at = NULL; k->targeted_by->aim = 0; k->targeted_by = NULL; } if ( k->subdue == ch ) k->subdue = NULL; remove_threat (k, ch); remove_attacker (k, ch); remove_sighting (k, ch); } if ( !IS_NPC (ch) && ch->pc->edit_player ) unload_pc (ch->pc->edit_player); if ( !IS_NPC (ch) ) save_char (ch, TRUE); if ( !IS_NPC (ch) && !ch->desc ) { for ( td = descriptor_list; td; td = td->next ) if ( td->original == ch ) do_return (td->character, "", 0); } if ( ch->in_room == NOWHERE ) { system_log("NOWHERE extracting char. (handler.c, extract_char)", TRUE); abort(); } stop_followers (ch); /* Enable reset for killed mob */ if ( IS_NPC (ch) ) { if ( ch->mob->reset_zone != 0 || ch->mob->reset_cmd != 0 ) zone_table [ch->mob->reset_zone].cmd [ch->mob->reset_cmd].enabled = 1; } if ( ch->desc ) { if ( ch->desc->snoop.snooping && ch->desc->snoop.snooping->desc ) ch->desc->snoop.snooping->desc->snoop.snoop_by = 0; if ( ch->desc->snoop.snoop_by && ch->desc->snoop.snoop_by->desc ) { send_to_char ("Your victim is no longer among us.\n\r", ch->desc->snoop.snoop_by); ch->desc->snoop.snoop_by->desc->snoop.snooping = 0; } ch->desc->snoop.snooping = ch->desc->snoop.snoop_by = 0; } if ( ch->fighting ) stop_fighting (ch); for (k = combat_list; k ; k = next_char) { /* FUNDAMENTALLY FLAWED LOGIC */ next_char = k->next_fighting; if ( k->fighting == ch ) stop_fighting (k); } /* Must remove from room before removing the equipment! */ was_in = ch->in_room; char_from_room (ch); ch->in_room = was_in; if ( ch->right_hand ) extract_obj (ch->right_hand); if ( ch->left_hand ) extract_obj (ch->left_hand); while ( ch->equip ) extract_obj (ch->equip); ch->deleted = 1; if ( IS_NPC (ch) ) { while ( ch->hour_affects ) affect_remove (ch, ch->hour_affects); } if ( ch->desc != NULL ) ch->desc->character = NULL; knockout = 1; /* Get N/PC out of character_list ASAP */ if ( ch->desc != NULL && !ch->desc->account && !IS_SET (ch->flags, FLAG_GUEST) ) { td = ch->desc; if ( !maintenance_lock ){ temp_arg = get_text_buffer (NULL, text_list, "greetings"); SEND_TO_Q (temp_arg, td); } else{ temp_arg = get_text_buffer (NULL, text_list, "greetings.maintenance"); SEND_TO_Q (temp_arg, td); } SEND_TO_Q ("Your Choice: ", td); td->connected = 1; ch->desc = NULL; td->character = NULL; td->original = NULL; td->prompt_mode = 0; td->login_time = time_now; td->time_last_activity = mud_time; } } CHAR_DATA *get_char_room_vis (CHAR_DATA *ch, char *name) { CHAR_DATA *tch = NULL; int j = 1; int number = 0; char *tmp = NULL; char *temp_arg = NULL; /* The player may use '.' to indicate last targeted n/pc. */ if ( !strcmp (name, ".") ) { if ( !ch->pc ) return NULL; if ( is_he_here (ch, ch->pc->dot_shorthand, TRUE) ) return ch->pc->dot_shorthand; } if ( !strcmp (name, "self") || !strcmp (name, "me") ) return ch; tmp = name; if ( !(number = get_number (&tmp)) ) return NULL; for ( tch = ch->room->people; tch; tch = tch->next_in_room ) { temp_arg = char_names (tch); if ( name_is (tmp, IS_MORTAL (ch) ? temp_arg : tch->name) ) { if ( CAN_SEE(ch, tch) || ch == tch ) { if ( j == number ) { if ( ch->pc ) ch->pc->dot_shorthand = tch; return tch; } j++; } } } return NULL; } CHAR_DATA *get_char_room_vis2 (CHAR_DATA *ch, int vnum, char *name) { ROOM_DATA *room = NULL; CHAR_DATA *tch = NULL; int j = 1; int number = 0; char tmpname [MAX_STRING_LENGTH] = {'\0'}; char *tmp = NULL; char *temp_arg = NULL; if ( !(room = vtor(vnum)) ) return NULL; /* The player may use '.' to indicate last targeted n/pc. */ if ( !strcmp (name, ".") ) { if ( !ch->pc ) return NULL; if ( is_he_here (ch, ch->pc->dot_shorthand, TRUE) ) return ch->pc->dot_shorthand; } if ( !strcmp (name, "self") || !strcmp (name, "me") ) return ch; strcpy (tmpname, name); tmp = tmpname; if ( !(number = get_number (&tmp)) ) return NULL; for ( tch = room->people; tch; tch = tch->next_in_room ) { temp_arg = char_names (tch); if ( name_is (tmp, IS_MORTAL (ch) ? temp_arg : tch->name) ) { if ( CAN_SEE(ch, tch) || ch == tch ) { if ( j == number ) { if ( ch->pc ) ch->pc->dot_shorthand = tch; return tch; } j++; } } } return NULL; } CHAR_DATA *get_char_vis(CHAR_DATA *ch, char *name) { CHAR_DATA *i = NULL; int j = 0; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; if ( !strcmp (name, "self") || !strcmp (name, "me") ) return ch; /* 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 ( i->deleted ) continue; if ( name_is (tmp, GET_NAMES (i)) ) if ( CAN_SEE (ch, i) ) { if ( j == number ) return i; j++; } } return 0; } OBJ_DATA *get_obj_in_list_vis_not_money (CHAR_DATA *ch, char *name, OBJ_DATA *list) { OBJ_DATA *obj = NULL; int j = 1; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; strcpy (tmpname, name); tmp = tmpname; if ( !(number = get_number (&tmp)) ) return NULL; if ( isdigit (*name) ) { if ( !(number = strtol(name, NULL, 10)) ) return NULL; for ( obj = list; number && obj; obj = obj->next_content ) { if ( GET_ITEM_TYPE (obj) == ITEM_MONEY ) continue; if ( CAN_SEE_OBJ (ch, obj) && !(--number) ) return obj; } return NULL; } for ( obj = list; obj && (j <= number); obj = obj->next_content ) { if ( GET_ITEM_TYPE (obj) == ITEM_MONEY ) continue; if (name_is(tmp, obj->name) || (GET_ITEM_TYPE(obj) == ITEM_BOOK && obj->book_title && name_is(tmp, obj->book_title)) ) if ( CAN_SEE_OBJ(ch, obj) ) { if ( j == number) return(obj); j++; } } return 0; } OBJ_DATA *get_obj_in_list_vis (CHAR_DATA *ch, char *name, OBJ_DATA *list) { OBJ_DATA *obj = NULL; int j = 1; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; if ( !name || !*name ) return NULL; if ( !list ) return NULL; strcpy (tmpname, name); tmp = tmpname; if ( !(number = get_number (&tmp)) ) return NULL; if ( *name == '#' ) { if ( !(number = strtol(&name [1], NULL, 10)) ) return NULL; for ( obj = list; number && obj; obj = obj->next_content ) if ( CAN_SEE_OBJ (ch, obj) && !(--number) ) return obj; return NULL; } for ( obj = list; obj && (j <= number); obj = obj->next_content ) { if (name_is(tmp, obj->name) || (GET_ITEM_TYPE(obj) == ITEM_BOOK && obj->book_title && name_is(tmp, obj->book_title)) ) if ( CAN_SEE_OBJ(ch, obj) ) { if ( j == number) return(obj); j++; } } return 0; } OBJ_DATA *get_obj_in_dark (CHAR_DATA *ch, char *name, OBJ_DATA *list) { OBJ_DATA *obj = NULL; int j = 1; int number = 0; char tmpname [MAX_INPUT_LENGTH]; char *tmp = NULL; *tmpname = '\0'; strcpy (tmpname, name); tmp = tmpname; if ( !(number = get_number (&tmp)) ) return 0; if ( *name == '#' ) { if ( !(number = strtol(&name [1], NULL, 10)) ) return NULL; for ( obj = list; number && obj; obj = obj->next_content ) if ( IS_OBJ_VIS (ch, obj) && !(--number) ) return obj; return NULL; } for ( obj = list; obj && (j <= number); obj = obj->next_content ) { if (name_is(tmp, obj->name) || (GET_ITEM_TYPE(obj) == ITEM_BOOK && obj->book_title && name_is(tmp, obj->book_title)) ) if ( IS_OBJ_VIS (ch, obj) ) { if ( j == number ) return obj; j++; } } return 0; } /* search the entire world for an object, and return a pointer */ OBJ_DATA *get_obj_vis(CHAR_DATA *ch, char *name) { OBJ_DATA *i = NULL; int j = 0; int number = 0; char tmpname[MAX_INPUT_LENGTH]; char *tmp = NULL; /* scan items carried */ if ((i = get_obj_in_list_vis(ch, name, ch->right_hand)) ) return(i); if ((i = get_obj_in_list_vis(ch, name, ch->left_hand)) ) return(i); /* scan room */ if ((i = get_obj_in_list_vis(ch, name, vtor (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 ( i->deleted ) continue; if (name_is(tmp, i->name) || (GET_ITEM_TYPE(i) == ITEM_BOOK && i->book_title && name_is(tmp, i->book_title)) ) if (CAN_SEE_OBJ(ch, i)) { if (j == number) return(i); j++; } } return(0); } /** 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_ch Will be NULL if no character was found, otherwise points * * **tar_obj Will be NULL if no object 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, CHAR_DATA *ch, CHAR_DATA **tar_ch, OBJ_DATA **tar_obj) { static char *ignore[] = { "the", "in", "on", "at", "\n" }; int i = 0; char name[256]; bool 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_ch = 0; *tar_obj = 0; /** Find visibile target person in room **/ if (IS_SET(bitvector, FIND_CHAR_ROOM)) { if ((*tar_ch = get_char_room_vis(ch, name))) { return(FIND_CHAR_ROOM); } } /** Find visibile target person in the world **/ if (IS_SET(bitvector, FIND_CHAR_WORLD)) { if ((*tar_ch = get_char_vis(ch, name))) { return(FIND_CHAR_WORLD); } } /** Find equipped object on character **/ if (IS_SET(bitvector, FIND_OBJ_EQUIP)) { for(found=FALSE, i=-1; (i< MAX_WEAR) && !found; i++) if ( get_equip (ch, i) && !cmp_strn(name, get_equip (ch, i)->name, strlen(name))) { *tar_obj = get_equip (ch, i); found = TRUE; } if (found) { return(FIND_OBJ_EQUIP); } } /** Find object in characters inventory **/ if (IS_SET(bitvector, FIND_OBJ_INV)) { if ((*tar_obj = get_obj_in_list_vis(ch, name, ch->right_hand))) { return(FIND_OBJ_INV); } if ((*tar_obj = get_obj_in_list_vis(ch, name, ch->left_hand))) { return(FIND_OBJ_INV); } if ((*tar_obj = get_obj_in_list_vis(ch, name, ch->equip)) ) { return(FIND_OBJ_INV); } } /** find visible object in the room **/ if ( IS_SET (bitvector, FIND_OBJ_ROOM) ) { if ( (*tar_obj = get_obj_in_list_vis(ch, name, vtor (ch->in_room)->contents)) ) { return (FIND_OBJ_ROOM); } } /** Find visible object in the world **/ if (IS_SET(bitvector, FIND_OBJ_WORLD)) { if ((*tar_obj = get_obj_vis(ch, name))) { return(FIND_OBJ_WORLD); } return(0); } return(0); } /* Return TRUE if obj with vnum is equipt */ bool get_obj_in_equip_num (CHAR_DATA *ch, long vnum) { OBJ_DATA *eq = NULL; for ( eq = ch->equip; eq; eq = eq->next_content ) if ( eq->virtual == vnum ) return 1; return 0; } void update_delays (void) { AFFECTED_TYPE *af = NULL; CHAR_DATA *ch = NULL; CHAR_DATA *ch_next = NULL; /** Affects on Character **/ for ( ch = character_list; ch; ch = ch_next ) { ch_next = ch->next; if ( !ch || ch->deleted || !ch->room || ch->in_room == NOWHERE ) continue; if ( IS_MORTAL(ch) && (af = get_affect (ch, AFFECT_HOLDING_BREATH)) ) { if ( --af->a.spell.duration <= 0 ) { if ( drowned (ch) ){ continue; } } } if ( ch->stun > 0 ) { ch->stun--; if ( ch->stun <= 0 ) { act ("You shake your head, recovering from the stun.", FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT); act ("$n shakes $s head, seeming to recover.", FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT); } } if ( ch->roundtime ) { ch->roundtime--; if ( ch->roundtime <= 0 ) { act ("You can perform another action, now.", FALSE, ch, 0, 0, TO_CHAR | TO_ACT_FORMAT); } } if ( ch->balance < 0 ) { ch->balance++; if ( ch->balance == 0 ) { send_to_char ("You feel as if you have fully regained your balance.\n", ch); } } if ( ch->aiming_at && ch->aim < 15 ) { ch->aim++; if ((ch->in_room == ch->aiming_at->in_room && ch->aim >= 5 && IS_NPC(ch)) || ch->aim == 15 ) { send_to_char ("You feel as if you have the best aim you're able to take.\n", ch); if ( IS_NPC(ch) && !ch->desc ) { if ( CAN_SEE (ch, ch->aiming_at) && (IS_SET (ch->act, ACT_AGGRESSIVE) || !IS_SUBDUEE (ch->aiming_at)) ) { do_fire (ch, "", 0); } else { ch->aiming_at = NULL; ch->aim = 0; } } } } if ( ch->whirling && ch->whirling < 4 ) { ch->whirling++; if ( ch->whirling == 4 ) { send_to_char ("You've got the sling whirling about as fast as you can manage.\n", ch); } } /** Deal with different types of delays **/ if ( ch->deleted || !ch->delay || --ch->delay ) continue; switch ( ch->delay_type ) { case DEL_PITCH: delayed_pitch (ch); break; case DEL_OOC: delayed_ooc (ch); break; case DEL_FORAGE: delayed_forage (ch); break; case DEL_RUMMAGE: delayed_rummage(ch); break; case DEL_QUAFF: delayed_quaff (ch); break; case DEL_APP_APPROVE: ch->delay += 10; break; case DEL_SKIN_1: delayed_skin_new1(ch); break; case DEL_SKIN_2: delayed_skin_new2(ch); break; case DEL_SKIN_3: delayed_skin_new3(ch); break; case DEL_COUNT_COIN: delayed_count_coin (ch); break; case DEL_IDENTIFY: delayed_identify (ch); break; case DEL_GATHER: delayed_gather (ch); break; case DEL_COMBINE: delayed_combine (ch); break; case DEL_WHAP: delayed_whap (ch); break; case DEL_WATER_REMOVE: delayed_remove (ch); break; case DEL_GET_ALL: delayed_get (ch); break; case DEL_EMPATHIC_HEAL: delayed_heal (ch); break; case DEL_MENTAL_BOLT: delayed_bolt (ch); break; case DEL_SEARCH: delayed_search (ch); break; case DEL_PICK: delayed_pick (ch); break; case DEL_ALERT: delayed_alert (ch); break; case DEL_INVITE: break_delay (ch); break; case DEL_CAMP1: delayed_camp1 (ch); break; case DEL_CAMP2: delayed_camp2 (ch); break; case DEL_CAMP3: delayed_camp3 (ch); break; case DEL_CAMP4: delayed_camp4 (ch); break; case DEL_TAKE: delayed_take (ch); break; case DEL_PUTCHAR: delayed_putchar (ch); break; case DEL_STARE: delayed_study (ch); break; case DEL_HIDE: delayed_hide (ch); break; case DEL_SCAN: delayed_scan (ch); break; case DEL_QUICK_SCAN: delayed_quick_scan (ch); break; case DEL_HIDE_OBJ: delayed_hide_obj (ch); break; case DEL_PICK_OBJ: delayed_pick_obj (ch); break; case DEL_BIND_WOUNDS: delayed_bind (ch); break; case DEL_TREAT_WOUND: delayed_treatment(ch); break; case DEL_LOAD_WEAPON: delayed_load(ch); break; case DEL_TRACK: delayed_track(ch); break; } } return; } void break_delay (CHAR_DATA *ch) { if ( ch->aim ) { send_to_char ("You cease aiming your weapon.\n", ch); ch->aim = 0; if ( ch->aiming_at ) { ch->aiming_at->targeted_by = NULL; ch->aiming_at = NULL; } return; } if ( ch->whirling ) { send_to_char ("You cease whirling your sling.\n", ch); ch->whirling = 0; return; } switch (ch->delay_type) { case DEL_LOAD_WEAPON: send_to_char ("You cease loading your weapon.\n", ch); ch->delay = 0; break; case DEL_WATER_REMOVE: send_to_char ("You cease attempting to remove that item.\n", ch); ch->delay = 0; break; case DEL_BIND_WOUNDS: REMOVE_BIT(ch->flags, FLAG_BINDING); ch->delay = 0; send_to_char ("You cease your ministrations.\n", ch); break; case DEL_TRACK: ch->delay = 0; send_to_char ("You discontinue your search for tracks.\n", ch); break; case DEL_TREAT_WOUND: ch->delay = 0; send_to_char ("You cease your ministrations.\n", ch); break; case DEL_BACKSTAB: ch->delay = 0; send_to_char("You abort your backstab attempt.\n\r",ch); break; case DEL_PURCHASE_ITEM: ch->delay = 0; ch->delay_type = 0; ch->delay_info1 = 0; ch->delay_info2 = 0; ch->delay_ch = NULL; send_to_char ("You decide against making the purchase.\n\r", ch); break; case DEL_PITCH: ch->delay = 0; ch->delay_obj = NULL; send_to_char ("You cease pitching the tent.\n\r", ch); break; case DEL_OOC: ch->delay = 0; send_to_char ("You decide against going to the OOC lounge.\n\r", ch); break; case DEL_FORAGE: ch->delay = 0; send_to_char ("You stop foraging.\n\r", ch); break; case DEL_WEAVESIGHT: ch->delay = 0; send_to_char ("You blink and shake your heard, ceasing your concentration.\n\r", ch); break; case DEL_RUMMAGE: ch->delay = 0; send_to_char ("You stop rummaging.\n\r", ch); break; case DEL_APP_APPROVE: ch->delay = 0; send_to_char ("You pass on this application.\n\r", ch); if ( ch->pc->msg ) { send_to_char ("Your prepared message was deleted.\n\r", ch); mem_free (ch->pc->msg); ch->pc->msg = NULL; } break; case DEL_SKIN_1: case DEL_SKIN_2: case DEL_SKIN_3: ch->delay = 0; ch->delay_type = 0; ch->delay_info1 = 0; ch->delay_info2 = 0; act ("You abruptly end your skinning.", TRUE, ch, 0, 0, TO_CHAR); act ("$n abruptly stops skinning.", FALSE, ch, 0, 0, TO_ROOM | TO_ACT_FORMAT); break; case DEL_COUNT_COIN: stop_counting (ch); break; case DEL_IDENTIFY: ch->delay = 0; if ( ch->delay_who ) { mem_free (ch->delay_who); ch->delay_who = NULL; } act ("You stop trying to identify the flora.", TRUE, ch, 0, 0, TO_CHAR); break; case DEL_GATHER: ch->delay = 0; if ( ch->delay_who ) { mem_free (ch->delay_who); ch->delay_who = NULL; } act ("You stop gathering.", TRUE, ch, 0, 0, TO_CHAR); break; case DEL_COMBINE: ch->delay_who = NULL; /* DON'T DEALLOCATE, OK? :) */ ch->delay = 0; act ("You stop combining. Unfortunately your ingrediates are " "ruined.", FALSE, ch, 0, 0, TO_CHAR); break; case DEL_GET_ALL: get_break_delay (ch); break; case DEL_EMPATHIC_HEAL: ch->delay = 0; ch->delay_ch = NULL; act ("You stop your healing concentration.", FALSE, ch, 0, 0, TO_CHAR); break; case DEL_MENTAL_BOLT: ch->delay = 0; ch->delay_ch = NULL; act ("You stop your mental attack.", FALSE, ch, 0, 0, TO_CHAR); break; case DEL_SEARCH: ch->delay = 0; act ("You stop searching.", FALSE, ch, 0, 0, TO_CHAR); act ("$n stops searching.", TRUE, ch, 0, 0, TO_ROOM); break; case DEL_PICK: ch->delay = 0; act ("You stop trying to pick the lock.", FALSE, ch, 0, 0, TO_CHAR); break; case DEL_ALERT: ch->delay = 0; act ("You forget about responding to the alert.", FALSE, ch, 0, 0, TO_CHAR); break; case DEL_INVITE: ch->delay = 0; send_to_char ("You decline to join.\n", ch); if ( is_he_here (ch, ch->delay_ch, 1) ) act ("$N declines your offer.", FALSE, ch->delay_ch, 0, ch, TO_CHAR); break; case DEL_CAMP1: case DEL_CAMP2: case DEL_CAMP3: case DEL_CAMP4: ch->delay = 0; send_to_char ("You stop building your camp.\n", ch); act ("$n stops building $s camp.", TRUE, ch, 0, 0, TO_ROOM); break; case DEL_TAKE: ch->delay = 0; send_to_char ("You stop trying to remove the object.\n", ch); act ("$n stops trying to get the object from the body.", FALSE, ch, 0, 0, TO_ROOM); break; case DEL_PUTCHAR: ch->delay = 0; send_to_char ("You stop doing what you're doing.\n", ch); act ("$n 'stops doing what $e's doing.", FALSE, ch, 0, 0, TO_ROOM); break; case DEL_STARE: ch->delay = 0; break; case DEL_HIDE: ch->delay = 0; send_to_char ("You stop trying to hide.\n", ch); break; case DEL_SCAN: ch->delay = 0; break; case DEL_QUICK_SCAN: ch->delay = 0; break; case DEL_HIDE_OBJ: ch->delay = 0; break; case DEL_PICK_OBJ: ch->delay = 0; break; } ch->delay_type = 0; } AFFECTED_TYPE *is_room_affected (AFFECTED_TYPE *af, int type) { while ( af ) { if ( af->type == type ) return af; af = af->next; } return NULL; } void add_room_affect (AFFECTED_TYPE **af, int type, int duration) { AFFECTED_TYPE *raffect = NULL; if ( (raffect = is_room_affected (*af, type)) ) { raffect->a.room.duration += duration; return; } raffect = (AFFECTED_TYPE *)alloc (sizeof (AFFECTED_TYPE), 13); raffect->type = type; raffect->a.room.duration = duration; raffect->next = *af; *af = raffect; return; } int is_in_room (CHAR_DATA *ch, CHAR_DATA *target) { CHAR_DATA *tch = NULL; for ( tch = ch->room->people; tch; tch = tch->next_in_room ) { if ( tch == target ) return 1; } return 0; } int add_registry (int reg_index, int value, char *string) { REGISTRY_DATA *new_reg = NULL; static int init = 0; for ( ; init < MAX_REGISTRY; init++ ) /* Only executes once in */ registry [init] = NULL; /* the life of the game */ if ( value == -1 ) { abort(); } CREATE (new_reg, REGISTRY_DATA, 1); new_reg->string = str_dup(string); new_reg->value = value; new_reg->next = registry [reg_index]; registry [reg_index] = new_reg; return 0; } void free_registry (void) { int i = 0; while ( registry[i] ){ i++; } i--; while ( i ) { mem_free (registry[i]->string); mem_free (registry[i]); i--; } mem_free (registry[0]->string); mem_free (registry[0]); } int lookup_value (char *string, int reg_index) { REGISTRY_DATA *reg = NULL; if ( !string ) return -1; for ( reg = registry [reg_index]; reg; reg = reg->next ) if ( !str_cmp (string, reg->string) ) return reg->value; return -1; } char *lookup_string (int value, int reg_index) { REGISTRY_DATA *reg = NULL; for ( reg = registry [reg_index]; reg; reg = reg->next ) if ( value == reg->value ) return reg->string; return NULL; } void reg_read_ov_lv_cap (FILE *fp_reg, char *buf) { int sn = 0; char *argument = NULL; char skill_name [MAX_STRING_LENGTH] = {'\0'}; char buf2 [MAX_STRING_LENGTH] = {'\0'}; while ( !feof (fp_reg) ) { (void)fgets (buf, MAX_STRING_LENGTH, fp_reg); if ( *buf && buf [strlen (buf) - 1] == '\n' ) buf [strlen (buf) - 1] = '\0'; if ( !*buf || *buf == '#' ) continue; argument = one_argument (buf, skill_name); if ( !str_cmp (skill_name, "[end]") ) return; if ( (sn = skill_index_lookup (skill_name)) == -1 ) { printf ("Unknown skill name in registry file: %s\n", skill_name); abort(); } argument = one_argument (argument, buf2); add_registry (REG_OV, sn, buf2); argument = one_argument (argument, buf2); add_registry (REG_LV, sn, buf2); argument = one_argument (argument, buf2); add_registry (REG_CAP, sn, buf2); } return; } void reg_read_skill_max_rates (FILE *fp_reg, char *buf) { int sn = 0; char *argument = NULL; char buf2 [MAX_STRING_LENGTH] = {'\0'}; char skill_name [MAX_STRING_LENGTH] = {'\0'}; while ( !feof (fp_reg) ) { (void)fgets (buf, MAX_STRING_LENGTH, fp_reg); if ( *buf && buf [strlen (buf) - 1] == '\n' ) buf [strlen (buf) - 1] = '\0'; if ( !*buf || *buf == '#' ) continue; argument = one_argument (buf, skill_name); if ( !str_cmp (buf, "[end]") ) return; if ( (sn = skill_index_lookup (skill_name)) == -1 ) { printf ("Unknown skill name in registry file: %s\n", skill_name); abort(); } argument = one_argument (argument, buf2); if ( !isdigit (*buf2) ) { printf ("Invalid hourly rate for skill %s\n", skill_name); abort(); } add_registry (REG_MAX_RATES, sn, buf2); } return; } void reg_read_variables (FILE *fp_reg, char *buf) { char buf2 [MAX_STRING_LENGTH] = {'\0'}; char buf3 [MAX_STRING_LENGTH] = {'\0'}; char *argument = NULL; int value = 0; while ( !feof (fp_reg) ) { (void)fgets (buf, MAX_STRING_LENGTH, fp_reg); if ( *buf && buf [strlen (buf) - 1] == '\n' ) buf [strlen (buf) - 1] = '\0'; if ( !*buf || *buf == '#' ) continue; argument = one_argument (buf, buf2); if ( !str_cmp (buf2, "[end]") ) return; argument = one_argument (argument, buf3); value = strtol(buf3, NULL, 10); if ( !value ) { system_log("ILLEGAL VARIABLE VALUE FOR VARIABLE:", TRUE); system_log(buf2, TRUE); system_log(buf3, TRUE); abort(); } if ( !str_cmp (buf2, "pulse_violence") ) pulse_violence = value; else { system_log("UNKNOWN VARIABLE:", TRUE); system_log(buf2, TRUE); abort(); } } } void insert_combat_msg (COMBAT_MSG_DATA *cm) { COMBAT_MSG_DATA *tcm = NULL; COMBAT_MSG_DATA *prev = NULL; if ( !cm_list ) { cm_list = cm; return; } if ( cm->off_result <= cm_list->off_result ) { cm->next = cm_list; cm_list = cm; return; } for ( tcm = cm_list; tcm; tcm = tcm->next ) { if ( cm->off_result <= tcm->off_result ) break; prev = tcm; } if ( !tcm ) prev->next = cm; else { cm->next = prev->next; prev->next = cm; } return; } void add_combat_message (char *line) { int r1 = 0; int r2 = 0; char *argument = NULL; char buf [MAX_STRING_LENGTH] = {'\0'}; static COMBAT_MSG_DATA *cm; static int party = 0; if ( !party ) { argument = one_argument (line, buf); if ( (r1 = index_lookup (rs_name, buf)) == -1 ) { system_log("Illegal 1st result in registry, line:", TRUE); system_log(line, TRUE); abort(); } argument = one_argument (argument, buf); if ( (r2 = index_lookup (rs_name, buf)) == -1 ) { system_log("Illegal 2nd result in registry, line:", TRUE); system_log(line, TRUE); abort(); } argument = one_argument (argument, buf); CREATE (cm, COMBAT_MSG_DATA, 1); *buf = toupper (*buf); if ( *buf == 'I' || *buf == 'P' || *buf == 'B' || *buf == 'D' || *buf == 'F' || *buf == '*' ) cm->table = *buf; else { system_log("Illegal table name: table, off-result:", TRUE); system_log(buf, TRUE); system_log(rs_name [r1], TRUE); abort(); } cm->off_result = r1; cm->def_result = r2; cm->next = NULL; } else argument = line; while ( isspace (*argument) ) argument++; if ( party == 0 ) cm->def_msg = str_dup (argument); else if ( party == 1 ) cm->off_msg = str_dup (argument); else cm->other_msg = str_dup (argument); if ( party == 0 ) insert_combat_msg (cm); party++; if ( party > 2 ) party = 0; return; } #define TABLE_USE_TABLE 1 #define TABLE_COMBAT_MESSAGE 2 void reg_read_tables (FILE *fp_reg, char *buf) { int table_id = 0; int sn = 0; char skill_name [MAX_STRING_LENGTH] = {'\0'}; char buf2 [MAX_STRING_LENGTH] = {'\0'}; char *argument = NULL; while ( !feof (fp_reg) ) { (void)fgets (buf, MAX_STRING_LENGTH, fp_reg); if ( *buf && buf [strlen (buf) - 1] == '\n' ) buf [strlen (buf) - 1] = '\0'; if ( !*buf || *buf == '#' ) continue; argument = one_argument (buf, buf2); if ( !str_cmp (buf2, "[end]") ) return; if ( !cmp_strn (buf2, "end-", 4) && table_id ) { table_id = 0; continue; } if ( !table_id ) { if ( !str_cmp (buf2, "begin-use-table") ) table_id = TABLE_USE_TABLE; else if ( !str_cmp (buf2, "begin-combat-message-table") ) table_id = TABLE_COMBAT_MESSAGE; else { system_log("UNKNOWN TABLE NAME:", TRUE); system_log(buf2, TRUE); abort(); } continue; } if ( table_id == TABLE_USE_TABLE ) { if ( (sn = skill_index_lookup (buf2)) == -1 ) { printf ("Unknown skill in USE-TABLE: %s\n", skill_name); abort(); } argument = one_argument (argument, buf2); if ( !strtol(buf2, NULL, 10) ) { system_log("ILLEGAL/NO VALUE IN REGISTRY, USE-TABLE, SKILL:", TRUE); system_log(skill_data[sn].skill_name, TRUE); abort(); } use_table [sn].delay = strtol(buf2, NULL, 10); } else if ( table_id == TABLE_COMBAT_MESSAGE ) { add_combat_message (buf); } } return; } void read_registry (void) { FILE *fp_reg; char buf [MAX_STRING_LENGTH] = {'\0'}; if ( !(fp_reg = fopen (REGISTRY_FILE, "r")) ) { perror ("Unable to open registry!"); abort(); } while ( !feof (fp_reg) ) { (void)fgets (buf, MAX_STRING_LENGTH, fp_reg); if ( *buf && buf [strlen (buf) - 1] == '\n' ) buf [strlen (buf) - 1] = '\0'; if ( !*buf || *buf == '#' ) continue; if ( !str_cmp (buf, "[END]") ) break; else if ( !str_cmp (buf, "[OV-LV-CAP]") ) reg_read_ov_lv_cap (fp_reg, buf); else if ( !str_cmp (buf, "[VARIABLES]") ) reg_read_variables (fp_reg, buf); else if ( !str_cmp (buf, "[TABLES]") ) reg_read_tables (fp_reg, buf); else if ( !str_cmp (buf, "[SKILL-MAX-RATES]") ) reg_read_skill_max_rates (fp_reg, buf); else if ( !str_cmp (buf, "[CRAFTS]") ) reg_read_crafts (fp_reg, buf); } fclose (fp_reg); return; } void setup_registry (void) { add_registry (REG_REGISTRY, REG_REGISTRY, "Registry"); add_registry (REG_REGISTRY, REG_DURATION, "Duration"); add_registry (REG_REGISTRY, REG_OV, "OV"); add_registry (REG_REGISTRY, REG_LV, "LV"); add_registry (REG_REGISTRY, REG_CAP, "Cap"); add_registry (REG_REGISTRY, REG_MISC, "Misc"); add_registry (REG_REGISTRY, REG_MAX_RATES, "Rates"); add_registry (REG_SKILLS, SKILL_SPEAK_ADUNAIC, "Adunaic"); add_registry (REG_SKILLS, SKILL_ALCHEMY, "Alchemy"); add_registry (REG_SKILLS, SKILL_SCRIPT_ANGERTHAS_DAERON, "Angerthas-Daeron"); add_registry (REG_SKILLS, SKILL_SCRIPT_ANGERTHAS_EREBOR, "Angerthas-Erebor"); add_registry (REG_SKILLS, SKILL_SCRIPT_ANGERTHAS_MORIA, "Angerthas-Moria"); add_registry (REG_SKILLS, SKILL_SCRIPT_ARNORIAN_TENGWAR, "Arnorian-Tengwar"); add_registry (REG_SKILLS, SKILL_SPEAK_ATLIDUK, "Atliduk"); add_registry (REG_SKILLS, SKILL_SENSITIVITY, "Aura-Sight"); add_registry (REG_SKILLS, SKILL_BACKSTAB, "Backstab"); add_registry (REG_SKILLS, SKILL_BAKING, "Baking"); add_registry (REG_SKILLS, SKILL_BARTER, "Barter"); add_registry (REG_SKILLS, SKILL_SCRIPT_BELERIAND_TENGWAR, "Beleriand-Tengwar"); add_registry (REG_SKILLS, SKILL_SPEAK_BLACK_SPEECH, "Black-Speech"); add_registry (REG_SKILLS, SKILL_BLACK_WISE, "Black-Wise"); add_registry (REG_SKILLS, SKILL_BLOCK, "Block"); add_registry (REG_SKILLS, SKILL_BRAWLING, "Brawling"); add_registry (REG_SKILLS, SKILL_BREWING, "Brewing"); add_registry (REG_SKILLS, SKILL_CANDLERY, "Candlery"); add_registry (REG_SKILLS, SKILL_SCRIPT_CERTHAS_DAERON, "Certhas-Daeron"); add_registry (REG_SKILLS, SKILL_CLAIRVOYANCE, "Clairvoyance"); add_registry (REG_SKILLS, SKILL_CLIMB, "Climb"); add_registry (REG_SKILLS, SKILL_COOKERY, "Cookery"); add_registry (REG_SKILLS, SKILL_CROSSBOW, "Crossbow"); add_registry (REG_SKILLS, SKILL_DUAL, "Dual-Wield"); add_registry (REG_SKILLS, SKILL_DANGER_SENSE, "Danger-Sense"); add_registry (REG_SKILLS, SKILL_DISARM, "Disarm"); add_registry (REG_SKILLS, SKILL_DISTILLING, "Distilling"); add_registry (REG_SKILLS, SKILL_DODGE, "Dodge"); add_registry (REG_SKILLS, SKILL_SPEAK_DUNAEL, "Dunael"); add_registry (REG_SKILLS, SKILL_EMPATHIC_HEAL, "Empathy"); add_registry (REG_SKILLS, SKILL_FARMING, "Farming"); add_registry (REG_SKILLS, SKILL_FORAGE, "Forage"); add_registry (REG_SKILLS, SKILL_GEMCRAFT, "Gemcraft"); add_registry (REG_SKILLS, SKILL_GLASSWORK, "Glasswork"); add_registry (REG_SKILLS, SKILL_GREY_WISE, "Grey-Wise"); add_registry (REG_SKILLS, SKILL_SCRIPT_GONDORIAN_TENGWAR, "Gondorian-Tengwar"); add_registry (REG_SKILLS, SKILL_SPEAK_HARADAIC, "Haradaic"); add_registry (REG_SKILLS, SKILL_HEALING, "Healing"); add_registry (REG_SKILLS, SKILL_HEAVY_BLUNT, "Heavy-Blunt"); add_registry (REG_SKILLS, SKILL_HEAVY_EDGE, "Heavy-Edge"); add_registry (REG_SKILLS, SKILL_HEAVY_PIERCE, "Heavy-Pierce"); add_registry (REG_SKILLS, SKILL_HERBALISM, "Herbalism"); add_registry (REG_SKILLS, SKILL_HEX, "Hex"); add_registry (REG_SKILLS, SKILL_HIDE, "Hide"); add_registry (REG_SKILLS, SKILL_HIDEWORKING, "Hideworking"); add_registry (REG_SKILLS, SKILL_HUNT, "Hunt"); add_registry (REG_SKILLS, SKILL_SPEAK_KHUZDUL, "Khuzdul"); add_registry (REG_SKILLS, SKILL_SPEAK_LABBA, "Labba"); add_registry (REG_SKILLS, SKILL_LIGHT_BLUNT, "Light-Blunt"); add_registry (REG_SKILLS, SKILL_LIGHT_EDGE, "Light-Edge"); add_registry (REG_SKILLS, SKILL_LIGHT_PIERCE, "Light-Pierce"); add_registry (REG_SKILLS, SKILL_LISTEN, "Listen"); add_registry (REG_SKILLS, SKILL_LITERACY, "Literacy"); add_registry (REG_SKILLS, SKILL_LONGBOW, "Longbow"); add_registry (REG_SKILLS, SKILL_PICK, "Picklock"); add_registry (REG_SKILLS, SKILL_MENTAL_BOLT, "Psychic-Bolt"); add_registry (REG_SKILLS, SKILL_MEDIUM_BLUNT, "Medium-Blunt"); add_registry (REG_SKILLS, SKILL_MEDIUM_EDGE, "Medium-Edge"); add_registry (REG_SKILLS, SKILL_MEDIUM_PIERCE, "Medium-Pierce"); add_registry (REG_SKILLS, SKILL_METALCRAFT, "Metalcraft"); add_registry (REG_SKILLS, SKILL_MINING, "Mining"); add_registry (REG_SKILLS, SKILL_SPEAK_NAHAIDUK, "Nahaiduk"); add_registry (REG_SKILLS, SKILL_SPEAK_NORLIDUK, "Norliduk"); add_registry (REG_SKILLS, SKILL_SCRIPT_NORTHERN_TENGWAR, "Northern-Tengwar"); add_registry (REG_SKILLS, SKILL_SCRIPT_NUMENIAN_TENGWAR, "Numenian-Tengwar"); add_registry (REG_SKILLS, SKILL_SPEAK_ORKISH, "Orkish"); add_registry (REG_SKILLS, SKILL_PARRY, "Parry"); add_registry (REG_SKILLS, SKILL_POLEARM, "Polearm"); add_registry (REG_SKILLS, SKILL_POTTERY, "Pottery"); add_registry (REG_SKILLS, SKILL_PRESCIENCE, "Prescience"); add_registry (REG_SKILLS, SKILL_SPEAK_PUKAEL, "Pukael"); add_registry (REG_SKILLS, SKILL_SPEAK_QUENYA, "Quenya"); add_registry (REG_SKILLS, SKILL_SCRIPT_QUENYAN_TENGWAR, "Quenyan-Tengwar"); add_registry (REG_SKILLS, SKILL_RIDE, "Ride"); add_registry (REG_SKILLS, SKILL_RITUAL, "Ritual"); add_registry (REG_SKILLS, SKILL_SPEAK_ROHIRRIC, "Rohirric"); add_registry (REG_SKILLS, SKILL_SAIL, "Sail"); add_registry (REG_SKILLS, SKILL_SCRIPT_SARATI, "Sarati"); add_registry (REG_SKILLS, SKILL_SCAN, "Scan"); add_registry (REG_SKILLS, SKILL_SEAFARING, "Seafaring"); add_registry (REG_SKILLS, SKILL_SEARCH, "Search"); add_registry (REG_SKILLS, SKILL_SHORTBOW, "Shortbow"); add_registry (REG_SKILLS, SKILL_SPEAK_SILVAN, "Silvan"); add_registry (REG_SKILLS, SKILL_SPEAK_SINDARIN, "Sindarin"); add_registry (REG_SKILLS, SKILL_SKIN, "Skin"); add_registry (REG_SKILLS, SKILL_SLING, "Sling"); add_registry (REG_SKILLS, SKILL_SNEAK, "Sneak"); add_registry (REG_SKILLS, SKILL_STAFF, "Staff"); add_registry (REG_SKILLS, SKILL_STEAL, "Steal"); add_registry (REG_SKILLS, SKILL_STONECRAFT, "Stonecraft"); add_registry (REG_SKILLS, SKILL_SUBDUE, "Subdue"); add_registry (REG_SKILLS, SKILL_SWIMMING, "Swim"); add_registry (REG_SKILLS, SKILL_SPEAK_TALATHIC, "Talathic"); add_registry (REG_SKILLS, SKILL_TELEPATHY, "Telepathy"); add_registry (REG_SKILLS, SKILL_SCRIPT_TENGWAR, "Tengwar"); add_registry (REG_SKILLS, SKILL_TEXTILECRAFT, "Textilecraft"); add_registry (REG_SKILLS, SKILL_THROWN, "Throwing"); add_registry (REG_SKILLS, SKILL_TRACKING, "Tracking"); add_registry (REG_SKILLS, SKILL_SPEAK_UMITIC, "Umitic"); add_registry (REG_SKILLS, SKILL_SPEAK_WESTRON, "Westron"); add_registry (REG_SKILLS, SKILL_WHITE_WISE, "White-Wise"); add_registry (REG_SKILLS, SKILL_WOODCRAFT, "Woodcraft"); add_registry (REG_MISC_NAMES, MISC_DELAY_OFFSET,"Delayoffset"); add_registry (REG_MISC_NAMES, MISC_MAX_CARRY_N, "Maxcarry_n"); add_registry (REG_MISC_NAMES, MISC_MAX_CARRY_W, "Maxcarry_w"); add_registry (REG_MISC_NAMES, MISC_MAX_MOVE, "Maxmove"); add_registry (REG_MISC_NAMES, MISC_STEAL_DEFENSE,"Stealdefense"); add_registry (REG_MISC, MISC_DELAY_OFFSET, "(str + dex) / 6"); add_registry (REG_MISC, MISC_MAX_CARRY_N, "dex / 3 + 4"); add_registry (REG_MISC, MISC_MAX_CARRY_W, "str * 2500"); add_registry (REG_MISC, MISC_MAX_MOVE, "(con + wil) / 2 * 5 + 25"); add_registry (REG_MISC, MISC_STEAL_DEFENSE, "(int + dex) / 2"); read_registry (); return; } void load_clan_registry (void) { FILE *fp_dr = NULL; NAME_SWITCH_DATA *last_name = NULL; NAME_SWITCH_DATA *name_switch = NULL; char *argument = NULL; char token [MAX_STRING_LENGTH] = {'\0'}; char buf [MAX_STRING_LENGTH] = {'\0'}; if ( !(fp_dr = fopen (CLAN_REGISTRY, "r")) ) { perror (CLAN_REGISTRY); system_log("Couldn't open CLAN_REGISTRY.", TRUE); return; } while ( fgets (buf, MAX_STRING_LENGTH - 1, fp_dr)) { if ( buf [strlen (buf) - 1] == '\n' ){ buf [strlen (buf) - 1] = '\0'; } argument = one_argument (buf, token); if ( !str_cmp (token, "newclanname")) { name_switch = (struct name_switch_data *)alloc ((int)sizeof (struct name_switch_data), 38); argument = one_argument (argument, token); name_switch->old_name = str_dup (token); argument = one_argument (argument, token); name_switch->new_name = str_dup (token); if ( !last_name ){ clan_name_switch_list = name_switch; } else{ last_name->next = name_switch; } last_name = name_switch; continue; } if ( !str_cmp (token, "clandef") ) { add_clandef (argument); continue; } } fclose (fp_dr); }