/* Some initializations for characters, including initial skills */ void do_start(struct char_data *ch) { GET_LEVEL(ch) = 1; GET_TOT_LEVEL(ch) = 1; GET_EXP(ch) = 1; GET_CLASS_1(ch) = GET_CLASS(ch); GET_MULTIS(ch) = 1; set_title(ch, NULL); roll_real_abils(ch); GET_MAX_HIT(ch) = 10; GET_MAX_MANA(ch) = 100; GET_MAX_MOVE(ch) = 100; switch (GET_CLASS(ch)) { case CLASS_ADEPT: break; case CLASS_MEDIC: break; case CLASS_BANDIT: SET_SKILL(ch, SKILL_SNEAK, 10); SET_SKILL(ch, SKILL_HIDE, 5); SET_SKILL(ch, SKILL_STEAL, 15); SET_SKILL(ch, SKILL_BACKSTAB, 10); SET_SKILL(ch, SKILL_PICK_LOCK, 10); SET_SKILL(ch, SKILL_TRACK, 10); break; case CLASS_SOLDIER: break; } advance_level(ch); GET_HIT(ch) = GET_MAX_HIT(ch); GET_MANA(ch) = GET_MAX_MANA(ch); GET_MOVE(ch) = GET_MAX_MOVE(ch); GET_COND(ch, THIRST) = 24; GET_COND(ch, HUNGER) = 24; GET_COND(ch, DRUNK) = 0; if (CONFIG_SITEOK_ALL) SET_BIT_AR(PLR_FLAGS(ch), PLR_SITEOK); }
/* return the modifier to a certain APPLY_x */ int morph_modifier(char_data *ch, byte loc) { int mod = 0; double prc; switch (loc) { case APPLY_STRENGTH: { mod = morph_data[GET_MORPH(ch)].attribute_bonus[STRENGTH]; break; } case APPLY_DEXTERITY: { mod = morph_data[GET_MORPH(ch)].attribute_bonus[DEXTERITY]; break; } case APPLY_CHARISMA: { mod = morph_data[GET_MORPH(ch)].attribute_bonus[CHARISMA]; break; } case APPLY_GREATNESS: { mod = morph_data[GET_MORPH(ch)].attribute_bonus[GREATNESS]; break; } case APPLY_INTELLIGENCE: { mod = morph_data[GET_MORPH(ch)].attribute_bonus[INTELLIGENCE]; break; } case APPLY_WITS: { mod = morph_data[GET_MORPH(ch)].attribute_bonus[WITS]; break; } case APPLY_HEALTH: { prc = morph_data[GET_MORPH(ch)].pool_mod[HEALTH] / 100.0; mod = (GET_MAX_HEALTH(ch) * prc) - GET_MAX_HEALTH(ch); break; } case APPLY_MOVE: { prc = morph_data[GET_MORPH(ch)].pool_mod[MOVE] / 100.0; mod = (GET_MAX_MOVE(ch) * prc) - GET_MAX_MOVE(ch); break; } case APPLY_MANA: { prc = morph_data[GET_MORPH(ch)].pool_mod[MANA] / 100.0; mod = (GET_MAX_MANA(ch) * prc) - GET_MAX_MANA(ch); break; } } return mod; }
/* nb, also mess up anyone affected by AFF_POISON */ void pulse_heal(void) { CharData *ch; int gain = number(18,24); for (ch = character_list; ch; ch = ch->next) { if(ch->in_room == NOWHERE) continue; if(!(pvpFactor() > 1)) { if( GET_POS(ch) == POS_INCAP ) damage(ch, ch, 1, TYPE_SUFFERING); else if( GET_POS(ch) == POS_MORTALLYW ) damage(ch, ch, 2, TYPE_SUFFERING); else if( GET_POS(ch) == POS_DEAD) { if(IN_ARENA(ch) || IN_QUEST_FIELD(ch) || ZONE_FLAGGED(world[ch->in_room].zone, ZONE_ARENA) || ZONE_FLAGGED(world[ch->in_room].zone, ZONE_SLEEPTAG)) // If they're dying in the arena, they eventually get better (or killed by someone) { GET_HIT(ch) = number(GET_HIT(ch), 1); sendChar(ch, "You slowly recover.\r\n"); update_pos(ch); } else { raw_kill(ch, NULL); continue; } } } if (IS_AFFECTED(ch, AFF_PULSE_HIT)) if (GET_HIT(ch) < GET_MAX_HIT(ch)) GET_HIT(ch) += gain; if (IS_AFFECTED(ch, AFF_PULSE_MANA)) if (GET_MANA(ch) < GET_MAX_MANA(ch)) GET_MANA(ch) += gain; if (IS_AFFECTED(ch, AFF_POISON)) doPoison(ch); if (IS_AFFECTED(ch, AFF_DISEASE)) doDisease(ch); if (affected_by_spell(ch, SKILL_INVIGORATE)) doInvigorate(ch); if (IS_BOUNTY_HUNTER(ch) && GET_ADVANCE_LEVEL(ch) >= 1 && IS_AFFECTED(ch, AFF_HIDE)) GET_MOVE(ch) = MIN(GET_MOVE(ch) + 3*gain, GET_MAX_MOVE(ch)); if (IS_PRESTIDIGITATOR(ch)) GET_MANA(ch) = MIN(GET_MANA(ch) + GET_ADVANCE_LEVEL(ch) * 2, GET_MAX_MANA(ch)); if (affected_by_spell(ch, SPELL_HIPPOCRATIC_OATH)) GET_MANA(ch) = MIN(GET_MANA(ch) + 25, GET_MAX_MANA(ch)); if (affected_by_spell(ch, SKILL_PET_MEND)) GET_HIT(ch) = MIN(GET_HIT(ch) * 115 / 100, GET_MAX_HIT(ch)); if (IS_HOLY_PRIEST(ch)) GET_MANA(ch) = MIN(GET_MANA(ch) + 10 + 2*GET_ADVANCE_LEVEL(ch), GET_MAX_MANA(ch)); /* The room might be poisoned! (Or later, otherwise dangerous) */ if (ch->in_room != NOWHERE) { if (ROOM_FLAGGED(ch->in_room, ROOM_POISONED)) { if (!mag_savingthrow(ch, SAVING_SPELL)) { act("$n chokes and gags!", TRUE, ch, 0, 0, TO_ROOM); act("You choke and gag!", TRUE, ch, 0, 0, TO_CHAR); add_affect( ch, ch, SPELL_POISON, 30, APPLY_NONE, 0, 5 TICKS, AFF_POISON, FALSE, FALSE, FALSE, FALSE); } } } if(IS_DEFENDER(ch) && !affected_by_spell(ch, SKILL_DEFENDER_HEALTH)) add_affect(ch, ch, SKILL_DEFENDER_HEALTH, GET_LEVEL(ch), APPLY_HIT, GET_ADVANCE_LEVEL(ch)*5, -1, FALSE, FALSE, FALSE, FALSE, FALSE); } }
/* cause the morph to happen: universal thru this function to prevent errors */ void perform_morph(char_data *ch, ubyte form) { ACMD(do_dismount); double move_mod, health_mod, mana_mod; if (IS_NPC(ch)) { return; } if (IS_RIDING(ch) && form != MORPH_NONE) { do_dismount(ch, "", 0, 0); } // read current pools health_mod = (double) GET_HEALTH(ch) / GET_MAX_HEALTH(ch); move_mod = (double) GET_MOVE(ch) / GET_MAX_MOVE(ch); mana_mod = (double) GET_MANA(ch) / GET_MAX_MANA(ch); /* Remove his morph bonuses from his current form */ update_morph_stats(ch, FALSE); /* Set the new form */ GET_MORPH(ch) = form; /* Add new morph bonuses */ update_morph_stats(ch, TRUE); // this fixes all the things affect_total(ch); // set new pools GET_HEALTH(ch) = (sh_int) (GET_MAX_HEALTH(ch) * health_mod); GET_MOVE(ch) = (sh_int) (GET_MAX_MOVE(ch) * move_mod); GET_MANA(ch) = (sh_int) (GET_MAX_MANA(ch) * mana_mod); /* check for claws */ if (MORPH_FLAGGED(ch, MORPH_FLAG_NO_CLAWS) && AFF_FLAGGED(ch, AFF_CLAWS)) { affects_from_char_by_aff_flag(ch, AFF_CLAWS); } }
/* * Ideally, this function should be in db.c, but I'll put it here for * portability. */ void init_mobile(struct char_data *mob) { clear_char(mob); GET_HIT(mob) = GET_MANA(mob) = 1; GET_MAX_MANA(mob) = GET_MAX_MOVE(mob) = 100; GET_NDD(mob) = GET_SDD(mob) = 1; GET_WEIGHT(mob) = 200; GET_HEIGHT(mob) = 198; GET_MOB_WEIGHT(mob) = 1; mob->real_abils.str = mob->real_abils.intel = mob->real_abils.wis = 11; mob->real_abils.dex = mob->real_abils.con = mob->real_abils.cha = 11; mob->aff_abils = mob->real_abils; SET_BIT(MOB_FLAGS(mob), MOB_ISNPC); mob->player_specials = &dummy_mob; }
void do_mob_report (struct char_data *ch) { struct char_data *mob; FILE *reportfile; int i; if (!(reportfile = fopen("report.mob", "w"))) { mlog("SYSERR: Mob report file unavailable."); send_to_char ("Report.mob could not be generated.\r\n",ch); return; } sprintf(buf, "MOBS\n----\n"); for (i=0; i<top_of_mobt;i++) { mob=read_mobile(i, REAL); char_to_room(mob, 0); sprintf(buf+strlen(buf), "[%5d] %s Spec Proc: ", GET_MOB_VNUM(mob), GET_NAME(mob)); if (mob_index[GET_MOB_RNUM(mob)].func!=NULL) get_spec_name(GET_MOB_RNUM(mob), buf2,'m'); else sprintf(buf2, "none"); sprintf(buf+strlen(buf), "%s\n",buf2); sprintf(buf+strlen(buf),mob->player.description); sprintf(buf+strlen(buf),"Difficulty: %d XP: %d HP: %d Mana: %d Gold %d\n", GET_DIFFICULTY(mob), GET_EXP(mob), GET_MAX_HIT(mob), GET_MAX_MANA(mob), GET_GOLD(mob)); sprintf(buf+strlen(buf),"Passive Defense: %d Damage Reduction: %d ", GET_PD(mob), GET_REDUCTION(mob)); sprintf(buf+strlen(buf), "Attack Type: %s\n", attack_hit_text[mob->mob_specials.attack_type].singular); sprintbit(MOB_FLAGS(mob), action_bits, buf2, sizeof(buf2)); sprintf(buf+strlen(buf),"Flags: %s\n", buf2); sprintbit(AFF_FLAGS(mob), affected_bits, buf2, sizeof(buf2)); sprintf(buf+strlen(buf),"Affects: %s\n\n-------\n", buf2); extract_char(mob); fprintf(reportfile, buf); buf[0]='\0'; }/*for i=0...*/ fclose (reportfile); send_to_char ("report.mob printed\r\n",ch); }
/* * Rough duplicate of PC's cast. * @param mob the mobile * @vict the target of the spell * @spell_num the spell * @return TRUE if the mob was able to cast a spell even though it failed */ bool mob_cast(struct char_data *mob, struct char_data *vict, int spell_num) { int manaCost = mag_manacost(mob, spell_num); if(spell_num > 0 && manaCost <= GET_MANA(mob) && spell_info[spell_num].min_level[(int)GET_CLASS(mob)] <= GET_LEVEL(mob) && !AFF_FLAGGED(mob, AFF_SILENCE) && GET_WAIT_STATE(mob) < 1) { /* This is a very simple check for 'spell success'. In the future a more * sophisticated approach should be implemented. */ if(rand_number(0, 30) <= GET_INT(mob)) { cast_spell(mob, vict, NULL, spell_num); } /* even if the mob fails, they will still be "stunned" for a round */ WAIT_STATE(mob, PULSE_VIOLENCE); GET_MANA(mob) = MAX(0, MIN(GET_MAX_MANA(mob), GET_MANA(mob) - manaCost)); return TRUE; } return FALSE; }
/* Ideally, this function should be in db.c, but I'll put it here for portability. */ static void init_mobile(struct char_data *mob) { clear_char(mob); GET_HIT(mob) = GET_MANA(mob) = 1; GET_MAX_MANA(mob) = GET_MAX_MOVE(mob) = 100; GET_NDD(mob) = GET_SDD(mob) = 1; GET_WEIGHT(mob) = 200; GET_HEIGHT(mob) = 198; mob->real_abils.str = mob->real_abils.intel = mob->real_abils.wis = 11; mob->real_abils.dex = mob->real_abils.con = mob->real_abils.cha = 11; mob->aff_abils = mob->real_abils; GET_SAVE(mob, SAVING_PARA) = 0; GET_SAVE(mob, SAVING_ROD) = 0; GET_SAVE(mob, SAVING_PETRI) = 0; GET_SAVE(mob, SAVING_BREATH) = 0; GET_SAVE(mob, SAVING_SPELL) = 0; SET_BIT_AR(MOB_FLAGS(mob), MOB_ISNPC); mob->player_specials = &dummy_mob; }
// Create a brand new character struct creature * account_create_char(struct account *account, const char *name) { struct creature *ch; int i; if (chars_available(account) <= 0) return NULL; ch = make_creature(true); ch->player.name = strdup(tmp_capitalize(tmp_tolower(name))); ch->char_specials.saved.idnum = top_player_idnum() + 1; account->chars = g_list_append(account->chars, GINT_TO_POINTER(GET_IDNUM(ch))); sql_exec ("insert into players (idnum, name, account) values (%ld, '%s', %d)", GET_IDNUM(ch), tmp_sqlescape(name), account->id); // New characters shouldn't get old mail. if (has_mail(GET_IDNUM(ch))) { if (purge_mail(GET_IDNUM(ch)) > 0) { errlog("Purging pre-existing mailfile for new character.(%s)", GET_NAME(ch)); } } // *** if this is our first player --- he be God *** if (GET_IDNUM(ch) == 1) { GET_EXP(ch) = 160000000; GET_LEVEL(ch) = LVL_GRIMP; ch->points.max_hit = 666; ch->points.max_mana = 555; ch->points.max_move = 444; GET_HOME(ch) = HOME_MODRIAN; ch->player_specials->saved.load_room = -1; ch->player_specials->saved.home_room = 1204; } else { ch->points.max_hit = 100; ch->points.max_mana = 100; ch->points.max_move = 82; GET_HOME(ch) = HOME_NEWBIE_SCHOOL; ch->player_specials->saved.load_room = -1; ch->player_specials->saved.home_room = -1; } ch->player_specials->rentcode = RENT_CREATING; set_title(ch, ""); ch->player.short_descr = NULL; ch->player.long_descr = NULL; ch->player.description = NULL; ch->player.time.birth = time(NULL); ch->player.time.death = 0; ch->player.time.played = 0; ch->player.time.logon = time(NULL); for (i = 0; i < MAX_SKILLS; i++) ch->player_specials->saved.skills[i] = 0; for (i = 0; i < MAX_WEAPON_SPEC; i++) { ch->player_specials->saved.weap_spec[i].vnum = 0; ch->player_specials->saved.weap_spec[i].level = 0; } ch->player_specials->saved.imm_qp = 0; ch->player_specials->saved.quest_id = 0; ch->player_specials->saved.qlog_level = 0; GET_REMORT_CLASS(ch) = -1; ch->player.weight = 100; ch->player.height = 100; ch->points.hit = GET_MAX_HIT(ch); ch->points.mana = GET_MAX_MANA(ch); ch->points.move = GET_MAX_MOVE(ch); ch->points.armor = 100; SET_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE | PRF_AUTOEXIT | PRF_NOSPEW | PRF_NOPLUG); SET_BIT(PRF2_FLAGS(ch), PRF2_AUTO_DIAGNOSE | PRF2_AUTOPROMPT | PRF2_DISPALIGN | PRF2_NEWBIE_HELPER); ch->char_specials.saved.affected_by = 0; ch->char_specials.saved.affected2_by = 0; ch->char_specials.saved.affected3_by = 0; for (i = 0; i < 5; i++) GET_SAVE(ch, i) = 0; GET_COND(ch, FULL) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 24); GET_COND(ch, THIRST) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 24); GET_COND(ch, DRUNK) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 0); POOFIN(ch) = NULL; POOFOUT(ch) = NULL; return ch; }
/* * Write the char to the file. * * @param ch the character to be written * @param fp the file to write to */ void fwrite_char( struct char_data *ch, FILE *fp ) { extern struct race_data * races; struct affected_type *paf; int sn, i; fprintf( fp, "#%s\n", IS_NPC( ch ) ? "MOB" : "PLAYER" ); fprintf( fp, "Name %s~\n", GET_NAME(ch) ); fprintf( fp, "ShtDsc %s~\n", GET_SHORT_DESC(ch) ? GET_SHORT_DESC(ch) : "" ); fprintf( fp, "LngDsc %s~\n", GET_LONG_DESC(ch) ? GET_LONG_DESC(ch) : "" ); fprintf( fp, "Dscr %s~\n", GET_DESCRIPTION(ch) ? GET_DESCRIPTION(ch) : "" ); // fprintf( fp, "Prmpt %s~\n", ch->pcdata->prompt ); fprintf( fp, "Sx %d\n", GET_SEX(ch) ); fprintf( fp, "Race %s~\n", races[ (int)GET_RACE(ch) ].name ); fprintf( fp, "Lvl %d\n", GET_LEVEL(ch) ); fprintf( fp, "Trst %d\n", GET_TRUST(ch) ); /* fprintf( fp, "Playd %ld\n", GET_PLAYED(ch) + (int)( time( 0 ) - GET_LOGON(ch) ) ); */ // fprintf( fp, "Note %ld\n", (unsigned long)ch->last_note ); fprintf( fp, "Room %ld\n", ( ch->in_room == NOWHERE && ch->was_in_room ) ? ch->was_in_room : ch->in_room ); fprintf( fp, "HpMnMv %d %d %d %d %d %d\n", GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch), GET_MOVE(ch), GET_MAX_MOVE(ch) ); fprintf( fp, "Gold %ld\n", GET_GOLD(ch) ); fprintf( fp, "Exp %ld\n", GET_EXP(ch) ); fprintf( fp, "Act %lld\n", PLR_FLAGS(ch) ); fprintf( fp, "Act2 %lld\n", PLR2_FLAGS(ch) ); fprintf( fp, "Pref %lld\n", PRF_FLAGS(ch) ); fprintf( fp, "Pref2 %lld\n", PRF2_FLAGS(ch) ); fprintf( fp, "AffdBy %lld\n", AFF_FLAGS(ch) ); fprintf( fp, "AffdBy2 %lld\n", AFF2_FLAGS(ch) ); /* Bug fix from Alander */ fprintf( fp, "Pos %d\n", GET_POS(ch) == POS_FIGHTING ? POS_STANDING : GET_POS(ch) ); fprintf( fp, "Prac %d\n", GET_PRACTICES(ch) ); fprintf( fp, "PAlign %d\n", GET_PERMALIGN(ch) ); fprintf( fp, "CAlign %d\n", GET_ALIGNMENT(ch) ); fprintf( fp, "SavThr " ); for ( i = 0; i < NUM_SAVES; i++ ) fprintf( fp, "%d%s", GET_SAVE(ch, i), (i != NUM_SAVES-1 ? ", " : "\n") ); fprintf( fp, "Hitroll %d\n", GET_HITROLL(ch) ); fprintf( fp, "Damroll %d\n", GET_DAMROLL(ch) ); fprintf( fp, "Armr " ); for ( i = 0; i < ARMOR_LIMIT; i++ ) fprintf( fp, "%d%s", GET_AC(ch, i), (i != ARMOR_LIMIT-1 ? ", " : "\n") ); fprintf( fp, "Wimp %d\n", GET_WIMP_LEV(ch) ); if ( IS_NPC( ch ) ) { fprintf( fp, "Vnum %ld\n", GET_MOB_VNUM(ch) ); } else { fprintf( fp, "Paswd %s~\n", GET_PASSWD(ch) ); fprintf( fp, "Poofin %s~\n", POOFIN(ch) ? POOFIN(ch) : "" ); fprintf( fp, "Poofout %s~\n", POOFOUT(ch) ? POOFOUT(ch) : "" ); fprintf( fp, "Ttle %s~\n", GET_TITLE(ch) ? GET_TITLE(ch) : "" ); fprintf( fp, "AtrPrm %d/%d %d %d %d %d %d %d\n", ch->real_abils.str, ch->real_abils.str_add, ch->real_abils.intel, ch->real_abils.wis, ch->real_abils.dex, ch->real_abils.con, ch->real_abils.cha, ch->real_abils.will ); fprintf( fp, "AtrMd %d/%d %d %d %d %d %d %d\n", ch->aff_abils.str, ch->aff_abils.str_add, ch->aff_abils.intel, ch->aff_abils.wis, ch->aff_abils.dex, ch->aff_abils.con, ch->aff_abils.cha, ch->aff_abils.will ); fprintf( fp, "Conditions " ); for ( i = 0; i < MAX_COND; i++ ) fprintf( fp, "%d%s", GET_COND(ch, i), (i != MAX_COND-1 ? ", " : "\n") ); fprintf( fp, "Addictions " ); for ( i = 0; i < MAX_COND; i++ ) fprintf( fp, "%d%s", GET_ADDICT(ch, i), (i != MAX_COND-1 ? ", " : "\n") ); for ( sn = 0; sn < MAX_SKILLS; sn++ ) { if ( skill_name( sn ) && strcmp( skill_name( sn ), "!UNUSED!" ) && GET_SKILL(ch, sn) > 0 ) { fprintf( fp, "Skill %d '%s'\n", GET_SKILL(ch, sn), skill_name( sn ) ); } } } for ( paf = ch->affected; paf; paf = paf->next ) { fprintf( fp, "Afft %18s~ %3d %3d %3d %lld\n", skill_name( paf->type ), paf->duration, paf->modifier, paf->location, paf->bitvector ); } for ( paf = ch->affected2; paf; paf = paf->next ) { fprintf( fp, "Afft2 %18s~ %3d %3d %3d %lld\n", skill_name( paf->type ), paf->duration, paf->modifier, paf->location, paf->bitvector ); } fprintf( fp, "End\n\n" ); return; }
void perform_psidrain(struct creature *ch, struct creature *vict) { int find_distance(struct room_data *tmp, struct room_data *location); int dist, drain, prob, percent; if (!can_psidrain(ch, vict, &dist, true)) return; if (AFF3_FLAGGED(vict, AFF3_PSISHIELD) && creature_distrusts(vict, ch)) { prob = CHECK_SKILL(ch, SKILL_PSIDRAIN) + GET_INT(ch); prob += skill_bonus(ch, SKILL_PSIDRAIN); percent = skill_bonus(vict, SPELL_PSISHIELD); percent += number(1, 120); if (mag_savingthrow(vict, GET_LEVEL(ch), SAVING_PSI)) percent *= 2; if (GET_INT(vict) > GET_INT(ch)) percent += (GET_INT(vict) - GET_INT(ch)) * 8; if (percent >= prob) { act("Your attack is deflected by $N's psishield!", false, ch, NULL, vict, TO_CHAR); act("$n's psychic attack is deflected by your psishield!", false, ch, NULL, vict, TO_VICT); act("$n staggers under an unseen force.", true, ch, NULL, vict, TO_NOTVICT); return; } } if (GET_MANA(vict) <= 0) { act("$E is completely drained of psychic energy.", true, ch, NULL, vict, TO_CHAR); return; } drain = dice(GET_LEVEL(ch), GET_INT(ch) + GET_REMORT_GEN(ch)) + CHECK_SKILL(ch, SKILL_PSIDRAIN); if (dist > 0) drain /= dist + 1; drain /= 4; drain = MAX(0, MIN(GET_MANA(vict), drain)); prob = CHECK_SKILL(ch, SKILL_PSIDRAIN) + GET_INT(ch) + (AFF3_FLAGGED(vict, AFF3_PSISHIELD) ? -20 : 0); if (is_fighting(vict)) prob += 15; if (dist > 0) prob -= dist * 3; act("$n strains against an unseen force.", false, ch, NULL, vict, TO_ROOM); // // failure // if (number(0, 121) > prob) { send_to_char(ch, "You are unable to create the drainage link!\r\n"); WAIT_STATE(ch, 2 RL_SEC); if (IS_NPC(vict) && !is_fighting(vict)) { if (ch->in_room == vict->in_room) { add_combat(vict, ch, false); add_combat(ch, vict, true); } else { remember(vict, ch); if (NPC2_FLAGGED(vict, NPC2_HUNT)) start_hunting(vict, ch); } } } // // success // else { act("A torrent of psychic energy is ripped out of $N's mind!", false, ch, NULL, vict, TO_CHAR); if (ch->in_room != vict->in_room && GET_LEVEL(vict) + number(0, CHECK_SKILL(vict, SKILL_PSIDRAIN)) > GET_LEVEL(ch)) act("Your psychic energy is ripped from you from afar!", false, ch, NULL, vict, TO_VICT); else act("Your psychic energy is ripped from you by $n!", false, ch, NULL, vict, TO_VICT); GET_MANA(vict) -= drain; GET_MANA(ch) = MIN(GET_MAX_MANA(ch), GET_MANA(ch) + drain); GET_MOVE(ch) -= 20; WAIT_STATE(vict, 1 RL_SEC); WAIT_STATE(ch, 5 RL_SEC); gain_skill_prof(ch, SKILL_PSIDRAIN); if (IS_NPC(vict) && !(is_fighting(vict))) { if (ch->in_room == vict->in_room) { remember(vict, ch); if (NPC2_FLAGGED(vict, NPC2_HUNT)) start_hunting(vict, ch); add_combat(vict, ch, false); add_combat(ch, vict, true); } } } }
bool psionic_mob_fight(struct creature *ch, struct creature *precious_vict) { struct creature *vict = NULL; if (!is_fighting(ch)) return false; // pick an enemy if (!(vict = choose_opponent(ch, precious_vict))) return false; int aggression = calculate_mob_aggression(ch, vict); // Psions can't really do anything when there's a psishield in place if (AFF3_FLAGGED(vict, AFF3_PSISHIELD) && can_cast_spell(ch, SPELL_PSIONIC_SHATTER)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSIONIC_SHATTER); return true; } // Prioritize healing with aggression if (GET_HIT(ch) < (GET_MAX_HIT(ch) * MIN(20, MAX(80, aggression)) / 100) && can_cast_spell(ch, SPELL_WOUND_CLOSURE)) { cast_spell(ch, ch, NULL, NULL, SPELL_WOUND_CLOSURE); return true; } if (aggression > 75) { // extremely aggressive - just attack hard if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return true; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return true; } } if (aggression > 50) { // somewhat aggressive - balance attacking with crippling if (GET_MANA(ch) < GET_MAX_MANA(ch) / 2 && can_cast_spell(ch, SKILL_PSIDRAIN) && can_psidrain(ch, vict, NULL, false)) { perform_psidrain(ch, vict); return true; } else if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH) && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH); return true; } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM) && can_cast_spell(ch, SPELL_MOTOR_SPASM)) { cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM); return true; } else if (!affected_by_spell(ch, SPELL_ADRENALINE) && can_cast_spell(ch, SPELL_ADRENALINE)) { cast_spell(ch, ch, NULL, NULL, SPELL_ADRENALINE); return true; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return true; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return true; } } if (aggression > 25) { // not very aggressive - play more defensively if (IS_PSIONIC(vict) && !affected_by_spell(ch, SPELL_PSYCHIC_RESISTANCE) && can_cast_spell(ch, SPELL_PSYCHIC_RESISTANCE)) { cast_spell(ch, ch, NULL, NULL, SPELL_PSYCHIC_RESISTANCE); return true; } else if (!IS_CONFUSED(vict) && can_cast_spell(ch, SPELL_CONFUSION) && (IS_MAGE(vict) || IS_PSIONIC(vict) || IS_CLERIC(vict) || IS_KNIGHT(vict) || IS_PHYSIC(vict))) { cast_spell(ch, vict, NULL, NULL, SPELL_CONFUSION); return true; } else if (GET_MOVE(ch) < GET_MAX_MOVE(ch) / 4 && can_cast_spell(ch, SPELL_ENDURANCE)) { cast_spell(ch, ch, NULL, NULL, SPELL_ENDURANCE); return true; } else if (GET_MOVE(ch) < GET_MAX_MOVE(ch) / 4 && can_cast_spell(ch, SPELL_DERMAL_HARDENING)) { cast_spell(ch, ch, NULL, NULL, SPELL_DERMAL_HARDENING); return true; } else if (!AFF2_FLAGGED(ch, AFF2_VERTIGO) && can_cast_spell(ch, SPELL_VERTIGO)) { cast_spell(ch, vict, NULL, NULL, SPELL_VERTIGO); return true; } else if (!affected_by_spell(vict, SPELL_PSYCHIC_FEEDBACK) && can_cast_spell(ch, SPELL_PSYCHIC_FEEDBACK)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_FEEDBACK); return true; } else if (!affected_by_spell(vict, SPELL_WEAKNESS) && can_cast_spell(ch, SPELL_WEAKNESS)) { cast_spell(ch, vict, NULL, NULL, SPELL_WEAKNESS); return true; } else if (!affected_by_spell(vict, SPELL_CLUMSINESS) && can_cast_spell(ch, SPELL_CLUMSINESS)) { cast_spell(ch, vict, NULL, NULL, SPELL_CLUMSINESS); return true; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return true; } } if (aggression > 5) { // attempt to neutralize or get away if (GET_POSITION(vict) > POS_SLEEPING && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) { cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD); return true; } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) { cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL); return true; } else if (can_cast_spell(ch, SPELL_AMNESIA)) { cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA); return true; } else if (can_cast_spell(ch, SPELL_FEAR)) { cast_spell(ch, vict, NULL, NULL, SPELL_FEAR); return true; } } return false; }
int mag_points_char(struct spell_info_type *sinfo, struct char_data *caster, struct char_data *vict, int level) { int modifier = dice(sinfo->num_dice, sinfo->size_dice); if (sinfo->unaffect) modifier = -modifier; modifier = modBySpecialization(caster, sinfo, modifier); gain_exp(caster, modifier * 2); switch (sinfo->point_loc) { case APPLY_AGE: vict->player.time.birth += (SECS_PER_MUD_YEAR * modifier); break; case APPLY_STR: GET_VSTR(vict) += modifier; GET_STR(vict) = MIN(100, GET_VSTR(vict)); break; case APPLY_DEX: GET_VDEX(vict) += modifier; GET_DEX(vict) = MIN(100, GET_VDEX(vict)); break; case APPLY_INT: GET_VINT(vict) += modifier; GET_INT(vict) = MIN(100, GET_VINT(vict)); break; case APPLY_WIS: GET_VWIS(vict) += modifier; GET_WIS(vict) = MIN(100, GET_VWIS(vict)); break; case APPLY_CON: GET_VCON(vict) += modifier; GET_CON(vict) = MIN(100, GET_VCON(vict)); break; case APPLY_AGI: GET_VAGI(vict) += modifier; GET_AGI(vict) = MIN(100, GET_VAGI(vict)); break; case APPLY_MANA: GET_MANA(vict) += modifier; if (GET_MANA(vict) > GET_MAX_MANA(vict)) GET_MANA(vict) = GET_MAX_MANA(vict); break; case APPLY_HIT: GET_HIT(vict) += modifier; if (GET_HIT(vict) > GET_MAX_HIT(vict)) GET_HIT(vict) = GET_MAX_HIT(vict); break; case APPLY_MOVE: GET_MOVE(vict) += modifier; if (GET_MOVE(vict) > GET_MAX_MOVE(vict)) GET_MOVE(vict) = GET_MAX_MOVE(vict); break; case APPLY_HITROLL: GET_HITROLL(vict) += modifier; break; case APPLY_DAMROLL: GET_DAMROLL(vict) += modifier; break; case APPLY_SAVING_PARA: GET_SAVE(vict,SAVING_PARA) += modifier; break; case APPLY_SAVING_ROD: GET_SAVE(vict,SAVING_ROD) += modifier; break; case APPLY_SAVING_PETRI: GET_SAVE(vict,SAVING_PETRI) += modifier; break; case APPLY_SAVING_BREATH: GET_SAVE(vict,SAVING_BREATH) += modifier; break; case APPLY_SAVING_SPELL: GET_SAVE(vict,SAVING_SPELL) += modifier; break; case APPLY_MAX_HIT: GET_MAX_HIT(vict) += modifier; break; case APPLY_MAX_MANA: GET_MAX_MANA(vict) += modifier; break; case APPLY_MAX_MOVE: GET_MAX_MOVE(vict) += modifier; break; case APPLY_RES_DARK: GET_RESIST(vict, DAM_DARK) += modifier; break; case APPLY_RES_FIRE: GET_RESIST(vict, DAM_FIRE) += modifier; break; case APPLY_RES_COLD: GET_RESIST(vict, DAM_COLD) += modifier; break; case APPLY_RES_ACID: GET_RESIST(vict, DAM_ACID) += modifier; break; case APPLY_RES_POISON: GET_RESIST(vict, DAM_POISON) += modifier; break; case APPLY_RES_DISEASE: GET_RESIST(vict, DAM_DISEASE) += modifier; break; case APPLY_RES_CHARM: GET_RESIST(vict, DAM_CHARM) += modifier; break; case APPLY_RES_SLEEP: GET_RESIST(vict, DAM_SLEEP) += modifier; break; case APPLY_RES_SLASH: GET_RESIST(vict, DAM_SLASH) += modifier; break; case APPLY_RES_PIERCE: GET_RESIST(vict, DAM_PIERCE) += modifier; break; case APPLY_RES_BLUDGEON: GET_RESIST(vict, DAM_BLUDGEON) += modifier; break; case APPLY_RES_NWEAP: GET_RESIST(vict, DAM_NWEAP) += modifier; break; case APPLY_RES_MWEAP: GET_RESIST(vict, DAM_MWEAP) += modifier; break; case APPLY_RES_MAGIC: GET_RESIST(vict, DAM_MAGIC) += modifier; break; case APPLY_RES_ELECTRICITY: GET_RESIST(vict, DAM_ELECTRICITY) += modifier; break; } return 1; }
void suffer_activity(int pulse) { struct char_data *ch, *next_ch; char *desc; char dam_msg1[120] = "msg1 for suffer room not defined, report this to an imm!\r\n"; char dam_msg2[120] = "msg2 for suffer room not defined, report this to an imm!\r\n"; char dam_msg3[120] = "msg3 for suffer room not defined, report this to an imm!\r\n"; char dam_msg4[120] = "msg4 for suffer room not defined, report this to an imm!\r\n"; char death_char[120] = "You drift into coma and die."; char death_room[120] = "$n has drifted into coma and dies."; char suffer_msg[120] = "$n is suffering."; int percent_hp; int min_dam = 10, max_dam = 20, dam_amount; int hot = FALSE, cold = FALSE , dry = FALSE; for (ch = character_list; ch; ch = next_ch) { next_ch = ch->next; if (GET_LEVEL(ch) >= LVL_IMMORT) /* Lets not hurt our immortals */ continue; if (IS_NPC(ch)) continue; // I'm adding in a check to make outlaws "suffer" if in a peace room // Added by Sanji if( (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL) || IN_ARENA(ch) || IS_SET_AR(ROOM_FLAGS((ch)->in_room), ROOM_CLAN)) && (IS_SET_AR(PLR_FLAGS(ch), PLR_HUNTED) || IS_SET_AR(PLR_FLAGS(ch), PLR_THIEF))) { int to_room = 18001; // Samsera center // hurt the little cheater GET_HIT(ch) = MAX(1, GET_HIT(ch) - GET_MAX_HIT(ch)/8); GET_MANA(ch) = MAX(0, GET_MANA(ch) - GET_MAX_MANA(ch)/8); GET_MOVE(ch) = MAX(0, GET_MOVE(ch) - GET_MAX_MOVE(ch)/8); // where to send the victim? //do //{ // to_room = number( 0, top_of_world ); //} while (IS_SET_AR(world[to_room].room_flags, ROOM_PRIVATE) || // IS_SET_AR(world[to_room].room_flags, ROOM_DEATH) || // IS_SET_AR(world[to_room].room_flags, ROOM_PEACEFUL)); // Lets send out a message, more can be added later. // send_to_char("Naughty naughty. No hiding!\r\n", ch); // Time to move the victim char_from_room(ch); char_to_room(ch, real_room(to_room)); look_at_room(ch, 0); } hot = (ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOT)); cold = (ROOM_FLAGGED(IN_ROOM(ch), ROOM_COLD)); dry = (ROOM_FLAGGED(IN_ROOM(ch), ROOM_DRY)); if (!hot && !cold && !dry) continue; /* Getting ready to pull the damage amount out of the extra desc in the room */ if ((desc = find_exdesc("min_dam", world[ch->in_room].ex_description)) != NULL) min_dam = atoi(desc); else min_dam = 0; if ((desc = find_exdesc("max_dam", world[ch->in_room].ex_description)) != NULL) max_dam = atoi(desc); else max_dam = 25; if (max_dam < min_dam) { send_to_char("SYSERR: Max damage lower then Min damage. Report to an Immortal.\r\n", ch); return; } dam_amount = number(min_dam, max_dam); if ((desc = find_exdesc("suffer1", world[ch->in_room].ex_description)) != NULL) sprintf(dam_msg1, "%s", desc); if ((desc = find_exdesc("suffer2", world[ch->in_room].ex_description)) != NULL) sprintf(dam_msg2, "%s", desc); if ((desc = find_exdesc("suffer3", world[ch->in_room].ex_description)) != NULL) sprintf(dam_msg3, "%s", desc); if ((desc = find_exdesc("suffer4", world[ch->in_room].ex_description)) != NULL) sprintf(dam_msg4, "%s", desc); if ((desc = find_exdesc("death_char", world[ch->in_room].ex_description)) != NULL) sprintf(death_char, "%s", desc); if ((desc = find_exdesc("death_room", world[ch->in_room].ex_description)) != NULL) sprintf(death_room, "%s", desc); if ((desc = find_exdesc("suffer_msg", world[ch->in_room].ex_description)) != NULL) sprintf(suffer_msg, "%s", desc); if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_COLD) && IS_AFFECTED(ch, AFF_NO_COLD)) continue; else if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOT) && IS_AFFECTED(ch, AFF_NO_HOT)) continue; else if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOT) && IS_AFFECTED(ch, AFF_NO_DRY)) continue; // DUH! added a check for soak if (((ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOT) || ROOM_FLAGGED(IN_ROOM(ch), ROOM_DRY)) && (GET_COND(ch, THIRST) > 0))) GET_COND(ch, THIRST) = 0; if (dam_amount >= GET_HIT(ch)) dam_amount = GET_HIT(ch) + number(4, 7); else act(suffer_msg, FALSE, ch, 0, 0, TO_ROOM); GET_HIT(ch) -= dam_amount; percent_hp = (100 * GET_HIT(ch)) / GET_MAX_HIT(ch); // need a check here to see if the char is still in the room! if ((ROOM_FLAGGED(IN_ROOM(ch), ROOM_HOT)) || (ROOM_FLAGGED(IN_ROOM(ch), ROOM_COLD)) || (ROOM_FLAGGED(IN_ROOM(ch), ROOM_DRY))){ if (percent_hp > 75) send_to_char(dam_msg1, ch); else if (percent_hp > 50) send_to_char(dam_msg2, ch); else if (percent_hp > 30) send_to_char(dam_msg3, ch); else if (percent_hp >= 15) send_to_char(dam_msg4, ch); else if (percent_hp >= 1) { GET_HIT(ch) = number (-3, -5); send_to_char("You have passed out.\r\n", ch); act("$n has passed out and fallen to the ground.", FALSE, ch, 0, 0, TO_ROOM); update_pos(ch); } else { GET_HIT(ch) = number(-7, -10); act(death_char, FALSE, ch, 0, 0, TO_CHAR); act(death_room, FALSE, ch, 0, 0, TO_ROOM); update_pos(ch); GET_MANA(ch) = 1; die(ch, NULL, 0); } } } /* End of for loop */ }
void beat_points_update(int pulse) { CHAR_DATA *i, *next_char; int restore; if (!UPDATE_PC_ON_BEAT) return; // only for PC's for (i = character_list; i; i = next_char) { next_char = i->next; if (IS_NPC(i)) continue; if (IN_ROOM(i) == NOWHERE) { log("SYSERR: Pulse character in NOWHERE."); continue; } if (RENTABLE(i) <= time(NULL)) { RENTABLE(i) = 0; AGRESSOR(i) = 0; AGRO(i) = 0; i->agrobd = false; } if (AGRO(i) < time(NULL)) AGRO(i) = 0; beat_punish(i); // This line is used only to control all situations when someone is // dead (POS_DEAD). You can comment it to minimize heartbeat function // working time, if you're sure, that you control these situations // everywhere. To the time of this code revision I've fix some of them // and haven't seen any other. // if (GET_POS(i) == POS_DEAD) // die(i, NULL); if (GET_POS(i) < POS_STUNNED) continue; // Restore hitpoints restore = hit_gain(i); restore = interpolate(restore, pulse); if (AFF_FLAGGED(i, AFF_BANDAGE)) { AFFECT_DATA* aff; for(aff = i->affected; aff; aff = aff->next) { if (aff->type == SPELL_BANDAGE) { restore += MIN(GET_REAL_MAX_HIT(i) / 10, aff->modifier); break; } } } if (GET_HIT(i) < GET_REAL_MAX_HIT(i)) GET_HIT(i) = MIN(GET_HIT(i) + restore, GET_REAL_MAX_HIT(i)); // Проверка аффекта !исступление!. Поместил именно здесь, // но если кто найдет более подходящее место переносите =) //Gorrah: перенес в handler::affect_total //check_berserk(i); // Restore PC caster mem if (!IS_MANA_CASTER(i) && !MEMQUEUE_EMPTY(i)) { restore = mana_gain(i); restore = interpolate(restore, pulse); GET_MEM_COMPLETED(i) += restore; if (AFF_FLAGGED(i, AFF_RECALL_SPELLS)) handle_recall_spells(i); while (GET_MEM_COMPLETED(i) > GET_MEM_CURRENT(i) && !MEMQUEUE_EMPTY(i)) { int spellnum; spellnum = MemQ_learn(i); GET_SPELL_MEM(i, spellnum)++; GET_CASTER(i) += spell_info[spellnum].danger; } if (MEMQUEUE_EMPTY(i)) { if (GET_RELIGION(i) == RELIGION_MONO) { send_to_char ("Наконец ваши занятия окончены. Вы с улыбкой захлопнули свой часослов.\r\n", i); act("Окончив занятия, $n с улыбкой захлопнул$g часослов.", FALSE, i, 0, 0, TO_ROOM); } else { send_to_char ("Наконец ваши занятия окончены. Вы с улыбкой убрали свои резы.\r\n", i); act("Окончив занятия, $n с улыбкой убрал$g резы.", FALSE, i, 0, 0, TO_ROOM); } } } if (!IS_MANA_CASTER(i) && MEMQUEUE_EMPTY(i)) { GET_MEM_TOTAL(i) = 0; GET_MEM_COMPLETED(i) = 0; } // Гейн маны у волхвов if (IS_MANA_CASTER(i) && GET_MANA_STORED(i) < GET_MAX_MANA(i)) { GET_MANA_STORED(i) += mana_gain(i); if (GET_MANA_STORED(i) >= GET_MAX_MANA(i)) { GET_MANA_STORED(i) = GET_MAX_MANA(i); send_to_char("Ваша магическая энергия полностью восстановилась\r\n", i); } } if (IS_MANA_CASTER(i) && GET_MANA_STORED(i) > GET_MAX_MANA(i)) { GET_MANA_STORED(i) = GET_MAX_MANA(i); } // Restore moves restore = move_gain(i); restore = interpolate(restore, pulse); // GET_MOVE(i) = MIN(GET_MOVE(i) + restore, GET_REAL_MAX_MOVE(i)); //MZ.overflow_fix if (GET_MOVE(i) < GET_REAL_MAX_MOVE(i)) GET_MOVE(i) = MIN(GET_MOVE(i) + restore, GET_REAL_MAX_MOVE(i)); //-MZ.overflow_fix } }
void regen_update( void ) { CharData *i, *next_char; int hit, mana, move; int vivify_level; for( i = character_list; i; i = next_char ) { next_char = i->next; if(affected_by_spell(i, SKILL_EMACIATED) && (GET_COND(i, HUNGER) != 0 || IS_VAMPIRE(i)) && GET_COND(i, THIRST) != 0) { if(!affected_by_spell(i, SKILL_EMACIATED_MANA) && !affected_by_spell(i, SKILL_EMACIATED_HIT)) affect_from_char(i, SKILL_EMACIATED); else if(percentSuccess(4)) { affect_from_char(i, SKILL_EMACIATED_MANA); affect_from_char(i, SKILL_EMACIATED_HIT); } } // Dwarves sober up 3x faster than most races (unless they drink more...) if(IS_DWARF(i) && !number(0, 35)) gain_condition(i, DRUNK, -1); vivify_level = spell_level(i, SPELL_VIVIFY); affect_from_char(i, SPELL_VIVIFY); if(GET_POS(i) <= POS_MEDITATING) { add_affect(i, i, SPELL_VIVIFY, MIN(vivify_level + 1, 100), APPLY_NONE, 0, -1, 0, FALSE, FALSE, FALSE, FALSE); } if(GET_POS(i) >= POS_MORTALLYW) { hit = hit_gain(i); mana = mana_gain(i); move = move_gain(i); if(affected_by_spell(i, SPELL_VIVIFY)) { if(hit > 0) hit += spell_level(i, SPELL_VIVIFY) * GET_MAX_HIT(i)/600; if(mana > 0) mana += spell_level(i, SPELL_VIVIFY) * GET_MAX_MANA(i)/600; if(move > 0) move += spell_level(i, SPELL_VIVIFY) * GET_MAX_MOVE(i)/600; } // Regeneration is increased on pvp holidays. If you're incapactitated, you will // eventually recover. if(pvpHoliday(i)) { if (GET_POS(i) < POS_SLEEPING) hit = 20; else { hit = (hit > 0) ? hit *3 : 20; mana = (mana > 0) ? mana*2 : 40; move = (move > 0) ? move*2 : 40; } } // 72 seconds per tick... if(hit < 0 || GET_HIT(i) < GET_MAX_HIT(i)) { if(hit>0) GET_HIT(i) += hit/72 + (hit % 72 > number(0, 71)? 1:0); else GET_HIT(i) = MAX(GET_HIT(i) + hit/72 + (-hit % 72 > number(0, 71)?-1:0), -9); } else { int surplus = (GET_HIT(i) - GET_MAX_HIT(i)); GET_HIT(i) -= surplus / 72 + (surplus % 72 > number(0, 71)? 1:0); } if(mana>0) GET_MANA(i) = MAX(MIN(GET_MANA(i) + mana/72 + (mana % 72 > number(0, 71)?1:0), GET_MAX_MANA(i)), 0); else GET_MANA(i) = MIN(GET_MANA(i) + mana/72 + (-mana % 72 > number(0, 71)?-1:0), GET_MAX_MANA(i)); if(move>0) GET_MOVE(i) = MIN(GET_MOVE(i) + move/72 + (move % 72 > number(0, 71)?1:0), GET_MAX_MOVE(i)); else GET_MOVE(i) = MAX(MIN(GET_MOVE(i) + move/72 + (-move % 72 > number(0, 71)?-1:0), GET_MAX_MOVE(i)), 0); update_pos(i); } } }
void save_player_to_file(struct creature *ch, const char *path) { void expire_old_grievances(struct creature *); // Save vital statistics FILE *ouf; char *tmp_path; struct alias_data *cur_alias; int idx; int hit = GET_HIT(ch), mana = GET_MANA(ch), move = GET_MOVE(ch); tmp_path = tmp_sprintf("%s.tmp", path); ouf = fopen(tmp_path, "w"); if (!ouf) { fprintf(stderr, "Unable to open XML player file for save.[%s] (%s)\n", path, strerror(errno)); return; } struct aff_stash *aff_stash = stash_creature_affects(ch); expire_old_grievances(ch); fprintf(ouf, "<creature name=\"%s\" idnum=\"%ld\">\n", GET_NAME(ch), ch->char_specials.saved.idnum); fprintf(ouf, "<points hit=\"%d\" mana=\"%d\" move=\"%d\" maxhit=\"%d\" maxmana=\"%d\" maxmove=\"%d\"/>\n", ch->points.hit, ch->points.mana, ch->points.move, ch->points.max_hit, ch->points.max_mana, ch->points.max_move); fprintf(ouf, "<money gold=\"%" PRId64 "\" cash=\"%" PRId64 "\" xp=\"%d\"/>\n", ch->points.gold, ch->points.cash, ch->points.exp); fprintf(ouf, "<stats level=\"%d\" sex=\"%s\" race=\"%s\" height=\"%d\" weight=\"%f\" align=\"%d\"/>\n", GET_LEVEL(ch), genders[(int)GET_SEX(ch)], race_name_by_idnum(GET_RACE(ch)), GET_HEIGHT(ch), GET_WEIGHT(ch), GET_ALIGNMENT(ch)); fprintf(ouf, "<class name=\"%s\"", class_names[GET_CLASS(ch)]); if (GET_REMORT_CLASS(ch) != CLASS_UNDEFINED) fprintf(ouf, " remort=\"%s\"", class_names[GET_REMORT_CLASS(ch)]); if (GET_REMORT_GEN(ch) > 0) fprintf(ouf, " gen=\"%d\"", GET_REMORT_GEN(ch)); if (IS_CYBORG(ch)) { if (GET_OLD_CLASS(ch) != -1) fprintf(ouf, " subclass=\"%s\"", borg_subchar_class_names[GET_OLD_CLASS(ch)]); if (GET_TOT_DAM(ch)) fprintf(ouf, " total_dam=\"%d\"", GET_TOT_DAM(ch)); if (GET_BROKE(ch)) fprintf(ouf, " broken=\"%d\"", GET_BROKE(ch)); } if (GET_CLASS(ch) == CLASS_MAGE && GET_SKILL(ch, SPELL_MANA_SHIELD) > 0) { fprintf(ouf, " manash_low=\"%ld\" manash_pct=\"%ld\"", ch->player_specials->saved.mana_shield_low, ch->player_specials->saved.mana_shield_pct); } fprintf(ouf, "/>\n"); fprintf(ouf, "<time birth=\"%ld\" death=\"%ld\" played=\"%ld\" last=\"%ld\"/>\n", ch->player.time.birth, ch->player.time.death, ch->player.time.played, ch->player.time.logon); fprintf(ouf, "<carnage pkills=\"%d\" akills=\"%d\" mkills=\"%d\" deaths=\"%d\" reputation=\"%d\"", GET_PKILLS(ch), GET_ARENAKILLS(ch), GET_MOBKILLS(ch), GET_PC_DEATHS(ch), ch->player_specials->saved.reputation); fprintf(ouf, "/>\n"); fprintf(ouf, "<attr str=\"%d\" int=\"%d\" wis=\"%d\" dex=\"%d\" con=\"%d\" cha=\"%d\"/>\n", ch->real_abils.str, ch->real_abils.intel, ch->real_abils.wis, ch->real_abils.dex, ch->real_abils.con, ch->real_abils.cha); fprintf(ouf, "<condition hunger=\"%d\" thirst=\"%d\" drunk=\"%d\"/>\n", GET_COND(ch, FULL), GET_COND(ch, THIRST), GET_COND(ch, DRUNK)); fprintf(ouf, "<player wimpy=\"%d\" lp=\"%d\" clan=\"%d\"/>\n", GET_WIMP_LEV(ch), GET_LIFE_POINTS(ch), GET_CLAN(ch)); if (ch->desc) ch->player_specials->desc_mode = ch->desc->input_mode; if (ch->player_specials->rentcode == RENT_CREATING || ch->player_specials->rentcode == RENT_REMORTING) { fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" " "currency=\"%d\" state=\"%s\"/>\n", ch->player_specials->rentcode, ch->player_specials->rent_per_day, ch->player_specials->rent_currency, desc_modes[(int)ch->player_specials->desc_mode]); } else { fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" currency=\"%d\"/>\n", ch->player_specials->rentcode, ch->player_specials->rent_per_day, ch->player_specials->rent_currency); } fprintf(ouf, "<home town=\"%d\" homeroom=\"%d\" loadroom=\"%d\"/>\n", GET_HOME(ch), GET_HOMEROOM(ch), GET_LOADROOM(ch)); fprintf(ouf, "<quest"); if (GET_QUEST(ch)) fprintf(ouf, " current=\"%d\"", GET_QUEST(ch)); if (GET_LEVEL(ch) >= LVL_IMMORT) fprintf(ouf, " allowance=\"%d\"", GET_QUEST_ALLOWANCE(ch)); if (GET_IMMORT_QP(ch) != 0) fprintf(ouf, " points=\"%d\"", GET_IMMORT_QP(ch)); fprintf(ouf, "/>\n"); fprintf(ouf, "<bits flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\"/>\n", ch->char_specials.saved.act, ch->player_specials->saved.plr2_bits); if (PLR_FLAGGED(ch, PLR_FROZEN)) { fprintf(ouf, "<frozen thaw_time=\"%d\" freezer_id=\"%d\"/>\n", ch->player_specials->thaw_time, ch->player_specials->freezer_id); } fprintf(ouf, "<prefs flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" tongue=\"%s\"/>\n", ch->player_specials->saved.pref, ch->player_specials->saved.pref2, tongue_name(GET_TONGUE(ch))); fprintf(ouf, "<affects flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" flag3=\"%" PRIx32 "\"/>\n", ch->char_specials.saved.affected_by, ch->char_specials.saved.affected2_by, ch->char_specials.saved.affected3_by); for (idx = 0; idx < MAX_WEAPON_SPEC; idx++) { if (GET_WEAP_SPEC(ch, idx).level > 0) fprintf(ouf, "<weaponspec vnum=\"%d\" level=\"%d\"/>\n", GET_WEAP_SPEC(ch, idx).vnum, GET_WEAP_SPEC(ch, idx).level); } if (GET_TITLE(ch) && *GET_TITLE(ch)) { fprintf(ouf, "<title>%s</title>\n", xmlEncodeTmp(GET_TITLE(ch))); } if (GET_LEVEL(ch) >= 50) { fprintf(ouf, "<immort badge=\"%s\" qlog=\"%d\" invis=\"%d\"/>\n", xmlEncodeSpecialTmp(BADGE(ch)), GET_QLOG_LEVEL(ch), GET_INVIS_LVL(ch)); if (POOFIN(ch) && *POOFIN(ch)) fprintf(ouf, "<poofin>%s</poofin>\n", xmlEncodeTmp(POOFIN(ch))); if (POOFOUT(ch) && *POOFOUT(ch)) fprintf(ouf, "<poofout>%s</poofout>\n", xmlEncodeTmp(POOFOUT(ch))); } if (ch->player.description && *ch->player.description) { fprintf(ouf, "<description>%s</description>\n", xmlEncodeTmp(tmp_gsub(tmp_gsub(ch->player.description, "\r\n", "\n"), "\r", ""))); } for (cur_alias = ch->player_specials->aliases; cur_alias; cur_alias = cur_alias->next) fprintf(ouf, "<alias type=\"%d\" alias=\"%s\" replace=\"%s\"/>\n", cur_alias->type, xmlEncodeSpecialTmp(cur_alias->alias), xmlEncodeSpecialTmp(cur_alias->replacement)); for (struct affected_type *cur_aff = aff_stash->saved_affs; cur_aff; cur_aff = cur_aff->next) fprintf(ouf, "<affect type=\"%d\" duration=\"%d\" modifier=\"%d\" location=\"%d\" level=\"%d\" instant=\"%s\" affbits=\"%lx\" index=\"%d\" owner=\"%ld\"/>\n", cur_aff->type, cur_aff->duration, cur_aff->modifier, cur_aff->location, cur_aff->level, (cur_aff->is_instant) ? "yes" : "no", cur_aff->bitvector, cur_aff->aff_index, cur_aff->owner); if (!IS_IMMORT(ch)) { for (idx = 0; idx < MAX_SKILLS; idx++) if (ch->player_specials->saved.skills[idx] > 0) fprintf(ouf, "<skill name=\"%s\" level=\"%d\"/>\n", spell_to_str(idx), GET_SKILL(ch, idx)); write_tongue_xml(ch, ouf); for (GList * it = GET_RECENT_KILLS(ch); it; it = it->next) { struct kill_record *kill = it->data; fprintf(ouf, "<recentkill vnum=\"%d\" times=\"%d\"/>\n", kill->vnum, kill->times); } for (GList * it = GET_GRIEVANCES(ch); it; it = it->next) { struct grievance *grievance = it->data; fprintf(ouf, "<grievance time=\"%lu\" player=\"%d\" reputation=\"%d\" kind=\"%s\"/>\n", (long unsigned)grievance->time, grievance->player_id, grievance->rep, grievance_kind_descs[grievance->grievance]); } } if (IS_PC(ch) && ch->player_specials->tags) { GHashTableIter iter; char *key; g_hash_table_iter_init(&iter, ch->player_specials->tags); while (g_hash_table_iter_next(&iter, (gpointer *)&key, NULL)) { fprintf(ouf, "<tag tag=\"%s\"/>\n", key); } } fprintf(ouf, "</creature>\n"); fclose(ouf); // on success, move temp file on top of the old file rename(tmp_path, path); restore_creature_affects(ch, aff_stash); free(aff_stash); GET_HIT(ch) = MIN(GET_MAX_HIT(ch), hit); GET_MANA(ch) = MIN(GET_MAX_MANA(ch), mana); GET_MOVE(ch) = MIN(GET_MAX_MOVE(ch), move); }
void check_idling( CharData * ch ) { #define VOID_TIME 8 #define EXTRACT_TIME 32 void Crash_rentsave(CharData *ch, int cost); void Crash_cryosave(CharData *ch, int cost); /* ** CONJURED timer */ int i = 0; for(;i < 4;i++) { if( GET_CONJ_CNT(ch, i) > 0) { SET_CONJ_CNT(ch, i) -= 1; if(SET_CONJ_CNT(ch, i) == 0) switch(GET_CLASS(ch)) { case CLASS_RANGER: sendChar( ch, "The creatures of the wild will answer your call again.\r\n" ); break; case CLASS_NECROMANCER: sendChar(ch, "The dead will heed your summons once more.\r\n"); case CLASS_MAGIC_USER: switch(i) { case TIMER_GATE: sendChar(ch, "Demons will answer your summons again.\r\n"); break; case TIMER_MONSTER: sendChar(ch, "Monsters will answer your summons again.\r\n"); break; case TIMER_ELEMENTAL: sendChar(ch, "Elementals will answer your summons again.\r\n"); break; } break; default: sendChar( ch, "Conjured creatures will answer your summons again.\r\n" ); } } } /* ** HUNTED timer */ if( IS_SET_AR( PLR_FLAGS(ch), PLR_HUNTED ) && ch->desc && (--(ch)->player_specials->saved.phunt_countdown <= 0)) { sendChar( ch, "You are no longer hunted.\r\n" ); unset_hunted_player(ch); } /* ** THIEF timer */ if( IS_SET_AR(PLR_FLAGS(ch), PLR_THIEF) && ch->desc && (--(ch)->player_specials->saved.pthief_countdown <= 0)) { REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_THIEF); send_to_char("You are no longer a registered thief.\r\n", ch); (ch)->player_specials->saved.pthief_countdown = 0; } /* KILLER timer */ if (IS_SET_AR(PLR_FLAGS(ch), PLR_KILLER) && (--(ch)->player_specials->saved.pkill_countdown <= 0)) { REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_KILLER); send_to_char("You are no longer a registered killer.\r\n", ch); (ch)->player_specials->saved.pkill_countdown = 0; } /* JAILED timer */ if (IS_SET_AR(PLR_FLAGS(ch), PLR_JAILED) && (--(ch)->player_specials->saved.jail_timer <= 0)) { int jail_exit_room; REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_JAILED); if (PRF_FLAGGED(ch, PRF_GOLD_TEAM) && IN_ROOM(ch) == real_room(GOLD_TEAM_JAIL)) { jail_exit_room = real_room(GOLD_TEAM_START_ROOM); GET_HIT(ch) = GET_MAX_HIT(ch); GET_MANA(ch) = GET_MAX_MANA(ch); GET_MOVE(ch) = GET_MAX_MOVE(ch); char_from_room(ch); char_to_room(ch, jail_exit_room); look_at_room(ch, 0); } if (PRF_FLAGGED(ch, PRF_BLACK_TEAM) && IN_ROOM(ch) == real_room(BLACK_TEAM_JAIL)) { jail_exit_room = real_room(BLACK_TEAM_START_ROOM); GET_HIT(ch) = GET_MAX_HIT(ch); GET_MANA(ch) = GET_MAX_MANA(ch); GET_MOVE(ch) = GET_MAX_MOVE(ch); char_from_room(ch); char_to_room(ch, jail_exit_room); look_at_room(ch, 0); } if (PRF_FLAGGED(ch, PRF_ROGUE_TEAM) && IN_ROOM(ch) == real_room(ROGUE_TEAM_JAIL)) { jail_exit_room = real_room(ROGUE_TEAM_START_ROOM); GET_HIT(ch) = GET_MAX_HIT(ch); GET_MANA(ch) = GET_MAX_MANA(ch); GET_MOVE(ch) = GET_MAX_MOVE(ch); char_from_room(ch); char_to_room(ch, jail_exit_room); look_at_room(ch, 0); } sendChar(ch, "Your imprisonement is over.\r\n"); // if (PRF_FLAGGED(ch, PRF_GOLD_TEAM)) // jail_exit_room = IN_ROOM(ch); // else if (PRF_FLAGGED(ch, PRF_BLACK_TEAM)) // jail_exit_room = IN_ROOM(ch); // else if (PRF_FLAGGED(ch, PRF_ROGUE_TEAM)) // jail_exit_room = IN_ROOM(ch); // else // jail_exit_room = getStartRoom(ch); // char_to_room(ch, jail_exit_room); // look_at_room(ch, 0); } /* ** If your hunted there is NO escape. */ if(( ++(ch->char_specials.timer) > VOID_TIME ) && !IS_SET_AR(PLR_FLAGS(ch), PLR_HUNTED)) { if (GET_WAS_IN(ch) == NOWHERE && ch->in_room != NOWHERE) { GET_WAS_IN(ch) = ch->in_room; end_fight(ch); act("$n disappears into the void.", TRUE, ch, 0, 0, TO_ROOM); send_to_char("You have been idle, and are pulled into a void.\r\n", ch); save_char(ch, NOWHERE); Crash_crashsave(ch); GET_WAS_IN(ch) = ch->in_room; char_from_room(ch); char_to_room(ch, 1); } //else if (ch->char_specials.timer > EXTRACT_TIME) //{ //if (ch->in_room != NOWHERE) //char_from_room(ch); //char_to_room(ch, 1); //if (ch->desc) //SET_DCPENDING(ch->desc); //ch->desc = NULL; //Crash_idlesave(ch); /* apparently causing problems? */ //crashRentSave(ch, -1); //mudlog( NRM, LVL_LRGOD, TRUE, "%s force-rented and extracted (idle).", GET_NAME(ch)); //extract_char(ch); //} } #undef VOID_TIME #undef EXTRACT_TIME }
/* * 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 {
void aff_apply_modify(struct char_data *ch, byte loc, sbyte mod, char *msg) { switch (loc) { case APPLY_NONE: break; case APPLY_STR: GET_STR(ch) += mod; break; case APPLY_DEX: GET_DEX(ch) += mod; break; case APPLY_INT: GET_INT(ch) += mod; break; case APPLY_WIS: GET_WIS(ch) += mod; break; case APPLY_CON: GET_CON(ch) += mod; break; case APPLY_CHA: GET_CHA(ch) += mod; break; case APPLY_AGE: ch->player.time.birth -= (mod * SECS_PER_MUD_YEAR); break; case APPLY_CHAR_WEIGHT: GET_WEIGHT(ch) += mod; break; case APPLY_CHAR_HEIGHT: GET_HEIGHT(ch) += mod; break; case APPLY_MANA: GET_MAX_MANA(ch) += mod; break; case APPLY_HIT: GET_MAX_HIT(ch) += mod; break; case APPLY_MOVE: GET_MAX_MOVE(ch) += mod; break; case APPLY_AC: GET_AC(ch) += mod; break; case APPLY_HITROLL: GET_HITROLL(ch) += mod; break; case APPLY_DAMROLL: GET_DAMROLL(ch) += mod; break; case APPLY_SAVING_PARA: GET_SAVE(ch, SAVING_PARA) += mod; break; case APPLY_SAVING_ROD: GET_SAVE(ch, SAVING_ROD) += mod; break; case APPLY_SAVING_PETRI: GET_SAVE(ch, SAVING_PETRI) += mod; break; case APPLY_SAVING_BREATH: GET_SAVE(ch, SAVING_BREATH) += mod; break; case APPLY_SAVING_SPELL: GET_SAVE(ch, SAVING_SPELL) += mod; break; default: log("SYSERR: Unknown apply adjust %d attempt (%s, affect_modify).", loc, __FILE__); break; } /* switch */ }
void perform_smoke(struct creature *ch, int type) { const char *to_vict = NULL; struct affected_type af; int hp_mod = 0, mana_mod = 0, move_mod = 0, spell = 0; uint8_t lev = 0; int accum_dur = 0, accum_affect = 0; init_affect(&af); af.type = SMOKE_EFFECTS; af.level = 30; af.owner = GET_IDNUM(ch); switch (type) { case SMOKE_DIRTWEED: to_vict = "Your head hurts."; af.duration = 3; af.modifier = -2; af.location = APPLY_INT; af.bitvector = AFF_CONFUSION; af.aff_index = 1; accum_dur = 1; accum_affect = 1; move_mod = -number(3, 10); mana_mod = -number(1, 2); break; case SMOKE_DESERTWEED: af.location = APPLY_MOVE; af.duration = 4; af.modifier = 10; mana_mod = dice(1, 4); move_mod = dice(3, 4); break; case SMOKE_INDICA: to_vict = "Your mind is elevated to another plane."; af.location = APPLY_WIS; af.duration = 5; af.modifier = number(1, 2); mana_mod = dice(6, 4); move_mod = -number(1, 3); break; case SMOKE_UNHOLY_REEFER: af.location = APPLY_WIS; af.duration = 5; af.modifier = number(0, 2); mana_mod = number(1, 4); move_mod = -number(1, 3); spell = SPELL_ESSENCE_OF_EVIL; lev = 20; break; case SMOKE_MARIJUANA: to_vict = "You feel stoned."; af.location = APPLY_INT; af.duration = 3; af.modifier = -1; mana_mod = dice(4, 4); break; case SMOKE_TOBACCO: af.location = APPLY_MOVE; af.duration = 3; af.modifier = -number(10, 20); accum_dur = 1; mana_mod = dice(3, 3); break; case SMOKE_HEMLOCK: to_vict = "The smoke burns your lungs!"; af.location = APPLY_HIT; af.duration = number(3, 6); af.modifier = -number(30, 60); accum_affect = 1; hp_mod = -number(10, 16); mana_mod = -10; move_mod = -10; spell = SPELL_POISON; lev = LVL_AMBASSADOR; break; case SMOKE_PEYOTE: to_vict = "You feel a strange sensation."; spell = SPELL_ASTRAL_SPELL; lev = LVL_GRIMP; af.location = APPLY_MANA; af.modifier = number(10, 20); af.duration = number(1, 3); move_mod = number(6, 12); break; case SMOKE_HOMEGROWN: to_vict = "There's no place like home..."; spell = SPELL_WORD_OF_RECALL; lev = number(30, 60); mana_mod = number(20, 40); move_mod = number(2, 10); break; default: af.type = 0; break; } if (to_vict) act(to_vict, false, ch, NULL, NULL, TO_CHAR); GET_HIT(ch) = MIN(MAX(GET_HIT(ch) + hp_mod, 0), GET_MAX_HIT(ch)); GET_MANA(ch) = MIN(MAX(GET_MANA(ch) + mana_mod, 0), GET_MAX_MANA(ch)); GET_MOVE(ch) = MIN(MAX(GET_MOVE(ch) + move_mod, 0), GET_MAX_MOVE(ch)); if (af.type && (!affected_by_spell(ch, af.type) || accum_affect || accum_dur)) affect_join(ch, &af, accum_dur, true, accum_affect, true); if (spell && lev) call_magic(ch, ch, NULL, NULL, spell, (int)lev, CAST_CHEM); WAIT_STATE(ch, 6); }
/* 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); } } }
/* Some initializations for characters, including initial skills If mode == 0, then act as though the character was entering the game for the first time. Otherwise, act as though the character is being set to that level. */ void do_start(struct creature *ch, int mode) { void advance_level(struct creature *ch, int8_t keep_internal); int8_t new_player = 0; int i; struct obj_data *implant_save[NUM_WEARS]; struct obj_data *tattoo_save[NUM_WEARS]; // remove implant affects for (i = 0; i < NUM_WEARS; i++) { if (GET_IMPLANT(ch, i)) implant_save[i] = raw_unequip_char(ch, i, EQUIP_IMPLANT); else implant_save[i] = NULL; if (GET_TATTOO(ch, i)) tattoo_save[i] = raw_unequip_char(ch, i, EQUIP_TATTOO); else tattoo_save[i] = NULL; } if (GET_EXP(ch) == 0 && !IS_REMORT(ch) && !IS_VAMPIRE(ch)) new_player = true; GET_LEVEL(ch) = 1; GET_EXP(ch) = 1; if (mode) roll_real_abils(ch); for (i = 1; i <= MAX_SKILLS; i++) SET_SKILL(ch, i, 0); if (IS_VAMPIRE(ch)) GET_LIFE_POINTS(ch) = 1; else GET_LIFE_POINTS(ch) = 3 * (GET_WIS(ch) + GET_CON(ch)) / 40; ch->points.max_hit = 20; ch->points.max_mana = 100; ch->points.max_move = 82; if (IS_TABAXI(ch)) { SET_SKILL(ch, SKILL_CLAW, LEARNED(ch)); SET_SKILL(ch, SKILL_BITE, LEARNED(ch)); } if (IS_ELF(ch)) { SET_SKILL(ch, SKILL_ARCHERY, LEARNED(ch)); } switch (GET_CLASS(ch)) { case CLASS_MAGIC_USER: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_CLERIC: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_THIEF: SET_SKILL(ch, SKILL_PUNCH, 15); SET_SKILL(ch, SKILL_SNEAK, 10); SET_SKILL(ch, SKILL_HIDE, 5); SET_SKILL(ch, SKILL_STEAL, 15); break; case CLASS_WARRIOR: SET_SKILL(ch, SKILL_PUNCH, 20); break; case CLASS_BARB: SET_SKILL(ch, SKILL_PUNCH, 15); break; case CLASS_PSIONIC: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_PHYSIC: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_CYBORG: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_KNIGHT: SET_SKILL(ch, SKILL_PUNCH, 20); break; case CLASS_RANGER: SET_SKILL(ch, SKILL_PUNCH, 15); GET_MAX_MOVE(ch) += dice(4, 9); break; case CLASS_MONK: SET_SKILL(ch, SKILL_PUNCH, 20); break; case CLASS_MERCENARY: SET_SKILL(ch, SKILL_PUNCH, 20); case CLASS_BARD: SET_SKILL(ch, SKILL_PUNCH, 25); SET_SKILL(ch, SKILL_ARCHERY, 25); break; } if (new_player) { if (PAST_CLASS(GET_CLASS(ch))) { deposit_past_bank(ch->desc->account, 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch)); ch->points.gold = 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch); } else if (FUTURE_CLASS(GET_CLASS(ch))) { deposit_future_bank(ch->desc->account, 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch)); ch->points.cash = 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch); } // New players do not start with the gown at this point // This has been left in for reference for generic newbie starting gear for the future. // New players start with a hospital gown and items most dear to them /* struct obj_data *gown = read_object(33800); if (gown != NULL) { equip_char(ch, gown, WEAR_ABOUT, EQUIP_WORN); } */ // Good clerics start with a holy symbol on neck if ((GET_CLASS(ch) == CLASS_CLERIC) && IS_GOOD(ch)) { struct obj_data *talisman = read_object(1280); if (talisman != NULL) { equip_char(ch, talisman, WEAR_NECK_1, EQUIP_WORN); } } // Evil clerics start with a holy symbol on hold if ((GET_CLASS(ch) == CLASS_CLERIC) && IS_EVIL(ch)) { struct obj_data *symbol = read_object(1260); if (symbol != NULL) { equip_char(ch, symbol, WEAR_HOLD, EQUIP_WORN); } } // Good knights start with a holy symbol on finger if ((GET_CLASS(ch) == CLASS_KNIGHT) && IS_GOOD(ch)) { struct obj_data *ring = read_object(1287); if (ring != NULL) { equip_char(ch, ring, WEAR_FINGER_L, EQUIP_WORN); } } // Evil knights start with a holy symbol on neck if ((GET_CLASS(ch) == CLASS_KNIGHT) && IS_EVIL(ch)) { struct obj_data *pendant = read_object(1270); if (pendant != NULL) { equip_char(ch, pendant, WEAR_NECK_1, EQUIP_WORN); } } // Bards start with a percussion instrument held, and stringed in inventory if (GET_CLASS(ch) == CLASS_BARD) { struct obj_data *lute = read_object(3218); if (lute != NULL) { obj_to_char(lute, ch); } } set_title(ch, "the complete newbie"); } advance_level(ch, 0); GET_MAX_MOVE(ch) += GET_CON(ch); GET_HIT(ch) = GET_MAX_HIT(ch); GET_MANA(ch) = GET_MAX_MANA(ch); GET_MOVE(ch) = GET_MAX_MOVE(ch); GET_COND(ch, THIRST) = 24; GET_COND(ch, FULL) = 24; GET_COND(ch, DRUNK) = 0; if (new_player) { ch->player.time.played = 0; ch->player.time.logon = time(NULL); } for (i = 0; i < NUM_WEARS; i++) { if (implant_save[i]) equip_char(ch, implant_save[i], i, EQUIP_IMPLANT); if (tattoo_save[i]) equip_char(ch, tattoo_save[i], i, EQUIP_TATTOO); } }