/************************************************************************** * File: handler.c Part of CircleMUD * * Usage: internal funcs: moving and finding chars/objs * * * * All rights reserved. See license.doc for complete information. * * * * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University * * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. * ************************************************************************ */ #include <string.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <assert.h> #include "structs.h" #include "awake.h" #include "utils.h" #include "comm.h" #include "db.h" #include "handler.h" #include "interpreter.h" #include "spells.h" #include "memory.h" #include "dblist.h" // memory object extern class memoryClass *Mem; extern class objList ObjList; /* external vars */ extern char *MENU; extern char *QMENU; extern const char *spells[]; extern int top_of_world; extern int top_of_zone_table; extern struct char_data *character_list; extern struct descriptor_data *descriptor_list; extern struct room_data *world; extern struct zone_data *zone_table; /* external functions */ extern void stop_fighting(struct char_data * ch); extern void remove_follower(struct char_data * ch); extern void clearMemory(struct char_data * ch); extern void Crash_rentsave(struct char_data *ch, int cost); extern void print_object_location(int, struct obj_data *, struct char_data *, int); extern int skill_web(struct char_data *, int); extern int return_general(int skill_num); extern int can_wield_both(struct char_data *, struct obj_data *, struct obj_data *); extern int ability_cost(int abil, int level); extern int max_ability(int i); extern bool save_etext(struct char_data *ch); extern bool write_spells(struct char_data *ch); struct obj_data *find_obj(struct char_data *ch, char *name, int num); char *fname(char *namelist) { static char holder[30]; register char *point; for (point = holder; isalpha(*namelist); namelist++, point++) *point = *namelist; *point = '\0'; return (holder); } int isname(char *str, char *namelist) { if(*namelist == '\0') return 0; if (namelist[0] == '\0') return 0; register char *curname, *curstr; curname = namelist; for (;;) { for (curstr = str;; curstr++, curname++) { if ((!*curstr && !isalpha(*curname)) || is_abbrev(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 age_stat_affect(struct char_data *ch) { switch (GET_RACE(ch)) { case RACE_HUMAN: if (GET_AGE(ch) < 55) return; GET_STR(ch) -= (int)((GET_AGE(ch) - 49) / 6); GET_QUI(ch) -= (int)((GET_AGE(ch) - 49) / 6); GET_BOD(ch) -= (int)((GET_AGE(ch) - 49) / 6); GET_CHA(ch) -= (int)((GET_AGE(ch) - 49) / 7); GET_INT(ch) -= (int)((GET_AGE(ch) - 49) / 8); GET_WIL(ch) -= (int)((GET_AGE(ch) - 49) / 8); GET_REA(ch) -= (int)((GET_AGE(ch) - 49) / 7); break; case RACE_DWARF: if (GET_AGE(ch) < 125) return; GET_STR(ch) -= (int)((GET_AGE(ch) - 115) / 15); GET_QUI(ch) -= (int)((GET_AGE(ch) - 115) / 10); GET_BOD(ch) -= (int)((GET_AGE(ch) - 115) / 20); GET_CHA(ch) -= (int)((GET_AGE(ch) - 115) / 15); GET_INT(ch) -= (int)((GET_AGE(ch) - 115) / 15); GET_WIL(ch) -= (int)((GET_AGE(ch) - 115) / 20); GET_REA(ch) -= (int)((GET_AGE(ch) - 115) / 12); break; case RACE_ELF: if (GET_AGE(ch) < 300) return; GET_STR(ch) -= (int)((GET_AGE(ch) - 275) / 30); GET_QUI(ch) -= (int)((GET_AGE(ch) - 275) / 50); GET_BOD(ch) -= (int)((GET_AGE(ch) - 275) / 25); GET_CHA(ch) -= (int)((GET_AGE(ch) - 275) / 50); GET_INT(ch) -= (int)((GET_AGE(ch) - 275) / 50); GET_WIL(ch) -= (int)((GET_AGE(ch) - 275) / 40); GET_REA(ch) -= (int)((GET_AGE(ch) - 275) / 50); break; case RACE_ORK: if (GET_AGE(ch) < 45) return; GET_STR(ch) -= (int)((GET_AGE(ch) - 38) / 9); GET_QUI(ch) -= (int)((GET_AGE(ch) - 38) / 8); GET_BOD(ch) -= (int)((GET_AGE(ch) - 38) / 10); GET_CHA(ch) -= (int)((GET_AGE(ch) - 38) / 7); GET_INT(ch) -= (int)((GET_AGE(ch) - 38) / 7); GET_WIL(ch) -= (int)((GET_AGE(ch) - 38) / 8); GET_REA(ch) -= (int)((GET_AGE(ch) - 38) / 7); break; case RACE_TROLL: if (GET_AGE(ch) < 50) return; GET_STR(ch) -= (int)((GET_AGE(ch) - 42) / 10); GET_QUI(ch) -= (int)((GET_AGE(ch) - 42) / 8); GET_BOD(ch) -= (int)((GET_AGE(ch) - 42) / 15); GET_CHA(ch) -= (int)((GET_AGE(ch) - 42) / 8); GET_INT(ch) -= (int)((GET_AGE(ch) - 42) / 8); GET_WIL(ch) -= (int)((GET_AGE(ch) - 42) / 9); GET_REA(ch) -= (int)((GET_AGE(ch) - 42) / 8); break; } } void affect_modify(struct char_data * ch, byte loc, sbyte mod, long bitv, bool add) { int maxabil; if (add) { SET_BIT(AFF_FLAGS(ch), bitv); } else { REMOVE_BIT(AFF_FLAGS(ch), bitv); mod = -mod; } maxabil = ((IS_NPC(ch) || (GET_LEVEL(ch) >= LVL_MANAGER)) ? 50 : 20); switch (loc) { case APPLY_NONE: break; case APPLY_STR: GET_STR(ch) += mod; break; case APPLY_QUI: GET_QUI(ch) += mod; break; case APPLY_INT: GET_INT(ch) += mod; break; case APPLY_WIL: GET_WIL(ch) += mod; break; case APPLY_BOD: GET_BOD(ch) += mod; break; case APPLY_CHA: GET_CHA(ch) += mod; break; case APPLY_MAG: GET_MAG(ch) += (mod * 100); break; case APPLY_ESS: GET_ESS(ch) += (mod * 100); break; case APPLY_REA: GET_REA(ch) += mod; break; case APPLY_AGE: ch->player.time.birth -= (mod * SECS_PER_MUD_YEAR); break; case APPLY_CHAR_WEIGHT: GET_WEIGHT(ch) += mod; break; case APPLY_CHAR_HEIGHT: GET_HEIGHT(ch) += mod; break; case APPLY_MENTAL: GET_MAX_MENTAL(ch) += mod * 100; break; case APPLY_PHYSICAL: GET_MAX_PHYSICAL(ch) += mod * 100; break; case APPLY_BALLISTIC: GET_BALLISTIC(ch) += mod; break; case APPLY_IMPACT: GET_IMPACT(ch) += mod; break; case APPLY_ASTRAL_POOL: GET_ASTRAL(ch) += mod; break; case APPLY_COMBAT_POOL: GET_COMBAT(ch) += mod; break; case APPLY_HACKING_POOL: GET_HACKING(ch) += mod; break; case APPLY_MAGIC_POOL: GET_MAGIC(ch) += mod; /* GET_MAGIC gets their magic pool, GET_MAG is for attribute*/ break; case APPLY_INITIATIVE_DICE: GET_INIT_DICE(ch) += mod; break; case APPLY_TARGET: GET_TARGET_MOD(ch) += mod; break; default: // sprintf(buf, "SYSLOG: Unknown apply adjust: %s/%d.", GET_NAME(ch), loc); // log(buf); break; } /* switch */ } void apply_focus_effect( struct char_data *ch, struct obj_data *object ) { int i; if (object->worn_by == NULL ) return; if (GET_OBJ_TYPE(object) != ITEM_FOCUS) return; if (GET_OBJ_VAL(object, 9) != GET_IDNUM(ch)) return; if (GET_OBJ_VAL(object, 5) == 0) { if ((GET_FOCI(ch) + 1) > GET_INT(ch)) return; GET_OBJ_VAL(object, 5) = 1; GET_FOCI(ch)++; } for (i = 0; i < MAX_OBJ_AFFECT; i++) affect_modify(ch, object->affected[i].location, object->affected[i].modifier, object->obj_flags.bitvector, TRUE); } void remove_focus_effect( struct char_data *ch, struct obj_data *object ) { int i; if (GET_OBJ_TYPE(object) != ITEM_FOCUS) return; if (GET_OBJ_VAL(object, 9) != GET_IDNUM(ch)) return; if (GET_OBJ_VAL(object, 5) == 0) return; GET_OBJ_VAL(object, 5) = 0; GET_FOCI(ch)--; for (i = 0; i < MAX_OBJ_AFFECT; i++) affect_modify(ch, object->affected[i].location, object->affected[i].modifier, object->obj_flags.bitvector, FALSE); } /* 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 obj_data *wielded = GET_EQ(ch, WEAR_WIELD); struct obj_data *cyber, *obj = NULL, *one, *two; struct affected_type *af; spell_t *spell; sh_int i, j, skill; if (IS_IC(ch) || IS_PERSONA(ch) || IS_PROJECT(ch)) return; /* effects of used equipment */ for (i = 0; i < (NUM_WEARS - 1); i++) { if (GET_EQ(ch, i)) { if (GET_OBJ_TYPE(GET_EQ(ch, i)) == ITEM_FOCUS) remove_focus_effect(ch, GET_EQ(ch, i)); else for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, GET_EQ(ch, i)->affected[j].location, GET_EQ(ch, i)->affected[j].modifier, GET_EQ(ch, i)->obj_flags.bitvector, FALSE); } } /* effects of foci in inventory * for (obj = ch->carrying; obj; obj = obj->next_content) if (GET_OBJ_TYPE(obj) == ITEM_FOCUS) remove_focus_effect(ch, obj);*/ /* effects of cyberware */ for (cyber = ch->cyberware; cyber; cyber = cyber->next_content) { for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, cyber->affected[j].location, cyber->affected[j].modifier, cyber->obj_flags.bitvector, FALSE); } /* effects of bioware */ for (cyber = ch->bioware; cyber; cyber = cyber->next_content) { if (GET_OBJ_VAL(cyber, 2) != 4 || (GET_OBJ_VAL(cyber, 2) == 4 && GET_OBJ_VAL(cyber, 5) > 0)) for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, cyber->affected[j].location, cyber->affected[j].modifier, cyber->obj_flags.bitvector, FALSE); } /* effects of spells */ for (af = ch->affected; af; af = af->next) affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE); ch->aff_abils = ch->real_abils; /* calculate reaction before you add eq, cyberware, etc so that things * * such as wired reflexes work properly (as they only modify reaction * * and not intelligence and quickness). -cjd */ ch->real_abils.rea = (ch->real_abils.intel + ch->real_abils.qui) >> 1; GET_REA(ch) = (GET_INT(ch) + GET_QUI(ch)) >> 1; if (PLR_FLAGGED(ch, PLR_NEWBIE) && GET_REP(ch) > 15) { REMOVE_BIT(PLR_FLAGS(ch), PLR_NEWBIE); for (cyber = ch->cyberware; cyber; cyber = cyber->next_content) { if (IS_OBJ_STAT(cyber, ITEM_NODONATE)) REMOVE_BIT(GET_OBJ_EXTRA(cyber), ITEM_NODONATE); if (IS_OBJ_STAT(cyber, ITEM_NOSELL)) REMOVE_BIT(GET_OBJ_EXTRA(cyber), ITEM_NOSELL); } } /* set the dice pools before equip so that they can be affected */ /* combat pool is equal to quickness, wil, and int divided by 2 */ GET_COMBAT(ch) = 0; GET_HACKING(ch) = 0; GET_ASTRAL(ch) = 0; GET_MAGIC(ch) = 0; // reset initiative dice GET_INIT_DICE(ch) = 0; /* reset # of foci char has */ if (!IS_NPC(ch)) GET_FOCI(ch) = 0; /* effects of foci in inventory * for (obj = ch->carrying; obj; obj = obj->next_content) if (GET_OBJ_TYPE(obj) == ITEM_FOCUS) apply_focus_effect(ch, obj);*/ /* effects of equipment */ for (i = 0; i < (NUM_WEARS - 1); i++) if (GET_EQ(ch, i)) { if (GET_OBJ_TYPE(GET_EQ(ch, i)) == ITEM_FOCUS) apply_focus_effect(ch, GET_EQ(ch,i)); else for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, GET_EQ(ch, i)->affected[j].location, GET_EQ(ch, i)->affected[j].modifier, GET_EQ(ch, i)->obj_flags.bitvector, TRUE); } /* effects of cyberware */ for (cyber = ch->cyberware; cyber; cyber = cyber->next_content) { for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, cyber->affected[j].location, cyber->affected[j].modifier, cyber->obj_flags.bitvector, TRUE); } /* effects of bioware */ for (cyber = ch->bioware; cyber; cyber = cyber->next_content){ if (GET_OBJ_VAL(cyber, 2) != 4 || (GET_OBJ_VAL(cyber, 2) == 4 && GET_OBJ_VAL(cyber, 5) > 0)) for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, cyber->affected[j].location, cyber->affected[j].modifier, cyber->obj_flags.bitvector, TRUE); } for (af = ch->affected; af; af = af->next) affect_modify(ch, af->location, af->modifier, af->bitvector, TRUE); // take age into account if (!IS_NPC(ch) && GET_LEVEL(ch) < LVL_LEGEND) age_stat_affect(ch); /* Make certain values are between 1..50, not < 0 and not > 50! */ i = ((IS_NPC(ch) || (GET_LEVEL(ch) >= LVL_MANAGER)) ? 50 : 15); GET_QUI(ch) = MAX(1, MIN(GET_QUI(ch), i)); GET_CHA(ch) = MAX(1, MIN(GET_CHA(ch), i)); GET_INT(ch) = MAX(1, MIN(GET_INT(ch), i)); GET_WIL(ch) = MAX(1, MIN(GET_WIL(ch), i)); GET_BOD(ch) = MAX(1, MIN(GET_BOD(ch), i)); GET_STR(ch) = MAX(1, MIN(GET_STR(ch), i)); GET_MAG(ch) = MAX(0, MIN(GET_MAG(ch), i * 100)); GET_ESS(ch) = MAX(0, MIN(GET_ESS(ch), 600)); GET_REA(ch) = MAX(1, MIN(GET_REA(ch), i)); if ((IS_NPC(ch) || GET_TRADITION(ch) == TRAD_ADEPT) && GET_SKILL(ch, SKILL_REFLEXES) > 0) GET_INIT_DICE(ch) += MIN(3, GET_SKILL(ch, SKILL_REFLEXES)); /* fix pools to take into account new attributes */ one = (GET_WIELDED(ch, 0) ? GET_EQ(ch, WEAR_WIELD) : (struct obj_data *) NULL); two = (GET_WIELDED(ch, 1) ? GET_EQ(ch, WEAR_HOLD) : (struct obj_data *) NULL); if (!one && !two) skill = GET_SKILL(ch, SKILL_UNARMED_COMBAT); else if (one) { if (!GET_SKILL(ch, GET_OBJ_VAL(one, 4))) skill = GET_SKILL(ch, return_general(GET_OBJ_VAL(one, 4))); else skill = GET_SKILL(ch, GET_OBJ_VAL(one, 4)); } else if (two) { if (!GET_SKILL(ch, GET_OBJ_VAL(two, 4))) skill = GET_SKILL(ch, return_general(GET_OBJ_VAL(two, 4))); else skill = GET_SKILL(ch, GET_OBJ_VAL(two, 4)); } else { if (GET_SKILL(ch, GET_OBJ_VAL(one, 4)) <= GET_SKILL(ch, GET_OBJ_VAL(two, 4))) { if (!GET_SKILL(ch, GET_OBJ_VAL(one, 4))) skill = GET_SKILL(ch, return_general(GET_OBJ_VAL(one, 4))); else skill = GET_SKILL(ch, GET_OBJ_VAL(one, 4)); } else { if (!GET_SKILL(ch, GET_OBJ_VAL(two, 4))) skill = GET_SKILL(ch, return_general(GET_OBJ_VAL(two, 4))); else skill = GET_SKILL(ch, GET_OBJ_VAL(two, 4)); } } GET_COMBAT(ch) += (GET_QUI(ch) + GET_WIL(ch) + GET_INT(ch)) / 2; if ((IS_NPC(ch) || GET_TRADITION(ch) == TRAD_ADEPT) && GET_SKILL(ch, SKILL_COMBAT_SENSE) > 0) GET_COMBAT(ch) += MIN(3, GET_SKILL(ch, SKILL_COMBAT_SENSE)); GET_DEFENSE(ch) = MIN(GET_DEFENSE(ch), GET_COMBAT(ch)); GET_OFFENSE(ch) = GET_COMBAT(ch) - GET_DEFENSE(ch); if (GET_OFFENSE(ch) > skill) { GET_DEFENSE(ch) += GET_OFFENSE(ch) - skill; GET_OFFENSE(ch) = skill; } if (GET_SKILL(ch, SKILL_COMPUTER) > 0) GET_HACKING(ch) += GET_SKILL(ch, SKILL_COMPUTER) + GET_REA(ch); if (!(!IS_NPC(ch) && GET_TRADITION(ch) != TRAD_SHAMANIC && GET_TRADITION(ch) != TRAD_HERMETIC)) GET_ASTRAL(ch) += (GET_MAG(ch) / 100) + GET_INT(ch) + GET_SKILL(ch, SKILL_SORCERY); if (!(!IS_NPC(ch) && GET_TRADITION(ch) != TRAD_SHAMANIC && GET_TRADITION(ch) != TRAD_HERMETIC)) GET_MAGIC(ch) += GET_SKILL(ch, SKILL_SORCERY); } /* 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; affected_alloc = new struct affected_type; *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, int message) { struct char_data *tch = character_list; struct affected_type *af2, *temp; bool found = FALSE; assert(ch->affected); affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE); if (af->sustained_by < 0) while (tch != NULL && (IS_NPC(tch) ? tch->nr : 0) != -af->sustained_by) tch = tch->next; else while (tch != NULL && (IS_NPC(tch) ? 0 : GET_IDNUM(tch)) != af->sustained_by) tch = tch->next; if (tch) for (af2 = tch->affected; af2 && !found; af2 = af2->next) if ((af2->type == af->type) && (af2->caster == TRUE) && (af2->sustained_by == (IS_NPC(ch) ? -ch->nr : GET_IDNUM(ch)))) { if (af2->type < MAX_SPELLS) { sprintf(buf, "You no longer sustain %s.\r\n", spells[af->type]); if (message && af->type != SPELL_HEAL && af->type != SPELL_ANTIDOTE && af->type != SPELL_STABILIZE && af->type != SPELL_CURE_DISEASE) send_to_char(buf, tch); if (GET_SUSTAINED(tch) > 0) GET_SUSTAINED(tch) -= 1; } REMOVE_FROM_LIST(af2, tch->affected, next); if ( af != af2 ) delete af2; found = TRUE; } if (af->type == SPELL_INFLUENCE && ch->master) stop_follower(ch); else if (af->type == SPELL_LIGHT && ch->in_room != NOWHERE) world[ch->in_room].light--; REMOVE_FROM_LIST(af, ch->affected, next); delete af; affect_total(ch); } /* Call affect_remove with every spell of spelltype "skill" */ void affect_from_char(struct char_data * ch, sh_int type) { struct affected_type *hjp; for (hjp = ch->affected; hjp; hjp = hjp->next) if (hjp->type == type) affect_remove(ch, hjp, 1); } /* * Return if a char is affected by a spell (SPELL_XXX), NULL indicates * not affected */ int affected_by_spell(struct char_data * ch, sh_int type) { struct affected_type *hjp; struct obj_data *obj; int i; for (hjp = ch->affected; hjp; hjp = hjp->next) if ((hjp->type == type) && (hjp->caster == FALSE)) return 1; for (obj = ch->carrying; obj; obj = obj->next_content) if (GET_OBJ_TYPE(obj) == ITEM_FOCUS && GET_OBJ_VAL(obj, 0) == FOCI_LOCK && GET_OBJ_VAL(obj, 9) == (IS_NPC(ch) ? -1 : GET_IDNUM(ch)) && GET_OBJ_VAL(obj, 8) == type) return 2; for (i = 0; i < NUM_WEARS; i++) if ((obj = GET_EQ(ch, i)) && GET_OBJ_TYPE(obj) == ITEM_FOCUS && GET_OBJ_VAL(obj, 0) == FOCI_LOCK && GET_OBJ_VAL(obj, 8) == type && GET_OBJ_VAL(obj, 9) == (IS_NPC(ch) ? -1 : GET_IDNUM(ch))) return 2; return 0; } void affect_join(struct char_data * ch, struct affected_type * af, bool add_dur, bool avg_dur, bool add_mod, bool avg_mod) { struct affected_type *hjp; bool found = FALSE; for (hjp = ch->affected; !found && hjp; hjp = hjp->next) { if (hjp->type == af->type) { if (add_dur) af->duration += hjp->duration; if (avg_dur) af->duration >>= 1; if (add_mod) af->modifier += hjp->modifier; if (avg_mod) af->modifier >>= 1; affect_remove(ch, hjp, 1); 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 *temp; if (ch == NULL || ch->in_room == NOWHERE) { log("SYSLOG: NULL or NOWHERE in handler.c, char_from_room"); exit(1); } if (FIGHTING(ch) != NULL) stop_fighting(ch); if (GET_EQ(ch, WEAR_LIGHT) != NULL) if (GET_OBJ_TYPE(GET_EQ(ch, WEAR_LIGHT)) == ITEM_LIGHT) if (GET_OBJ_VAL(GET_EQ(ch, WEAR_LIGHT), 2)) /* Light is ON */ world[ch->in_room].light--; if (affected_by_spell(ch, SPELL_LIGHT)) world[ch->in_room].light--; REMOVE_FROM_LIST(ch, world[ch->in_room].people, next_in_room); ch->in_room = NOWHERE; ch->next_in_room = NULL; } /* place a character in a room */ void char_to_room(struct char_data * ch, int room) { if (!ch || room < 0 || room > top_of_world) log("SYSLOG: Illegal value(s) passed to char_to_room"); else { ch->next_in_room = world[room].people; world[room].people = ch; ch->in_room = room; if (GET_EQ(ch, WEAR_LIGHT)) if (GET_OBJ_TYPE(GET_EQ(ch, WEAR_LIGHT)) == ITEM_LIGHT) if (GET_OBJ_VAL(GET_EQ(ch, WEAR_LIGHT), 2)) /* Light ON */ world[room].light++; if (affected_by_spell(ch, SPELL_LIGHT)) world[room].light++; } } #define IS_INVIS(o) IS_OBJ_STAT(o, ITEM_INVISIBLE) /* give an object to a char */ void obj_to_char(struct obj_data * object, struct char_data * ch) { struct obj_data *i = NULL, *op = NULL; int j; if (object && ch) { for (i = ch->carrying; i; i = i->next_content) { if (i->item_number == object->item_number && !strcmp(i->description, object->description) && IS_INVIS(i) == IS_INVIS(object)) break; op = i; } if (i) { object->next_content = i; if (op) op->next_content = object; else ch->carrying = object; } else { 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)++; /* set flag for crash-save system */ if (!IS_NPC(ch)) SET_BIT(PLR_FLAGS(ch), PLR_CRASH); if (GET_OBJ_TYPE(object) == ITEM_FOCUS) apply_focus_effect(ch, object); } else log("SYSLOG: NULL obj or char passed to obj_to_char"); } void old_obj_to_char(struct obj_data * object, struct char_data * ch) { int j; if (object && ch) { 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)++; /* set flag for crash-save system */ if (!IS_NPC(ch)) SET_BIT(PLR_FLAGS(ch), PLR_CRASH); if (GET_OBJ_TYPE(object) == ITEM_FOCUS) apply_focus_effect(ch, object); } else log("SYSLOG: NULL obj or char passed to obj_to_char"); } void reduce_abilities(struct char_data *vict) { int i; if (vict->real_abils.mag >= 0) return; for (i = number(SKILL_PERCEPTION, SKILL_RESISTANCE); vict->real_abils.mag < 0; i = number(SKILL_PERCEPTION, SKILL_RESISTANCE)) { if (GET_SKILL(vict, i) > 0) { vict->real_abils.mag += ability_cost(i, GET_SKILL(vict, i)); SET_SKILL(vict, i, GET_SKILL(vict, i) - 1); vict->real_abils.mag -= ability_cost(i, GET_SKILL(vict, i)); send_to_char(vict, "Your loss in magic makes you feel less " "skilled in %s.\r\n", spells[i]); } // just in case... if ((GET_SKILL(vict, SKILL_PERCEPTION) + GET_SKILL(vict, SKILL_COMBAT_SENSE) + GET_SKILL(vict, SKILL_REFLEXES) + GET_SKILL(vict, SKILL_KILL_HANDS) + GET_SKILL(vict, SKILL_RESISTANCE)) < 1) { vict->real_abils.mag = MAX(0, vict->real_abils.mag); return; } } } void obj_to_cyberware(struct obj_data * object, struct char_data * ch) { int temp; if (object && ch) { if (GET_OBJ_TYPE(object) != ITEM_CYBERWARE) { log("Non-cyberware object type passed to obj_to_bioware."); return; } object->next_content = ch->cyberware; ch->cyberware = object; object->carried_by = ch; object->in_room = NOWHERE; if (!IS_NPC(ch)) SET_BIT(PLR_FLAGS(ch), PLR_CRASH); ch->real_abils.ess -= GET_TOTEM(ch) == TOTEM_EAGLE ? GET_OBJ_VAL(object, 1) << 1 : GET_OBJ_VAL(object, 1); if (GET_TRADITION(ch) == TRAD_ADEPT) { ch->real_abils.mag -= GET_TOTEM(ch) == TOTEM_EAGLE ? GET_OBJ_VAL(object, 1) << 1 : GET_OBJ_VAL(object, 1); if (ch->real_abils.mag < 0) reduce_abilities(ch); } else ch->real_abils.mag = (int)(ch->real_abils.ess / 100) * 100; if (GET_OBJ_VAL(object, 4) != 1) object->obj_flags.value[4] = 1; for (temp = 0; temp < MAX_OBJ_AFFECT; temp++) affect_modify(ch, object->affected[temp].location, object->affected[temp].modifier, object->obj_flags.bitvector, TRUE); affect_total(ch); } else log("SYSLOG: NULL obj or char passed to obj_to_cyberware"); } void obj_to_bioware(struct obj_data * object, struct char_data * ch) { int temp; if (object && ch) { if (GET_OBJ_TYPE(object) != ITEM_BIOWARE) { log("Non-bioware object type passed to obj_to_bioware."); return; } object->next_content = ch->bioware; ch->bioware = object; object->carried_by = ch; object->in_room = NOWHERE; if (!IS_NPC(ch)) SET_BIT(PLR_FLAGS(ch), PLR_CRASH); GET_INDEX(ch) -= GET_OBJ_VAL(object, 1); if (GET_OBJ_VAL(object, 4) != 1) object->obj_flags.value[4] = 1; if (GET_OBJ_VAL(object, 2) != 4 || GET_OBJ_VAL(object, 5) > 0) for (temp = 0; temp < MAX_OBJ_AFFECT; temp++) affect_modify(ch, object->affected[temp].location, object->affected[temp].modifier, object->obj_flags.bitvector, TRUE); affect_total(ch); } else log("SYSLOG: NULL obj or char passed to obj_to_bioware"); } void obj_from_bioware(struct obj_data *bio) { struct obj_data *temp; int i; if (bio == NULL) { log("SYSLOG: NULL object passed to obj_from_bioware"); return; } if (!IS_NPC(bio->carried_by)) SET_BIT(PLR_FLAGS(bio->carried_by), PLR_CRASH); GET_INDEX(bio->carried_by) += GET_OBJ_VAL(bio, 1); if (GET_OBJ_VAL(bio, 2) == 4 && GET_OBJ_VAL(bio, 5) < 1) for (i = 0; i < MAX_OBJ_AFFECT; i++) affect_modify(bio->carried_by, bio->affected[i].location, bio->affected[i].modifier, bio->obj_flags.bitvector, FALSE); affect_total(bio->carried_by); REMOVE_FROM_LIST(bio, bio->carried_by->bioware, next_content); bio->carried_by = NULL; bio->next_content = NULL; } /* take an object from a char */ void obj_from_char(struct obj_data * object) { struct obj_data *temp; int i; if (object == NULL) { log("SYSLOG: NULL object passed to obj_from_char"); return; } REMOVE_FROM_LIST(object, object->carried_by->carrying, next_content); /* set flag for crash-save system */ if (!IS_NPC(object->carried_by)) SET_BIT(PLR_FLAGS(object->carried_by), PLR_CRASH); if (GET_OBJ_TYPE(object) == ITEM_FOCUS) remove_focus_effect(object->carried_by, object); IS_CARRYING_W(object->carried_by) -= GET_OBJ_WEIGHT(object); IS_CARRYING_N(object->carried_by)--; object->carried_by = NULL; object->next_content = NULL; } /* Removes a piece of cyberware from the cyberware list */ void obj_from_cyberware(struct obj_data * cyber) { struct obj_data *temp; int i; if (cyber == NULL) { log("SYSLOG: NULL object passed to obj_from_cyberware"); return; } /* set flag for crash-save system */ if (!IS_NPC(cyber->carried_by)) SET_BIT(PLR_FLAGS(cyber->carried_by), PLR_CRASH); cyber->carried_by->real_abils.ess += GET_OBJ_VAL(cyber, 1); if (GET_TRADITION(cyber->carried_by) == TRAD_ADEPT) cyber->carried_by->real_abils.mag += GET_OBJ_VAL(cyber, 1); else if (GET_TRADITION(cyber->carried_by) == TRAD_HERMETIC || GET_TRADITION(cyber->carried_by) == TRAD_SHAMANIC) cyber->carried_by->real_abils.mag = (int)(cyber->carried_by->real_abils.ess / 100) * 100; for (i = 0; i < MAX_OBJ_AFFECT; i++) affect_modify(cyber->carried_by, cyber->affected[i].location, cyber->affected[i].modifier, cyber->obj_flags.bitvector, FALSE); affect_total(cyber->carried_by); REMOVE_FROM_LIST(cyber, cyber->carried_by->cyberware, next_content); cyber->carried_by = NULL; cyber->next_content = NULL; } /* Return the effect of a piece of armor in position eq_pos */ int apply_ballistic(struct char_data * ch, int eq_pos) { assert(GET_EQ(ch, eq_pos)); if (!(GET_OBJ_TYPE(GET_EQ(ch, eq_pos)) == ITEM_ARMOR)) return 0; return (GET_OBJ_VAL(GET_EQ(ch, eq_pos), 0)); } int apply_impact(struct char_data * ch, int eq_pos) { assert(GET_EQ(ch, eq_pos)); if (!(GET_OBJ_TYPE(GET_EQ(ch, eq_pos)) == ITEM_ARMOR)) return 0; return (GET_OBJ_VAL(GET_EQ(ch, eq_pos), 1)); } void equip_char(struct char_data * ch, struct obj_data * obj, int pos) { int j, maxb = 0, maxi = 0; int invalid_class(struct char_data *ch, struct obj_data *obj); assert(pos >= 0 && pos < NUM_WEARS); if (IS_NPC(ch) && pos == WEAR_WIELD) { if (!GET_EQ(ch, WEAR_WIELD)) GET_WIELDED(ch, 0) = 1; else if (!GET_EQ(ch, WEAR_HOLD) && can_wield_both(ch, GET_EQ(ch, WEAR_WIELD), obj)) { pos = WEAR_HOLD; GET_WIELDED(ch, 1) = 1; } else { sprintf(buf, "SYSLOG: trying to equip invalid or third weapon: %s, %s", GET_NAME(ch), obj->short_description); log(buf); return; } } else if (GET_EQ(ch, pos)) { sprintf(buf, "SYSLOG: Char is already equipped: %s, %s", GET_NAME(ch), obj->short_description); log(buf); return; } if (obj->carried_by) { log("SYSLOG: EQUIP: Obj is carried_by when equip."); return; } if (obj->in_room != NOWHERE) { log("SYSLOG: EQUIP: Obj is in_room when equip."); return; } if (invalid_class(ch, obj)) { act("You are zapped by $p and instantly let go of it.", FALSE, ch, obj, 0, TO_CHAR); act("$n is zapped by $p and instantly lets go of it.", FALSE, ch, obj, 0, TO_ROOM); obj_to_char(obj, ch); /* changed to drop in inventory instead of * ground */ return; } GET_EQ(ch, pos) = obj; obj->worn_by = ch; obj->worn_on = pos; if (GET_OBJ_TYPE(obj) == ITEM_ARMOR) { for (j = 0; j < NUM_WEARS - 1; j++) if (GET_EQ(ch, j) && j != pos) { if (apply_ballistic(ch, j) > maxb) maxb = apply_ballistic(ch, j); if (apply_impact(ch, j) > maxi) maxi = apply_impact(ch, j); } if (apply_ballistic(ch, pos) > maxb) GET_BALLISTIC(ch) += apply_ballistic(ch, pos) - maxb; if (apply_impact(ch, pos) > maxi) GET_IMPACT(ch) += apply_impact(ch, pos) - maxi; } if (ch->in_room != NOWHERE) { if (pos == WEAR_LIGHT && GET_OBJ_TYPE(obj) == ITEM_LIGHT) if (GET_OBJ_VAL(obj, 2)) /* if light is ON */ world[ch->in_room].light++; } // changed for autoequiping //else //log("SYSLOG: ch->in_room = NOWHERE when equipping char."); // if (GET_OBJ_TYPE(obj) != ITEM_FOCUS) for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, obj->affected[j].location, obj->affected[j].modifier, obj->obj_flags.bitvector, TRUE); affect_total(ch); } struct obj_data *unequip_char(struct char_data * ch, int pos) { int j, maxb = 0, maxi = 0; struct obj_data *obj, *tempobj; bool natural = TRUE; if (pos < 0 || pos >= NUM_WEARS) { sprintf(buf, "SYSERR: pos < 0 || pos >= NUM_WEARS, %s - %d", GET_NAME(ch), pos); log(buf); } assert(pos >= 0 && pos < NUM_WEARS); if (!GET_EQ(ch, pos)) { sprintf(buf, "SYSERR: Trying to remove non-existent item from %s at %d", GET_NAME(ch), pos); log(buf); } assert(GET_EQ(ch, pos)); obj = GET_EQ(ch, pos); obj->worn_by = NULL; obj->worn_on = -1; if (GET_OBJ_TYPE(obj) == ITEM_ARMOR) { for (j = 0; j < NUM_WEARS; j++) if (GET_EQ(ch, j) && j != pos) { if (apply_ballistic(ch, j) > maxb) maxb = apply_ballistic(ch, j); if (apply_impact(ch, j) > maxi) maxi = apply_impact(ch, j); } if (apply_ballistic(ch, pos) > maxb) GET_BALLISTIC(ch) -= apply_ballistic(ch, pos) - maxb; if (apply_impact(ch, pos) > maxi) GET_IMPACT(ch) -= apply_impact(ch, pos) - maxi; } if (ch->in_room != NOWHERE) { if (pos == WEAR_LIGHT && GET_OBJ_TYPE(obj) == ITEM_LIGHT) if (GET_OBJ_VAL(obj, 2)) /* if light is ON */ world[ch->in_room].light--; } if (pos == WEAR_HOLD || pos == WEAR_WIELD) GET_WIELDED(ch, pos - WEAR_WIELD) = 0; // these were removed because of the autoequip routines //else //log("SYSLOG: ch->in_room = NOWHERE when equipping char."); GET_EQ(ch, pos) = NULL; // if (GET_OBJ_TYPE(obj) != ITEM_FOCUS) for (j = 0; j < MAX_OBJ_AFFECT; j++) affect_modify(ch, obj->affected[j].location, obj->affected[j].modifier, obj->obj_flags.bitvector, FALSE); /* Give natural vision back */ for ( tempobj = ch->cyberware; tempobj != NULL; tempobj = tempobj->next_content ) { if ( !str_cmp(tempobj->short_description,"thermographic vision") || !str_cmp(tempobj->short_description,"low-light vision") || !str_cmp(tempobj->short_description,"flare compensation") || !str_cmp(tempobj->short_description,"optical magnification") || !str_cmp(tempobj->short_description,"electrical magnification") ) natural = FALSE; } if ( natural ) { switch (GET_RACE(ch)) { case RACE_ELF: case RACE_ORK: SET_BIT(ch->char_specials.saved.affected_by, AFF_LOW_LIGHT); break; case RACE_TROLL: case RACE_DWARF: SET_BIT(ch->char_specials.saved.affected_by, AFF_INFRAVISION); break; default: break; } } affect_total(ch); return (obj); } int get_number(char **name) { int i; char *ppos; char number[MAX_INPUT_LENGTH]; *number = '\0'; if ((ppos = strchr((const char *)*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; } /* 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 (GET_OBJ_RNUM(i) == num) return i; return NULL; } int from_ip_zone(int vnum) { int counter; if (vnum == -1) // obj made using create_obj, like mail and corpses return 0; else if (vnum < 0 || vnum > (zone_table[top_of_zone_table].top)) return 1; for (counter = 0; counter <= top_of_zone_table; counter++) if (!(zone_table[counter].connected) && vnum >= (zone_table[counter].number * 100) && vnum <= zone_table[counter].top) return 1; 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 (GET_OBJ_RNUM(i) == nr) // return i; // 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 = 0, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp = tmpname; strcpy(tmp, name); if (!(number = get_number(&tmp))) return NULL; for (i = world[room].people; i && (j <= number); i = i->next_in_room) if (isname(tmp, i->player.name)) if (++j == number) return i; return NULL; } /* 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 (GET_MOB_RNUM(i) == nr) return i; return NULL; } /* put an object in a room */ void obj_to_room(struct obj_data * object, int room) { struct obj_data *i = NULL, *op = NULL; if (!object || room < 0 || room > top_of_world) log("SYSLOG: Illegal value(s) passed to obj_to_room"); else { for (i = world[room].contents; i; i = i->next_content) { if (i->item_number == object->item_number && !strcmp(i->description, object->description) && IS_INVIS(i) == IS_INVIS(object)) break; op = i; } if (i) { object->next_content = i; if (op) op->next_content = object; else world[room].contents = object; } else { object->next_content = world[room].contents; world[room].contents = object; } object->in_room = room; object->carried_by = NULL; if (ROOM_FLAGGED(room, ROOM_HOUSE)) SET_BIT(ROOM_FLAGS(room), ROOM_HOUSE_CRASH); } } /* Take an object from a room */ void obj_from_room(struct obj_data * object) { struct obj_data *temp; if (!object || object->in_room == NOWHERE) { log("SYSLOG: NULL object or obj not in a room passed to obj_from_room"); return; } REMOVE_FROM_LIST(object, world[object->in_room].contents, next_content); if (ROOM_FLAGGED(object->in_room, ROOM_HOUSE)) SET_BIT(ROOM_FLAGS(object->in_room), ROOM_HOUSE_CRASH); object->in_room = NOWHERE; object->next_content = NULL; } /* 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; struct obj_data *i = NULL, *op = NULL; for (i = obj_to->contains; i; i = i->next_content) { if (i->item_number == obj->item_number && !strcmp(i->description, obj->description) && IS_INVIS(i) == IS_INVIS(obj)) break; op=i; } if (i) { obj->next_content = i; if (op) op->next_content = obj; else obj_to->contains = obj; } else { obj->next_content = obj_to->contains; obj_to->contains = obj; } obj->in_obj = obj_to; for (tmp_obj = obj->in_obj; tmp_obj->in_obj; tmp_obj = tmp_obj->in_obj) GET_OBJ_WEIGHT(tmp_obj) += GET_OBJ_WEIGHT(obj); /* top level object. Subtract weight from inventory if necessary. */ GET_OBJ_WEIGHT(tmp_obj) += GET_OBJ_WEIGHT(obj); if (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 *temp, *obj_from; if (obj->in_obj == NULL) { log("error (handler.c): trying to illegally extract obj from obj"); return; } obj_from = obj->in_obj; REMOVE_FROM_LIST(obj, obj_from->contains, next_content); /* Subtract weight from containers container */ for (temp = obj->in_obj; temp->in_obj; temp = temp->in_obj) GET_OBJ_WEIGHT(temp) -= GET_OBJ_WEIGHT(obj); /* Subtract weight from char that carries the object */ GET_OBJ_WEIGHT(temp) -= GET_OBJ_WEIGHT(obj); if (temp->carried_by) IS_CARRYING_W(temp->carried_by) -= GET_OBJ_WEIGHT(obj); obj->in_obj = NULL; obj->next_content = NULL; } /* Set all carried_by to point to new owner */ void object_list_new_owner(struct obj_data * list, struct char_data * ch) { if (list) { object_list_new_owner(list->contains, ch); object_list_new_owner(list->next_content, ch); list->carried_by = ch; } } /* Extract an object from the world */ void extract_obj(struct obj_data * obj) { bool set = FALSE; if (obj->worn_by != NULL) if (unequip_char(obj->worn_by, obj->worn_on) != obj) log("SYSLOG: Inconsistent worn_by and worn_on pointers!!"); if (obj->in_room != NOWHERE) { obj_from_room(obj); set = TRUE; } if (obj->carried_by) { obj_from_char(obj); if (set) log("SYSLOG: More than one list pointer set!"); set = TRUE; } if (obj->in_obj) { obj_from_obj(obj); if (set) log("SYSLOG: More than one list pointer set!"); set = TRUE; } /* Get rid of the contents of the object, as well. */ while (obj->contains) extract_obj(obj->contains); if (!ObjList.Remove(obj)) { sprintf(buf, "ObjList.Remove returned FALSE! (%d)", GET_OBJ_VNUM(obj)); log(buf); } if (GET_OBJ_RNUM(obj) >= 0) (obj_index[GET_OBJ_RNUM(obj)].number)--; Mem->DeleteObject(obj); } /* Extract a ch completely from the world, and leave his stuff behind */ void extract_char(struct char_data * ch) { struct char_data *k, *temp; struct descriptor_data *t_desc; struct obj_data *obj, *next; int i, wield[2]; extern struct char_data *combat_list; ACMD(do_return); void die_follower(struct char_data * ch); 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, 0); } if (ch->in_room == NOWHERE) { log("SYSLOG: NOWHERE extracting char. (handler.c, extract_char)"); exit(1); } if (ch->followers || ch->master) die_follower(ch); /* Forget snooping, if applicable */ if (ch->desc) { if (ch->desc->snooping) { ch->desc->snooping->snoop_by = NULL; ch->desc->snooping = NULL; } if (ch->desc->snoop_by) { SEND_TO_Q("Your victim is no longer among us.\r\n", ch->desc->snoop_by); ch->desc->snoop_by->snooping = NULL; ch->desc->snoop_by = NULL; } } /* transfer objects to room, if any */ while (ch->carrying) { obj = ch->carrying; obj_from_char(obj); obj_to_room(obj, ch->in_room); } /* extract all cyberware from NPC's since it can't be reused */ if (IS_NPC(ch)) { for (obj = ch->cyberware; obj; obj = next) { next = obj->next_content; obj_from_cyberware(obj); extract_obj(obj); } for (obj = ch->bioware; obj; obj = next) { next = obj->next_content; obj_from_bioware(obj); extract_obj(obj); } } wield[0] = GET_WIELDED(ch, 0); wield[1] = GET_WIELDED(ch, 1); /* transfer equipment to room, if any */ for (i = 0; i < NUM_WEARS; i++) if (GET_EQ(ch, i)) obj_to_room(unequip_char(ch, i), ch->in_room); if (FIGHTING(ch)) stop_fighting(ch); for (k = combat_list; k; k = temp) { temp = k->next_fighting; if (FIGHTING(k) == ch) stop_fighting(k); } while (ch->affected) affect_remove(ch, ch->affected, 0); char_from_room(ch); /* pull the char from the list */ REMOVE_FROM_LIST(ch, character_list, next); if (ch->desc && ch->desc->original) do_return(ch, "", 0, 0); if (!IS_NPC(ch)) { GET_WIELDED(ch, 0) = wield[0]; GET_WIELDED(ch, 1) = wield[1]; REMOVE_BIT(PLR_FLAGS(ch), PLR_MATRIX | PLR_PROJECT | PLR_SWITCHED | PLR_WRITING | PLR_MAILING | PLR_EDITING | PLR_SPELL_CREATE | PLR_CUSTOMIZE); save_char(ch, GET_LOADROOM(ch)); save_etext(ch); write_spells(ch); Crash_delete_crashfile(ch); if (ch->desc) { if (STATE(ch->desc) == CON_QMENU) SEND_TO_Q(QMENU, ch->desc); else { STATE(ch->desc) = CON_MENU; SEND_TO_Q(MENU, ch->desc); } } } else { if (GET_MOB_RNUM(ch) > -1) /* if mobile */ mob_index[GET_MOB_RNUM(ch)].number--; clearMemory(ch); /* Only NPC's can have memory */ Mem->DeleteCh(ch); } } /* *********************************************************************** Here follows high-level versions of some earlier routines, ie functions which incorporate the actual player-data. *********************************************************************** */ struct char_data *get_player_vis(struct char_data * ch, char *name, int inroom) { struct char_data *i; for (i = character_list; i; i = i->next) if (!IS_NPC(i) && (!inroom || i->in_room == ch->in_room) && !str_cmp(i->player.name, name) && CAN_SEE(ch, i) && !(isname("neuromancer", GET_NAME(i)) && GET_REAL_LEVEL(ch) < LVL_OWNER)) return i; return NULL; } struct char_data *get_char_room_vis(struct char_data * ch, char *name) { struct char_data *i; int j = 0, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp = tmpname; /* JE 7/18/94 :-) :-) */ if (!str_cmp(name, "self") || !str_cmp(name, "me")) return ch; /* 0.<name> means PC with name */ strcpy(tmp, name); if (!(number = get_number(&tmp))) return get_player_vis(ch, tmp, 1); for (i = world[ch->in_room].people; i && j <= number; i = i->next_in_room) if (isname(tmp, i->player.name) && CAN_SEE(ch, i)) if (++j == number) return i; return NULL; } struct char_data *get_char_vis(struct char_data * ch, char *name) { struct char_data *i; int j = 0, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp = tmpname; /* check the room first */ if ((i = get_char_room_vis(ch, name)) != NULL) return i; strcpy(tmp, name); if (!(number = get_number(&tmp))) return get_player_vis(ch, tmp, 0); for (i = character_list; i && (j <= number); i = i->next) if (isname(tmp, i->player.name) && CAN_SEE(ch, i)) if (++j == number) return i; return NULL; } struct obj_data *get_obj_in_list_vis(struct char_data * ch, char *name, struct obj_data * list) { struct obj_data *i; int j = 0, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp = tmpname; strcpy(tmp, name); if (!(number = get_number(&tmp))) return NULL; for (i = list; i && (j <= number); i = i->next_content) if (isname(tmp, i->name)) if (CAN_SEE_OBJ(ch, i)) if (++j == number) return i; return NULL; } /* 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 = 0, number; char tmpname[MAX_INPUT_LENGTH]; char *tmp = tmpname; /* 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(tmp, name); if (!(number = get_number(&tmp))) return NULL; // return find_obj(ch, tmp, number); return ObjList.FindObj(ch, tmp, number); return NULL; } struct obj_data *get_object_in_equip_vis(struct char_data * ch, char *arg, struct obj_data * equipment[], int *j) { char tmpname[MAX_INPUT_LENGTH]; char *tmp = tmpname; int i = 0, number; strcpy(tmp, arg); if (!(number = get_number(&tmp))) return NULL; for ((*j) = 0; (*j) < NUM_WEARS && i <= number; (*j)++) if (equipment[(*j)]) if (CAN_SEE_OBJ(ch, equipment[(*j)])) if (isname(tmp, equipment[(*j)]->name)) if (++i == number) return (equipment[(*j)]); return NULL; } int belongs_to(struct char_data *ch, struct obj_data *obj) { if (GET_OBJ_TYPE(obj) == ITEM_MONEY && GET_OBJ_VAL(obj, 1) == 1 && (IS_NPC(ch) ? GET_OBJ_VAL(obj, 3) == 0 : GET_OBJ_VAL(obj, 3) == 1) && GET_OBJ_VAL(obj, 4) == (IS_NPC(ch) ? ch->nr : GET_IDNUM(ch))) return 1; else return 0; } struct obj_data *get_first_credstick(struct char_data *ch, char *arg) { struct obj_data *obj; int i; for (obj = ch->carrying; obj; obj = obj->next_content) if (belongs_to(ch, obj) && isname(arg, obj->name)) return obj; for (i = 0; i < NUM_WEARS - 1; i++) if (GET_EQ(ch, i) && belongs_to(ch, GET_EQ(ch, i)) && isname(arg, GET_EQ(ch, i)->name)) return GET_EQ(ch, i); return NULL; } struct obj_data *create_credstick(struct char_data *ch, int amount) { struct obj_data *obj; int num; if (amount <= 0) { log("SYSLOG: Try to create negative or 0 nuyen."); return NULL; } else if (!IS_NPC(ch)) { log("SYSLOG: Creating a credstick for a PC corpse."); return NULL; } if (amount < 2500) num = 100; // plastic credstick else if (amount < 10000) num = 101; // steel credstick else if (amount < 50000) num = 102; // silver credstick else if (amount < 150000) num = 103; // titanium credstick else if (amount < 500000) num = 104; // platinum credstick else num = 105; // emerald credstick obj = read_object(num, VIRTUAL); GET_OBJ_VAL(obj, 0) = amount; GET_OBJ_VAL(obj, 3) = 0; GET_OBJ_VAL(obj, 4) = ch->nr; if (num < 102) GET_OBJ_VAL(obj, 5) = (number(1, 9) * 100000) + (number(0, 9) * 10000) + (number(0, 9) * 1000) + (number(0, 9) * 100) + (number(0, 9) * 10) + number(0, 9); return obj; } struct obj_data *create_nuyen(int amount) { struct obj_data *obj; if (amount <= 0) { log("SYSLOG: Try to create negative or 0 nuyen."); return NULL; } obj = read_object(110, VIRTUAL); GET_OBJ_VAL(obj, 0) = amount; return obj; } int find_skill_num(char *name) { int index = 0, ok; char *temp, *temp2; char first[256], first2[256]; while (*spells[++index] != '\n') { if (is_abbrev(name, spells[index])) return index; ok = 1; temp = any_one_arg((char *)spells[index], first); temp2 = any_one_arg(name, first2); while (*first && *first2 && ok) { if (!is_abbrev(first2, first)) ok = 0; temp = any_one_arg(temp, first); temp2 = any_one_arg(temp2, first2); } if (ok && !*first2) return index; } return -1; } /* 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, struct char_data * ch, struct char_data ** tar_ch, struct obj_data ** tar_obj) { int i, found; char name[256]; one_argument(arg, name); if (!*name) return (0); *tar_ch = NULL; *tar_obj = NULL; if (IS_SET(bitvector, FIND_CHAR_ROOM)) { /* Find person in room */ if ((*tar_ch = get_char_room_vis(ch, name))) { return (FIND_CHAR_ROOM); } } if (IS_SET(bitvector, FIND_CHAR_WORLD)) { if ((*tar_ch = get_char_vis(ch, name))) { return (FIND_CHAR_WORLD); } } if (IS_SET(bitvector, FIND_OBJ_EQUIP)) { if ((*tar_obj = get_object_in_equip_vis(ch, name, ch->equipment, &i))) return (FIND_OBJ_EQUIP); } if (IS_SET(bitvector, FIND_OBJ_INV)) { if ((*tar_obj = get_obj_in_list_vis(ch, name, ch->carrying))) { return (FIND_OBJ_INV); } } if (IS_SET(bitvector, FIND_OBJ_ROOM)) { if ((*tar_obj = 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_obj = get_obj_vis(ch, name))) { return (FIND_OBJ_WORLD); } } return (0); } /* a function to scan for "all" or "all.x" */ int find_all_dots(char *arg) { if (!strcmp(arg, "all")) return FIND_ALL; else if (!strncmp(arg, "all.", 4)) { strcpy(arg, arg + 4); return FIND_ALLDOT; } else return FIND_INDIV; }