void make_corpse(struct char_data * ch) { struct obj_data *corpse, *o; struct obj_data *money; int i; corpse = create_obj(); corpse->item_number = NOTHING; IN_ROOM(corpse) = NOWHERE; corpse->name = str_dup("corpse"); sprintf(buf2, "The corpse of %s is lying here.", GET_NAME(ch)); corpse->description = str_dup(buf2); sprintf(buf2, "the corpse of %s", GET_NAME(ch)); corpse->short_description = str_dup(buf2); GET_OBJ_TYPE(corpse) = ITEM_CONTAINER; GET_OBJ_WEAR(corpse) = ITEM_WEAR_TAKE; GET_OBJ_EXTRA(corpse) = ITEM_NODONATE; GET_OBJ_VAL(corpse, 0) = 0; /* You can't store stuff in a corpse */ GET_OBJ_VAL(corpse, 3) = 1; /* corpse identifier */ GET_OBJ_WEIGHT(corpse) = GET_WEIGHT(ch) + IS_CARRYING_W(ch); GET_OBJ_RENT(corpse) = 100000; if (IS_NPC(ch)) GET_OBJ_TIMER(corpse) = max_npc_corpse_time; else GET_OBJ_TIMER(corpse) = max_pc_corpse_time; /* transfer character's inventory to the corpse */ corpse->contains = ch->carrying; for (o = corpse->contains; o != NULL; o = o->next_content) o->in_obj = corpse; object_list_new_owner(corpse, NULL); /* transfer character's equipment to the corpse */ for (i = 0; i < NUM_WEARS; i++) if (GET_EQ(ch, i)) { remove_otrigger(GET_EQ(ch, i), ch); obj_to_obj(unequip_char(ch, i), corpse); } /* transfer gold */ if (GET_GOLD(ch) > 0) { /* following 'if' clause added to fix gold duplication loophole */ if (IS_NPC(ch) || (!IS_NPC(ch) && ch->desc)) { money = create_money(GET_GOLD(ch)); obj_to_obj(money, corpse); } GET_GOLD(ch) = 0; } ch->carrying = NULL; IS_CARRYING_N(ch) = 0; IS_CARRYING_W(ch) = 0; obj_to_room(corpse, IN_ROOM(ch)); }
void update_object(struct obj_data * obj, int use) { if (GET_OBJ_TIMER(obj) > 0) GET_OBJ_TIMER(obj) -= use; if (obj->contains) update_object(obj->contains, use); if (obj->next_content) update_object(obj->next_content, use); }
static void update_object(struct obj_data *obj, int use) { /* dont update objects with a timer trigger */ if (!SCRIPT_CHECK(obj, OTRIG_TIMER) && (GET_OBJ_TIMER(obj) > 0)) GET_OBJ_TIMER(obj) -= use; if (obj->contains) update_object(obj->contains, use); if (obj->next_content) update_object(obj->next_content, use); }
struct obj_data * Obj_from_store(struct obj_file_elem object, int *locate) { struct obj_data *obj; int j; if (real_object(object.item_number) > -1) { obj = read_object(object.item_number, VNUMBER); *locate = (int) object.locate; GET_OBJ_VAL(obj, 0) = object.value[0]; GET_OBJ_VAL(obj, 1) = object.value[1]; GET_OBJ_VAL(obj, 2) = object.value[2]; GET_OBJ_VAL(obj, 3) = object.value[3]; GET_OBJ_VAL(obj, 4) = object.value[4]; GET_OBJ_VAL(obj, 5) = object.value[5]; GET_OBJ_VAL(obj, 6) = object.value[6]; GET_OBJ_VAL(obj, 7) = object.value[7]; GET_OBJ_VAL(obj, 8) = object.value[8]; GET_OBJ_VAL(obj, 9) = object.value[9]; GET_OBJ_EXTRA(obj) = object.extra_flags; GET_OBJ_WEIGHT(obj) = object.weight; GET_OBJ_TIMER(obj) = object.timer; obj->obj_flags.bitvector = object.bitvector; for (j = 0; j < MAX_OBJ_AFFECT; j++) obj->affected[j] = object.affected[j]; return obj; } else return NULL; }
struct obj_data *Obj_from_store(struct obj_file_elem object, int *location) { struct obj_data *obj; int j; *location = 0; if (real_object(object.item_number) != NOTHING) { obj = read_object(object.item_number, VIRTUAL); #if USE_AUTOEQ *location = object.location; #endif GET_OBJ_VAL(obj, 0) = object.value[0]; GET_OBJ_VAL(obj, 1) = object.value[1]; GET_OBJ_VAL(obj, 2) = object.value[2]; GET_OBJ_VAL(obj, 3) = object.value[3]; GET_OBJ_EXTRA(obj) = object.extra_flags; GET_OBJ_WEIGHT(obj) = object.weight; GET_OBJ_TIMER(obj) = object.timer; obj->obj_flags.bitvector = object.bitvector; for (j = 0; j < MAX_OBJ_AFFECT; j++) obj->affected[j] = object.affected[j]; return (obj); } else return (NULL); }
int Obj_to_store_from(struct obj_data * obj, FILE * fl, int locate) { int j; struct obj_file_elem object; object.item_number = GET_OBJ_VNUM(obj); object.locate = (sh_int) locate; /* where worn or inventory? */ object.value[0] = GET_OBJ_VAL(obj, 0); object.value[1] = GET_OBJ_VAL(obj, 1); object.value[2] = GET_OBJ_VAL(obj, 2); object.value[3] = GET_OBJ_VAL(obj, 3); object.value[4] = GET_OBJ_VAL(obj, 4); object.value[5] = GET_OBJ_VAL(obj, 5); object.value[6] = GET_OBJ_VAL(obj, 6); object.value[7] = GET_OBJ_VAL(obj, 7); object.value[8] = GET_OBJ_VAL(obj, 8); object.value[9] = GET_OBJ_VAL(obj, 9); object.extra_flags = GET_OBJ_EXTRA(obj); object.weight = GET_OBJ_WEIGHT(obj); object.timer = GET_OBJ_TIMER(obj); object.bitvector = obj->obj_flags.bitvector; for (j = 0; j < MAX_OBJ_AFFECT; j++) object.affected[j] = obj->affected[j]; if (fwrite(&object, sizeof(struct obj_file_elem), 1, fl) < 1) { perror("Error writing object in Obj_to_store"); return 0; } return 1; }
/* ** Update PCs, NPCs, and objects */ void point_update( void ) { int slot; void update_char_objects(CharData * ch); /* handler.c */ void extract_obj(ObjData * obj); /* handler.c */ void update_char_quests(CharData * ch); /* quest.c */ CharData *i, *next_char; ObjData *j, *next_thing, *jj, *next_thing2, *debugnext; int loopvar; /* characters */ for( i = character_list; i; i = next_char ) { next_char = i->next; // state flags i->tickstate = 0; /* dismount anyone who's gotten separated from their steed */ /* Note that it's superfluous to check for both rider AND mount */ if (i->rider && i->rider->in_room != i->in_room) { i->rider->mount = NULL; i->rider = NULL; } /* Prayer timer */ if (i->player_specials->saved.prayer_time > 0) { if (i->player_specials->saved.prayer_time == 1) { i->player_specials->saved.prayer_time = 0; send_to_char("Your prayers will be heard once again.\r\n", i); } else i->player_specials->saved.prayer_time -= 1; } for(slot = 0; slot<4; slot++) { if (COOLDOWN(i, slot) ) { COOLDOWN(i, slot) -= 1; if (!COOLDOWN(i, slot) ) { switch( GET_CLASS(i) ) { case CLASS_DEATH_KNIGHT: break; case CLASS_SOLAMNIC_KNIGHT: break; case CLASS_MAGIC_USER: break; case CLASS_SHADOW_DANCER: if(slot == SLOT_SLIPPERY_MIND) break; else if(slot == SLOT_NODESHIFT) sendChar(i, "You may once again shift your spectrum.\r\n"); else sendChar(i, "ERROR!\r\n"); break; case CLASS_THIEF: if(slot== SLOT_BLACKJACK) { sendChar(i, "You are able to use blackjack again.\r\n"); break; } else sendChar(i, "ERROR!\r\n"); case CLASS_ASSASSIN: if(slot == SLOT_DETERRENCE) sendChar(i, "You are able to use deterrence again.\r\n"); else sendChar(i, "ERROR!\r\n"); break; case CLASS_CLERIC: if(slot == SLOT_SHADOW_FORM) sendChar(i, "You are ready to enter shadow form again..\r\n"); else sendChar(i, "ERROR!\r\n"); case CLASS_WARRIOR: if(slot == SLOT_REDOUBT) sendChar(i, "You can shield yourself again.\r\n"); else if(slot == SLOT_COMMANDING_SHOUT) sendChar(i, "You can shout commands again.\r\n"); else sendChar(i, "ERROR!\r\n"); break; case CLASS_SHOU_LIN: break; case CLASS_RANGER: break; case CLASS_NECROMANCER: if(slot == SLOT_QUICKEN) sendChar(i, "You may once again rise from the grave.\r\n"); else if(slot == SLOT_METAMORPHOSIS) sendChar(i, "You may once again metamorphisize.\r\n"); else sendChar(i, "ERROR!\r\n"); break; default: sendChar(i, "ERROR!\r\n"); break; } } } } if( IS_AFFECTED(i, AFF_PLAGUE )) infectious(i); if( !IS_NPC(i) ) { update_char_objects(i); if( GET_LEVEL(i) < LVL_GOD ) check_idling(i); update_char_quests(i); } gain_condition(i, HUNGER, IS_AFFECTED(i, AFF_REGENERATE)? -2:-1); gain_condition(i, DRUNK, -1); /* Amara get thirsty in different ways */ if (IS_AMARA(i)) { if (IN_ROOM(i) >= 0 && IN_ROOM(i) <= top_of_world) { switch (SECT(IN_ROOM(i))) { case SECT_WATER_SWIM: case SECT_WATER_NOSWIM: gain_condition(i, THIRST, 1); break; case SECT_UNDERWATER: case SECT_UNDERWATER_RIVER: gain_condition(i, THIRST, 24); break; default: gain_condition(i, THIRST, -2); break; } } else gain_condition(i, THIRST, -2); } else gain_condition(i, THIRST, -1); }/* for */ debugnext = NULL; /* objects */ for( j = object_list; j; j = next_thing ) { next_thing = j->next; /* Next in object list */ debugnext = j; // we didn't crash if we got here if( IS_SET_AR( j->obj_flags.extra_flags, ITEM_TIMED )) { if( GET_OBJ_TIMER(j) > 0 ) GET_OBJ_TIMER(j)--; if (GET_OBJ_TIMER(j) == 0) { if(contains_soulbound(j)) { GET_OBJ_TIMER(j) = 1; continue; } if (SCRIPT_CHECK(j, OTRIG_TIMER)) { REMOVE_BIT_AR(j->obj_flags.extra_flags, ITEM_TIMED); timer_otrigger(j); continue; // don't do anything more with this } } if( GET_OBJ_TYPE(j) == ITEM_KEY ) { static char *keyVaporMsgs[] = { "$p vanishes with a flash.", "$p begins to shake violently.", "$p begins to vibrate.", "$p begins to hum.", "$p begins to glow." }; if( GET_OBJ_TIMER(j) < (sizeof( keyVaporMsgs )/sizeof( *keyVaporMsgs ))) { int vaporMsg = GET_OBJ_TIMER(j); if( j->carried_by ) act( keyVaporMsgs[ vaporMsg ], FALSE, j->carried_by, j, 0, TO_CHAR); else if( j->worn_by ) { act( keyVaporMsgs[ vaporMsg ], FALSE, j->worn_by, j, 0, TO_CHAR); for( loopvar = 0; loopvar < NUM_WEARS; loopvar++ ) { if( j->worn_by->equipment[loopvar] == j ) j->worn_by->equipment[loopvar] = 0; } } else if( j->in_room != NOWHERE && world[j->in_room].people ) { act( keyVaporMsgs[ vaporMsg ], FALSE, world[j->in_room].people, j, 0, TO_CHAR); act( keyVaporMsgs[ vaporMsg ], FALSE, world[j->in_room].people, j, 0, TO_ROOM); } extract_obj(j); continue; }/* ITEM_KEY has timed out */ }/* if ITEM_KEY */ else if (GET_OBJ_TYPE(j) == ITEM_AFFECT) { if (!GET_OBJ_TIMER(j)) { if (j->in_room != NOWHERE && world[j->in_room].people) { act(j->action_description, FALSE, world[j->in_room].people, j, 0, TO_CHAR); act(j->action_description, FALSE, world[j->in_room].people, j, 0, TO_ROOM); } extract_obj(j); continue; // object gone, don't act further on it! } } else if( !GET_OBJ_TIMER(j) ) { /* The object timed out - delete it */ if( j->carried_by ) act( "$p crumbles to dust and is blown away.", FALSE, j->carried_by, j, 0, TO_CHAR ); else if( j->worn_by ) { act("$p crumbles to dust and is blown away.", FALSE, j->worn_by, j, 0, TO_CHAR); unequip_char( j->worn_by, j->worn_at ); } else if( j->in_room != NOWHERE && world[j->in_room].people ) { act( "$p crumbles to dust and is blown away.", FALSE, world[j->in_room].people, j, 0, TO_CHAR); act( "$p crumbles to dust and is blown away.", FALSE, world[j->in_room].people, j, 0, TO_ROOM); } extract_obj(j); continue; // object gone, don't act further on it! } } /* if OBJ_TIMED */ /* if this looks like a portal */ if ( (GET_OBJ_RNUM(j) >= 0 && GET_OBJ_RNUM(j) <= top_of_objt) && obj_index[GET_OBJ_RNUM(j)].func == portal_proc && GET_OBJ_TYPE(j) == ITEM_OTHER ) { /* Mage created portals are type other, permanent portals are type portal. */ /* Permanent portals thus don't decay. */ if (GET_OBJ_VAL(j, 2) > 0) GET_OBJ_VAL(j,2)--; } /* ** Digger */ /* If this is a corpse */ if ((GET_OBJ_TYPE(j) == ITEM_CONTAINER) && GET_OBJ_VAL(j, 3)) { /* timer count down */ if (GET_OBJ_TIMER(j) > 0) GET_OBJ_TIMER(j)--; // PC corpses which are empty will decay eventually.. if(!CAN_WEAR(j, ITEM_WEAR_TAKE) && !(j->contains)) { GET_OBJ_TIMER(j) = MAX(GET_OBJ_TIMER(j) / 3, 0); } if (!GET_OBJ_TIMER(j)) { if(contains_soulbound(j)) { GET_OBJ_TIMER(j) = 1; continue; } if (j->carried_by) act("$p decays in your hands.", FALSE, j->carried_by, j, 0, TO_CHAR); else if ((j->in_room != NOWHERE) && (world[j->in_room].people)) { static char *decay_messages[] = { "A quivering hoard of maggots consumes $p.", "A flock of vultures swoop down from the sky to devour $p.", "The $p rots and decays as the shards of bone are blown to the four winds.", "The $p rots and decays leaving behind the pungent stench of death.", "A bolt of holy fire streaks from the heavens to burn the corpse of $p to ash.", "The $p rots to ash and is swept away by the winds of time." }; int decay_idx = (int)( random() % ( sizeof( decay_messages ) / sizeof( *decay_messages ))); act( decay_messages[ decay_idx ], TRUE, world[j->in_room].people, j, 0, TO_ROOM); act( decay_messages[ decay_idx ], TRUE, world[j->in_room].people, j, 0, TO_CHAR); }/* JBP */ for (jj = j->contains; jj; jj = next_thing2) { next_thing2 = jj->next_content; /* Next in inventory */ obj_from_obj(jj); if (j->in_obj) { if ( GET_OBJ_TYPE(j) != ITEM_KEY && GET_OBJ_TYPE(j) != ITEM_SCROLL && GET_OBJ_TYPE(j) != ITEM_POTION && GET_OBJ_TYPE(j) != ITEM_DUST && (GET_OBJ_VNUM(j) == 1460 || GET_OBJ_VNUM(j) == 1461 || GET_OBJ_VNUM(j) == 1462 ) ) continue; // Refrigeration to keep food from rotting. obj_to_obj(jj, j->in_obj); } else if (j->carried_by) obj_to_room(jj, j->carried_by->in_room); else if (j->in_room != NOWHERE) obj_to_room(jj, j->in_room); else { /* OLD WAY: assert(FALSE); */ mudlog(NRM, LVL_IMMORT, TRUE, "SYSERR: Something is wrong with a container." ); obj_to_room(jj, real_room(1201)); } } extract_obj(j); } } /* Imhotep: Added support for ITEM_TROPHY pieces that decay after * a given MUD date */ if(IS_OBJ_STAT(j, ITEM_TROPHY)) { if(GET_OBJ_TIMER(j) < TICKS_SO_FAR) { if (j->carried_by) act("$p shimmers and vanishes out of your hands!", FALSE, j->carried_by, j, 0, TO_CHAR); else if (j->worn_by) { act("$p shimmers and vanishes!", FALSE, j->worn_by, j, 0, TO_CHAR); unequip_char(j->worn_by, j->worn_at); } else if (j->in_room != NOWHERE && world[j->in_room].people) { act("$p shimmers and vanishes!", FALSE, world[j->in_room].people, j, 0, TO_CHAR); act("$p shimmers and vanishes!", FALSE, world[j->in_room].people, j, 0, TO_ROOM); } extract_obj(j); continue; } } } }/* point_update */
void do_obj_report (struct char_data *ch) { struct obj_data *obj, *key; int i=0, j=0, found=0; FILE *reportfile; if (!(reportfile = fopen("report.obj", "w"))) { mlog("SYSERR: Object report file unavailable."); send_to_char ("Report.obj could not be generated.\r\n",ch); return; } sprintf(buf, "OBJECTS\n-------\n"); for (i=0; i<top_of_objt;i++) { obj=read_object(i, REAL); sprintf(buf+strlen(buf), "[%5d] %s\nSpec Proc: ", GET_OBJ_VNUM(obj), obj->short_description); if (obj_index[GET_OBJ_RNUM(obj)].func!=NULL) get_spec_name(GET_OBJ_RNUM(obj), buf2,'o'); else sprintf(buf2, "none"); sprintf(buf+strlen(buf), "%s Aliases: %s\n", buf2, GET_OBJ_NAME(obj)); sprinttype(GET_OBJ_TYPE(obj), item_types, buf2, sizeof(buf2)); sprintf (buf+strlen(buf),"Type: %s Worn on: ",buf2); sprintbit(obj->obj_flags.wear_flags, wear_bits, buf2, sizeof(buf2)); sprintf(buf+strlen(buf), "%s\n", buf2); sprintf(buf+strlen(buf), "Weight: %d, Value: %d, Cost/day: %d, Timer: %d\n", GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj), GET_OBJ_RENT(obj), GET_OBJ_TIMER(obj)); sprintbit(obj->obj_flags.bitvector, affected_bits, buf2, sizeof(buf2)); sprintf(buf+strlen(buf), "Affects player: %s\n",buf2); sprintbit(obj->obj_flags.bitvector, affected_bits, buf2, sizeof(buf2)); sprintf(buf+strlen(buf), "Extra bits: %s\n",buf2); switch (GET_OBJ_TYPE(obj)) { case ITEM_LIGHT: if (GET_OBJ_VAL(obj, 2) == -1) strcpy(buf, "Hours left: Infinite\n"); else sprintf(buf+strlen(buf), "Hours left: [%d]\n", GET_OBJ_VAL(obj, 2)); break; case ITEM_SCROLL: case ITEM_POTION: sprintf(buf+strlen(buf), "Spells: (Level %d) %s, %s, %s\n", GET_OBJ_VAL(obj, 0), skill_name(GET_OBJ_VAL(obj, 1)), skill_name(GET_OBJ_VAL(obj, 2)), skill_name(GET_OBJ_VAL(obj, 3))); break; case ITEM_WAND: case ITEM_STAFF: sprintf(buf+strlen(buf), "Spell: %s at level %d, %d (of %d) charges remaining\n", skill_name(GET_OBJ_VAL(obj, 3)), GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 1)); break; case ITEM_WEAPON: sprintf(buf+strlen(buf), "Ave. Dam: %d, Message type: %d\n", get_weapon_dam(obj), GET_OBJ_VAL(obj, 3)); break; case ITEM_ARMOR: sprintf(buf+strlen(buf), "Passive Defense: [%d]\n", GET_OBJ_VAL(obj, 0)); sprintf(buf+strlen(buf), "Damage Reduction: [%d]\n", GET_OBJ_VAL(obj, 1)); break; case ITEM_TRAP: sprintf(buf+strlen(buf), "Spell: %d, - Hitpoints: %d\n", GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1)); break; case ITEM_CONTAINER: sprintbit(GET_OBJ_VAL(obj, 1), container_bits, buf2, sizeof(buf2)); sprintf(buf+strlen(buf), "Weight capacity: %d, Lock Type: %s, Key Num: %d ", GET_OBJ_VAL(obj, 0), buf2, GET_OBJ_VAL(obj, 2)); if (GET_OBJ_VAL(obj, 2) > 0) { key=read_object(GET_OBJ_VAL(obj,2), VIRTUAL); if (key) { sprintf(buf+strlen(buf), "(%s)", GET_OBJ_NAME(key)); extract_obj(key); } else sprintf(buf+strlen(buf), "(Error: Key does not exist!)"); } sprintf(buf+strlen(buf), "\n"); break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: sprinttype(GET_OBJ_VAL(obj, 2), drinks, buf2, sizeof(buf2)); sprintf(buf+strlen(buf), "Capacity: %d, Contains: %d, Poisoned: %s, Liquid: %s\n", GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), YESNO(GET_OBJ_VAL(obj, 3)),buf2); break; case ITEM_FOOD: sprintf(buf+strlen(buf), "Makes full: %d, Poisoned: %s\n", GET_OBJ_VAL(obj, 0),YESNO(GET_OBJ_VAL(obj, 3))); break; case ITEM_MONEY: sprintf(buf, "Coins: %d\n", GET_OBJ_VAL(obj, 0)); break; case ITEM_PORTAL: sprintf(buf, "To room: %d\n", GET_OBJ_VAL(obj, 0)); break; default: sprintf(buf+strlen(buf), "Values 0-3: [%d] [%d] [%d] [%d]\n", GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3)); break; } found = 0; sprintf(buf+strlen(buf), "Affects on player stats:\n"); for (j = 0; j < MAX_OBJ_AFFECT; j++) if (obj->affected[j].modifier) { sprinttype(obj->affected[j].location, apply_types, buf2, sizeof(buf2)); sprintf(buf+strlen(buf), " %+d to %s\n",obj->affected[j].modifier, buf2); found=1; } if (!found) sprintf(buf+strlen(buf)," None\n"); sprintf(buf+strlen(buf), "\n--------\n"); extract_obj(obj); fprintf(reportfile, buf); buf[0]='\0'; }/*for i=0...*/ fclose (reportfile); send_to_char ("report.obj printed\r\n",ch); }
void make_corpse(struct char_data *ch) { char buf2[MAX_NAME_LENGTH + 64]; struct obj_data *corpse, *o; struct obj_data *money; int i; corpse = create_obj(); corpse->item_number = NOTHING; IN_ROOM(corpse) = NOWHERE; corpse->name = strdup("corpse"); snprintf(buf2, sizeof(buf2), "The corpse of %s is lying here.", GET_NAME(ch)); corpse->description = strdup(buf2); snprintf(buf2, sizeof(buf2), "the corpse of %s", GET_NAME(ch)); corpse->short_description = strdup(buf2); GET_OBJ_TYPE(corpse) = ITEM_CONTAINER; GET_OBJ_WEAR(corpse) = ITEM_WEAR_TAKE; GET_OBJ_EXTRA(corpse) = ITEM_NODONATE; GET_OBJ_VAL(corpse, 0) = 0; /* You can't store stuff in a corpse */ GET_OBJ_VAL(corpse, 3) = 1; /* corpse identifier */ GET_OBJ_WEIGHT(corpse) = GET_WEIGHT(ch) + IS_CARRYING_W(ch); GET_OBJ_RENT(corpse) = 100000; if (IS_NPC(ch)) GET_OBJ_TIMER(corpse) = max_npc_corpse_time; else GET_OBJ_TIMER(corpse) = max_pc_corpse_time; /* transfer character's inventory to the corpse */ corpse->contains = ch->carrying; for (o = corpse->contains; o != NULL; o = o->next_content) o->in_obj = corpse; object_list_new_owner(corpse, NULL); /* transfer character's equipment to the corpse */ for (i = 0; i < NUM_WEARS; i++) if (GET_EQ(ch, i)) obj_to_obj(unequip_char(ch, i), corpse); /* transfer gold */ if (GET_GOLD(ch) > 0) { /* * following 'if' clause added to fix gold duplication loophole * The above line apparently refers to the old "partially log in, * kill the game character, then finish login sequence" duping * bug. The duplication has been fixed (knock on wood) but the * test below shall live on, for a while. -gg 3/3/2002 */ if (IS_NPC(ch) || ch->desc) { money = create_money(GET_GOLD(ch)); obj_to_obj(money, corpse); } GET_GOLD(ch) = 0; } ch->carrying = NULL; IS_CARRYING_N(ch) = 0; IS_CARRYING_W(ch) = 0; obj_to_room(corpse, IN_ROOM(ch)); }
void mag_affect_obj(struct char_data *caster, struct obj_data *object, struct spell_info_type *sinfo, int level) { int i, j; if (object) { for (i = 0; i < NUM_MODIFY; i++) { switch (sinfo->obj_aff[i].location) { case OBJ_EXTRA: if (strcmp(sinfo->command, "darkness") == 0) { REMOVE_BIT(GET_OBJ_EXTRA(object), sinfo->spell_obj_bit); break; } if (!sinfo->spell_obj_bit) SET_BIT(GET_OBJ_EXTRA(object), sinfo->obj_aff[i].location); else SET_BIT(GET_OBJ_EXTRA(object), sinfo->spell_obj_bit); break; case OBJ_VALUE_0: if (strcmp(sinfo->command, "enchant shield") == 0) { if (GET_OBJ_WEAR(object) == ITEM_WEAR_SHIELD) { GET_OBJ_VAL(object, 0) += number((level / 20), sinfo->obj_aff[i].modifier); } } else { GET_OBJ_VAL(object, 0) += sinfo->obj_aff[i].modifier; } break; case OBJ_VALUE_1: GET_OBJ_VAL(object, 1) += sinfo->obj_aff[i].modifier; break; case OBJ_VALUE_2: GET_OBJ_VAL(object, 2) += sinfo->obj_aff[i].modifier; break; case OBJ_VALUE_3: GET_OBJ_VAL(object, 3) += sinfo->obj_aff[i].modifier; break; case OBJ_VALUE_4: GET_OBJ_VAL(object, 4) += sinfo->obj_aff[i].modifier; break; case OBJ_DAMROLL: if (strcmp(sinfo->command, "enchant weapon") == 0) { for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_DAMROLL; object->affected[0].modifier = number((level / 33), sinfo->obj_aff[i].modifier); } } break; case OBJ_HITROLL: if (strcmp(sinfo->command, "enchant weapon") == 0) { for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_HITROLL; object->affected[0].modifier = number((level / 33), sinfo->obj_aff[i].modifier); } } break; case OBJ_SAVING_PARA: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_SAVING_PARA; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_SAVING_ROD: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_SAVING_ROD; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_SAVING_PETRI: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_SAVING_PETRI; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_SAVING_BREATH: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_SAVING_BREATH; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_SAVING_SPELL: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_SAVING_SPELL; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_MAX_HIT: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_MAX_HIT; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_MAX_MANA: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_MAX_MANA; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_MAX_MOVE: for (j = 0; j < MAX_OBJ_AFFECT; j++) if (object->affected[j].location != APPLY_NONE) break; if (j == MAX_OBJ_AFFECT) { object->affected[0].location = APPLY_MAX_MOVE; object->affected[0].modifier = sinfo->obj_aff[i].modifier; } break; case OBJ_RES_LIGHT: GET_OBJ_RESIST(object, DAM_LIGHT) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_DARK: GET_OBJ_RESIST(object, DAM_DARK) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_FIRE: GET_OBJ_RESIST(object, DAM_FIRE) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_COLD: GET_OBJ_RESIST(object, DAM_COLD) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_ACID: GET_OBJ_RESIST(object, DAM_ACID) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_POISON: GET_OBJ_RESIST(object, DAM_POISON) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_DISEASE: GET_OBJ_RESIST(object, DAM_DISEASE) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_CHARM: GET_OBJ_RESIST(object, DAM_CHARM) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_SLEEP: GET_OBJ_RESIST(object, DAM_SLEEP) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_SLASH: GET_OBJ_RESIST(object, DAM_SLASH) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_PIERCE: GET_OBJ_RESIST(object, DAM_PIERCE) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_BLUDGEON: GET_OBJ_RESIST(object, DAM_BLUDGEON) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_NWEAP: GET_OBJ_RESIST(object, DAM_NWEAP) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_MWEAP: GET_OBJ_RESIST(object, DAM_MWEAP) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_MAGIC: GET_OBJ_RESIST(object, DAM_MAGIC) += sinfo->obj_aff[i].modifier; break; case OBJ_RES_ELECTRICITY: GET_OBJ_RESIST(object, DAM_ELECTRICITY) += sinfo->obj_aff[i].modifier; break; case OBJ_TIMER: GET_OBJ_TIMER(object) += (sinfo->obj_aff[i].modifier * level); break; } } } }
void Obj_to_store(struct obj_data * obj, int objnum, int obj_pos, FILE * fl) { void olc_print_bitvectors(FILE *f, long bitvector, long max); int j; fprintf(fl, "-obj_begin-\n"); fprintf(fl, "-obj_number- %d\n", GET_OBJ_VNUM(obj)); fprintf(fl, "-obj_tnum- %d\n", objnum); fprintf(fl, "-obj_pos- %d\n", obj_pos); if (GET_OBJ_VAL(obj, 0)) { fprintf(fl, "-obj_value0- %d\n", GET_OBJ_VAL(obj, 0)); } if (GET_OBJ_VAL(obj, 1)) { fprintf(fl, "-obj_value1- %d\n", GET_OBJ_VAL(obj, 1)); } if (GET_OBJ_VAL(obj, 2)) { fprintf(fl, "-obj_value2- %d\n", GET_OBJ_VAL(obj, 2)); } if (GET_OBJ_VAL(obj, 3)) { fprintf(fl, "-obj_value3- %d\n", GET_OBJ_VAL(obj, 3)); } if (GET_OBJ_VAL(obj, 4)) { fprintf(fl, "-obj_value4- %d\n", GET_OBJ_VAL(obj, 4)); } if (GET_OBJ_TIMER(obj)) { fprintf(fl, "-obj_timer- %d\n", GET_OBJ_TIMER(obj)); } if (GET_OBJ_EXTRA(obj)) { fprintf(fl, "-obj_extra_flags- "); olc_print_bitvectors(fl, GET_OBJ_EXTRA(obj), NUM_ITEM_FLAGS); fprintf(fl, "\n"); } if (GET_OBJ_BITV(obj)) { fprintf(fl, "-obj_bitvector- "); olc_print_bitvectors(fl, GET_OBJ_BITV(obj), NUM_AFF_FLAGS); fprintf(fl, "\n"); } if (GET_OBJ_BITV2(obj)) { fprintf(fl, "-obj_bitvector- "); olc_print_bitvectors(fl, GET_OBJ_BITV2(obj), NUM_AFF2_FLAGS); fprintf(fl, "\n"); } for (j = 0; j < MAX_OBJ_AFFECT; j++) { if (obj->affected[j].location) { fprintf(fl, "-obj_affect_loc- %d\n", obj->affected[j].location); fprintf(fl, "-obj_affect_mod- %d\n", obj->affected[j].modifier); } } switch (GET_OBJ_TYPE(obj)) { case ITEM_SPELLBOOK: if (GET_OBJ_SPELLLIST(obj)) { for (j = 0; j < GET_OBJ_VAL(obj, 0); j++) { if (GET_OBJ_SPELLLISTNUM(obj, j)) { fprintf(fl, "-obj_spellbook_entry- %s\n", spells[find_skill_num_def(GET_OBJ_SPELLLISTNUM(obj, j))].command); } } } break; case ITEM_POTION: case ITEM_SCROLL: if (GET_OBJ_VAL(obj, 1)) { fprintf(fl, "-obj_spell1- %s\n", spells[find_skill_num_def(GET_OBJ_VAL(obj, 1))].command); } if (GET_OBJ_VAL(obj, 2)) { fprintf(fl, "-obj_spell2- %s\n", spells[find_skill_num_def(GET_OBJ_VAL(obj, 2))].command); } if (GET_OBJ_VAL(obj, 3)) { fprintf(fl, "-obj_spell3- %s\n", spells[find_skill_num_def(GET_OBJ_VAL(obj, 3))].command); } break; case ITEM_WAND: case ITEM_STAFF: if (GET_OBJ_VAL(obj, 1)) { fprintf(fl, "-obj_spell1- %s\n", spells[find_skill_num_def(GET_OBJ_VAL(obj, 1))].command); } break; } fprintf(fl, "-obj_end-\n"); }
void oedit_parse(struct descriptor_data *d, char *arg) { int number, max_val, min_val; char *oldtext = NULL; switch (OLC_MODE(d)) { case OEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': write_to_output(d, "Saving object to memory.\r\n"); oedit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d)); /* Fall through. */ case 'n': case 'N': cleanup_olc(d, CLEANUP_ALL); return; default: write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Do you wish to save this object internally?\r\n"); return; } case OEDIT_MAIN_MENU: /* * Throw us out to whichever edit mode based on user input. */ switch (*arg) { case 'q': case 'Q': if (OLC_VAL(d)) { /* Something has been modified. */ write_to_output(d, "Do you wish to save this object internally? : "); OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '1': write_to_output(d, "Enter namelist : "); OLC_MODE(d) = OEDIT_EDIT_NAMELIST; break; case '2': write_to_output(d, "Enter short desc : "); OLC_MODE(d) = OEDIT_SHORTDESC; break; case '3': write_to_output(d, "Enter long desc :-\r\n| "); OLC_MODE(d) = OEDIT_LONGDESC; break; case '4': OLC_MODE(d) = OEDIT_ACTDESC; send_editor_help(d); write_to_output(d, "Enter action description:\r\n\r\n"); if (OLC_OBJ(d)->action_description) { write_to_output(d, "%s", OLC_OBJ(d)->action_description); oldtext = strdup(OLC_OBJ(d)->action_description); } string_write(d, &OLC_OBJ(d)->action_description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; break; case '5': oedit_disp_type_menu(d); OLC_MODE(d) = OEDIT_TYPE; break; case '6': oedit_disp_extra_menu(d); OLC_MODE(d) = OEDIT_EXTRAS; break; case '7': oedit_disp_wear_menu(d); OLC_MODE(d) = OEDIT_WEAR; break; case '8': write_to_output(d, "Enter weight : "); OLC_MODE(d) = OEDIT_WEIGHT; break; case '9': write_to_output(d, "Enter cost : "); OLC_MODE(d) = OEDIT_COST; break; case 'a': case 'A': write_to_output(d, "Enter cost per day : "); OLC_MODE(d) = OEDIT_COSTPERDAY; break; case 'b': case 'B': write_to_output(d, "Enter timer : "); OLC_MODE(d) = OEDIT_TIMER; break; case 'c': case 'C': /* * Clear any old values */ GET_OBJ_VAL(OLC_OBJ(d), 0) = 0; GET_OBJ_VAL(OLC_OBJ(d), 1) = 0; GET_OBJ_VAL(OLC_OBJ(d), 2) = 0; GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; oedit_disp_val1_menu(d); break; case 'd': case 'D': oedit_disp_prompt_apply_menu(d); break; case 'e': case 'E': /* * If extra descriptions don't exist. */ if (OLC_OBJ(d)->ex_description == NULL) { CREATE(OLC_OBJ(d)->ex_description, struct extra_descr_data, 1); OLC_OBJ(d)->ex_description->next = NULL; } OLC_DESC(d) = OLC_OBJ(d)->ex_description; oedit_disp_extradesc_menu(d); break; case 'm': case 'M': write_to_output(d, "Enter new minimum level: "); OLC_MODE(d) = OEDIT_LEVEL; break; case 'p': case 'P': oedit_disp_perm_menu(d); OLC_MODE(d) = OEDIT_PERM; break; case 's': case 'S': OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU; dg_script_menu(d); return; default: oedit_disp_menu(d); break; } return; /* * end of OEDIT_MAIN_MENU */ case OLC_SCRIPT_EDIT: if (dg_script_edit_parse(d, arg)) return; break; case OEDIT_EDIT_NAMELIST: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->name) free(OLC_OBJ(d)->name); OLC_OBJ(d)->name = str_udup(arg); break; case OEDIT_SHORTDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->short_description) free(OLC_OBJ(d)->short_description); OLC_OBJ(d)->short_description = str_udup(arg); break; case OEDIT_LONGDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->description) free(OLC_OBJ(d)->description); OLC_OBJ(d)->description = str_udup(arg); break; case OEDIT_TYPE: number = atoi(arg); if ((number < 1) || (number >= NUM_ITEM_TYPES)) { write_to_output(d, "Invalid choice, try again : "); return; } else GET_OBJ_TYPE(OLC_OBJ(d)) = number; break; case OEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_FLAGS)) { oedit_disp_extra_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT(GET_OBJ_EXTRA(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_extra_menu(d); return; } case OEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_WEARS)) { write_to_output(d, "That's not a valid choice!\r\n"); oedit_disp_wear_menu(d); return; } else if (number == 0) /* Quit. */ break; else { TOGGLE_BIT(GET_OBJ_WEAR(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_wear_menu(d); return; } case OEDIT_WEIGHT: GET_OBJ_WEIGHT(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_COST: GET_OBJ_COST(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_COSTPERDAY: GET_OBJ_RENT(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_TIMER: GET_OBJ_TIMER(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_LEVEL: GET_OBJ_LEVEL(OLC_OBJ(d)) = atoi(arg); break; case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; if (number > 0 && number <= NUM_AFF_FLAGS) TOGGLE_BIT(GET_OBJ_PERM(OLC_OBJ(d)), 1 << (number - 1)); oedit_disp_perm_menu(d); return; case OEDIT_VALUE_1: /* * Lucky, I don't need to check any of these for out of range values. * Hmm, I'm not so sure - Rv */ GET_OBJ_VAL(OLC_OBJ(d), 0) = atoi(arg); /* * proceed to menu 2 */ oedit_disp_val2_menu(d); return; case OEDIT_VALUE_2: /* * Here, I do need to check for out of range values. */ number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number < 0 || number >= NUM_SPELLS) oedit_disp_val2_menu(d); else { GET_OBJ_VAL(OLC_OBJ(d), 1) = number; oedit_disp_val3_menu(d); } break; case ITEM_CONTAINER: /* * Needs some special handling since we are dealing with flag values * here. */ if (number < 0 || number > 4) oedit_disp_container_flags_menu(d); else if (number != 0) { TOGGLE_BIT(GET_OBJ_VAL(OLC_OBJ(d), 1), 1 << (number - 1)); OLC_VAL(d) = 1; oedit_disp_val2_menu(d); } else oedit_disp_val3_menu(d); break; default: GET_OBJ_VAL(OLC_OBJ(d), 1) = number; oedit_disp_val3_menu(d); } return; case OEDIT_VALUE_3: number = atoi(arg); /* * Quick'n'easy error checking. */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: min_val = -1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 1; max_val = 50; break; case ITEM_WAND: case ITEM_STAFF: min_val = 0; max_val = 20; break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: min_val = 0; max_val = NUM_LIQ_TYPES - 1; break; case ITEM_KEY: min_val = 0; max_val = 32099; break; default: min_val = -32000; max_val = 32000; } GET_OBJ_VAL(OLC_OBJ(d), 2) = LIMIT(number, min_val, max_val); oedit_disp_val4_menu(d); return; case OEDIT_VALUE_4: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: min_val = -1; max_val = NUM_SPELLS - 1; break; case ITEM_WAND: case ITEM_STAFF: min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 0; max_val = NUM_ATTACK_TYPES - 1; break; default: min_val = -32000; max_val = 32000; break; } GET_OBJ_VAL(OLC_OBJ(d), 3) = LIMIT(number, min_val, max_val); break; case OEDIT_PROMPT_APPLY: if ((number = atoi(arg)) == 0) break; else if (number < 0 || number > MAX_OBJ_AFFECT) { oedit_disp_prompt_apply_menu(d); return; } OLC_VAL(d) = number - 1; OLC_MODE(d) = OEDIT_APPLY; oedit_disp_apply_menu(d); return; case OEDIT_APPLY: if ((number = atoi(arg)) == 0) { OLC_OBJ(d)->affected[OLC_VAL(d)].location = 0; OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = 0; oedit_disp_prompt_apply_menu(d); } else if (number < 0 || number >= NUM_APPLIES) oedit_disp_apply_menu(d); else { int counter; /* add in check here if already applied.. deny builders another */ if (GET_LEVEL(d->character) < LVL_IMPL) { for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (OLC_OBJ(d)->affected[counter].location == number) { write_to_output(d, "Object already has that apply."); return; } } } OLC_OBJ(d)->affected[OLC_VAL(d)].location = number; write_to_output(d, "Modifier : "); OLC_MODE(d) = OEDIT_APPLYMOD; } return; case OEDIT_APPLYMOD: OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = atoi(arg); oedit_disp_prompt_apply_menu(d); return; case OEDIT_EXTRADESC_KEY: if (genolc_checkstring(d, arg)) { if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); OLC_DESC(d)->keyword = str_udup(arg); } oedit_disp_extradesc_menu(d); return; case OEDIT_EXTRADESC_MENU: switch ((number = atoi(arg))) { case 0: if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { struct extra_descr_data **tmp_desc; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /* * Clean up pointers */ for (tmp_desc = &(OLC_OBJ(d)->ex_description); *tmp_desc; tmp_desc = &((*tmp_desc)->next)) { if (*tmp_desc == OLC_DESC(d)) { *tmp_desc = NULL; break; } } free(OLC_DESC(d)); } break; case 1: OLC_MODE(d) = OEDIT_EXTRADESC_KEY; write_to_output(d, "Enter keywords, separated by spaces :-\r\n| "); return; case 2: OLC_MODE(d) = OEDIT_EXTRADESC_DESCRIPTION; send_editor_help(d); write_to_output(d, "Enter the extra description:\r\n\r\n"); if (OLC_DESC(d)->description) { write_to_output(d, "%s", OLC_DESC(d)->description); oldtext = strdup(OLC_DESC(d)->description); } string_write(d, &OLC_DESC(d)->description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; return; case 3: /* * Only go to the next description if this one is finished. */ if (OLC_DESC(d)->keyword && OLC_DESC(d)->description) { struct extra_descr_data *new_extra; if (OLC_DESC(d)->next) OLC_DESC(d) = OLC_DESC(d)->next; else { /* Make new extra description and attach at end. */ CREATE(new_extra, struct extra_descr_data, 1); OLC_DESC(d)->next = new_extra; OLC_DESC(d) = OLC_DESC(d)->next; } } /* * No break - drop into default case. */ default: oedit_disp_extradesc_menu(d); return; } break; default: mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: Reached default case in oedit_parse()!"); write_to_output(d, "Oops...\r\n"); break; }
/* * Display main menu. */ void oedit_disp_menu(struct descriptor_data *d) { char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; struct obj_data *obj; obj = OLC_OBJ(d); get_char_colors(d->character); clear_screen(d); /* * Build buffers for first part of menu. */ sprinttype(GET_OBJ_TYPE(obj), item_types, buf1, sizeof(buf1)); sprintbit(GET_OBJ_EXTRA(obj), extra_bits, buf2, sizeof(buf2)); /* * Build first half of menu. */ write_to_output(d, "-- Item number : [%s%d%s]\r\n" "%s1%s) Namelist : %s%s\r\n" "%s2%s) S-Desc : %s%s\r\n" "%s3%s) L-Desc :-\r\n%s%s\r\n" "%s4%s) A-Desc :-\r\n%s%s" "%s5%s) Type : %s%s\r\n" "%s6%s) Extra flags : %s%s\r\n", cyn, OLC_NUM(d), nrm, grn, nrm, yel, (obj->name && *obj->name) ? obj->name : "undefined", grn, nrm, yel, (obj->short_description && *obj->short_description) ? obj->short_description : "undefined", grn, nrm, yel, (obj->description && *obj->description) ? obj->description : "undefined", grn, nrm, yel, (obj->action_description && *obj->action_description) ? obj->action_description : "<not set>\r\n", grn, nrm, cyn, buf1, grn, nrm, cyn, buf2 ); /* * Send first half. */ /* * Build second half of menu. */ sprintbit(GET_OBJ_WEAR(obj), wear_bits, buf1, sizeof(buf1)); sprintbit(GET_OBJ_PERM(obj), affected_bits, buf2, sizeof(buf2)); write_to_output(d, "%s7%s) Wear flags : %s%s\r\n" "%s8%s) Weight : %s%d\r\n" "%s9%s) Cost : %s%d\r\n" "%sA%s) Cost/Day : %s%d\r\n" "%sB%s) Timer : %s%d\r\n" "%sC%s) Values : %s%d %d %d %d\r\n" "%sD%s) Applies menu\r\n" "%sE%s) Extra descriptions menu\r\n" "%sM%s) Min Level : %s%d\r\n" "%sP%s) Perm Affects: %s%s\r\n" "%sS%s) Script : %s%s\r\n" "%sQ%s) Quit\r\n" "Enter choice : ", grn, nrm, cyn, buf1, grn, nrm, cyn, GET_OBJ_WEIGHT(obj), grn, nrm, cyn, GET_OBJ_COST(obj), grn, nrm, cyn, GET_OBJ_RENT(obj), grn, nrm, cyn, GET_OBJ_TIMER(obj), grn, nrm, cyn, GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1), GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3), grn, nrm, grn, nrm, grn, nrm, cyn, GET_OBJ_LEVEL(obj), grn, nrm, cyn, buf2, grn, nrm, cyn, OLC_SCRIPT(d) ? "Set." : "Not Set.", grn, nrm ); OLC_MODE(d) = OEDIT_MAIN_MENU; }
/** * formerly obj_from_store * * @param FILE *fl The open item file. * @param obj_vnum vnum The vnum of the item being loaded, or NOTHING for non-prototyped item. * @param int *location A place to bind the current WEAR_x position of the item; also used to track container contents. * @param char_data *notify Optional: A person to notify if an item is updated (NULL for none). * @return obj_data* The loaded item, or NULL if it's not available. */ obj_data *Obj_load_from_file(FILE *fl, obj_vnum vnum, int *location, char_data *notify) { void scale_item_to_level(obj_data *obj, int level); char line[MAX_INPUT_LENGTH], error[MAX_STRING_LENGTH], s_in[MAX_INPUT_LENGTH]; obj_data *proto = obj_proto(vnum); struct extra_descr_data *ex; obj_data *obj, *new; bool end = FALSE; int length, i_in[3]; int l_in; bool seek_end = FALSE; // up-front *location = 0; // load based on vnum or, if NOTHING, create anonymous object if (proto) { obj = read_object(vnum, FALSE); } else { // what we do here depends on input ... if the vnum was real, but no proto, it's a deleted obj if (vnum == NOTHING) { obj = create_obj(); } else { obj = NULL; seek_end = TRUE; // signal it to skip obj data } } // default to version 0 if (obj) { OBJ_VERSION(obj) = 0; } // for fread_string sprintf(error, "Obj_load_from_file %d", vnum); // for more readable if/else chain #define OBJ_FILE_TAG(src, tag, len) (!strn_cmp((src), (tag), ((len) = strlen(tag)))) while (!end) { if (!get_line(fl, line)) { log("SYSERR: Unexpected end of obj file in Obj_load_from_file"); exit(1); } if (OBJ_FILE_TAG(line, "End", length)) { end = TRUE; } else if (seek_end) { // are we looking for the end of the object? ignore this line // WARNING: don't put any ifs that require "obj" above seek_end; obj is not guaranteed continue; } else if (OBJ_FILE_TAG(line, "Version:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { OBJ_VERSION(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Location:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0]) == 1) { *location = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Keywords:", length)) { if (GET_OBJ_KEYWORDS(obj) && (!proto || GET_OBJ_KEYWORDS(obj) != GET_OBJ_KEYWORDS(proto))) { free(GET_OBJ_KEYWORDS(obj)); } GET_OBJ_KEYWORDS(obj) = fread_string(fl, error); } else if (OBJ_FILE_TAG(line, "Short-desc:", length)) { if (GET_OBJ_SHORT_DESC(obj) && (!proto || GET_OBJ_SHORT_DESC(obj) != GET_OBJ_SHORT_DESC(proto))) { free(GET_OBJ_SHORT_DESC(obj)); } GET_OBJ_SHORT_DESC(obj) = fread_string(fl, error); } else if (OBJ_FILE_TAG(line, "Long-desc:", length)) { if (GET_OBJ_LONG_DESC(obj) && (!proto || GET_OBJ_LONG_DESC(obj) != GET_OBJ_LONG_DESC(proto))) { free(GET_OBJ_LONG_DESC(obj)); } GET_OBJ_LONG_DESC(obj) = fread_string(fl, error); } else if (OBJ_FILE_TAG(line, "Action-desc:", length)) { if (GET_OBJ_ACTION_DESC(obj) && (!proto || GET_OBJ_ACTION_DESC(obj) != GET_OBJ_ACTION_DESC(proto))) { free(GET_OBJ_ACTION_DESC(obj)); } GET_OBJ_ACTION_DESC(obj) = fread_string(fl, error); } else if (OBJ_FILE_TAG(line, "Extra-desc:", length)) { if (proto && obj->ex_description == proto->ex_description) { obj->ex_description = NULL; } CREATE(ex, struct extra_descr_data, 1); ex->next = obj->ex_description; obj->ex_description = ex; ex->keyword = fread_string(fl, error); ex->description = fread_string(fl, error); } else if (OBJ_FILE_TAG(line, "Val-0:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_VAL(obj, 0) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Val-1:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_VAL(obj, 1) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Val-2:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_VAL(obj, 2) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Type:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_TYPE(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Wear:", length)) { if (sscanf(line + length + 1, "%s", s_in)) { GET_OBJ_WEAR(obj) = asciiflag_conv(s_in); } } else if (OBJ_FILE_TAG(line, "Flags:", length)) { if (sscanf(line + length + 1, "%s", s_in)) { GET_OBJ_EXTRA(obj) = asciiflag_conv(s_in); } } else if (OBJ_FILE_TAG(line, "Affects:", length)) { if (sscanf(line + length + 1, "%s", s_in)) { obj->obj_flags.bitvector = asciiflag_conv(s_in); } } else if (OBJ_FILE_TAG(line, "Timer:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_TIMER(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Current-scale:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_CURRENT_SCALE_LEVEL(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Min-scale:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_MIN_SCALE_LEVEL(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Max-scale:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_MAX_SCALE_LEVEL(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Material:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_OBJ_MATERIAL(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Last-empire:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { obj->last_empire_id = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Last-owner:", length)) { if (sscanf(line + length + 1, "%d", &l_in)) { obj->last_owner_id = l_in; } } else if (OBJ_FILE_TAG(line, "Stolen-timer:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { obj->stolen_timer = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Autostore-timer:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { GET_AUTOSTORE_TIMER(obj) = i_in[0]; } } else if (OBJ_FILE_TAG(line, "Apply:", length)) { if (sscanf(line + length + 1, "%d %d %d", &i_in[0], &i_in[1], &i_in[2])) { obj->affected[i_in[0]].location = i_in[1]; obj->affected[i_in[0]].modifier = i_in[2]; } } else if (OBJ_FILE_TAG(line, "Bound-to:", length)) { if (sscanf(line + length + 1, "%d", &i_in[0])) { struct obj_binding *bind; CREATE(bind, struct obj_binding, 1); bind->idnum = i_in[0]; bind->next = OBJ_BOUND_TO(obj); OBJ_BOUND_TO(obj) = bind; } } else if (OBJ_FILE_TAG(line, "Trigger:", length)) {
void oedit_parse(struct descriptor_data *d, char *arg) { int number, max_val, min_val; char *oldtext = NULL; struct board_info *tmp; struct obj_data *obj; obj_rnum robj; switch (OLC_MODE(d)) { case OEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': oedit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d)); if (CONFIG_OLC_SAVE) { oedit_save_to_disk(real_zone_by_thing(OLC_NUM(d))); write_to_output(d, "Object saved to disk.\r\n"); } else write_to_output(d, "Object saved to memory.\r\n"); if (GET_OBJ_TYPE(OLC_OBJ(d)) == ITEM_BOARD) { if ((tmp=locate_board(GET_OBJ_VNUM(OLC_OBJ(d)))) != NULL) { save_board(tmp); } else { tmp = create_new_board(GET_OBJ_VNUM(OLC_OBJ(d))); BOARD_NEXT(tmp) = bboards; bboards = tmp; } } /* Fall through. */ case 'n': case 'N': cleanup_olc(d, CLEANUP_ALL); return; case 'a': /* abort quit */ case 'A': oedit_disp_menu(d); return; default: write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Do you wish to save your changes? : \r\n"); return; } case OEDIT_MAIN_MENU: /* * Throw us out to whichever edit mode based on user input. */ switch (*arg) { case 'q': case 'Q': if (STATE(d) != CON_IEDIT) { if (OLC_VAL(d)) { /* Something has been modified. */ write_to_output(d, "Do you wish to save your changes? : "); OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); } else { send_to_char(d->character, "\r\nCommitting iedit changes.\r\n"); obj = OLC_IOBJ(d); *obj = *(OLC_OBJ(d)); GET_ID(obj) = max_obj_id++; /* find_obj helper */ add_to_lookup_table(GET_ID(obj), (void *)obj); if (GET_OBJ_VNUM(obj) != NOTHING) { /* remove any old scripts */ if (SCRIPT(obj)) { extract_script(obj, OBJ_TRIGGER); SCRIPT(obj) = NULL; } free_proto_script(obj, OBJ_TRIGGER); robj = real_object(GET_OBJ_VNUM(obj)); copy_proto_script(&obj_proto[robj], obj, OBJ_TRIGGER); assign_triggers(obj, OBJ_TRIGGER); } SET_BIT_AR(GET_OBJ_EXTRA(obj), ITEM_UNIQUE_SAVE); /* Xap - ought to save the old pointer, free after assignment I suppose */ mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s iedit a unique #%d", GET_NAME(d->character), GET_OBJ_VNUM(obj)); if (d->character) { REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_WRITING); STATE(d) = CON_PLAYING; act("$n stops using OLC.", TRUE, d->character, 0, 0, TO_ROOM); } free(d->olc); d->olc = NULL; } return; case '1': write_to_output(d, "Enter namelist : "); OLC_MODE(d) = OEDIT_EDIT_NAMELIST; break; case '2': write_to_output(d, "Enter short desc : "); OLC_MODE(d) = OEDIT_SHORTDESC; break; case '3': write_to_output(d, "Enter long desc :-\r\n| "); OLC_MODE(d) = OEDIT_LONGDESC; break; case '4': OLC_MODE(d) = OEDIT_ACTDESC; send_editor_help(d); write_to_output(d, "Enter action description:\r\n\r\n"); if (OLC_OBJ(d)->action_description) { write_to_output(d, "%s", OLC_OBJ(d)->action_description); oldtext = strdup(OLC_OBJ(d)->action_description); } string_write(d, &OLC_OBJ(d)->action_description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; break; case '5': oedit_disp_type_menu(d); OLC_MODE(d) = OEDIT_TYPE; break; case '6': oedit_disp_extra_menu(d); OLC_MODE(d) = OEDIT_EXTRAS; break; case '7': oedit_disp_wear_menu(d); OLC_MODE(d) = OEDIT_WEAR; break; case '8': write_to_output(d, "Enter weight : "); OLC_MODE(d) = OEDIT_WEIGHT; break; case '9': write_to_output(d, "Enter cost : "); OLC_MODE(d) = OEDIT_COST; break; case 'a': case 'A': write_to_output(d, "Enter cost per day : "); OLC_MODE(d) = OEDIT_COSTPERDAY; break; case 'b': case 'B': write_to_output(d, "Enter timer : "); OLC_MODE(d) = OEDIT_TIMER; break; case 'c': case 'C': /* * Clear any old values */ GET_OBJ_VAL(OLC_OBJ(d), 0) = 0; GET_OBJ_VAL(OLC_OBJ(d), 1) = 0; GET_OBJ_VAL(OLC_OBJ(d), 2) = 0; GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; OLC_VAL(d) = 1; oedit_disp_val1_menu(d); break; case 'd': case 'D': oedit_disp_prompt_apply_menu(d); break; case 'e': case 'E': /* * If extra descriptions don't exist. */ if (OLC_OBJ(d)->ex_description == NULL) { CREATE(OLC_OBJ(d)->ex_description, struct extra_descr_data, 1); OLC_OBJ(d)->ex_description->next = NULL; } OLC_DESC(d) = OLC_OBJ(d)->ex_description; oedit_disp_extradesc_menu(d); break; case 'm': case 'M': write_to_output(d, "Enter new minimum level: "); OLC_MODE(d) = OEDIT_LEVEL; break; case 'p': case 'P': oedit_disp_perm_menu(d); OLC_MODE(d) = OEDIT_PERM; break; case 's': case 'S': if (STATE(d) != CON_IEDIT) { OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU; dg_script_menu(d); } else { write_to_output(d, "\r\nScripts cannot be modified on individual objects.\r\nEnter choice : "); } return; default: oedit_disp_menu(d); break; } return; /* * end of OEDIT_MAIN_MENU */ case OLC_SCRIPT_EDIT: if (dg_script_edit_parse(d, arg)) return; break; case OEDIT_EDIT_NAMELIST: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->name) free(OLC_OBJ(d)->name); OLC_OBJ(d)->name = str_udup(arg); break; case OEDIT_SHORTDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->short_description) free(OLC_OBJ(d)->short_description); OLC_OBJ(d)->short_description = str_udup(arg); break; case OEDIT_LONGDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->description) free(OLC_OBJ(d)->description); OLC_OBJ(d)->description = str_udup(arg); break; case OEDIT_TYPE: number = atoi(arg); if ((number < 1) || (number >= NUM_ITEM_TYPES)) { write_to_output(d, "Invalid choice, try again : "); return; } else GET_OBJ_TYPE(OLC_OBJ(d)) = number; /* what's the boundschecking worth if we don't do this ? -- Welcor */ GET_OBJ_VAL(OLC_OBJ(d), 0) = GET_OBJ_VAL(OLC_OBJ(d), 1) = GET_OBJ_VAL(OLC_OBJ(d), 2) = GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; break; case OEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_FLAGS)) { oedit_disp_extra_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT_AR(GET_OBJ_EXTRA(OLC_OBJ(d)), number - 1); oedit_disp_extra_menu(d); return; } case OEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_WEARS)) { write_to_output(d, "That's not a valid choice!\r\n"); oedit_disp_wear_menu(d); return; } else if (number == 0) /* Quit. */ break; else { TOGGLE_BIT_AR(GET_OBJ_WEAR(OLC_OBJ(d)), (number - 1)); oedit_disp_wear_menu(d); return; } case OEDIT_WEIGHT: GET_OBJ_WEIGHT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_WEIGHT); break; case OEDIT_COST: GET_OBJ_COST(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_COST); break; case OEDIT_COSTPERDAY: GET_OBJ_RENT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_RENT); break; case OEDIT_TIMER: switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_PORTAL: GET_OBJ_TIMER(OLC_OBJ(d)) = LIMIT(atoi(arg), -1, MAX_OBJ_TIMER); break; default: GET_OBJ_TIMER(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_TIMER); break; } break; case OEDIT_LEVEL: GET_OBJ_LEVEL(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, LVL_IMPL); break; case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; if (number > 0 && number <= NUM_AFF_FLAGS) { /* Setting AFF_CHARM on objects like this is dangerous. */ if (number != AFF_CHARM) { TOGGLE_BIT_AR(GET_OBJ_PERM(OLC_OBJ(d)), number); } } oedit_disp_perm_menu(d); return; case OEDIT_VALUE_1: /* * Lucky, I don't need to check any of these for out of range values. * Hmm, I'm not so sure - Rv */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 0) = MIN(MAX(atoi(arg), -50), 50); break; case ITEM_CONTAINER: GET_OBJ_VAL(OLC_OBJ(d), 0) = LIMIT(atoi(arg), -1, MAX_CONTAINER_SIZE); break; default: GET_OBJ_VAL(OLC_OBJ(d), 0) = atoi(arg); } /* * proceed to menu 2 */ oedit_disp_val2_menu(d); return; case OEDIT_VALUE_2: /* * Here, I do need to check for out of range values. */ number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) GET_OBJ_VAL(OLC_OBJ(d), 1) = -1; else GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, NUM_SPELLS-1); oedit_disp_val3_menu(d); break; case ITEM_CONTAINER: case ITEM_VEHICLE: case ITEM_HATCH: case ITEM_WINDOW: case ITEM_PORTAL: /* * Needs some special handling since we are dealing with flag values * here. */ if (number < 0 || number > 4) oedit_disp_container_flags_menu(d); else if (number != 0) { TOGGLE_BIT(GET_OBJ_VAL(OLC_OBJ(d), 1), 1 << (number - 1)); OLC_VAL(d) = 1; oedit_disp_val2_menu(d); } else oedit_disp_val3_menu(d); break; case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, MAX_WEAPON_NDICE); oedit_disp_val3_menu(d); break; default: GET_OBJ_VAL(OLC_OBJ(d), 1) = number; oedit_disp_val3_menu(d); } return; case OEDIT_VALUE_3: number = atoi(arg); /* * Quick'n'easy error checking. */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 2) = -1; oedit_disp_val4_menu(d); return; } min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 1; max_val = MAX_WEAPON_SDICE; break; case ITEM_WAND: case ITEM_STAFF: min_val = 0; max_val = 20; break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: min_val = 0; max_val = NUM_LIQ_TYPES - 1; break; case ITEM_KEY: min_val = 0; max_val = 32099; break; default: min_val = -32000; max_val = 32000; } GET_OBJ_VAL(OLC_OBJ(d), 2) = LIMIT(number, min_val, max_val); oedit_disp_val4_menu(d); return; case OEDIT_VALUE_4: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 3) = -1; oedit_disp_menu(d); return; } min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WAND: case ITEM_STAFF: min_val = 1; max_val = NUM_SPELLS - 1; break; case ITEM_WEAPON: min_val = 0; max_val = NUM_ATTACK_TYPES - 1; break; default: min_val = -32000; max_val = 32000; break; } GET_OBJ_VAL(OLC_OBJ(d), 3) = LIMIT(number, min_val, max_val); break; case OEDIT_PROMPT_APPLY: if ((number = atoi(arg)) == 0) break; else if (number < 0 || number > MAX_OBJ_AFFECT) { oedit_disp_prompt_apply_menu(d); return; } OLC_VAL(d) = number - 1; OLC_MODE(d) = OEDIT_APPLY; oedit_disp_apply_menu(d); return; case OEDIT_APPLY: if ((number = atoi(arg)) == 0) { OLC_OBJ(d)->affected[OLC_VAL(d)].location = 0; OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = 0; oedit_disp_prompt_apply_menu(d); } else if (number < 0 || number >= NUM_APPLIES) oedit_disp_apply_menu(d); else { int counter; /* add in check here if already applied.. deny builders another */ if (GET_LEVEL(d->character) < LVL_IMPL) { for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (OLC_OBJ(d)->affected[counter].location == number) { write_to_output(d, "Object already has that apply."); return; } } } OLC_OBJ(d)->affected[OLC_VAL(d)].location = number; write_to_output(d, "Modifier : "); OLC_MODE(d) = OEDIT_APPLYMOD; } return; case OEDIT_APPLYMOD: OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = atoi(arg); oedit_disp_prompt_apply_menu(d); return; case OEDIT_EXTRADESC_KEY: if (genolc_checkstring(d, arg)) { if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); OLC_DESC(d)->keyword = str_udup(arg); } oedit_disp_extradesc_menu(d); return; case OEDIT_EXTRADESC_MENU: switch ((number = atoi(arg))) { case 0: if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { struct extra_descr_data *temp; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /* * Clean up pointers */ REMOVE_FROM_LIST(OLC_DESC(d), OLC_OBJ(d)->ex_description, next); free(OLC_DESC(d)); OLC_DESC(d) = NULL; } break; case 1: OLC_MODE(d) = OEDIT_EXTRADESC_KEY; write_to_output(d, "Enter keywords, separated by spaces :-\r\n| "); return; case 2: OLC_MODE(d) = OEDIT_EXTRADESC_DESCRIPTION; send_editor_help(d); write_to_output(d, "Enter the extra description:\r\n\r\n"); if (OLC_DESC(d)->description) { write_to_output(d, "%s", OLC_DESC(d)->description); oldtext = strdup(OLC_DESC(d)->description); } string_write(d, &OLC_DESC(d)->description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; return; case 3: /* * Only go to the next description if this one is finished. */ if (OLC_DESC(d)->keyword && OLC_DESC(d)->description) { struct extra_descr_data *new_extra; if (OLC_DESC(d)->next) OLC_DESC(d) = OLC_DESC(d)->next; else { /* Make new extra description and attach at end. */ CREATE(new_extra, struct extra_descr_data, 1); OLC_DESC(d)->next = new_extra; OLC_DESC(d) = OLC_DESC(d)->next; } } /* * No break - drop into default case. */ default: oedit_disp_extradesc_menu(d); return; } break; default: mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: Reached default case in oedit_parse()!"); write_to_output(d, "Oops...\r\n"); break; }
/* Update PCs, NPCs, and objects */ void point_update(void) { struct char_data *i, *next_char; struct obj_data *j, *next_thing, *jj, *next_thing2; /* characters */ for (i = character_list; i; i = next_char) { next_char = i->next; gain_condition(i, FULL, -1); gain_condition(i, DRUNK, -1); gain_condition(i, THIRST, -1); if (GET_POS(i) >= POS_STUNNED) { GET_HIT(i) = MIN(GET_HIT(i) + hit_gain(i), GET_MAX_HIT(i)); GET_MANA(i) = MIN(GET_MANA(i) + mana_gain(i), GET_MAX_MANA(i)); GET_MOVE(i) = MIN(GET_MOVE(i) + move_gain(i), GET_MAX_MOVE(i)); if (AFF_FLAGGED(i, AFF_POISON)) if (damage(i, i, 2, SPELL_POISON) == -1) continue; /* Oops, they died. -gg 6/24/98 */ if (GET_POS(i) <= POS_STUNNED) update_pos(i); } else if (GET_POS(i) == POS_INCAP) { if (damage(i, i, 1, TYPE_SUFFERING) == -1) continue; } else if (GET_POS(i) == POS_MORTALLYW) { if (damage(i, i, 2, TYPE_SUFFERING) == -1) continue; } if (!IS_NPC(i)) { update_char_objects(i); if (GET_LEVEL(i) < idle_max_level) check_idling(i); } } /* objects */ for (j = object_list; j; j = next_thing) { next_thing = j->next; /* Next in object list */ /* If this is a corpse */ if (IS_CORPSE(j)) { /* timer count down */ if (GET_OBJ_TIMER(j) > 0) GET_OBJ_TIMER(j)--; if (!GET_OBJ_TIMER(j)) { if (j->carried_by) act("$p decays in your hands.", FALSE, j->carried_by, j, 0, TO_CHAR); else if ((IN_ROOM(j) != NOWHERE) && (world[IN_ROOM(j)].people)) { act("A quivering horde of maggots consumes $p.", TRUE, world[IN_ROOM(j)].people, j, 0, TO_ROOM); act("A quivering horde of maggots consumes $p.", TRUE, world[IN_ROOM(j)].people, j, 0, TO_CHAR); } for (jj = j->contains; jj; jj = next_thing2) { next_thing2 = jj->next_content; /* Next in inventory */ obj_from_obj(jj); if (j->in_obj) obj_to_obj(jj, j->in_obj); else if (j->carried_by) obj_to_room(jj, IN_ROOM(j->carried_by)); else if (IN_ROOM(j) != NOWHERE) obj_to_room(jj, IN_ROOM(j)); else core_dump(); } extract_obj(j); } } /* If the timer is set, count it down and at 0, try the trigger */ /* note to .rej hand-patchers: make this last in your point-update() */ else if (GET_OBJ_TIMER(j)>0) { GET_OBJ_TIMER(j)--; if (!GET_OBJ_TIMER(j)) timer_otrigger(j); } } }
/* main loop (of sorts).. basically interpreter throws all input to here. */ void oedit_parse(struct descriptor_data *d, char *arg) { int number, max_val, min_val; char *oldtext = NULL; switch (OLC_MODE(d)) { case OEDIT_CONFIRM_SAVESTRING: switch (*arg) { case 'y': case 'Y': oedit_save_internally(d); mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d)); if (CONFIG_OLC_SAVE) { oedit_save_to_disk(real_zone_by_thing(OLC_NUM(d))); write_to_output(d, "Object saved to disk.\r\n"); } else write_to_output(d, "Object saved to memory.\r\n"); cleanup_olc(d, CLEANUP_ALL); return; case 'n': case 'N': /* If not saving, we must free the script_proto list. */ OLC_OBJ(d)->proto_script = OLC_SCRIPT(d); free_proto_script(OLC_OBJ(d), OBJ_TRIGGER); cleanup_olc(d, CLEANUP_ALL); return; case 'a': /* abort quit */ case 'A': oedit_disp_menu(d); return; default: write_to_output(d, "Invalid choice!\r\n"); write_to_output(d, "Do you wish to save your changes? : \r\n"); return; } case OEDIT_MAIN_MENU: /* Throw us out to whichever edit mode based on user input. */ switch (*arg) { case 'q': case 'Q': if (OLC_VAL(d)) { /* Something has been modified. */ write_to_output(d, "Do you wish to save your changes? : "); OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; case '1': write_to_output(d, "Enter keywords : "); OLC_MODE(d) = OEDIT_KEYWORD; break; case '2': write_to_output(d, "Enter short desc : "); OLC_MODE(d) = OEDIT_SHORTDESC; break; case '3': write_to_output(d, "Enter long desc :-\r\n| "); OLC_MODE(d) = OEDIT_LONGDESC; break; case '4': OLC_MODE(d) = OEDIT_ACTDESC; send_editor_help(d); write_to_output(d, "Enter action description:\r\n\r\n"); if (OLC_OBJ(d)->action_description) { write_to_output(d, "%s", OLC_OBJ(d)->action_description); oldtext = strdup(OLC_OBJ(d)->action_description); } string_write(d, &OLC_OBJ(d)->action_description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; break; case '5': oedit_disp_type_menu(d); OLC_MODE(d) = OEDIT_TYPE; break; case '6': oedit_disp_extra_menu(d); OLC_MODE(d) = OEDIT_EXTRAS; break; case '7': oedit_disp_wear_menu(d); OLC_MODE(d) = OEDIT_WEAR; break; case '8': write_to_output(d, "Enter weight : "); OLC_MODE(d) = OEDIT_WEIGHT; break; case '9': write_to_output(d, "Enter cost : "); OLC_MODE(d) = OEDIT_COST; break; case 'a': case 'A': write_to_output(d, "Enter cost per day : "); OLC_MODE(d) = OEDIT_COSTPERDAY; break; case 'b': case 'B': write_to_output(d, "Enter timer : "); OLC_MODE(d) = OEDIT_TIMER; break; case 'c': case 'C': /* Clear any old values */ GET_OBJ_VAL(OLC_OBJ(d), 0) = 0; GET_OBJ_VAL(OLC_OBJ(d), 1) = 0; GET_OBJ_VAL(OLC_OBJ(d), 2) = 0; GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; OLC_VAL(d) = 1; oedit_disp_val1_menu(d); break; case 'd': case 'D': oedit_disp_prompt_apply_menu(d); break; case 'e': case 'E': /* If extra descriptions don't exist. */ if (OLC_OBJ(d)->ex_description == NULL) { CREATE(OLC_OBJ(d)->ex_description, struct extra_descr_data, 1); OLC_OBJ(d)->ex_description->next = NULL; } OLC_DESC(d) = OLC_OBJ(d)->ex_description; oedit_disp_extradesc_menu(d); break; case 'm': case 'M': write_to_output(d, "Enter new minimum level: "); OLC_MODE(d) = OEDIT_LEVEL; break; case 'p': case 'P': oedit_disp_perm_menu(d); OLC_MODE(d) = OEDIT_PERM; break; case 's': case 'S': OLC_SCRIPT_EDIT_MODE(d) = SCRIPT_MAIN_MENU; dg_script_menu(d); return; case 'w': case 'W': write_to_output(d, "Copy what object? "); OLC_MODE(d) = OEDIT_COPY; break; case 'x': case 'X': write_to_output(d, "Are you sure you want to delete this object? "); OLC_MODE(d) = OEDIT_DELETE; break; default: oedit_disp_menu(d); break; } return; /* end of OEDIT_MAIN_MENU */ case OLC_SCRIPT_EDIT: if (dg_script_edit_parse(d, arg)) return; break; case OEDIT_KEYWORD: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->name) free(OLC_OBJ(d)->name); OLC_OBJ(d)->name = str_udup(arg); break; case OEDIT_SHORTDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->short_description) free(OLC_OBJ(d)->short_description); OLC_OBJ(d)->short_description = str_udup(arg); break; case OEDIT_LONGDESC: if (!genolc_checkstring(d, arg)) break; if (OLC_OBJ(d)->description) free(OLC_OBJ(d)->description); OLC_OBJ(d)->description = str_udup(arg); break; case OEDIT_TYPE: number = atoi(arg); if ((number < 0) || (number >= NUM_ITEM_TYPES)) { write_to_output(d, "Invalid choice, try again : "); return; } else GET_OBJ_TYPE(OLC_OBJ(d)) = number; /* what's the boundschecking worth if we don't do this ? -- Welcor */ GET_OBJ_VAL(OLC_OBJ(d), 0) = GET_OBJ_VAL(OLC_OBJ(d), 1) = GET_OBJ_VAL(OLC_OBJ(d), 2) = GET_OBJ_VAL(OLC_OBJ(d), 3) = 0; break; case OEDIT_EXTRAS: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_FLAGS)) { oedit_disp_extra_menu(d); return; } else if (number == 0) break; else { TOGGLE_BIT_AR(GET_OBJ_EXTRA(OLC_OBJ(d)), (number - 1)); oedit_disp_extra_menu(d); return; } case OEDIT_WEAR: number = atoi(arg); if ((number < 0) || (number > NUM_ITEM_WEARS)) { write_to_output(d, "That's not a valid choice!\r\n"); oedit_disp_wear_menu(d); return; } else if (number == 0) /* Quit. */ break; else { TOGGLE_BIT_AR(GET_OBJ_WEAR(OLC_OBJ(d)), (number - 1)); oedit_disp_wear_menu(d); return; } case OEDIT_WEIGHT: GET_OBJ_WEIGHT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_WEIGHT); break; case OEDIT_COST: GET_OBJ_COST(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_COST); break; case OEDIT_COSTPERDAY: GET_OBJ_RENT(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_RENT); break; case OEDIT_TIMER: GET_OBJ_TIMER(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, MAX_OBJ_TIMER); break; case OEDIT_LEVEL: GET_OBJ_LEVEL(OLC_OBJ(d)) = LIMIT(atoi(arg), 0, LVL_IMPL); break; case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; if (number > 0 && number <= NUM_AFF_FLAGS) { /* Setting AFF_CHARM on objects like this is dangerous. */ if (number != AFF_CHARM) { TOGGLE_BIT_AR(GET_OBJ_AFFECT(OLC_OBJ(d)), number); } } oedit_disp_perm_menu(d); return; case OEDIT_VALUE_1: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_FURNITURE: if (number < 0 || number > MAX_PEOPLE) oedit_disp_val1_menu(d); else { GET_OBJ_VAL(OLC_OBJ(d), 0) = number; oedit_disp_val2_menu(d); } break; case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 0) = MIN(MAX(atoi(arg), -50), 50); break; case ITEM_CONTAINER: GET_OBJ_VAL(OLC_OBJ(d), 0) = LIMIT(atoi(arg), -1, MAX_CONTAINER_SIZE); break; default: GET_OBJ_VAL(OLC_OBJ(d), 0) = atoi(arg); } /* proceed to menu 2 */ oedit_disp_val2_menu(d); return; case OEDIT_VALUE_2: /* Here, I do need to check for out of range values. */ number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) GET_OBJ_VAL(OLC_OBJ(d), 1) = -1; else GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, NUM_SPELLS); oedit_disp_val3_menu(d); break; case ITEM_CONTAINER: /* Needs some special handling since we are dealing with flag values here. */ if (number < 0 || number > 4) oedit_disp_container_flags_menu(d); else if (number != 0) { TOGGLE_BIT(GET_OBJ_VAL(OLC_OBJ(d), 1), 1 << (number - 1)); OLC_VAL(d) = 1; oedit_disp_val2_menu(d); } else oedit_disp_val3_menu(d); break; case ITEM_WEAPON: GET_OBJ_VAL(OLC_OBJ(d), 1) = LIMIT(number, 1, MAX_WEAPON_NDICE); oedit_disp_val3_menu(d); break; default: GET_OBJ_VAL(OLC_OBJ(d), 1) = number; oedit_disp_val3_menu(d); } return; case OEDIT_VALUE_3: number = atoi(arg); /* Quick'n'easy error checking. */ switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 2) = -1; oedit_disp_val4_menu(d); return; } min_val = 1; max_val = NUM_SPELLS; break; case ITEM_WEAPON: min_val = 1; max_val = MAX_WEAPON_SDICE; break; case ITEM_WAND: case ITEM_STAFF: min_val = 0; max_val = 20; break; case ITEM_DRINKCON: case ITEM_FOUNTAIN: min_val = 0; max_val = NUM_LIQ_TYPES - 1; number--; break; case ITEM_KEY: min_val = 0; max_val = 65099; break; default: min_val = -65000; max_val = 65000; } GET_OBJ_VAL(OLC_OBJ(d), 2) = LIMIT(number, min_val, max_val); oedit_disp_val4_menu(d); return; case OEDIT_VALUE_4: number = atoi(arg); switch (GET_OBJ_TYPE(OLC_OBJ(d))) { case ITEM_SCROLL: case ITEM_POTION: if (number == 0 || number == -1) { GET_OBJ_VAL(OLC_OBJ(d), 3) = -1; oedit_disp_menu(d); return; } min_val = 1; max_val = NUM_SPELLS; break; case ITEM_WAND: case ITEM_STAFF: min_val = 1; max_val = NUM_SPELLS; break; case ITEM_WEAPON: min_val = 0; max_val = NUM_ATTACK_TYPES - 1; break; default: min_val = -65000; max_val = 65000; break; } GET_OBJ_VAL(OLC_OBJ(d), 3) = LIMIT(number, min_val, max_val); break; case OEDIT_PROMPT_APPLY: if ((number = atoi(arg)) == 0) break; else if (number < 0 || number > MAX_OBJ_AFFECT) { oedit_disp_prompt_apply_menu(d); return; } OLC_VAL(d) = number - 1; OLC_MODE(d) = OEDIT_APPLY; oedit_disp_apply_menu(d); return; case OEDIT_APPLY: if (((number = atoi(arg)) == 0) || ((number = atoi(arg)) == 1)) { OLC_OBJ(d)->affected[OLC_VAL(d)].location = 0; OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = 0; oedit_disp_prompt_apply_menu(d); } else if (number < 0 || number > NUM_APPLIES) oedit_disp_apply_menu(d); else { int counter; /* add in check here if already applied.. deny builders another */ if (GET_LEVEL(d->character) < LVL_IMPL) { for (counter = 0; counter < MAX_OBJ_AFFECT; counter++) { if (OLC_OBJ(d)->affected[counter].location == number) { write_to_output(d, "Object already has that apply."); return; } } } OLC_OBJ(d)->affected[OLC_VAL(d)].location = number - 1; write_to_output(d, "Modifier : "); OLC_MODE(d) = OEDIT_APPLYMOD; } return; case OEDIT_APPLYMOD: OLC_OBJ(d)->affected[OLC_VAL(d)].modifier = atoi(arg); oedit_disp_prompt_apply_menu(d); return; case OEDIT_EXTRADESC_KEY: if (genolc_checkstring(d, arg)) { if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); OLC_DESC(d)->keyword = str_udup(arg); } oedit_disp_extradesc_menu(d); return; case OEDIT_EXTRADESC_MENU: switch ((number = atoi(arg))) { case 0: if (!OLC_DESC(d)->keyword || !OLC_DESC(d)->description) { struct extra_descr_data *temp; if (OLC_DESC(d)->keyword) free(OLC_DESC(d)->keyword); if (OLC_DESC(d)->description) free(OLC_DESC(d)->description); /* Clean up pointers */ REMOVE_FROM_LIST(OLC_DESC(d), OLC_OBJ(d)->ex_description, next); free(OLC_DESC(d)); OLC_DESC(d) = NULL; } break; case 1: OLC_MODE(d) = OEDIT_EXTRADESC_KEY; write_to_output(d, "Enter keywords, separated by spaces :-\r\n| "); return; case 2: OLC_MODE(d) = OEDIT_EXTRADESC_DESCRIPTION; send_editor_help(d); write_to_output(d, "Enter the extra description:\r\n\r\n"); if (OLC_DESC(d)->description) { write_to_output(d, "%s", OLC_DESC(d)->description); oldtext = strdup(OLC_DESC(d)->description); } string_write(d, &OLC_DESC(d)->description, MAX_MESSAGE_LENGTH, 0, oldtext); OLC_VAL(d) = 1; return; case 3: /* Only go to the next description if this one is finished. */ if (OLC_DESC(d)->keyword && OLC_DESC(d)->description) { struct extra_descr_data *new_extra; if (OLC_DESC(d)->next) OLC_DESC(d) = OLC_DESC(d)->next; else { /* Make new extra description and attach at end. */ CREATE(new_extra, struct extra_descr_data, 1); OLC_DESC(d)->next = new_extra; OLC_DESC(d) = OLC_DESC(d)->next; } } /* No break - drop into default case. */ default: oedit_disp_extradesc_menu(d); return; } break; case OEDIT_COPY: if ((number = real_object(atoi(arg))) != NOTHING) { oedit_setup_existing(d, number); } else write_to_output(d, "That object does not exist.\r\n"); break; case OEDIT_DELETE: if (*arg == 'y' || *arg == 'Y') { if (delete_object(GET_OBJ_RNUM(OLC_OBJ(d))) != NOTHING) write_to_output(d, "Object deleted.\r\n"); else write_to_output(d, "Couldn't delete the object!\r\n"); cleanup_olc(d, CLEANUP_ALL); } else if (*arg == 'n' || *arg == 'N') { oedit_disp_menu(d); OLC_MODE(d) = OEDIT_MAIN_MENU; } else write_to_output(d, "Please answer 'Y' or 'N': "); return; default: mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: Reached default case in oedit_parse()!"); write_to_output(d, "Oops...\r\n"); break; }