/*************************************************************************** * char_cmp_race ***************************************************************************/ bool char_cmp_race(struct char_data *vch, const char *arg, struct buf_type *buf) { if (buf != NULL) { char flag[MAX_STRING_LENGTH]; int col = 0; int iter; add_buf(buf, "search by a mob's race.\n\r"); add_buf(buf, "available races:\n\r"); add_buf(buf, "\n\r "); for (iter = 0; race_table[iter].name != NULL; iter++) { sprintf(flag, "%-19.18s", race_table[iter].name); add_buf(buf, flag); if (++col % 3 == 0) add_buf(buf, "\n\r "); } if (col % 3 != 0) add_buf(buf, "\n\r"); return false; } while (isspace((int)*arg) || arg[0] == '=') arg++; return vch->race == race_lookup(arg); }
/* * Set position of a victim. */ void update_pos( CHAR_DATA *victim, int agg ) { if ( (victim->health + victim->agghealth - 7) > 0 && (victim->position < P_SLEEP || victim->position > P_STAND) ) { victim->position = P_STAND; return; } if(IS_SET(victim->plr_flags, PLR_ARREST) && (victim->health + victim->agghealth - 7) <= 0) { victim->health = 6; victim->agghealth = 7; victim->position = P_STAND; if(victim->fighting) { act("$N loads $n into a police cruiser to be taken to gaol.", victim, NULL, victim->fighting, TO_NOTVICT, 0); act("$N loads you into a police car and you are hauled away.", victim, NULL, victim->fighting, TO_CHAR, 0); act("You pack $n into a police car to be taken off to gaol.", victim, NULL, victim->fighting, TO_VICT, 0); } else { act("The police load $n into a cruiser to be taken to gaol.", victim, NULL, NULL, TO_NOTVICT, 0); act("A group of police officers haul you away.", victim, NULL, NULL, TO_CHAR, 1); } char_from_room(victim); char_to_room(victim, get_room_index(ROOM_VNUM_JAIL)); return; } if (((IS_NATURAL(victim)) && ((victim->health + victim->agghealth - 7) < 0 || (victim->health + victim->agghealth - 7) < 0)) || ( (victim->health + victim->agghealth - 7) < 0 && victim->RBPG <= 1 )) { victim->position = P_DEAD; return; } if ( (victim->health + victim->agghealth - 7) == 0 ) victim->position = P_INCAP; if ( (victim->health + victim->agghealth - 7) < 0 ) { if ( victim->race == race_lookup("human")) victim->position = P_MORT; else if( victim->agghealth > 0 && !agg ) victim->position = P_TORPOR; else victim->position = P_MORT; } return; }
MOB_INDEX_DATA *new_mob_index(void) { MOB_INDEX_DATA *pMob; if (!mob_index_free) { pMob = alloc_perm(sizeof(*pMob)); top_mob_index++; } else { pMob = mob_index_free; mob_index_free = mob_index_free->next; } pMob->next = NULL; pMob->spec_fun = NULL; pMob->pShop = NULL; pMob->area = NULL; pMob->player_name = str_dup("no name"); pMob->short_descr = str_dup("(no short description)"); pMob->long_descr = str_dup("(no long description)\r\n"); pMob->description = &str_empty[0]; pMob->vnum = 0; pMob->count = 0; pMob->killed = 0; pMob->sex = 0; pMob->level = 0; pMob->act = ACT_IS_NPC; pMob->affected_by = 0; pMob->alignment = 2; pMob->hitroll = 0; pMob->race = race_lookup("human"); /* - Hugin */ pMob->form = 0; /* ROM patch -- Hugin */ pMob->parts = 0; /* ROM patch -- Hugin */ pMob->imm_flags = 0; /* ROM patch -- Hugin */ pMob->res_flags = 0; /* ROM patch -- Hugin */ pMob->vuln_flags = 0; /* ROM patch -- Hugin */ pMob->material = str_dup("unknown"); /* -- Hugin */ pMob->off_flags = 0; /* ROM patch -- Hugin */ pMob->size = SIZE_MEDIUM; /* ROM patch -- Hugin */ pMob->ac[AC_PIERCE] = 0; /* ROM patch -- Hugin */ pMob->ac[AC_BASH] = 0; /* ROM patch -- Hugin */ pMob->ac[AC_SLASH] = 0; /* ROM patch -- Hugin */ pMob->ac[AC_EXOTIC] = 0; /* ROM patch -- Hugin */ pMob->hit[DICE_NUMBER] = 0; /* ROM patch -- Hugin */ pMob->hit[DICE_TYPE] = 0; /* ROM patch -- Hugin */ pMob->hit[DICE_BONUS] = 0; /* ROM patch -- Hugin */ pMob->mana[DICE_NUMBER] = 0; /* ROM patch -- Hugin */ pMob->mana[DICE_TYPE] = 0; /* ROM patch -- Hugin */ pMob->mana[DICE_BONUS] = 0; /* ROM patch -- Hugin */ pMob->damage[DICE_NUMBER] = 0; /* ROM patch -- Hugin */ pMob->damage[DICE_TYPE] = 0; /* ROM patch -- Hugin */ pMob->damage[DICE_NUMBER] = 0; /* ROM patch -- Hugin */ pMob->start_pos = POS_STANDING; /* -- Hugin */ pMob->default_pos = POS_STANDING; /* -- Hugin */ pMob->wealth = 0; return pMob; }
/* * Advancement stuff. */ void Character::advance_level( bool hide ) { char buf[MAX_STRING_LENGTH]; int add_hp, add_mana, add_move, dracnum, add_prac; this->pcdata->last_level = ( this->played + (int) (current_time - this->logon) ) / 3600; /* sprintf( buf, "the %s", title_table [this->class_num] [this->level] [this->sex == SEX_FEMALE ? 1 : 0] ); set_title( this, buf ); */ add_hp = con_app[get_curr_stat(this,STAT_CON)].hitp + number_range( class_table[this->class_num].hp_min, class_table[this->class_num].hp_max ); add_mana = number_range(2,(2*get_curr_stat(this,STAT_INT) + get_curr_stat(this,STAT_WIS))/5); if (!class_table[this->class_num].fMana) add_mana /= 2; add_move = number_range( 1, (get_curr_stat(this,STAT_CON) + get_curr_stat(this,STAT_DEX))/6 ); add_prac = wis_app[get_curr_stat(this,STAT_WIS)].practice; add_hp = add_hp * 9/10; add_mana = add_mana * 9/10; add_move = add_move * 9/10; add_hp = UMAX( 2, add_hp ); add_mana = UMAX( 2, add_mana ); add_move = UMAX( 6, add_move ); this->max_hit += add_hp; this->max_mana += add_mana; this->max_move += add_move; this->practice += add_prac; this->train += 1; this->pcdata->perm_hit += add_hp; this->pcdata->perm_mana += add_mana; this->pcdata->perm_move += add_move; if (this->level == 10 && (this->race == race_lookup("draconian"))) { /* if (this->alignment > 500) dracnum = number_range(0, 4); else if (this->alignment < 500) dracnum = number_range(10, 14); else dracnum = number_range(5, 9); */ dracnum = number_range(0,14); this->drac = dracnum; sprintf(buf, "You scream in agony as %s scales pierce your tender skin!\n\r", draconian_table[this->drac].colour); send_to_char(buf,this); if (this->perm_stat[STAT_STR] < 25) this->perm_stat[STAT_STR]++; else this->train++; if (this->perm_stat[draconian_table[this->drac].attr_prime] < 25) this->perm_stat[draconian_table[this->drac].attr_prime]++; else this->train++; } if (!hide) { sprintf(buf, "{BYou have leveled!{x\n\r" "You gain %d hit point%s, %d mana, %d move, and %d practice%s.\n\r", add_hp, add_hp == 1 ? "" : "s", add_mana, add_move, add_prac, add_prac == 1 ? "" : "s"); send_to_char( buf, this ); } return; }
/* * Inflict damage from a hit. */ int damage(CHAR_DATA *ch,CHAR_DATA *victim,int dam,int dt,int dam_type, bool show, int agg, int combo) { /*OBJ_DATA *corpse;*/ bool immune; if ( victim->position == P_DEAD ) return P_DEAD; /* @@@@@ FIX TORPOR if ( victim->position == P_TORPOR ) return P_TORPOR; */ /* damage reduction */ if ( dam > 15) dam = (dam - 5)/2 + 5; if(IS_SET(ch->form, FORM_HORRID)) dam++; /* @@@@@ FIX BITE DAMAGE FOR SERPENTIS 3 if(is_affected(ch, skill_lookup("skin of the adder")) && dam_type == DAM_BITE) dam++; */ /* In case of -ve agg ratings */ if (agg < 0) agg = 0; /* soakage */ dam = do_soak(victim, dam, agg); if ( victim != ch ) { if ( victim->position > P_STUN ) { if ( victim->fighting == NULL ) { set_fighting( victim, ch ); if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) ) mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL ); } if (victim->timer <= 4) victim->position = P_FIGHT; } if ( victim->position > P_STUN ) { if ( ch->fighting == NULL ) set_fighting( ch, victim ); } /* * More charm stuff. */ if ( victim->master == ch ) stop_follower( victim ); } /* * Inviso attacks ... not. */ if ( IS_AFFECTED(ch, AFF_INVISIBLE) ) { affect_strip( ch, gsn_invis ); REMOVE_BIT( ch->affected_by, AFF_INVISIBLE ); act( "$n fades into existence.", ch, NULL, NULL, TO_ROOM, 0 ); } /* * Damage modifiers. */ if ( dam > 1 && !IS_NPC(victim) && victim->condition[COND_DRUNK] > 10 ) dam = 9 * dam / 10; if ( dam > 1 && !IS_NPC(victim) && victim->condition[COND_HIGH] > 10 ) dam = 9 * dam / 10; if ( dam > 1 && ((IS_AFFECTED(victim, AFF_PROTECT_EVIL) && !IS_NATURAL(ch) )) ) dam -= dam / 4; immune = FALSE; /* * Check for parry, and dodge. if ( dt >= TYPE_HIT && ch != victim) { if ( check_parry( ch, victim ) ) return -1; if ( check_dodge( ch, victim ) ) return -1; } */ switch(check_immune(victim,dam_type)) { case(IS_IMMUNE): immune = TRUE; dam = 0; break; case(IS_RESISTANT): dam -= dam/3; break; case(IS_VULNERABLE): dam += dam/2; break; } if (show) dam_message( ch, victim, dam, dt, immune, combo ); if(dam > (victim->health + victim->agghealth -7)) { victim->position = P_MORT; stop_fighting(ch, TRUE); } else if(dam == (victim->health + victim->agghealth -7)) { victim->position = P_INCAP; stop_fighting(ch, TRUE); } if (dam == 0) return -1; else if(IS_SET(ch->off_flags, BANDAGED)) REMOVE_BIT(ch->off_flags, BANDAGED); /* * Hurt the victim. * Inform the victim of his new state. */ if( (victim->race == race_lookup("vampire")) && (dt == DAM_FIRE) ) { victim->agghealth -= dam; update_pos( victim, UMAX(1, agg) ); if(agg <= 0) agg = 1; } else if( (victim->race == race_lookup("werewolf")) && (dt == DAM_SILVER) ) { victim->agghealth -= dam; update_pos( victim, UMAX(1, agg) ); if(agg <= 0) agg = 1; } else if( (victim->race == race_lookup("faerie")) && (dt == DAM_IRON) ) { victim->health -= dam; victim->GHB += dam/3; update_pos( victim, agg ); } else if(agg) { victim->agghealth -= dam; update_pos( victim, agg ); } else { victim->health -= dam; update_pos( victim, 0 ); } switch( victim->position ) { case P_MORT: act( "$n is mortally wounded, and will die soon, if not aided.", victim, NULL, NULL, TO_ROOM, 0 ); send_to_char("You are mortally wounded, and may die soon, if not aided.\n\r", victim ); break; case P_INCAP: act( "$n is incapacitated and will slowly die, if not aided.", victim, NULL, NULL, TO_ROOM, 0 ); send_to_char("You are incapacitated and will slowly die, if not aided.\n\r", victim ); break; case P_TORPOR: act( "$n is mortally wounded, and will slowly die if not aided.", victim, NULL, NULL, TO_ROOM, 0 ); send_to_char("You enter torpor.\n\r", victim ); break; case P_STUN: act( "$n is stunned, but will probably recover.", victim, NULL, NULL, TO_ROOM, 0 ); send_to_char("You are stunned, but will probably recover.\n\r", victim ); break; case P_DEAD: act( "$n is DEAD!!", victim, 0, 0, TO_ROOM, 0 ); send_to_char( "You have been KILLED!!\n\r\n\r", victim ); break; default: if ( dam > MAX_HEALTH / 4 ) send_to_char( "That really did HURT!\n\r", victim ); if ( (victim->health + victim->agghealth - 7) < MAX_HEALTH / 4 ) send_to_char( "You sure are BLEEDING!\n\r", victim ); break; } if(dam_type == DAM_FIRE) fire_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR); if(dam_type == DAM_COLD) cold_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR); if(dam_type == DAM_LIGHTNING) shock_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR); if(dam_type == DAM_ACID) acid_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR); if(dam_type == DAM_POISON) poison_effect((void *) victim, agg+dam/2, dam, TARGET_CHAR); /* * Sleep spells and extremely wounded folks. */ if ( !IS_AWAKE(victim) ) stop_fighting( victim, FALSE ); /* * Payoff for killing things. */ if ( (victim->position == P_INCAP && IS_NPC(victim)) || victim->position == P_DEAD || victim->position == P_TORPOR ) { if ( !IS_NPC(victim) ) { log_string( LOG_GAME, Format("%s killed by %s at %d", victim->name, (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->vnum) ); } snprintf( log_buf, 2*MIL, "\tY[WIZNET]\tn %s got toasted by %s at %s [room %d]", (IS_NPC(victim) ? victim->short_descr : victim->name), (IS_NPC(ch) ? ch->short_descr : ch->name), ch->in_room->name, ch->in_room->vnum); if (IS_NPC(victim)) wiznet(log_buf,NULL,NULL,WIZ_MOBDEATHS,0,0); else wiznet(log_buf,NULL,NULL,WIZ_DEATHS,0,0); /* * Death trigger */ if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) ) { victim->position = P_STAND; mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH ); } if((!str_cmp(ch->description, "") || strlen(ch->description) < 10) && ch->played > 10*60*60) { send_to_char("No experience without a description.\n\r", ch); } else { if(ch->ooc_xp_count < 2) { send_to_char("You learn from your encounter.\n\r", ch); ch->oocxp += 1; ch->ooc_xp_count++; } else if(IS_SET(victim->act2, ACT2_HUNTER) && ch->ooc_xp_count < 50) { send_to_char("You learn from your encounter.\n\r", ch); ch->exp += 1; ch->ooc_xp_count++; } } if(ch->quest) { if(ch->quest->quest_type == Q_HITMAN && ch->quest->victim == victim) (*quest_table[ch->quest->quest_type].q_fun) (ch, 2); if(victim->quest != NULL && victim->quest->quest_type == Q_HITMAN && victim->quest->victim == victim && victim->quest->questor != ch) (*quest_table[victim->quest->quest_type].q_fun) (victim->quest->questor, 3); if(victim->quest != NULL && (victim->quest->quest_type == Q_BODYGUARD || victim->quest->quest_type == Q_RESCUE) && victim->quest->victim == victim) (*quest_table[victim->quest->quest_type].q_fun) (victim->quest->questor, 3); } if(victim->position != P_TORPOR || agg) update_pos( victim, agg ); return victim->position; } if ( victim == ch ) return ch->position; /* Link dead salvation. */ if ( !IS_NPC(victim) && victim->desc == NULL ) { do_function(victim, &do_flee,""); } tail_chain( ); return victim->position; }
void raw_kill( CHAR_DATA *victim, int absolute ) { int i = 0; /* if(victim->fighting != NULL) { if(victim->fighting->ooc_xp_count < 2) { send_to_char("You learn from your encounter.\n\r", victim->fighting); victim->fighting->exp += 1; } stop_fighting( victim, TRUE ); } */ if(!absolute && victim->race == race_lookup("werewolf") && ((i = dice_rolls(victim, victim->max_RBPG, 8)) > 0 || victim->agghealth > 0)) { bool tag = FALSE; if(victim->health < 0) victim->health = 0; if(victim->agghealth < 0) { victim->agghealth = 0; tag = TRUE; } if(absolute) tag = TRUE; if(tag) { i -= 7 - victim->health; if(i > 0) victim->agghealth += UMIN(7 - victim->agghealth, i); } else while((victim->agghealth + victim->health - 7) <= 0) { if(victim->health >= 7) victim->agghealth++; else victim->health++; } send_to_char("It hurts, but your body starts to heal.\n\r", victim); update_pos(victim, 0); if((victim->agghealth + victim->health - 7) > 0) return; } if(victim->clan == clan_lookup("bone gnawer") && victim->disc[DISC_TRIBE] >= 5 && victim->max_willpower > 0) { victim->max_willpower--; if(victim->willpower > victim->max_willpower) { victim->willpower = victim->max_willpower; } if(victim->health <= 0) victim->health = 1; if(victim->agghealth <= 0) victim->agghealth = 1; while((victim->agghealth + victim->health - 7) <= 0) { if(victim->health >= 7) victim->agghealth++; else victim->health++; } send_to_char("It hurts, but you'll live.\n\r", victim); return; } death_cry( victim ); make_corpse( victim ); if ( IS_NPC(victim) ) { victim->pIndexData->killed++; extract_char( victim, TRUE ); return; } clear_orgs(victim); if(victim->desc) victim->desc->connected = CON_DECEASED; SET_BIT(victim->act, ACT_REINCARNATE); char_from_room(victim); char_from_list(victim); send_to_char("You are DEAD!\n\r[Hit Return to Continue]\n\r", victim); victim->exp = get_points(victim); save_char_obj(victim); return; }
/* * Read in a char. */ int fread_char( struct char_data *ch, FILE *fp ) { int error_count = 0; char *word; char buf [ MAX_STRING_LENGTH ]; struct affected_type *paf; int sn; int i; int j; int status; int status1; char *p; int tmpi; int num_keys; int last_key = 0; char def_sdesc [] = "Your short description was corrupted."; char def_ldesc [] = "Your long description was corrupted."; char def_desc [] = "Your description was corrupted."; char def_title [] = "Your title was corrupted."; struct key_data key_tab [] = { { "ShtDsc", TRUE, (int) &def_sdesc, { &GET_SHORT_DESC(ch), NULL } }, { "LngDsc", TRUE, (int) &def_ldesc, { &GET_LONG_DESC(ch), NULL } }, { "Dscr", TRUE, (int) &def_desc, { &GET_DESCRIPTION(ch), NULL } }, { "Sx", FALSE, SEX_MALE, { &GET_SEX(ch), NULL } }, { "Race", FALSE, MAND, { &GET_RACE(ch), NULL } }, { "Lvl", FALSE, MAND, { &GET_LEVEL(ch), NULL } }, { "Trst", FALSE, 0, { &GET_TRUST(ch), NULL } }, { "HpMnMv", FALSE, MAND, { &GET_HIT(ch), &GET_MAX_HIT(ch), &GET_MANA(ch), &GET_MAX_MANA(ch), &GET_MOVE(ch), &GET_MAX_MOVE(ch), NULL } }, { "Gold", FALSE, 0, { &GET_GOLD(ch), NULL } }, { "Exp", FALSE, MAND, { &GET_EXP(ch), NULL } }, { "Act", FALSE, DEFLT, { &PLR_FLAGS(ch), NULL } }, { "Act2", FALSE, DEFLT, { &PLR2_FLAGS(ch), NULL } }, { "AffdBy", FALSE, 0, { &AFF_FLAGS(ch), NULL } }, { "AffdBy2", FALSE, 0, { &AFF2_FLAGS(ch), NULL } }, { "Pref", FALSE, 0, { &PRF_FLAGS(ch), NULL } }, { "Pref2", FALSE, 0, { &PRF2_FLAGS(ch), NULL } }, { "Pos", FALSE, POS_STANDING, { &GET_POS(ch), NULL } }, { "Prac", FALSE, MAND, { &GET_PRACTICES(ch), NULL } }, { "PAlign", FALSE, 0, { &GET_PERMALIGN(ch), NULL } }, { "CAlign", FALSE, 0, { &GET_ALIGNMENT(ch), NULL } }, { "Ttle", TRUE, (int) &def_title, { &GET_TITLE(ch), NULL } }, #if 0 { "SavThr", FALSE, MAND, { &ch->saving_throw, NULL } }, { "Hit", FALSE, MAND, { &ch->hitroll, NULL } }, { "Dam", FALSE, MAND, { &ch->damroll, NULL } }, { "Armr", FALSE, MAND, { &ch->armor, NULL } }, { "Wimp", FALSE, 10, { &ch->wimpy, NULL } }, { "Deaf", FALSE, 0, { &ch->deaf, NULL } }, { "Immskll",TRUE, DEFLT, { &ch->pcdata->immskll, NULL } }, { "AtrPrm", FALSE, MAND, { &ch->pcdata->perm_str, &ch->pcdata->perm_int, &ch->pcdata->perm_wis, &ch->pcdata->perm_dex, &ch->pcdata->perm_con, NULL } }, { "AtrMd", FALSE, MAND, { &ch->pcdata->mod_str, &ch->pcdata->mod_int, &ch->pcdata->mod_wis, &ch->pcdata->mod_dex, &ch->pcdata->mod_con, NULL } }, { "Cond", FALSE, DEFLT, { &ch->pcdata->condition [0], &ch->pcdata->condition [1], &ch->pcdata->condition [2], NULL } }, { "Pglen", FALSE, 20, { &ch->pcdata->pagelen, NULL } }, { "Playd", FALSE, 0, { &ch->played, NULL } }, #endif { "Paswd", TRUE, MAND, { &GET_PASSWD(ch), NULL } }, { "Poofin", TRUE, DEFLT, { &POOFIN(ch), NULL } }, { "Poofout", TRUE, DEFLT, { &POOFOUT(ch), NULL } }, { "\0", FALSE, 0 } }; for ( num_keys = 0; *key_tab [num_keys].key; ) num_keys++; for ( ; !feof (fp) ; ) { word = fread_word_stat( fp, &status ); if ( !word ) { log( "fread_char: Error reading key. EOF?" ); fread_to_eol( fp ); break; } /* This little diddy searches for the keyword from the last keyword found */ for ( i = last_key; i < last_key + num_keys && str_cmp (key_tab [i % num_keys].key, word); ) i++; i = i % num_keys; if ( !str_cmp (key_tab [i].key, word) ) last_key = i; else i = num_keys; if ( *key_tab [i].key ) /* Key entry found in key_tab */ { if ( key_tab [i].string == SPECIFIED ) log( "Key already specified." ); /* Entry is a string */ else if ( key_tab [i].string ) { if ( ( p = fread_string( fp, (char*)&status ) ) && !status ) { free( *(char **)key_tab [i].ptrs [0] ); *(char **)key_tab [i].ptrs [0] = p; } } /* Entry is an integer */ else for ( j = 0; key_tab [i].ptrs [j]; j++ ) { tmpi = fread_number_stat( fp, &status ); if ( !status ) *(int *)key_tab [i].ptrs [j] = tmpi; } if ( status ) { fread_to_eol( fp ); continue; } else key_tab [i].string = SPECIFIED; } else if ( *word == '*' || !str_cmp( word, "Nm" ) ) fread_to_eol( fp ); else if ( !str_cmp( word, "End" ) ) break; else if ( !str_cmp( word, "Room" ) ) { ch->in_room = fread_number_stat( fp, &status ); if ( !ch->in_room ) ch->in_room = NOWHERE; } else if ( !str_cmp( word, "Race" ) ) { i = race_lookup( fread_string( fp, (char*)&status ) ); if ( status ) log( "Fread_char: Unknown Race." ); else GET_RACE(ch) = i; } else if ( !str_cmp( word, "Skill" ) ) { i = fread_number_stat( fp, &status ); sn = skill_lookup( fread_word_stat( fp, &status1 ) ); if ( status || status1 ) { log( "Fread_char: Error reading skill." ); fread_to_eol( fp ); continue; } if ( sn < 0 ) log( "Fread_char: unknown skill." ); else GET_SKILL(ch, sn) = i; } else if ( !str_cmp ( word, "Afft" ) ) { int status; CREATE(paf, struct affected_type, 1); memset(paf, 0, sizeof( struct affected_type )); paf->type = skill_lookup( fread_string( fp, (char*)&status ) ); paf->duration = fread_number_stat( fp, &status ); paf->modifier = fread_number_stat( fp, &status ); paf->location = fread_number_stat( fp, &status ); paf->bitvector = fread_number_stat( fp, &status ); paf->next = ch->affected; ch->affected = paf; } else {
/* --------------------------------------------------------------------- * CMD_EVAL * This monster evaluates an if/or/and statement * There are five kinds of statement: * 1) keyword and value (no $-code) if random 30 * 2) keyword, comparison and value if people > 2 * 3) keyword and actor if isnpc $n * 4) keyword, actor and value if carries $n sword * 5) keyword, actor, comparison and value if level $n >= 10 * *---------------------------------------------------------------------- */ int cmd_eval( sh_int vnum, char *line, int check, CHAR_DATA *mob, CHAR_DATA *ch, const void *arg1, const void *arg2, CHAR_DATA *rch ) { CHAR_DATA *lval_char = mob; CHAR_DATA *vch = (CHAR_DATA *) arg2; OBJ_DATA *obj1 = (OBJ_DATA *) arg1; OBJ_DATA *obj2 = (OBJ_DATA *) arg2; OBJ_DATA *lval_obj = NULL; char *original, buf[MAX_INPUT_LENGTH], code; int lval = 0, oper = 0, rval = -1; original = line; line = one_argument( line, buf ); if ( buf[0] == '\0' || mob == NULL ) return FALSE; /* * If this mobile has no target, let's assume our victim is the one */ if ( mob->mprog_target == NULL ) mob->mprog_target = ch; switch ( check ) { /* * Case 1: keyword and value */ case CHK_RAND: return( atoi( buf ) < number_percent() ); case CHK_MOBHERE: if ( is_number( buf ) ) return( get_mob_vnum_room( mob, atoi(buf) ) ); else return( (bool) (get_char_room( mob, buf) != NULL) ); case CHK_OBJHERE: if ( is_number( buf ) ) return( get_obj_vnum_room( mob, atoi(buf) ) ); else return( (bool) (get_obj_here( mob, buf) != NULL) ); case CHK_MOBEXISTS: return( (bool) (get_char_world( mob, buf) != NULL) ); case CHK_OBJEXISTS: return( (bool) (get_obj_world( mob, buf) != NULL) ); /* * Case 2 begins here: We sneakily use rval to indicate need * for numeric eval... */ case CHK_PEOPLE: rval = count_people_room( mob, 0 ); break; case CHK_PLAYERS: rval = count_people_room( mob, 1 ); break; case CHK_MOBS: rval = count_people_room( mob, 2 ); break; case CHK_CLONES: rval = count_people_room( mob, 3 ); break; case CHK_ORDER: rval = get_order( mob ); break; case CHK_HOUR: rval = time_info.hour; break; default:; } /* * Case 2 continued: evaluate expression */ if ( rval >= 0 ) { if ( (oper = keyword_lookup( fn_evals, buf )) < 0 ) { sprintf( buf, "Cmd_eval: prog %d syntax error(2) '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } one_argument( line, buf ); lval = rval; rval = atoi( buf ); return( num_eval( lval, oper, rval ) ); } /* * Case 3,4,5: Grab actors from $* codes */ if ( buf[0] != '$' || buf[1] == '\0' ) { sprintf( buf, "Cmd_eval: prog %d syntax error(3) '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } else code = buf[1]; switch( code ) { case 'i': lval_char = mob; break; case 'n': lval_char = ch; break; case 't': lval_char = vch; break; case 'r': lval_char = rch == NULL ? get_random_char( mob ) : rch ; break; case 'o': lval_obj = obj1; break; case 'p': lval_obj = obj2; break; case 'q': lval_char = mob->mprog_target; break; default: sprintf( buf, "Cmd_eval: prog %d syntax error(4) '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } /* * From now on, we need an actor, so if none was found, bail out */ if ( lval_char == NULL && lval_obj == NULL ) return FALSE; /* * Case 3: Keyword, comparison and value */ switch( check ) { case CHK_ISPC: return( lval_char != NULL && !IS_NPC( lval_char ) ); case CHK_ISNPC: return( lval_char != NULL && IS_NPC( lval_char ) ); case CHK_ISGOOD: return( lval_char != NULL && IS_GOOD( lval_char ) ); case CHK_ISEVIL: return( lval_char != NULL && IS_EVIL( lval_char ) ); case CHK_ISNEUTRAL: return( lval_char != NULL && IS_NEUTRAL( lval_char ) ); case CHK_ISIMMORT: return( lval_char != NULL && IS_IMMORTAL( lval_char ) ); case CHK_ISCHARM: /* A relic from MERC 2.2 MOBprograms */ return( lval_char != NULL && IS_AFFECTED( lval_char, AFF_CHARM ) ); case CHK_ISFOLLOW: return( lval_char != NULL && lval_char->master != NULL && lval_char->master->in_room == lval_char->in_room ); case CHK_ISACTIVE: return( lval_char != NULL && lval_char->position > POS_SLEEPING ); case CHK_ISDELAY: return( lval_char != NULL && lval_char->mprog_delay > 0 ); case CHK_ISVISIBLE: switch( code ) { default : case 'i': case 'n': case 't': case 'r': case 'q': return( lval_char != NULL && can_see( mob, lval_char ) ); case 'o': case 'p': return( lval_obj != NULL && can_see_obj( mob, lval_obj ) ); } case CHK_HASTARGET: return( lval_char != NULL && lval_char->mprog_target != NULL && lval_char->in_room == lval_char->mprog_target->in_room ); case CHK_ISTARGET: return( lval_char != NULL && mob->mprog_target == lval_char ); default:; } /* * Case 4: Keyword, actor and value */ line = one_argument( line, buf ); switch( check ) { case CHK_AFFECTED: return( lval_char != NULL && IS_SET(lval_char->affected_by, flag_lookup(buf, affect_flags)) ); case CHK_ACT: return( lval_char != NULL && IS_SET(lval_char->act, flag_lookup(buf, act_flags)) ); case CHK_IMM: return( lval_char != NULL && IS_SET(lval_char->imm_flags, flag_lookup(buf, imm_flags)) ); case CHK_OFF: return( lval_char != NULL && IS_SET(lval_char->off_flags, flag_lookup(buf, off_flags)) ); case CHK_CARRIES: if ( is_number( buf ) ) return( lval_char != NULL && has_item( lval_char, atoi(buf), -1, FALSE ) ); else return( lval_char != NULL && (get_obj_carry( lval_char, buf ) != NULL) ); case CHK_WEARS: if ( is_number( buf ) ) return( lval_char != NULL && has_item( lval_char, atoi(buf), -1, TRUE ) ); else return( lval_char != NULL && (get_obj_wear( lval_char, buf ) != NULL) ); case CHK_HAS: return( lval_char != NULL && has_item( lval_char, -1, item_lookup(buf), FALSE ) ); case CHK_USES: return( lval_char != NULL && has_item( lval_char, -1, item_lookup(buf), TRUE ) ); case CHK_NAME: switch( code ) { default : case 'i': case 'n': case 't': case 'r': case 'q': return( lval_char != NULL && is_name( buf, lval_char->name ) ); case 'o': case 'p': return( lval_obj != NULL && is_name( buf, lval_obj->name ) ); } case CHK_POS: return( lval_char != NULL && lval_char->position == position_lookup( buf ) ); case CHK_CLAN: return( lval_char != NULL && lval_char->clan == clan_lookup( buf ) ); case CHK_RACE: return( lval_char != NULL && lval_char->race == race_lookup( buf ) ); case CHK_OBJTYPE: return( lval_obj != NULL && lval_obj->item_type == item_lookup( buf ) ); default:; } /* * Case 5: Keyword, actor, comparison and value */ if ( (oper = keyword_lookup( fn_evals, buf )) < 0 ) { sprintf( buf, "Cmd_eval: prog %d syntax error(5): '%s'", vnum, original ); bug( buf, 0 ); return FALSE; } one_argument( line, buf ); rval = atoi( buf ); switch( check ) { case CHK_VNUM: switch( code ) { default : case 'i': case 'n': case 't': case 'r': case 'q': if( lval_char != NULL && IS_NPC( lval_char ) ) lval = lval_char->pIndexData->vnum; break; case 'o': case 'p': if ( lval_obj != NULL ) lval = lval_obj->pIndexData->vnum; } break; case CHK_HPCNT: if ( lval_char != NULL ) lval = (lval_char->hit * 100)/(UMAX(1,lval_char->max_hit)); break; case CHK_ROOM: if ( lval_char != NULL && lval_char->in_room != NULL ) lval = lval_char->in_room->vnum; break; case CHK_SEX: if ( lval_char != NULL ) lval = lval_char->sex; break; case CHK_LEVEL: if ( lval_char != NULL ) lval = lval_char->level; break; case CHK_ALIGN: if ( lval_char != NULL ) lval = lval_char->alignment; break; case CHK_MONEY: /* Money is converted to silver... */ if ( lval_char != NULL ) lval = lval_char->gold + (lval_char->silver * 100); break; case CHK_OBJVAL0: if ( lval_obj != NULL ) lval = lval_obj->value[0]; break; case CHK_OBJVAL1: if ( lval_obj != NULL ) lval = lval_obj->value[1]; break; case CHK_OBJVAL2: if ( lval_obj != NULL ) lval = lval_obj->value[2]; break; case CHK_OBJVAL3: if ( lval_obj != NULL ) lval = lval_obj->value[3]; break; case CHK_OBJVAL4: if ( lval_obj != NULL ) lval = lval_obj->value[4]; break; case CHK_GRPSIZE: if( lval_char != NULL ) lval = count_people_room( lval_char, 4 ); break; default: return FALSE; } return( num_eval( lval, oper, rval ) ); }
MOB_INDEX_DATA *new_mob_index( void ) { MOB_INDEX_DATA *pMob; int i; if ( !mob_index_free ) { CREATE( pMob, MOB_INDEX_DATA, 1 ); top_mob_index++; } else { pMob = mob_index_free; mob_index_free = mob_index_free->next; } pMob->next = NULL; pMob->spec_fun = NULL; pMob->pShop = NULL; pMob->pRepair = NULL; pMob->area = NULL; pMob->player_name = str_dup( "no name" ); pMob->name2 = str_dup( "null" ); pMob->name3 = str_dup( "null" ); pMob->name4 = str_dup( "null" ); pMob->name5 = str_dup( "null" ); pMob->name6 = str_dup( "null" ); pMob->short_descr = str_dup( "(no short description)" ); pMob->long_descr = str_dup( "(no long description)" ); pMob->description = &str_empty[0]; pMob->vnum = 0; pMob->count = 0; pMob->killed = 0; pMob->sex = 0; pMob->level = 0; ext_flags_clear( pMob->act ); EXT_SET_BIT( pMob->act, ACT_IS_NPC ); pMob->languages = LANG_COMMON; pMob->speaking = 0; pMob->corpse_vnum = 0; pMob->skin_multiplier = 0; for(i=0;i < 16 ;i++) pMob->spells[i] = 0; for(i=0;i < MAX_RESIST ;i++) { pMob->resists[i] = 0; pMob->healing_from[i] = 0; } for(i=0;i<MAX_VECT_BANK;i++) pMob->affected_by[i] = 0; pMob->alignment = 0; pMob->hitroll = 0; pMob->race = race_lookup( "human" ); pMob->form = 0; pMob->parts = 0; pMob->material = str_dup("unknown"); ext_flags_clear( pMob->off_flags ); pMob->size = SIZE_MEDIUM; pMob->ac[AC_PIERCE] = 100; pMob->ac[AC_BASH] = 100; pMob->ac[AC_SLASH] = 100; pMob->ac[AC_EXOTIC] = 100; pMob->stats[0] =13; pMob->stats[1] =13; pMob->stats[2] =13; pMob->stats[3] =13; pMob->stats[4] =13; pMob->stats[5] =13; pMob->stats[6] =13; pMob->hit[DICE_NUMBER] = 0; pMob->hit[DICE_TYPE] = 0; pMob->hit[DICE_BONUS] = 0; pMob->damage[DICE_NUMBER] = 0; pMob->damage[DICE_TYPE] = 0; pMob->damage[DICE_NUMBER] = 0; pMob->start_pos = POS_STANDING; pMob->default_pos = POS_STANDING; pMob->wealth = 0; pMob->comments = str_dup(""); pMob->new_format = TRUE; return pMob; }
void load_mobiles(FILE * fp) { MOB_INDEX_DATA *pMobIndex; if (!area_last) { /* OLC */ bug("Load_mobiles: no #AREA seen yet.", 0); exit(1); } for (;;) { sh_int vnum; char letter; int iHash; letter = fread_letter(fp); if (letter != '#') { bug("Load_mobiles: # not found.", 0); exit(1); } vnum = fread_number(fp); if (vnum == 0) break; fBootDb = FALSE; if (get_mob_index(vnum) != NULL) { bug("Load_mobiles: vnum %d duplicated.", vnum); exit(1); } fBootDb = TRUE; pMobIndex = alloc_perm(sizeof(*pMobIndex)); pMobIndex->vnum = vnum; pMobIndex->area = area_last; /* OLC */ pMobIndex->new_format = TRUE; newmobs++; pMobIndex->player_name = fread_string(fp); pMobIndex->short_descr = fread_string(fp); pMobIndex->long_descr = fread_string(fp); pMobIndex->long_descr_orig = fread_string(fp); pMobIndex->description = fread_string(fp); pMobIndex->race = race_lookup(fread_string(fp)); pMobIndex->long_descr[0] = UPPER(pMobIndex->long_descr[0]); pMobIndex->description[0] = UPPER(pMobIndex->description[0]); pMobIndex->act = fread_flag(fp) | ACT_IS_NPC | race_table[pMobIndex->race].act; pMobIndex->affected_by = fread_flag(fp) | race_table[pMobIndex->race].aff; pMobIndex->pShop = NULL; pMobIndex->alignment = fread_number(fp); pMobIndex->group = fread_number(fp); pMobIndex->level = fread_number(fp); pMobIndex->hitroll = fread_number(fp); /* read hit dice */ pMobIndex->hit[DICE_NUMBER] = fread_number(fp); /* 'd' */ fread_letter(fp); pMobIndex->hit[DICE_TYPE] = fread_number(fp); /* '+' */ fread_letter(fp); pMobIndex->hit[DICE_BONUS] = fread_number(fp); /* read mana dice */ pMobIndex->mana[DICE_NUMBER] = fread_number(fp); fread_letter(fp); pMobIndex->mana[DICE_TYPE] = fread_number(fp); fread_letter(fp); pMobIndex->mana[DICE_BONUS] = fread_number(fp); /* read damage dice */ pMobIndex->damage[DICE_NUMBER] = fread_number(fp); fread_letter(fp); pMobIndex->damage[DICE_TYPE] = fread_number(fp); fread_letter(fp); pMobIndex->damage[DICE_BONUS] = fread_number(fp); pMobIndex->dam_type = attack_lookup(fread_word(fp)); /* read armor class */ pMobIndex->ac[AC_PIERCE] = fread_number(fp) * 10; pMobIndex->ac[AC_BASH] = fread_number(fp) * 10; pMobIndex->ac[AC_SLASH] = fread_number(fp) * 10; pMobIndex->ac[AC_EXOTIC] = fread_number(fp) * 10; /* read flags and add in data from the race table */ pMobIndex->off_flags = fread_flag(fp) | race_table[pMobIndex->race].off; pMobIndex->imm_flags = fread_flag(fp) | race_table[pMobIndex->race].imm; pMobIndex->res_flags = fread_flag(fp) | race_table[pMobIndex->race].res; pMobIndex->vuln_flags = fread_flag(fp) | race_table[pMobIndex->race].vuln; /* vital statistics */ pMobIndex->start_pos = position_lookup(fread_word(fp)); pMobIndex->default_pos = position_lookup(fread_word(fp)); pMobIndex->sex = sex_lookup(fread_word(fp)); pMobIndex->wealth = fread_number(fp); pMobIndex->form = fread_flag(fp) | race_table[pMobIndex->race].form; pMobIndex->parts = fread_flag(fp) | race_table[pMobIndex->race].parts; /* size */ pMobIndex->size = size_lookup(fread_word(fp)); pMobIndex->material = str_dup(fread_word(fp)); for (;;) { letter = fread_letter(fp); if (letter == 'F') { char *word; long vector; word = fread_word(fp); vector = fread_flag(fp); if (!str_prefix(word, "act")) REMOVE_BIT(pMobIndex->act, vector); else if (!str_prefix(word, "aff")) REMOVE_BIT(pMobIndex->affected_by, vector); else if (!str_prefix(word, "off")) REMOVE_BIT(pMobIndex->off_flags, vector); else if (!str_prefix(word, "imm")) REMOVE_BIT(pMobIndex->imm_flags, vector); else if (!str_prefix(word, "res")) REMOVE_BIT(pMobIndex->res_flags, vector); else if (!str_prefix(word, "vul")) REMOVE_BIT(pMobIndex->vuln_flags, vector); else if (!str_prefix(word, "for")) REMOVE_BIT(pMobIndex->form, vector); else if (!str_prefix(word, "par")) REMOVE_BIT(pMobIndex->parts, vector); else { bug("Flag remove: flag not found.", 0); exit(1); } } else if (letter == 'M') { MPROG_LIST *pMprog; char *word; int trigger = 0; pMprog = alloc_perm(sizeof(*pMprog)); word = fread_word(fp); if (!(trigger = flag_lookup(word, mprog_flags))) { bug("MOBprogs: invalid trigger.", 0); exit(1); } SET_BIT(pMobIndex->mprog_flags, trigger); pMprog->trig_type = trigger; pMprog->vnum = fread_number(fp); pMprog->trig_phrase = fread_string(fp); pMprog->next = pMobIndex->mprogs; pMobIndex->mprogs = pMprog; } else { ungetc(letter, fp); break; } } iHash = vnum % MAX_KEY_HASH; pMobIndex->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMobIndex; top_mob_index++; top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob; /* OLC */ assign_area_vnum(vnum); /* OLC */ kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL - 1)].number++; } return; }