/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Player skills module * ****************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <time.h> #include "mud.h" char *const spell_flag[] = { "water", "earth", "air", "astral", "area", "distant", "reverse", "noself", "_unused2_", "accumulative", "recastable", "noscribe", "nobrew", "group", "object", "character", "secretskill", "pksensitive", "stoponfail", "nofight", "nodispel", "deq", "noapplystack", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" }; char *const spell_saves[] = { "none", "poison_death", "wands", "para_petri", "breath", "spell_staff" }; char *const spell_save_effect[] = { "none", "negate", "eightdam", "quarterdam", "halfdam", "3qtrdam", "reflect", "absorb" }; char *const spell_damage[] = { "none", "fire", "water", "earth", "energy", "air", "holy", "unholy", "undead" }; char *const spell_action[] = { "none", "create", "destroy", "resist", "suscept", "divinate", "obscure", "change" }; char *const spell_power[] = { "none", "minor", "greater", "major" }; char *const spell_class[] = { "none", "lunar", "solar", "travel", "summon", "life", "death", "illusion" }; char *const target_type[] = { "ignore", "offensive", "defensive", "self", "objinv", "objroom" }; void show_char_to_char(CHAR_DATA * list, CHAR_DATA * ch); void show_list_to_char(OBJ_DATA * list, CHAR_DATA * ch, bool fShort, bool fShowN, const int iDefaultAction); int ris_save(CHAR_DATA * ch, int chance, int ris); bool check_illegal_psteal(CHAR_DATA * ch, CHAR_DATA * victim); /* from magic.c */ void failed_casting(struct skill_type *skill, CHAR_DATA * ch, CHAR_DATA * victim, OBJ_DATA * obj); /* * Dummy function */ void skill_notfound(CHAR_DATA * ch, char *argument) { send_to_char("Huh?\n\r", ch); return; } int get_ssave(char *name) { int x; for (x = 0; x < sizeof(spell_saves) / sizeof(spell_saves[0]); x++) if (!str_cmp(name, spell_saves[x])) return x; return -1; } int get_starget(char *name) { int x; for (x = 0; x < sizeof(target_type) / sizeof(target_type[0]); x++) if (!str_cmp(name, target_type[x])) return x; return -1; } int get_sflag(char *name) { int x; for (x = 0; x < sizeof(spell_flag) / sizeof(spell_flag[0]); x++) if (!str_cmp(name, spell_flag[x])) return x; return -1; } int get_sdamage(char *name) { int x; for (x = 0; x < sizeof(spell_damage) / sizeof(spell_damage[0]); x++) if (!str_cmp(name, spell_damage[x])) return x; return -1; } int get_saction(char *name) { int x; for (x = 0; x < sizeof(spell_action) / sizeof(spell_action[0]); x++) if (!str_cmp(name, spell_action[x])) return x; return -1; } int get_ssave_effect(char *name) { int x; for (x = 0; x < sizeof(spell_save_effect) / sizeof(spell_save_effect[0]); x++) if (!str_cmp(name, spell_save_effect[x])) return x; return -1; } int get_spower(char *name) { int x; for (x = 0; x < sizeof(spell_power) / sizeof(spell_power[0]); x++) if (!str_cmp(name, spell_power[x])) return x; return -1; } int get_sclass(char *name) { int x; for (x = 0; x < sizeof(spell_class) / sizeof(spell_class[0]); x++) if (!str_cmp(name, spell_class[x])) return x; return -1; } bool is_legal_kill(CHAR_DATA * ch, CHAR_DATA * vch) { if (IS_NPC(ch) || IS_NPC(vch)) return TRUE; if (ch->pcdata->clan && vch->pcdata->clan && ch->pcdata->clan == vch->pcdata->clan) return FALSE; if (is_safe(ch, vch)) return FALSE; return TRUE; } extern char *target_name; /* from magic.c */ int check_twohand_shield(CHAR_DATA *ch) { OBJ_DATA *shield; if ((shield = get_eq_char(ch, WEAR_SHIELD)) && IS_OBJ_STAT(shield, ITEM_TWOHANDED)) { send_to_char("You cannot do that while wearing a two-handed shield.\n\r", ch); return FALSE; } else return TRUE; } /* * Perform a binary search on a section of the skill table * Each different section of the skill table is sorted alphabetically * Only match skills player knows -Thoric */ bool check_skill(CHAR_DATA * ch, char *command, char *argument) { int sn; int first = gsn_first_skill; int top = gsn_first_weapon - 1; int mana, blood; struct timeval time_used; CHAR_DATA *starget; sh_int begmod = 0; // Used to penalize beginners on the to hit on skills /* bsearch for the skill */ for (;;) { sn = (first + top) >> 1; if (LOWER(command[0]) == LOWER(skill_table[sn]->name[0]) && !str_prefix(command, skill_table[sn]->name) && (skill_table[sn]->skill_fun || skill_table[sn]->spell_fun != spell_null) && (can_use_skill(ch, 0, sn))) break; if (first >= top) return FALSE; if (strcmp(command, skill_table[sn]->name) < 1) top = sn - 1; else first = sn + 1; } if (!check_pos(ch, skill_table[sn]->minimum_position)) return TRUE; if (IS_NPC(ch) && (IS_AFFECTED(ch, AFF_CHARM) || IS_AFFECTED(ch, AFF_POSSESS))) { send_to_char("For some reason, you seem unable to perform that...\n\r", ch); act(AT_GREY, "$n wanders around aimlessly.", ch, NULL, NULL, TO_ROOM); return TRUE; } /* check if mana is required */ if (skill_table[sn]->min_mana) { mana = IS_NPC(ch) ? 0 : skill_table[sn]->min_mana; blood = UMAX(1, (mana + 4) / 8); /* NPCs don't have PCDatas. -- Altrag */ if (IS_VAMPIRE(ch)) { if (ch->pcdata->condition[COND_BLOODTHIRST] < blood) { send_to_char("You don't have enough blood power.\n\r", ch); return TRUE; } } else if (!IS_NPC(ch) && ch->mana < mana) { send_to_char("You don't have enough mana.\n\r", ch); return TRUE; } } else { mana = 0; blood = 0; } /* * Is this a real do-fun, or a really a spell? */ if (!skill_table[sn]->skill_fun) { ch_ret retcode = rNONE; void *vo = NULL; CHAR_DATA *victim = NULL; OBJ_DATA *obj = NULL; int suc; target_name = ""; switch (skill_table[sn]->target) { default: bug("Check_skill: bad target for sn %d.", sn); send_to_char("Something went wrong...\n\r", ch); return TRUE; case TAR_IGNORE: vo = NULL; starget = NULL; if (argument[0] == '\0') { if ((victim = who_fighting(ch)) != NULL) target_name = victim->name; } else target_name = argument; break; case TAR_CHAR_OFFENSIVE: if (argument[0] == '\0' && (victim = who_fighting(ch)) == NULL) { ch_printf(ch, "Confusion overcomes you as your '%s' has no target.\n\r", skill_table[sn]->name); return TRUE; } else if (argument[0] != '\0' && (victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return TRUE; } if (is_safe(ch, victim)) return TRUE; if (ch == victim && SPELL_FLAG(skill_table[sn], SF_NOSELF)) { send_to_char("You can't target yourself!\n\r", ch); return TRUE; } if (!IS_NPC(ch)) { if (IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim) { send_to_char("You can't do that on your own follower.\n\r", ch); return TRUE; } } check_illegal_pk(ch, victim); vo = (void *) victim; starget = victim; break; case TAR_CHAR_DEFENSIVE: if (argument[0] != '\0' && (victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return TRUE; } if (!victim) victim = ch; if (ch == victim && SPELL_FLAG(skill_table[sn], SF_NOSELF)) { send_to_char("You can't target yourself!\n\r", ch); return TRUE; } vo = (void *) victim; starget = victim; break; case TAR_CHAR_SELF: vo = (void *) ch; starget = ch; break; case TAR_OBJ_INV: if ((obj = get_obj_carry(ch, argument)) == NULL) { send_to_char("You can't find that.\n\r", ch); return TRUE; } vo = (void *) obj; starget = NULL; break; case TAR_OBJ_ROOM: if ((obj = get_obj_here(ch, argument)) == NULL) { send_to_char("You are not in the room with that.\n\r", ch); return TRUE; } vo = (void *) obj; starget = NULL; break; } /* waitstate */ if (!ch->fighting) WAIT_STATE(ch, skill_table[sn]->beats*2); else ch->fight_timer = get_btimer(ch, sn, NULL); /* check for failure */ if (!IS_NPC(ch) && ch->pcdata->ranking[sn] <= 1) begmod = 30; if (!IS_NPC(ch) && ch->pcdata->ranking[sn] == 2) begmod = 15; if (!IS_NPC(ch) && ch->pcdata->ranking[sn] == 4) begmod = -15; suc = 1; if (IS_NPC(ch)) { if (number_percent() > 85) suc = 0; } else { if ((number_percent() + skill_table[sn]->difficulty * 5) > (90 + (ch->pcdata->learned[sn]*10))) suc = 0; } if (!suc) { failed_casting(skill_table[sn], ch, vo, obj); learn_from_failure(ch, sn, starget); if (mana) { if (IS_VAMPIRE(ch)) gain_condition(ch, COND_BLOODTHIRST, -blood / 2); else { ch->mana -= mana / 2; if (skill_table[sn]->type == SKILL_SKILL) gain_mana_per(ch, victim, mana/2); } } return TRUE; } if (mana) { if (IS_VAMPIRE(ch)) gain_condition(ch, COND_BLOODTHIRST, -blood); else { ch->mana -= mana; if (skill_table[sn]->type == SKILL_SKILL) gain_mana_per(ch, victim, mana/2); } } start_timer(&time_used); retcode = (*skill_table[sn]->spell_fun) (sn, ch->level, ch, vo); end_timer(&time_used); update_userec(&time_used, &skill_table[sn]->userec); if (retcode == rCHAR_DIED || retcode == rERROR) return TRUE; if (char_died(ch)) return TRUE; if (retcode == rSPELL_FAILED) { learn_from_failure(ch, sn, starget); retcode = rNONE; } else { learn_from_success(ch, sn, starget); } if (skill_table[sn]->target == TAR_CHAR_OFFENSIVE && victim != ch && !char_died(victim)) { CHAR_DATA *vch; CHAR_DATA *vch_next; for (vch = ch->in_room->first_person; vch; vch = vch_next) { vch_next = vch->next_in_room; if (victim == vch && !victim->fighting && victim->master != ch) { retcode = one_hit(victim, ch, TYPE_UNDEFINED, LM_BODY); break; } } } return TRUE; } //for flee, don't remove if(!ch->fighting && !IS_NPC(ch)) ch->fight_timer = 0; if(ch->fight_timer > 0) { displayFightTimer(ch); return TRUE; } if (mana) { if (IS_VAMPIRE(ch)) gain_condition(ch, COND_BLOODTHIRST, -blood); else { ch->mana -= mana; if (skill_table[sn]->type == SKILL_SKILL) gain_mana_per(ch, NULL, mana/2); } } ch->prev_cmd = ch->last_cmd; /* haus, for automapping */ ch->last_cmd = skill_table[sn]->skill_fun; start_timer(&time_used); (*skill_table[sn]->skill_fun) (ch, argument); end_timer(&time_used); update_userec(&time_used, &skill_table[sn]->userec); tail_chain(); return TRUE; } void do_skin(CHAR_DATA * ch, char *argument) { OBJ_DATA *korps; OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *skin; bool found; char *name; char buf[MSL]; found = FALSE; if (argument[0] == '\0') { send_to_char("Whose corpse do you wish to skin?\n\r", ch); return; } if ((corpse = get_obj_here(ch, argument)) == NULL) { send_to_char("You cannot find that here.\n\r", ch); return; } if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) { send_to_char("You have no weapon with which to perform this deed.\n\r", ch); return; } if (corpse->item_type != ITEM_CORPSE_PC) { send_to_char("You can only skin the bodies of player characters.\n\r", ch); return; } if (wielding_skill_weapon(ch, 0) != 7) { send_to_char("There is nothing you can do with this corpse.\n\r", ch); return; } if (get_obj_index(OBJ_VNUM_SKIN) == NULL) { bug("Vnum 23 (OBJ_VNUM_SKIN) not found for do_skin!", 0); return; } korps = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC), 0); skin = create_object(get_obj_index(OBJ_VNUM_SKIN), 0); name = IS_NPC(ch) ? korps->short_descr : corpse->short_descr; sprintf(buf, skin->short_descr, name); STRFREE(skin->short_descr); skin->short_descr = STRALLOC(buf); sprintf(buf, skin->description, name); STRFREE(skin->description); skin->description = STRALLOC(buf); act(AT_BLOOD, "$n strips the skin from $p.", ch, corpse, NULL, TO_ROOM); act(AT_BLOOD, "You strip the skin from $p.", ch, corpse, NULL, TO_CHAR); /* act( AT_MAGIC, "\nThe skinless corpse is dragged through the ground by a strange force...", ch, corpse, NULL, TO_CHAR); act( AT_MAGIC, "\nThe skinless corpse is dragged through the ground by a strange force...", ch, corpse, NULL, TO_ROOM); extract_obj( corpse ); */ obj_to_char(skin, ch); return; } /* * Lookup a skills information * High god command */ void do_slookup(CHAR_DATA * ch, char *argument) { char buf[MSL]; char arg[MIL]; int sn; int iRace; SKILLTYPE *skill = NULL; argument = one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Slookup what?\n\r", ch); return; } if (!str_cmp(arg, "all")) { for (sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++) pager_printf(ch, "Sn: %4d Slot: %4d Skill/spell: '%-20s' Damtype: %s\n\r", sn, skill_table[sn]->slot, skill_table[sn]->name, spell_damage[SPELL_DAMAGE(skill_table[sn])]); } else if (!str_cmp(arg, "mana")) { pager_printf(ch, " Sn Name Mana Tier Sphere Beats Group\n\r"); pager_printf(ch, "---------------------------------------------------------------------------\n\r"); for (sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++) { if (atoi(argument) >= 1 && atoi(argument) <= 4) { if (atoi(argument) == skill_table[sn]->masterydiff[0]) { pager_printf(ch, "%4d %-25s %-3d %d %d %-2d %d\n\r", sn, skill_table[sn]->name, skill_table[sn]->min_mana, skill_table[sn]->masterydiff[0], skill_table[sn]->stype, skill_table[sn]->beats, skill_table[sn]->group[0]); } } } return; } else if (!str_cmp(arg, "prototype")) { pager_printf(ch, " Sn Name Creator\n\r"); pager_printf(ch, "-------------------------------------------\n\r"); for (sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++) if (skill_table[sn]->prototype > 0) { pager_printf(ch, "%4d %-20s %-15s\n\r", sn, skill_table[sn]->name, skill_table[sn]->made_char); } } else if (!str_cmp(arg, "herbs")) { for (sn = 0; sn < top_herb && herb_table[sn] && herb_table[sn]->name; sn++) pager_printf(ch, "%d) %s\n\r", sn, herb_table[sn]->name); } else { SMAUG_AFF *aff; int cnt = 0; if (arg[0] == 'h' && is_number(arg + 1)) { sn = atoi(arg + 1); if (!IS_VALID_HERB(sn)) { send_to_char("Invalid herb.\n\r", ch); return; } skill = herb_table[sn]; } else if (is_number(arg)) { sn = atoi(arg); if ((skill = get_skilltype(sn)) == NULL) { send_to_char("Invalid sn.\n\r", ch); return; } sn %= 1000; } else if ((sn = skill_lookup(arg)) >= 0) skill = skill_table[sn]; else if ((sn = herb_lookup(arg)) >= 0) skill = herb_table[sn]; else { send_to_char("No such skill, spell, proficiency or tongue.\n\r", ch); return; } if (!skill) { send_to_char("Not created yet.\n\r", ch); return; } ch_printf(ch, "Sn: %4d Slot: %4d %s: '%-20s'\n\r", sn, skill->slot, skill_tname[skill->type], skill->name); if (skill->prototype) ch_printf(ch, "Prototype: %s ", (skill->prototype == 0) ? "No" : "Yes"); if (skill->made_char) ch_printf(ch, "Made By: %s ", skill->made_char); ch_printf(ch, "\n\r"); if (skill->info) ch_printf(ch, "DamType: %s ActType: %s ClassType: %s PowerType: %s\n\r", spell_damage[SPELL_DAMAGE(skill)], spell_action[SPELL_ACTION(skill)], spell_class[SPELL_CLASS(skill)], spell_power[SPELL_POWER(skill)]); if (skill->flags) { int x; strcpy(buf, "Flags:"); for (x = 0; x < 32; x++) if (SPELL_FLAG(skill, 1 << x)) { strcat(buf, " "); strcat(buf, spell_flag[x]); } strcat(buf, "\n\r"); send_to_char(buf, ch); } ch_printf(ch, "Saves: %s SaveEffect: %s\n\r", spell_saves[(int) skill->saves], spell_save_effect[SPELL_SAVE(skill)]); if (skill->difficulty != '\0') ch_printf(ch, "Difficulty: %d\n\r", (int) skill->difficulty); ch_printf(ch, "Tier %d TrainerNum %d Group %d Sphere %d", skill->masterydiff[0], skill->bookinfo[0], skill->group[0], skill->stype); if (skill->targetlimb > 0) ch_printf(ch, " Targetlimb %d\n\r", skill->targetlimb); else send_to_char("\n\r", ch); ch_printf(ch, "Type: %s Target: %s Minpos: %d Mana: %d Beats: %d Range: %d\n\r", skill_tname[skill->type], target_type[URANGE(TAR_IGNORE, skill->target, TAR_OBJ_ROOM)], skill->minimum_position, skill->min_mana, skill->beats, skill->range); ch_printf(ch, "Flags: %d Guild: %d Value: %d Info: %d Code: %s\n\r", skill->flags, skill->guild, skill->value, skill->info, skill->skill_fun ? skill_name(skill->skill_fun) : spell_name(skill->spell_fun)); ch_printf(ch, "Dammsg: %s\n\rWearoff: %s\n", skill->noun_damage, skill->msg_off ? skill->msg_off : "(none set)"); if (skill->dice && skill->dice[0] != '\0') ch_printf(ch, "Dice: %s\n\r", skill->dice); if (skill->teachers && skill->teachers[0] != '\0') ch_printf(ch, "Teachers: %s\n\r", skill->teachers); if (skill->components && skill->components[0] != '\0') ch_printf(ch, "Components: %s\n\r", skill->components); if (skill->participants) ch_printf(ch, "Participants: %d\n\r", (int) skill->participants); if (skill->userec.num_uses) send_timer(&skill->userec, ch); for (aff = skill->affects; aff; aff = aff->next) { if (aff == skill->affects) send_to_char("\n\r", ch); sprintf(buf, "Affect %d", ++cnt); if (aff->location) { strcat(buf, " modifies "); strcat(buf, a_types[aff->location % REVERSE_APPLY]); strcat(buf, " by '"); strcat(buf, aff->modifier); if (aff->bitvector != -1) strcat(buf, "' and"); else strcat(buf, "'"); } if (aff->bitvector != -1) { strcat(buf, " applies "); strcat(buf, a_flags[aff->bitvector]); } if (aff->duration[0] != '\0' && aff->duration[0] != '0') { strcat(buf, " for '"); strcat(buf, aff->duration); strcat(buf, "' rounds"); } if (aff->location >= REVERSE_APPLY) strcat(buf, " (affects caster only)"); strcat(buf, "\n\r"); send_to_char(buf, ch); if (!aff->next) send_to_char("\n\r", ch); } if (skill->hit_char && skill->hit_char[0] != '\0') ch_printf(ch, "Hitchar : %s\n\r", skill->hit_char); if (skill->hit_vict && skill->hit_vict[0] != '\0') ch_printf(ch, "Hitvict : %s\n\r", skill->hit_vict); if (skill->hit_room && skill->hit_room[0] != '\0') ch_printf(ch, "Hitroom : %s\n\r", skill->hit_room); if (skill->hit_dest && skill->hit_dest[0] != '\0') ch_printf(ch, "Hitdest : %s\n\r", skill->hit_dest); if (skill->miss_char && skill->miss_char[0] != '\0') ch_printf(ch, "Misschar : %s\n\r", skill->miss_char); if (skill->miss_vict && skill->miss_vict[0] != '\0') ch_printf(ch, "Missvict : %s\n\r", skill->miss_vict); if (skill->miss_room && skill->miss_room[0] != '\0') ch_printf(ch, "Missroom : %s\n\r", skill->miss_room); if (skill->die_char && skill->die_char[0] != '\0') ch_printf(ch, "Diechar : %s\n\r", skill->die_char); if (skill->die_vict && skill->die_vict[0] != '\0') ch_printf(ch, "Dievict : %s\n\r", skill->die_vict); if (skill->die_room && skill->die_room[0] != '\0') ch_printf(ch, "Dieroom : %s\n\r", skill->die_room); if (skill->imm_char && skill->imm_char[0] != '\0') ch_printf(ch, "Immchar : %s\n\r", skill->imm_char); if (skill->imm_vict && skill->imm_vict[0] != '\0') ch_printf(ch, "Immvict : %s\n\r", skill->imm_vict); if (skill->imm_room && skill->imm_room[0] != '\0') ch_printf(ch, "Immroom : %s\n\r", skill->imm_room); if (skill->type != SKILL_HERB) { if (skill->type == SKILL_RACIAL) { send_to_char("\n\r--------------------------[RACE USE]--------------------------\n\r", ch); for (iRace = 0; iRace < MAX_RACE; iRace++) { sprintf(buf, "%8.8s) lvl: %3d max: %2d%%", race_table[iRace]->race_name, skill->race_level[iRace], skill->race_adept[iRace]); if (!strcmp(race_table[iRace]->race_name, "unused")) sprintf(buf, " "); if ((iRace > 0) && (iRace % 2 == 1)) strcat(buf, "\n\r"); else strcat(buf, " "); send_to_char(buf, ch); } } } send_to_char("\n\r", ch); } return; } /* * Set a skill's attributes or what skills a player has. * High god command, with support for creating skills/spells/herbs/etc */ void do_sset(CHAR_DATA * ch, char *argument) { char arg1[MIL]; char arg2[MIL]; char arg3[MIL]; /* Used for mastery setting -- Xerves 2/00 */ CHAR_DATA *victim; int value; int mvalue = -1; int sn, i; bool fAll; argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (arg1[0] == '\0' || arg2[0] == '\0' || argument[0] == '\0') { send_to_char("Syntax: sset <victim> <skill> <point value/keep> [mastery value]\n\r", ch); send_to_char("or: sset <victim> all <point value/keep> [mastery value]\n\r", ch); if (get_ftrust(ch) >= LEVEL_HI_STAFF) /* Tracker1 */ { send_to_char("or: sset save skill table\n\r", ch); send_to_char("or: sset save herb table\n\r", ch); send_to_char("or: sset create skill 'new skill'\n\r", ch); send_to_char("or: sset create herb 'new herb'\n\r", ch); send_to_char("or: sset create ability 'new ability'\n\r", ch); } if (get_ftrust(ch) >= LEVEL_STAFF) /* Tracker1 */ { send_to_char("or: sset <sn> <field> <value>\n\r", ch); send_to_char("\n\rField being one of:\n\r", ch); send_to_char(" name code target minpos slot mana beats dammsg wearoff guild minlevel\n\r", ch); send_to_char(" type damtype acttype classtype powertype seffect flag dice value difficulty\n\r", ch); send_to_char(" affect rmaffect mastery hit miss die imm (char/vict/room) targetlimb\n\r", ch); send_to_char(" components teachers racelevel raceadept prototype madeby group tier sphere\n\r", ch); send_to_char("Affect having the fields: <location> <modfifier> [duration] [bitvector]\n\r", ch); send_to_char("(See AFFECTTYPES for location, and AFFECTED_BY for bitvector)\n\r", ch); } send_to_char("Skill being any skill or spell.\n\r", ch); return; } if (get_ftrust(ch) > LEVEL_HI_STAFF /* Tracker1 */ && !str_cmp(arg1, "save") && !str_cmp(argument, "table")) { if (!str_cmp(arg2, "skill")) { send_to_char("Saving skill table...\n\r", ch); save_skill_table(); save_classes(); /* save_races(); */ return; } if (!str_cmp(arg2, "herb")) { send_to_char("Saving herb table...\n\r", ch); save_herb_table(); return; } } if (get_ftrust(ch) > LEVEL_HI_STAFF /* Tracker1 */ && !str_cmp(arg1, "create") && (!str_cmp(arg2, "skill") || !str_cmp(arg2, "herb") || !str_cmp(arg2, "ability"))) { struct skill_type *skill; sh_int type = SKILL_UNKNOWN; if (!str_cmp(arg2, "herb")) { type = SKILL_HERB; if (top_herb >= MAX_HERB) { ch_printf(ch, "The current top herb is %d, which is the maximum. " "To add more herbs,\n\rMAX_HERB will have to be " "raised in mud.h, and the mud recompiled.\n\r", top_sn); return; } } else if (top_sn >= MAX_SKILL) { ch_printf(ch, "The current top sn is %d, which is the maximum. " "To add more skills,\n\rMAX_SKILL will have to be " "raised in mud.h, and the mud recompiled.\n\r", top_sn); return; } CREATE(skill, struct skill_type, 1); skill->slot = 0; if (type == SKILL_HERB) { int max, x; herb_table[top_herb++] = skill; for (max = x = 0; x < top_herb - 1; x++) if (herb_table[x] && herb_table[x]->slot > max) max = herb_table[x]->slot; skill->slot = max + 1; } else skill_table[top_sn++] = skill; skill->min_mana = 0; skill->name = str_dup(argument); skill->noun_damage = str_dup(""); skill->msg_off = str_dup(""); skill->spell_fun = spell_smaug; skill->type = type; skill->prototype = 1; skill->made_char = ch->name; if (!str_cmp(arg2, "ability")) skill->type = SKILL_RACIAL; for (i = 0; i < MAX_RACE; i++) { skill->race_level[i] = LEVEL_IMMORTAL; skill->race_adept[i] = 95; } send_to_char("Done.\n\r", ch); return; } if (arg1[0] == 'h') sn = atoi(arg1 + 1); else sn = atoi(arg1); if (get_trust(ch) > LEVEL_STAFF /* Tracker1 */ && ((arg1[0] == 'h' && is_number(arg1 + 1) && (sn = atoi(arg1 + 1)) >= 0) || (is_number(arg1) && (sn = atoi(arg1)) >= 0))) { struct skill_type *skill; if (arg1[0] == 'h') { if (sn >= top_herb) { send_to_char("Herb number out of range.\n\r", ch); return; } skill = herb_table[sn]; } else { if ((skill = get_skilltype(sn)) == NULL) { send_to_char("Skill number out of range.\n\r", ch); return; } sn %= 1000; } if (!str_cmp(arg2, "difficulty")) { skill->difficulty = atoi(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "participants")) { skill->participants = atoi(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "damtype")) { int x = get_sdamage(argument); if (x == -1) send_to_char("Not a spell damage type.\n\r", ch); else { SET_SDAM(skill, x); send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "acttype")) { int x = get_saction(argument); if (x == -1) send_to_char("Not a spell action type.\n\r", ch); else { SET_SACT(skill, x); send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "classtype")) { int x = get_sclass(argument); if (x == -1) send_to_char("Not a spell class type.\n\r", ch); else { SET_SCLA(skill, x); send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "powertype")) { int x = get_spower(argument); if (x == -1) send_to_char("Not a spell power type.\n\r", ch); else { SET_SPOW(skill, x); send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "seffect")) { int x = get_ssave_effect(argument); if (x == -1) send_to_char("Not a spell save effect type.\n\r", ch); else { SET_SSAV(skill, x); send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "flag")) { int x = get_sflag(argument); if (x == -1) send_to_char("Not a spell flag.\n\r", ch); else { TOGGLE_BIT(skill->flags, 1 << x); send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "saves")) { int x = get_ssave(argument); if (x == -1) send_to_char("Not a saving type.\n\r", ch); else { skill->saves = x; send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "code")) { SPELL_FUN *spellfun; DO_FUN *dofun; if ((spellfun = spell_function(argument)) != spell_notfound) { skill->spell_fun = spellfun; skill->skill_fun = NULL; } else if ((dofun = skill_function(argument)) != skill_notfound) { skill->skill_fun = dofun; skill->spell_fun = NULL; } else { send_to_char("Not a spell or skill.\n\r", ch); return; } send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "target")) { int x = get_starget(argument); if (x == -1) send_to_char("Not a valid target type.\n\r", ch); else { skill->target = x; send_to_char("Ok.\n\r", ch); } return; } if (!str_cmp(arg2, "sphere")) { if (atoi(argument) < 1 || atoi(argument) > MAX_SPHERE) { ch_printf(ch, "Valid range is 1 to %d.\n\r", MAX_SPHERE); return; } else { skill->stype = atoi(argument); send_to_char("Ok.\n\r", ch); return; } } if (!str_cmp(arg2, "targetlimb")) { if (atoi(argument) < 0 || atoi(argument) > 5) { send_to_char("Range is 0 to 5.\n\r", ch); return; } else { skill->targetlimb = atoi(argument); send_to_char("Ok.\n\r", ch); return; } } if (!str_cmp(arg2, "group")) { if (atoi(argument) < 1 || atoi(argument) > MAX_GROUP) { ch_printf(ch, "Valid range is 1 to %d.\n\r", MAX_GROUP); return; } else { skill->group[0] = atoi(argument); send_to_char("Ok.\n\r", ch); return; } } if (!str_cmp(arg2, "masterydiff") || !str_cmp(arg2, "mastery diff") || !str_cmp(arg2, "tier")) { if (atoi(argument) < 1 || atoi(argument) > MAX_RANKING) { ch_printf(ch, "Valid range is 1 to %d.\n\r", MAX_RANKING); return; } else { skill->masterydiff[0] = atoi(argument); send_to_char("Ok.\n\r", ch); return; } } if (!str_cmp(arg2, "minpos")) { skill->minimum_position = URANGE(POS_DEAD, atoi(argument), POS_DRAG); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "minlevel")) { skill->min_level = URANGE(1, atoi(argument), MAX_LEVEL); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "slot")) { skill->slot = URANGE(0, atoi(argument), 30000); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "mana")) { skill->min_mana = URANGE(0, atoi(argument), 2000); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "beats")) { skill->beats = URANGE(0, atoi(argument), 120); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "range")) { skill->range = URANGE(0, atoi(argument), 20); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "guild")) { skill->guild = atoi(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "value")) { skill->value = atoi(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "type")) { skill->type = get_skill(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "rmaffect")) { SMAUG_AFF *aff = skill->affects; SMAUG_AFF *aff_next; int num = atoi(argument); int cnt = 1; if (!aff) { send_to_char("This spell has no special affects to remove.\n\r", ch); return; } if (num == 1) { skill->affects = aff->next; DISPOSE(aff->duration); DISPOSE(aff->modifier); DISPOSE(aff); send_to_char("Removed.\n\r", ch); return; } for (; aff; aff = aff->next) { if (++cnt == num && (aff_next = aff->next) != NULL) { aff->next = aff_next->next; DISPOSE(aff_next->duration); DISPOSE(aff_next->modifier); DISPOSE(aff_next); send_to_char("Removed.\n\r", ch); return; } } send_to_char("Not found.\n\r", ch); return; } /* * affect <location> <modifier> <duration> <bitvector> */ if (!str_cmp(arg2, "affect")) { char location[MIL]; char modifier[MIL]; char duration[MIL]; /* char bitvector[MIL]; */ int loc, bit, tmpbit; SMAUG_AFF *aff; argument = one_argument(argument, location); argument = one_argument(argument, modifier); argument = one_argument(argument, duration); if (location[0] == '!') loc = get_atype(location + 1) + REVERSE_APPLY; else loc = get_atype(location); if ((loc % REVERSE_APPLY) < 0 || (loc % REVERSE_APPLY) >= MAX_APPLY_TYPE) { send_to_char("Unknown affect location. See AFFECTTYPES.\n\r", ch); return; } bit = -1; if (argument[0] != 0) { if ((tmpbit = get_aflag(argument)) == -1) ch_printf(ch, "Unknown bitvector: %s. See AFFECTED_BY\n\r", argument); else bit = tmpbit; } CREATE(aff, SMAUG_AFF, 1); if (!str_cmp(duration, "0")) duration[0] = '\0'; if (!str_cmp(modifier, "0")) modifier[0] = '\0'; aff->duration = str_dup(duration); aff->location = loc; aff->modifier = str_dup(modifier); aff->bitvector = bit; aff->next = skill->affects; skill->affects = aff; send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "racelevel")) { char arg3[MIL]; int race; argument = one_argument(argument, arg3); race = atoi(arg3); if (race >= MAX_RACE || race < 0) send_to_char("Not a valid race.\n\r", ch); else skill->race_level[race] = URANGE(0, atoi(argument), MAX_LEVEL); return; } if (!str_cmp(arg2, "raceadept")) { char arg3[MIL]; int race; argument = one_argument(argument, arg3); race = atoi(arg3); if (race >= MAX_RACE || race < 0) send_to_char("Not a valid race.\n\r", ch); else skill->race_adept[race] = URANGE(0, atoi(argument), 100); return; } if (!str_cmp(arg2, "name")) { DISPOSE(skill->name); skill->name = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "prototype")) { int pro = atoi(argument); if (get_trust(ch) < LEVEL_STAFF) /* Tracker1 */ { send_to_char("Sorry, only staff can change this.\n\r", ch); return; } if (pro > 1 || pro < 0) { send_to_char("0 for no, 1 for yes\n\r", ch); return; } skill->prototype = atoi(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "madeby")) { if (get_trust(ch) < LEVEL_STAFF) /* Tracker1 */ { send_to_char("Sorry, only staff can change this.\n\r", ch); return; } DISPOSE(skill->made_char); skill->made_char = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "dammsg")) { DISPOSE(skill->noun_damage); if (!str_cmp(argument, "clear")) skill->noun_damage = str_dup(""); else skill->noun_damage = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "wearoff")) { DISPOSE(skill->msg_off); if (str_cmp(argument, "clear")) skill->msg_off = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "hitchar")) { if (skill->hit_char) DISPOSE(skill->hit_char); if (str_cmp(argument, "clear")) skill->hit_char = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "hitvict")) { if (skill->hit_vict) DISPOSE(skill->hit_vict); if (str_cmp(argument, "clear")) skill->hit_vict = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "hitroom")) { if (skill->hit_room) DISPOSE(skill->hit_room); if (str_cmp(argument, "clear")) skill->hit_room = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "hitdest")) { if (skill->hit_dest) DISPOSE(skill->hit_dest); if (str_cmp(argument, "clear")) skill->hit_dest = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "misschar")) { if (skill->miss_char) DISPOSE(skill->miss_char); if (str_cmp(argument, "clear")) skill->miss_char = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "missvict")) { if (skill->miss_vict) DISPOSE(skill->miss_vict); if (str_cmp(argument, "clear")) skill->miss_vict = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "missroom")) { if (skill->miss_room) DISPOSE(skill->miss_room); if (str_cmp(argument, "clear")) skill->miss_room = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "diechar")) { if (skill->die_char) DISPOSE(skill->die_char); if (str_cmp(argument, "clear")) skill->die_char = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "dievict")) { if (skill->die_vict) DISPOSE(skill->die_vict); if (str_cmp(argument, "clear")) skill->die_vict = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "dieroom")) { if (skill->die_room) DISPOSE(skill->die_room); if (str_cmp(argument, "clear")) skill->die_room = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "immchar")) { if (skill->imm_char) DISPOSE(skill->imm_char); if (str_cmp(argument, "clear")) skill->imm_char = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "immvict")) { if (skill->imm_vict) DISPOSE(skill->imm_vict); if (str_cmp(argument, "clear")) skill->imm_vict = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "immroom")) { if (skill->imm_room) DISPOSE(skill->imm_room); if (str_cmp(argument, "clear")) skill->imm_room = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "dice")) { if (skill->dice) DISPOSE(skill->dice); if (str_cmp(argument, "clear")) skill->dice = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "components")) { if (skill->components) DISPOSE(skill->components); if (str_cmp(argument, "clear")) skill->components = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } if (!str_cmp(arg2, "teachers")) { if (skill->teachers) DISPOSE(skill->teachers); if (str_cmp(argument, "clear")) skill->teachers = str_dup(argument); send_to_char("Ok.\n\r", ch); return; } do_sset(ch, ""); return; } //sset <victim> <skill> <point value> <mastery value> if ((victim = get_char_world(ch, arg1)) == NULL) { if ((sn = skill_lookup(arg1)) >= 0) { sprintf(arg1, "%d %s %s", sn, arg2, argument); do_sset(ch, arg1); } else send_to_char("They aren't here.\n\r", ch); return; } if (IS_NPC(victim)) { send_to_char("Not on NPC's.\n\r", ch); return; } argument = one_argument(argument, arg3); fAll = !str_cmp(arg2, "all"); sn = 0; if (!fAll && (sn = skill_lookup(arg2)) < 0) { send_to_char("No such skill or spell.\n\r", ch); return; } if (!is_number(arg3) && str_cmp(arg3, "keep")) { send_to_char("Point Value must be numeric.\n\r", ch); return; } value = atoi(arg3); if (!str_cmp(arg3, "keep")) value = -1; if (value < -1 || value > MAX_SKPOINTS) { ch_printf(ch, "Point Value range is 0 to %d.\n\r", MAX_SKPOINTS); return; } if (argument[0] != '\0') { if (!is_number(argument)) { send_to_char("Mastery Value must be numeric.\n\r", ch); return; } mvalue = atoi(argument); if (mvalue < 0 || mvalue > MAX_RANKING) { ch_printf(ch, "Mastery Value range is 0 to %d.\n\r", MAX_RANKING); return; } } if (fAll) { for (sn = 0; sn < top_sn; sn++) { /* Fix by Narn to prevent ssetting skills the player shouldn't have. */ if (skill_table[sn]->name) { if (value >= 0) victim->pcdata->learned[sn] = value; if (mvalue >= 0) victim->pcdata->ranking[sn] = mvalue; if ((skill_table[sn]->group[0] < 23 || skill_table[sn]->group[0] > 29) && (skill_table[sn]->group[0] < 31 || skill_table[sn]->group[0] > 34)) { if (value >= 0) victim->pcdata->spellpoints[skill_table[sn]->group[0]] = value; if (mvalue >= 0) victim->pcdata->spellgroups[skill_table[sn]->group[0]] = mvalue; } } } } else { if ((skill_table[sn]->group[0] < 23 || skill_table[sn]->group[0] > 29) && (skill_table[sn]->group[0] < 31 || skill_table[sn]->group[0] > 34)) { if (value >= 0) victim->pcdata->spellpoints[skill_table[sn]->group[0]] = value; if (mvalue >= 0) victim->pcdata->spellgroups[skill_table[sn]->group[0]] = mvalue; } if (value >= 0) victim->pcdata->learned[sn] = value; if (mvalue >= 0) victim->pcdata->ranking[sn] = mvalue; } return; } int group_in_sphere(int group) { switch (group) { case 1: case 2: case 3: case 4: case 5: return 3; case 6: case 19: case 20: case 21: case 22: case 23: return 4; case 7: case 8: case 9: case 10: case 18: return 5; case 11: case 12: case 13: return 2; case 14: case 15: case 16: case 17: return 1; } return 0; } //Gets values to modify flux on a skill/spell, the actually "curving" of the system to prevent super characters //Can make some beginnger skills/spells master difficulty to learn if you are going against the grain int get_skillflux_value(CHAR_DATA *ch, int ssn) { int sn; int i; int snvalue = 0; //Point value for the sn's group/mastery int restvalue = 0; //Point value for the other groups/mastery int totalvalue = 0; //Point total for all spheres. int diff = 0; int master = 0; int specialist = 0; //Check to see if points are setup yet in spherepoints and grouppoints if (ch->pcdata->spherepoints[1] == -1 || ch->pcdata->grouppoints[1] == -1) { for (i = 1; i <= MAX_SPHERE; i++) ch->pcdata->spherepoints[i] = 0; for (i = 1; i <= MAX_GROUP+5; i++) ch->pcdata->grouppoints[i] = 0; for (sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++) { if (skill_table[sn]->group[0] > 0) { if (skill_table[sn]->stype == 4 && skill_table[sn]->group[0] != 6) { ch->pcdata->grouppoints[skill_table[sn]->group[0]+MAX_GROUP] += ch->pcdata->learned[sn]; ch->pcdata->spherepoints[skill_table[sn]->stype] += ch->pcdata->learned[sn]; } else { ch->pcdata->grouppoints[skill_table[sn]->group[0]] += ch->pcdata->learned[sn]; ch->pcdata->spherepoints[skill_table[sn]->stype] += ch->pcdata->learned[sn]; } } } } //Check to see if player is beyond Beginner for (sn = 0; sn < top_sn && skill_table[sn] && skill_table[sn]->name; sn++) { if ((ch->pcdata->ranking[sn] >= 2 || ch->pcdata->learned[sn] >= 6) && (skill_table[sn]->type == SKILL_SPELL || skill_table[sn]->type == SKILL_SKILL)) { diff = 1; //Beyond the "grace period" above the curve break; } } //Next check groups, if the sn is in the "master" sphere, compare against other groups instead of spheres //Has to possess majority of points or more for (i = 1; i <= MAX_SPHERE; i++) { totalvalue += ch->pcdata->spherepoints[i]; } for (i = 1; i <= MAX_SPHERE; i++) { if (ch->pcdata->spherepoints[i] > totalvalue/2) // > 50 percent of all points break; } if (ch->pcdata->spherepoints[skill_table[ssn]->stype] == totalvalue) { specialist = 1; master = 1; } else if (i > MAX_SPHERE) master = 0; //no master sphere else if (skill_table[ssn]->stype == i) master = 1; //skill is in master sphere else if (i <= MAX_SPHERE) master = 0; //there is a master sphere, but you aren't in it if (master == 1 && diff == 1) //spell/skill is in the master sphere { int group = skill_table[ssn]->group[0]; if (skill_table[ssn]->stype == 4 && skill_table[ssn]->group[0] != 6) group = skill_table[ssn]->group[0]+MAX_GROUP; for (i = 1; i <= MAX_GROUP+5; i++) { if (group_in_sphere(i) == skill_table[ssn]->stype) { if (i == group) snvalue += ch->pcdata->grouppoints[i]; else restvalue += ch->pcdata->grouppoints[i]; } } } else //spell/skill is not in the master sphere { for (i = 1; i <= MAX_SPHERE; i++) { if (skill_table[ssn]->stype == i) snvalue += ch->pcdata->spherepoints[i]; else restvalue += ch->pcdata->spherepoints[i]; } } //now we have all the values talied, lets spit out the percents and modify based on the "curve" //a slightly less mean curve when you first start out so you can start a few different things at once before //getting blasted by the curve if (diff == 0) { if (snvalue > restvalue) return 100; else return 70; } if (restvalue <= 0 || specialist == 1) diff = 1000; else diff = 1000*snvalue/(restvalue+snvalue); //1000 diff means 1:1 500 diff means 1:2 10000 diff means 10:1, etc. Higher the more dominant the group/sphere //Lower the less dominant. Higher dominance equals more gain, pretty straight. if (master == 0) //no dominant group, lets make one :-) { if (diff < 1000) { return (diff*100/1000); } else return 100; } if (master == 1) //bonus if you are learning in the master sphere { if (diff < 1000) { return 60+(diff*40/1000); } else return 100; } return 100; } //return points earned on percent based on mastery alone, used for learn_from_success/failure int base_learn_value(CHAR_DATA *ch, int sn) { int change = 0; int pos = 0; if (ch->pcdata->learned[sn] >= 1 && ch->pcdata->learned[sn] <= 4) { if (ch->pcdata->learned[sn] == 1) change = number_range(500, 750); if (ch->pcdata->learned[sn] == 2) change = number_range(400, 600); if (ch->pcdata->learned[sn] == 3) change = number_range(350, 550); if (ch->pcdata->learned[sn] == 4) change = number_range(300, 500); } else if (ch->pcdata->learned[sn] >= 5 && ch->pcdata->learned[sn] <= 7) { if (ch->pcdata->learned[sn] == 5) change = number_range(200, 300); if (ch->pcdata->learned[sn] == 6) change = number_range(170, 250); if (ch->pcdata->learned[sn] == 7) change = number_range(130, 190); if (ch->pcdata->ranking[sn] == 1 && ch->pcdata->learned[sn] >= 5) change /= 3; } else if (ch->pcdata->learned[sn] >= 8 && ch->pcdata->learned[sn] <= 10) { if (ch->pcdata->learned[sn] == 8) change = number_range(80, 120); if (ch->pcdata->learned[sn] == 9) change = number_range(65, 90); if (ch->pcdata->learned[sn] == 10) change = number_range(50, 70); if (ch->pcdata->ranking[sn] == 1) change = 1; if (ch->pcdata->ranking[sn] == 2 && ch->pcdata->learned[sn] >= 8) change /= 3; } else if (ch->pcdata->learned[sn] >= 11 && ch->pcdata->learned[sn] <= 13) { if (ch->pcdata->learned[sn] == 11) change = number_range(35, 45); if (ch->pcdata->learned[sn] == 12) change = number_range(25, 30); if (ch->pcdata->learned[sn] == 13) change = number_range(20, 25); if (ch->pcdata->ranking[sn] < 4) change = 1; } else if (ch->pcdata->learned[sn] >= 14 && ch->pcdata->learned[sn] <= 19) { change = number_range(5, 15); if (ch->pcdata->learned[sn] >= 15 && ch->pcdata->ranking[sn] < 5) change = 0; if (ch->pcdata->learned[sn] >= 18 && ch->pcdata->ranking[sn] < 6) change = 0; } else { if (ch->pcdata->spercent[sn] > 3000) change = 0; else change = number_range(3, 10); } change = change * sysdata.exp_percent / 100; if (change > 0) pos = 1; if (ch->race == RACE_HUMAN) change = change * 150 / 100; if (sn > 0 && sn < top_sn && skill_table[sn] && skill_table[sn]->name && skill_table[sn]->type == SKILL_SPELL && ch->race == RACE_OGRE) change = change * 20 / 100; else { if (ch->race == RACE_OGRE) change = change * 80 / 100; } if (sn > 0 && sn < top_sn && skill_table[sn] && skill_table[sn]->name && skill_table[sn]->type == SKILL_SPELL && ch->race == RACE_FAIRY) change = change * 175 / 100; //Agent sphere for hobbits if (sn > 0 && sn < top_sn && skill_table[sn] && skill_table[sn]->name && skill_table[sn]->stype == 2 && ch->race == RACE_HOBBIT) change = change * 175 / 100; if (skill_table[sn]->difficulty >= 0 && skill_table[sn]->difficulty <= 13) { if (skill_table[sn]->difficulty == 1) change = change * 95 / 100; if (skill_table[sn]->difficulty == 2) change *= .9; if (skill_table[sn]->difficulty == 3) change = change * 80 / 100; if (skill_table[sn]->difficulty == 4) change = change * 70 / 100; if (skill_table[sn]->difficulty == 5) change = change * 65 / 100; if (skill_table[sn]->difficulty == 6) change = change * 50 / 100; if (skill_table[sn]->difficulty == 7) change = change * 33 / 100; if (skill_table[sn]->difficulty == 8) change = change * 25 / 100; if (skill_table[sn]->difficulty == 9) change = change * 20 / 100; if (skill_table[sn]->difficulty == 10) change = change * 15 / 100; if (skill_table[sn]->difficulty == 11) change = change * 10 / 100; if (skill_table[sn]->difficulty == 12) change = change * 5 / 100; if (skill_table[sn]->difficulty == 13) change = change * 1 / 100; } else { bug("Sn %d as a difficulty out of the range >= 0 <= 13", sn); } change = change * get_skillflux_value(ch, sn) / 100; if (change < 1 && pos == 1) change = 1; return change; } /* Added these back in, but made the chance to increase minimal -- Xerves 11/1/99 */ // Put back in for new skill system, a more hybrid version of stock/new system -- Xerves 2001 void learn_from_success(CHAR_DATA * ch, int sn, CHAR_DATA *target) { int change; SKILLTYPE *skill = get_skilltype(sn); int pos = 0; int x; if (IS_NPC(ch)) return; if (sn == -1) return; for (x = 0; x < 5; x++) //no learning list { if (ch->pcdata->nolearn[x] == sn) return; } change = base_learn_value(ch, sn); if (change > 0) pos = 1; if (target && !IS_NPC(target) && is_affected(target, sn) && !SPELL_FLAG(skill, SF_ACCUMULATIVE) && !SPELL_FLAG(skill, SF_RECASTABLE)) change /= 3; //Come on quit casting the bloody spell already if they have it already if (target && IS_NPC(target) && xIS_SET(target->act, ACT_MOUNTSAVE)) { change = 0; pos = 0; } if (change < 1 && pos == 1) change = 1; ch->pcdata->spercent[sn] += change; if (ch->pcdata->spercent[sn] >= 10000) { ch_printf(ch, "&R*********************************************************************\n\r"); ch_printf(ch, "&R*****Your skills in %s has increased 1 Point.*****\n\r", skill_table[sn]->name); ch_printf(ch, "&R*********************************************************************\n\r"); ch->pcdata->learned[sn]++; ch->pcdata->spercent[sn] = 200; //So skill doesn't go down in a few minutes if (skill_table[sn]->stype == 4 && skill_table[sn]->group[0] != 6) { ch->pcdata->grouppoints[skill_table[sn]->group[0]+MAX_GROUP]++; ch->pcdata->spherepoints[skill_table[sn]->stype]++; } else { ch->pcdata->grouppoints[skill_table[sn]->group[0]]++; ch->pcdata->spherepoints[skill_table[sn]->stype]++; } } return; } void learn_from_failure(CHAR_DATA * ch, int sn, CHAR_DATA *target) { int change; SKILLTYPE *skill = get_skilltype(sn); int x; int pos = 0; if (IS_NPC(ch)) return; if (sn == 1) return; for (x = 0; x < 5; x++) //no learning list { if (ch->pcdata->nolearn[x] == sn) return; } change = base_learn_value(ch, sn); if (change > 0) pos = 1; change /= 3; //Failure gives you only 1/3 of the points if (sn == gsn_critical) //slow this down quite a bit on failures... change /= 4; if (target && !IS_NPC(target) && is_affected(target, sn) && !SPELL_FLAG(skill, SF_ACCUMULATIVE) && !SPELL_FLAG(skill, SF_RECASTABLE)) change /= 3; //Come on quit casting the bloody spell already if they have it already if (target && IS_NPC(target) && xIS_SET(target->act, ACT_MOUNTSAVE)) { change = 0; pos = 0; } if (change < 1 && pos == 1) change = 1; ch->pcdata->spercent[sn] += change; if (ch->pcdata->spercent[sn] >= 10000) { ch_printf(ch, "&R*********************************************************************\n\r"); ch_printf(ch, "&R*****Your skills in %s has increased 1 Point.*****\n\r", skill_table[sn]->name); ch_printf(ch, "&R*********************************************************************\n\r"); ch->pcdata->learned[sn]++; ch->pcdata->spercent[sn] = 200; //So skill does not go down in a few minutes if (skill_table[sn]->stype == 4 && skill_table[sn]->group[0] != 6) { ch->pcdata->grouppoints[skill_table[sn]->group[0]+MAX_GROUP]++; ch->pcdata->spherepoints[skill_table[sn]->stype]++; } else { ch->pcdata->grouppoints[skill_table[sn]->group[0]]++; ch->pcdata->spherepoints[skill_table[sn]->stype]++; } } return; } void do_gouge(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; AFFECT_DATA af; sh_int dam; int chance; sh_int level; sh_int mastery; mastery = MASTERED(ch, gsn_gouge); level = POINT_LEVEL(LEARNED(ch, gsn_gouge), MASTERED(ch, gsn_gouge)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (!can_use_skill(ch, 0, gsn_gouge)) { send_to_char("You do not yet know of this skill.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't get close enough while mounted.\n\r", ch); return; } if ((victim = who_fighting(ch)) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } chance = 15+(level/6)+((get_curr_dex(ch) - get_curr_dex(victim))*2); chance = ((get_curr_dex(victim) - get_curr_dex(ch)) * 10) + 10; if (!IS_NPC(ch) && !IS_NPC(victim)) chance += sysdata.gouge_plr_vs_plr; if (victim->fighting && victim->fighting->who != ch) chance += sysdata.gouge_nontank; if (number_range(1, 100) <= chance) { dam = number_range(1, 1+(level/20)); global_retcode = damage(ch, victim, dam, gsn_gouge, 0, -1); if (global_retcode == rNONE) { if (!IS_AFFECTED(victim, AFF_BLIND)) { af.type = gsn_blindness; af.location = APPLY_TOHIT; af.modifier = -4; af.duration = number_range(8+(level/10), 10+(level/8)); af.bitvector = meb(AFF_BLIND); affect_to_char(victim, &af); act(AT_SKILL, "You can't see a thing!", victim, NULL, NULL, TO_CHAR); } ch->fight_timer = skill_table[gsn_gouge]->beats; victim->fight_timer += 2*skill_table[gsn_gouge]->beats; } else if (global_retcode == rVICT_DIED) { act(AT_BLOOD, "Your fingers plunge into your victim's brain, causing immediate death!", ch, NULL, NULL, TO_CHAR); } if (global_retcode != rCHAR_DIED && global_retcode != rVICT_DIED && global_retcode != rBOTH_DIED) learn_from_success(ch, gsn_gouge, victim); } else { ch->fight_timer = skill_table[gsn_gouge]->beats; global_retcode = damage(ch, victim, 0, gsn_gouge, 0, -1); learn_from_failure(ch, gsn_gouge, victim); } return; } void do_manashot(CHAR_DATA *ch, char *argument) { int level; CHAR_DATA *victim = NULL; int dam; level = POINT_LEVEL(LEARNED(ch, gsn_manashot), MASTERED(ch, gsn_manashot)); if (ch->fighting) victim = ch->fighting->who; if (argument[0] != '\0') { if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not in the room with you.\n\r", ch); return; } } if (!check_twohand_shield(ch)) return; if (!victim) { send_to_char("Syntax: manashot <target>\n\rDo not need to supply a target if fighting.\n\r", ch); return; } if (is_room_safe(ch)) { send_to_char("This room is a safe area, you cannot fight here.\n\r", ch); return; } dam = UMAX(6, level-2); dam = number_range(dam*80/100, dam*120/100); if (is_immune(victim, -1, RIS_MAGIC)) { act(AT_WHITE, "$n releases a powerful manashot toward $N, but $N is immune to magic.", ch, NULL, victim, TO_NOTVICT); act(AT_WHITE, "$n releases a powerful manashot toward you, but you are immune to magic.", ch, NULL, victim, TO_VICT); act(AT_WHITE, "You release a powerful manashot toward $N, but $N is immune to magic.", ch, NULL, victim, TO_CHAR); damage(ch, victim, 0, gsn_manashot, 0, -1); return; } if (saves_spell_staff(level, victim)) dam = dam * 3 / 4; act(AT_WHITE, "$n channels $s energy and blasts $N with a powerful manashot.", ch, NULL, victim, TO_NOTVICT); act(AT_WHITE, "$n channels $s energy and blasts you with a powerful manashot.", ch, NULL, victim, TO_VICT); act(AT_WHITE, "You channel your energy and blast $N with a powerful manashot.", ch, NULL, victim, TO_CHAR); damage(ch, victim, dam, gsn_manashot, 0, -1); learn_from_success(ch, gsn_manashot, victim); if (ch->fighting) ch->fight_timer = get_btimer(ch, gsn_manashot, NULL); else WAIT_STATE(ch, skill_table[gsn_manashot]->beats*2); return; } void do_manaburst(CHAR_DATA *ch, char *argument) { int level; CHAR_DATA *vch; CHAR_DATA *vch_next; int dam; int num = 0; level = POINT_LEVEL(LEARNED(ch, gsn_manaburst), MASTERED(ch, gsn_manaburst)); if (is_room_safe(ch)) { send_to_char("This room is a safe area, you cannot fight here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; act(AT_WHITE, "$n starts scream and a large amount of energy pours and hits everything around $m.", ch, NULL, NULL, TO_ROOM); act(AT_WHITE, "You start screaming and a large amount of energy pours out and hits everything around you.", ch, NULL, NULL, TO_CHAR); for (vch = ch->in_room->first_person; vch; vch = vch_next) { vch_next = vch->next_in_room; if (ch->coord->x != vch->coord->x || ch->coord->y != vch->coord->y || ch->map != vch->map) continue; if (!IS_NPC(vch) && xIS_SET(vch->act, PLR_WIZINVIS) && vch->pcdata->wizinvis >= LEVEL_IMMORTAL) continue; if (IS_NPC(vch) && IS_AFFECTED(vch, AFF_CHARM) && vch->master == ch) continue; if (!IS_NPC(ch) && IS_NPC(vch) && IS_ACT_FLAG(vch, ACT_MOUNTSAVE)) continue; if (vch != ch && (IS_NPC(ch) ? !IS_NPC(vch) : IS_NPC(vch))) { num++; dam = 30+level*15/10; dam = number_range(dam*80/100, dam*120/100); if (saves_spell_staff(level, vch)) dam = dam * 3 / 4; damage(ch, vch, dam, gsn_manaburst, 0, -1); } if (char_died(ch)) return; } if (ch->fighting) ch->fight_timer = get_btimer(ch, gsn_manaburst, NULL); else WAIT_STATE(ch, skill_table[gsn_manaburst]->beats*2); if (num) learn_from_success(ch, gsn_manaburst, NULL); return; } void do_nervestrike(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; AFFECT_DATA af; int chance; int level; bool fail; level = POINT_LEVEL(LEARNED(ch, gsn_nervestrike), MASTERED(ch, gsn_nervestrike)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (!IS_NPC(ch) && ch->pcdata->ranking[gsn_nervestrike] <= 0) { send_to_char("Hard to strike at a nerve if you don't even know where one is.\n\r", ch); return; } if (!ch->fighting || !ch->fighting->who) { send_to_char("You can only use this during the heat of battle.\n\r", ch); return; } if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { victim = ch->fighting->who; } if (is_safe(ch, victim)) { send_to_char("You cannot nervestrike that target.\n\r", ch); return; } check_illegal_pk(ch, victim); check_attacker(ch, victim); if (!IS_NPC(ch) && HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } ch->fight_timer = get_btimer(ch, gsn_nervestrike, NULL); fail = FALSE; chance = 5+level/4; if (!IS_NPC(ch) && !IS_NPC(victim)) chance -= sysdata.stun_plr_vs_plr; else chance -= sysdata.stun_regular; chance += ((get_curr_dex(victim) + get_curr_str(victim)) - (get_curr_dex(ch) + get_curr_str(ch))) * 3; chance += URANGE(-10, (get_curr_int(ch)-14)/2 + (get_curr_wis(ch)-14)/2, 10); chance += victim->saving_para_petri; if (victim->max_hit > 2000) chance /= 2; if (victim->max_hit > 5000) chance /= 2; chance = URANGE(5, chance, 45); if (!fail) { if (number_range(1, 100) > chance) fail = TRUE; } if (!fail) { learn_from_success(ch, gsn_nervestrike, victim); ch->fight_timer = skill_table[gsn_nervestrike]->beats; act(AT_SKILL, "$N lunges at your neck and strikes a vital nerve. You are PARALYZED TEMPORARILY!", victim, NULL, ch, TO_CHAR); act(AT_SKILL, "You lunge at $N's neck and strike a vital nerve. $N is PARALYZED TEMPORARILY!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n lunges at $N's neck and strike a vital nerve. $N is PARALYZED TEMPORARILY!", ch, NULL, victim, TO_NOTVICT); if (!IS_AFFECTED(victim, AFF_PARALYSIS)) { af.type = gsn_stun; af.location = APPLY_ARMOR; af.modifier = -3; af.duration = 5+(MASTERED(ch, gsn_nervestrike)*3/2); if (IS_NPC(ch)) af.duration = 2+MASTERED(ch, gsn_nervestrike); af.bitvector = meb(AFF_PARALYSIS); affect_to_char(victim, &af); update_pos(victim); } start_hating(victim, ch); start_hunting(victim, ch); } else { ch->fight_timer = skill_table[gsn_nervestrike]->beats; learn_from_failure(ch, gsn_nervestrike, victim); act(AT_SKILL, "$n lunges at your neck and attempts to strike a vital nerve, but $e misses.", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You try to strike a vital nerve on $N's neck, but you miss.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n lunges at $N's neck and attempts to strike a vital nerve, but $e fails.", ch, NULL, victim, TO_NOTVICT); start_hating(victim, ch); start_hunting(victim, ch); } return; } void do_quickcombo(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim = NULL; int level; int sn[6]; char arg[MIL]; int x, y; int right; char buf[MSL]; int remain; for (x = 0; x <= 5; x++) sn[x] = 0; level = POINT_LEVEL(LEARNED(ch, gsn_quickcombo), MASTERED(ch, gsn_quickcombo)); if (argument[0] == '\0') { send_to_char("Syntax: quickcombo <right/left> <strike1> <strike2> [strike3] [strike4] [strike5] [victim]\n\r", ch); send_to_char("Note: strike3-5 is available if you have expert/elite/flawless in quickcombo.\n\r", ch); return; } argument = one_argument(argument, arg); if (!str_cmp(arg, "right")) right = 1; else right = 0; argument = one_argument(argument, arg); if ((sn[1] = skill_lookup(arg)) < 1) { send_to_char("Strike1 is not a valid strike.\n\r", ch); return; } if (skill_table[sn[1]]->group[0] != 7) //Group with all the strikes { send_to_char("Strike1 has to be an actual strike (ex: blitz)\n\r", ch); return; } argument = one_argument(argument, arg); if ((sn[2] = skill_lookup(arg)) < 1) { send_to_char("Strike2 is not a valid strike.\n\r", ch); return; } if (skill_table[sn[2]]->group[0] != 7) //Group with all the strikes { send_to_char("Strike2 has to be an actual strike (ex: blitz)\n\r", ch); return; } one_argument(argument, arg); if ((sn[3] = skill_lookup(arg)) >= 1) { argument = one_argument(argument, arg); if (MASTERED(ch, gsn_quickcombo) < 3) { send_to_char("You can only specify a 3rd strike if you have expert or higher mastery.\n\r", ch); return; } if (skill_table[sn[3]]->group[0] != 7) //Group with all the strikes { send_to_char("Strike3 has to be an actual strike (ex: blitz)\n\r", ch); return; } } one_argument(argument, arg); if ((sn[4] = skill_lookup(arg)) >= 1) { argument = one_argument(argument, arg); if (MASTERED(ch, gsn_quickcombo) < 5) { send_to_char("You can only specify a 4rd strike if you have elite or higher mastery.\n\r", ch); return; } if (skill_table[sn[4]]->group[0] != 7) //Group with all the strikes { send_to_char("Strike4 has to be an actual strike (ex: blitz)\n\r", ch); return; } } one_argument(argument, arg); if ((sn[5] = skill_lookup(arg)) >= 1) { argument = one_argument(argument, arg); if (MASTERED(ch, gsn_quickcombo) < 5) { send_to_char("You can only specify a 5th strike if you have flawless or higher mastery.\n\r", ch); return; } if (skill_table[sn[5]]->group[0] != 7) //Group with all the strikes { send_to_char("Strike5 has to be an actual strike (ex: blitz)\n\r", ch); return; } } for (x = 1; x <= 5; x++) { for (y = 1; y <= 5; y++) { if (x == y) continue; if (sn[x] <= 0 || sn[y] <= 0) continue; if (skill_table[sn[x]]->targetlimb == skill_table[sn[y]]->targetlimb) break; } if (y != 6) { send_to_char("Each strike has to target a different limb.\n\r", ch); return; } } if (ch->fighting) victim = ch->fighting->who; if (argument[0] != '\0') { if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not in the room with you.\n\r", ch); return; } } if (!victim) { do_quickcombo(ch, ""); return; } if (is_room_safe(ch)) { send_to_char("This room is a safe area, you cannot fight here.\n\r", ch); return; } sprintf(buf, "'%s' %s", victim->name, right ? "right" : "left"); //Legs/Arms need right/left argument if (skill_table[sn[1]]->targetlimb == 1 || skill_table[sn[1]]->targetlimb == 2) (*skill_table[sn[1]]->skill_fun) (ch, buf); else (*skill_table[sn[1]]->skill_fun) (ch, victim->name); if (skill_table[sn[2]]->targetlimb == 1 || skill_table[sn[2]]->targetlimb == 2) (*skill_table[sn[2]]->skill_fun) (ch, buf); else (*skill_table[sn[2]]->skill_fun) (ch, victim->name); if (sn[3] > 0) { if (skill_table[sn[3]]->targetlimb == 1 || skill_table[sn[3]]->targetlimb == 2) (*skill_table[sn[3]]->skill_fun) (ch, buf); else (*skill_table[sn[3]]->skill_fun) (ch, victim->name); } if (sn[4] > 0) { if (skill_table[sn[4]]->targetlimb == 1 || skill_table[sn[4]]->targetlimb == 2) (*skill_table[sn[4]]->skill_fun) (ch, buf); else (*skill_table[sn[4]]->skill_fun) (ch, victim->name); } if (sn[5] > 0) { if (skill_table[sn[5]]->targetlimb == 1 || skill_table[sn[5]]->targetlimb == 2) (*skill_table[sn[5]]->skill_fun) (ch, buf); else (*skill_table[sn[5]]->skill_fun) (ch, victim->name); } remain = ch->fight_timer * UMAX(40, (100-(level*2/3))) % 100; ch->fight_timer = ch->fight_timer * UMAX(40, (100-(level*2/3))) / 100; if (number_range(1, 100) <= remain) ch->fight_timer += 1; if (ch->fight_timer < 1) ch->fight_timer = 1; learn_from_success(ch, gsn_quickcombo, victim); return; } void do_kickdirt(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; AFFECT_DATA af; int chance; sh_int level; sh_int mastery; int sector; mastery = MASTERED(ch, gsn_kickdirt); level = POINT_LEVEL(LEARNED(ch, gsn_kickdirt), MASTERED(ch, gsn_kickdirt)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (!can_use_skill(ch, 0, gsn_kickdirt)) { send_to_char("You do not yet know of this skill.\n\r", ch); return; } if (ch->mount) { send_to_char("What do you want to do, blind your target with your mount?.\n\r", ch); return; } if ((victim = who_fighting(ch)) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (IN_WILDERNESS(ch)) { sector = map_sector[ch->map][ch->coord->x][ch->coord->y]; } else { sector = ch->in_room->sector_type; } if (sector != SECT_FIELD && sector != SECT_FOREST && sector != SECT_HILLS && sector != SECT_MOUNTAIN && sector != SECT_DESERT && sector != SECT_UNDERGROUND && sector != SECT_MINEGOLD && sector != SECT_MINEIRON && sector != SECT_HCORN && sector != SECT_HGRAIN && sector != SECT_STREE && sector != SECT_NTREE && sector != SECT_SCORN && sector != SECT_NCORN && sector != SECT_SIRON && sector != SECT_NIRON && sector != SECT_SGRAIN && sector != SECT_NGRAIN && sector != SECT_JUNGLE && sector != SECT_SHORE && sector != SECT_SWAMP && sector != SECT_PATH && sector != SECT_PLAINS && sector != SECT_BURNT && sector != SECT_STONE && sector != SECT_SSTONE && sector != SECT_NSTONE) { send_to_char("There has to be dirt on the ground to kick.\n\r", ch); return; } chance = 15+(level/4)+((get_curr_dex(ch) - get_curr_dex(victim))*5); if (number_range(1, 100) <= chance) { act(AT_RED, "$n kicks dirt into the eyes of $N blinding $M.", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "$n kicks dirt into your eyes blinding you!", ch, NULL, victim, TO_VICT); act(AT_RED, "You kick dirt into the eyes of $N blinding $M.", ch, NULL, victim, TO_CHAR); if (!IS_AFFECTED(victim, AFF_BLIND)) { af.type = gsn_blindness; af.location = APPLY_TOHIT; af.modifier = -2; af.duration = number_range(4+(level/10), 6+(level/8)); af.bitvector = meb(AFF_BLIND); affect_to_char(victim, &af); act(AT_SKILL, "You can't see a thing!", victim, NULL, NULL, TO_CHAR); } ch->fight_timer = skill_table[gsn_kickdirt]->beats; learn_from_success(ch, gsn_kickdirt, victim); } else { act(AT_RED, "$n kicks dirt toward the eyes of $N, but $E dodges it.", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "$n kicks dirt toward your eyes, but you happen to dodge it.", ch, NULL, victim, TO_VICT); act(AT_RED, "You kick dirt toward the eyes of $N, but $E dodges it.", ch, NULL, victim, TO_CHAR); ch->fight_timer = skill_table[gsn_kickdirt]->beats; learn_from_failure(ch, gsn_kickdirt, victim); } return; } void do_detrap(CHAR_DATA * ch, char *argument) { char arg[MIL]; OBJ_DATA *obj; OBJ_DATA *trap; TRAP_DATA *ntrap; OBJ_DATA *tool; int percent; sh_int level; sh_int mastery; trap = NULL; ntrap = NULL; mastery = MASTERED(ch, gsn_detrap); level = POINT_LEVEL(LEARNED(ch, gsn_detrap), MASTERED(ch, gsn_detrap)); switch (ch->substate) { default: if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } argument = one_argument(argument, arg); if (!can_use_skill(ch, 0, gsn_detrap)) { send_to_char("You do not yet know of this skill.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Detrap what?\n\r", ch); return; } if (ms_find_obj(ch)) return; if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if ((obj = get_obj_here(ch, arg)) == NULL) { send_to_char("You can't find that here.\n\r", ch); return; } act(AT_ACTION, "You carefully begin your attempt to remove a trap from $p...", ch, obj, NULL, TO_CHAR); act(AT_ACTION, "$n carefully attempts to remove a trap from $p...", ch, obj, NULL, TO_ROOM); ch->alloc_ptr = str_dup(obj->name); add_timer(ch, TIMER_DO_FUN, 6, do_detrap, 1); WAIT_STATE( ch, skill_table[gsn_detrap]->beats*2 ); return; case 1: if (!ch->alloc_ptr) { send_to_char("Your detrapping was interrupted!\n\r", ch); bug("do_detrap: ch->alloc_ptr NULL!", 0); return; } strcpy(arg, ch->alloc_ptr); DISPOSE(ch->alloc_ptr); ch->alloc_ptr = NULL; ch->substate = SUB_NONE; break; case SUB_TIMER_DO_ABORT: DISPOSE(ch->alloc_ptr); ch->substate = SUB_NONE; send_to_char("You carefully stop what you were doing.\n\r", ch); return; } if ((obj = get_obj_here(ch, arg)) == NULL) { send_to_char("You can't find that here.\n\r", ch); return; } trap = get_trap(obj); if (obj->trap) { ntrap = obj->trap; trap = NULL; } if (!trap && !ntrap) { send_to_char("You find no trap on that.\n\r", ch); return; } percent = UMIN(100, 30 + level + URANGE(-15, (14-get_curr_lck(ch))*3, 20)); if (ntrap) percent -= ntrap->difficulty; if (ntrap && ntrap->toolkit > 0) { for (tool = ch->first_carrying; tool; tool = tool->next_content) { if (tool->item_type == ITEM_TRAPTOOL && tool->value[0] == ntrap->toolkit) percent += ntrap->toolnegate; } } separate_obj(obj); if (number_range(1, 100) > percent) { send_to_char("Ooops!\n\r", ch); pre_spring_trap(ch, trap, ntrap, obj); learn_from_failure(ch, gsn_detrap, NULL); return; } if (ntrap) { if (ntrap->uid >= START_INV_TRAP) { UNLINK(ntrap, first_trap, last_trap, next, prev); ntrap->obj->trap = NULL; DISPOSE(ntrap); save_trap_file(NULL, NULL); } else { ntrap->obj->trap = NULL; ntrap->obj = NULL; ntrap->area = NULL; } } if (trap) extract_obj(trap); send_to_char("You successfully remove a trap.\n\r", ch); learn_from_success(ch, gsn_detrap, NULL); return; } void do_dig(CHAR_DATA * ch, char *argument) { char arg[MIL]; OBJ_DATA *obj; OBJ_DATA *startobj; bool found, shovel; EXIT_DATA *pexit; sh_int mastery; mastery = 10; if (IS_ONMAP_FLAG(ch)) { send_to_char("You cannot dig on an overland map.\n\r", ch); return; } switch (ch->substate) { default: if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } one_argument(argument, arg); if (arg[0] != '\0') { if ((pexit = find_door(ch, arg, TRUE)) == NULL && get_dir(arg) == -1) { send_to_char("What direction is that?\n\r", ch); return; } if (pexit) { if (!IS_SET(pexit->exit_info, EX_DIG) && !IS_SET(pexit->exit_info, EX_CLOSED)) { send_to_char("There is no need to dig out that exit.\n\r", ch); return; } } } else { switch (ch->in_room->sector_type) { case SECT_CITY: case SECT_INSIDE: send_to_char("The floor is too hard to dig through.\n\r", ch); return; case SECT_WATER_SWIM: case SECT_WATER_NOSWIM: case SECT_UNDERWATER: send_to_char("You cannot dig here.\n\r", ch); return; case SECT_AIR: send_to_char("What? In the air?!\n\r", ch); return; } } add_timer(ch, TIMER_DO_FUN, 3, do_dig, 1); ch->alloc_ptr = str_dup(arg); send_to_char("You begin digging...\n\r", ch); act(AT_PLAIN, "$n begins digging...", ch, NULL, NULL, TO_ROOM); return; case 1: if (!ch->alloc_ptr) { send_to_char("Your digging was interrupted!\n\r", ch); act(AT_PLAIN, "$n's digging was interrupted!", ch, NULL, NULL, TO_ROOM); bug("do_dig: alloc_ptr NULL", 0); return; } strcpy(arg, ch->alloc_ptr); DISPOSE(ch->alloc_ptr); break; case SUB_TIMER_DO_ABORT: DISPOSE(ch->alloc_ptr); ch->substate = SUB_NONE; send_to_char("You stop digging...\n\r", ch); act(AT_PLAIN, "$n stops digging...", ch, NULL, NULL, TO_ROOM); return; } ch->substate = SUB_NONE; /* not having a shovel makes it harder to succeed */ shovel = FALSE; for (obj = ch->first_carrying; obj; obj = obj->next_content) if (obj->item_type == ITEM_SHOVEL) { shovel = TRUE; break; } /* dig out an EX_DIG exit... */ if (arg[0] != '\0') { if ((pexit = find_door(ch, arg, TRUE)) != NULL && IS_SET(pexit->exit_info, EX_DIG) && IS_SET(pexit->exit_info, EX_CLOSED)) { if (number_range(1, 100) <= mastery * (shovel ? 8 : 1)) { REMOVE_BIT(pexit->exit_info, EX_CLOSED); send_to_char("You dig open a passageway!\n\r", ch); act(AT_PLAIN, "$n digs open a passageway!", ch, NULL, NULL, TO_ROOM); return; } } send_to_char("Your dig did not discover any exit...\n\r", ch); act(AT_PLAIN, "$n's dig did not discover any exit...", ch, NULL, NULL, TO_ROOM); return; } startobj = ch->in_room->first_content; found = FALSE; for (obj = startobj; obj; obj = obj->next_content) { /* twice as hard to find something without a shovel */ if (IS_OBJ_STAT(obj, ITEM_BURIED) && (number_range(1, 100) <= mastery * (shovel ? 8 : 1))) { found = TRUE; break; } } if (!found) { send_to_char("Your dig uncovered nothing.\n\r", ch); act(AT_PLAIN, "$n's dig uncovered nothing.", ch, NULL, NULL, TO_ROOM); return; } separate_obj(obj); xREMOVE_BIT(obj->extra_flags, ITEM_BURIED); act(AT_SKILL, "Your dig uncovered $p!", ch, obj, NULL, TO_CHAR); act(AT_SKILL, "$n's dig uncovered $p!", ch, obj, NULL, TO_ROOM); if (obj->item_type == ITEM_CORPSE_PC || obj->item_type == ITEM_CORPSE_NPC) adjust_favor(ch, 14, 1); return; } void do_search(CHAR_DATA * ch, char *argument) { char arg[MIL]; OBJ_DATA *obj; OBJ_DATA *container; OBJ_DATA *startobj; int percent, door; sh_int mastery; mastery = 30; door = -1; switch (ch->substate) { default: if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } argument = one_argument(argument, arg); if (arg[0] != '\0' && (door = get_door(arg)) == -1) { container = get_obj_here(ch, arg); if (!container) { send_to_char("You can't find that here.\n\r", ch); return; } if (container->item_type != ITEM_CONTAINER) { send_to_char("You can't search in that!\n\r", ch); return; } if (IS_SET(container->value[1], CONT_CLOSED)) { send_to_char("It is closed.\n\r", ch); return; } } add_timer(ch, TIMER_DO_FUN, 3, do_search, 1); send_to_char("You begin your search...\n\r", ch); ch->alloc_ptr = str_dup(arg); return; case 1: if (!ch->alloc_ptr) { send_to_char("Your search was interrupted!\n\r", ch); bug("do_search: alloc_ptr NULL", 0); return; } strcpy(arg, ch->alloc_ptr); DISPOSE(ch->alloc_ptr); break; case SUB_TIMER_DO_ABORT: DISPOSE(ch->alloc_ptr); ch->substate = SUB_NONE; send_to_char("You stop your search...\n\r", ch); return; } ch->substate = SUB_NONE; if (arg[0] == '\0') startobj = ch->in_room->first_content; else { if ((door = get_door(arg)) != -1) startobj = NULL; else { container = get_obj_here(ch, arg); if (!container) { send_to_char("You can't find that here.\n\r", ch); return; } startobj = container->first_content; } } if ((!startobj && door == -1) || IS_NPC(ch)) { send_to_char("You find nothing.\n\r", ch); return; } percent = mastery; if (door != -1) { EXIT_DATA *pexit; if ((pexit = get_exit(ch->in_room, door)) != NULL && IS_SET(pexit->exit_info, EX_SECRET) && IS_SET(pexit->exit_info, EX_xSEARCHABLE) && number_range(1,100) <= mastery) { act(AT_SKILL, "Your search reveals the $d!", ch, NULL, pexit->keyword, TO_CHAR); act(AT_SKILL, "$n finds the $d!", ch, NULL, pexit->keyword, TO_ROOM); REMOVE_BIT(pexit->exit_info, EX_SECRET); return; } } else for (obj = startobj; obj; obj = obj->next_content) { if (IS_OBJ_STAT(obj, ITEM_HIDDEN) && number_range(1, 100) <= mastery) { separate_obj(obj); xREMOVE_BIT(obj->extra_flags, ITEM_HIDDEN); act(AT_SKILL, "Your search reveals $p!", ch, obj, NULL, TO_CHAR); act(AT_SKILL, "$n finds $p!", ch, obj, NULL, TO_ROOM); return; } } send_to_char("You find nothing.\n\r", ch); return; } void set_thief(CHAR_DATA *ch, CHAR_DATA *victim) { INTRO_DATA *intro = NULL; CHAR_DATA *rch; if (!IS_NPC(victim)) { for (intro = victim->pcdata->first_introduction; intro; intro = intro->next) { if (intro->pid == ch->pcdata->pid && can_see_intro(ch, victim)) { if (intro->value > 0) intro->value *=-1; intro->value -=15000; if (intro->value < -150000) intro->value = -150000; SET_BIT(intro->flags, INTRO_MYTHIEF); REMOVE_BIT(intro->flags, INTRO_THIEF); intro->lastseen = time(0); break; } } } if (!IS_NPC(victim) && !intro && can_see_intro(ch, victim)) { CREATE(intro, INTRO_DATA, 1); intro->pid = ch->pcdata->pid; intro->value = -15000; intro->lastseen = time(0); SET_BIT(intro->flags, INTRO_MYTHIEF); LINK(intro, victim->pcdata->first_introduction, victim->pcdata->last_introduction, next, prev); } for (rch = ch->in_room->first_person; rch; rch = rch->next) { if (!IS_NPC(rch)) { for (intro = rch->pcdata->first_introduction; intro; intro = intro->next) { if (rch->pcdata->pid == intro->pid && rch != ch && rch != victim && can_see_intro(rch, victim)) { if (intro->value > 100000) continue; if (intro->value > 0) intro->value *=-1; intro->value -=15000; if (intro->value < -150000) intro->value = -150000; intro->lastseen = time(0); if (!IS_SET(intro->flags, INTRO_MYTHIEF)) SET_BIT(intro->flags, INTRO_THIEF); break; } } if (!intro && can_see_intro(rch, victim) && rch != ch && rch != victim) { CREATE(intro, INTRO_DATA, 1); intro->pid = ch->pcdata->pid; intro->value = -15000; intro->lastseen = time(0); SET_BIT(intro->flags, INTRO_THIEF); LINK(intro, rch->pcdata->first_introduction, rch->pcdata->last_introduction, next, prev); } save_char_obj(rch); } } if (!IS_NPC(victim)) save_char_obj(victim); save_char_obj(ch); } void do_gathertinder(CHAR_DATA *ch, char *argument) { int chance = 0; OBJ_DATA *tinder; int sector; if (IN_WILDERNESS(ch)) { sector = map_sector[ch->map][ch->coord->x][ch->coord->y]; } else { sector = ch->in_room->sector_type; } if (sector == SECT_FOREST || sector == SECT_STREE || sector == SECT_NTREE) { if (sector == SECT_FOREST) chance = 85; if (sector == SECT_STREE) chance = 55; if (sector == SECT_NTREE) chance = 20; if (number_range(1, 100) <= chance) { act(AT_ORANGE, "$n starts to search around for some free tinder and happens to find some.", ch, NULL, NULL, TO_ROOM); act(AT_ORANGE, "You start to search around for some free tinder and happen to find some!", ch, NULL, NULL, TO_CHAR); tinder = create_object(get_obj_index(OBJ_VNUM_TINDER), 1); if (!tinder) { bug("do_gathertinder. Missing the tinder vnum!"); return; } obj_to_room(tinder, ch->in_room, ch); WAIT_STATE(ch, PULSE_PER_SECOND*4); return; } else { act(AT_GREEN, "$n starts to search around for some free tinder, but happens to find none.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You start to search around for some free tinder, but you happen to fine none.", ch, NULL, NULL, TO_CHAR); WAIT_STATE(ch, PULSE_PER_SECOND*10); return; } } else { send_to_char("This will only work in an area highly populated with trees.\n\r", ch); return; } } void do_startfire(CHAR_DATA * ch, char *argument) { OBJ_DATA *tinder; OBJ_DATA *flint; OBJ_DATA *knife; OBJ_DATA *fire; int sector; int chance; int level = POINT_LEVEL(LEARNED(ch, gsn_startfire), MASTERED(ch, gsn_startfire)); if (IN_WILDERNESS(ch)) { sector = map_sector[ch->map][ch->coord->x][ch->coord->y]; } else { sector = ch->in_room->sector_type; } if ((knife = get_eq_char(ch, WEAR_WIELD)) == NULL) { send_to_char("You need to be wielding some knife like weapon to do this.\n\r", ch); return; } if (wielding_skill_weapon(ch, 0) != 7) { send_to_char("You need to be wielding some knife like weapon to do this.\n\r", ch); return; } for (tinder = ch->first_carrying; tinder; tinder = tinder->next_content) { if (tinder->item_type == ITEM_TINDER) { break; } } if (!tinder) { send_to_char("You need to have some tinder to start a fire. See (HELP STARTFIRE) to see how to get tinder.\n\r", ch); return; } for (flint = ch->first_carrying; flint; flint = flint->next_content) { if (flint->item_type == ITEM_FLINT) { break; } } if (!flint) { send_to_char("You need to have a flint to start a fire. See (HELP STARTFIRE) to see how to get a flint.\n\r", ch); return; } if (sector == SECT_WATER_SWIM || sector == SECT_WATER_NOSWIM || sector == SECT_UNDERWATER || sector == SECT_AIR || sector == SECT_OCEANFLOOR || sector == SECT_OCEAN || sector == SECT_RIVER) { send_to_char("You need dry ground to start a fire.\n\r", ch); return; } chance = 1 + (level*3/2); if (number_range(1, 100) <= chance) { act(AT_RED, "$n pulls out a $p and strikes it against a flint....a fire starts burning up the tinder.", ch, knife, NULL, TO_ROOM); act(AT_RED, "You pull out a $p and strike it against a flint....luckily a fire starts burning up the tinder.", ch, knife, NULL, TO_CHAR); learn_from_success(ch, gsn_startfire, NULL); fire = create_object(get_obj_index(OBJ_VNUM_FIRE), 1); if (!fire) { bug("do_startfire. Missing the fire vnum!"); return; } WAIT_STATE(ch, PULSE_PER_SECOND*2); obj_to_room(fire, ch->in_room, ch); separate_obj(tinder); obj_from_char(tinder); extract_obj(tinder); return; } else { act(AT_GREEN, "$n pulls out a $p and strikes it against a flint....no such luck though creating a fire.", ch, knife, NULL, TO_ROOM); act(AT_GREEN, "You pull out a $p and strike it against a flint.....no luck today, the tinder did not catch fire.", ch, knife, NULL, TO_CHAR); learn_from_failure(ch, gsn_startfire, NULL); WAIT_STATE(ch, PULSE_PER_SECOND*5); return; } } void do_forage(CHAR_DATA * ch, char *argument) { int sector; int food; char name[MSL]; char shortd[MSL]; char longd[MSL]; char arg[MIL]; int fv=1; int chance; int speed = PULSE_PER_SECOND*6; OBJ_DATA *ofood; if (check_npc(ch)) return; if (argument[0] == '\0') { send_to_char("Syntax: forage food [quick/normal/long]\n\r", ch); send_to_char("Syntax: forage water [quick/normal/long]\n\r", ch); return; } if (IN_WILDERNESS(ch)) { sector = map_sector[ch->map][ch->coord->x][ch->coord->y]; } else { sector = ch->in_room->sector_type; } argument = one_argument(argument, arg); if (!str_cmp(arg, "water")) { for (ofood = ch->first_carrying; ofood; ofood = ofood->next_content) { if (ofood->item_type == ITEM_DRINK_CON) { break; } } if (!ofood) { send_to_char("You need something to hold the water.\n\r", ch); return; } if (ofood->value[1] >= ofood->value[0]) { send_to_char("Your drinking container is full.\n\r", ch); return; } if (sector == SECT_WATER_SWIM || sector == SECT_WATER_NOSWIM || sector == SECT_RIVER) { act(AT_GREEN, "$n gets on $s knees and fills up $p with fresh water.", ch, ofood, NULL, TO_ROOM); act(AT_GREEN, "You get on your knees and fill up $p with fresh water.", ch, ofood, NULL, TO_CHAR); ofood->value[1] = ofood->value[0]; learn_from_success(ch, gsn_forage, NULL); WAIT_STATE(ch, speed); return; } else if (sector == SECT_FIELD || sector == SECT_FOREST || sector == SECT_HILLS || sector == SECT_PLAINS || sector == SECT_HCORN || sector == SECT_HGRAIN || sector == SECT_STREE || sector == SECT_NTREE || sector == SECT_SCORN || sector == SECT_NCORN || sector == SECT_SGRAIN || sector == SECT_NGRAIN || sector == SECT_PATH || sector == SECT_STONE || sector == SECT_SSTONE || sector == SECT_NSTONE) { chance = 5 + (POINT_LEVEL(LEARNED(ch, gsn_forage), MASTERED(ch, gsn_forage)/2)); if (!str_cmp(argument, "quick")) { chance -= 15; speed = PULSE_PER_SECOND*3; } else if (!str_cmp(argument, "long")) { chance += 15; speed = PULSE_PER_SECOND*14; } if (number_range(1, 100) > chance) { act(AT_GREEN, "$n gets on $s knees and starts to search for water....but finds none.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You get on your knees and search for water....no water here.", ch, NULL, NULL, TO_CHAR); learn_from_failure(ch, gsn_forage, NULL); WAIT_STATE(ch, speed); return; } else { act(AT_GREEN, "$n gets on $s knees and fills up $p with fresh water.", ch, ofood, NULL, TO_ROOM); act(AT_GREEN, "You get on your knees and fill up $p with fresh water.", ch, ofood, NULL, TO_CHAR); separate_obj(ofood); ofood->value[1] = ofood->value[0]; learn_from_success(ch, gsn_forage, NULL); WAIT_STATE(ch, speed); return; } } else if (sector == SECT_OCEANFLOOR || sector == SECT_OCEAN || sector == SECT_UNDERWATER) { send_to_char("You cannot find fresh water here.\n\r", ch); return; } else { send_to_char("You cannot forage for water here, sorry.\n\r", ch); return; } } if (!str_cmp(arg, "food")) { if (IN_WILDERNESS(ch) && sector == SECT_HCORN && resource_sector[ch->map][ch->coord->x][ch->coord->y] >= 3000) { chance = 30 + (POINT_LEVEL(LEARNED(ch, gsn_forage), MASTERED(ch, gsn_forage)/2)); if (!str_cmp(argument, "quick")) { chance -= 15; speed = PULSE_PER_SECOND*3; } else if (!str_cmp(argument, "long")) { chance += 20; speed = PULSE_PER_SECOND*14; } if (number_range(1, 100) > chance) { act(AT_GREEN, "$n gets on $s knees and starts to forage for food, but is able to find nothing.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You get on your knees and start to forage for food, but you are not able to find anything.", ch, NULL, NULL, TO_CHAR); learn_from_failure(ch, gsn_forage, NULL); WAIT_STATE(ch, speed); return; } sprintf(name, "fresh corn"); sprintf(shortd, "fresh corn"); sprintf(longd, "Someone has left behind some fresh corn for you to eat.\n\r"); fv = 3; } else if (sector == SECT_FIELD || sector == SECT_FOREST || sector == SECT_HILLS || sector == SECT_PLAINS || sector == SECT_STREE || sector == SECT_NTREE) { chance = 5 + (POINT_LEVEL(LEARNED(ch, gsn_forage), MASTERED(ch, gsn_forage)/2)); if (!str_cmp(argument, "quick")) { chance -= 15; speed = PULSE_PER_SECOND*3; } else if (!str_cmp(argument, "long")) { chance += 15; speed = PULSE_PER_SECOND*14; } if (number_range(1, 100) > chance) { act(AT_GREEN, "$n gets on $s knees and starts to forage for food, but is able to find nothing.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You get on your knees and start to forage for food, but you are not able to find anything.", ch, NULL, NULL, TO_CHAR); learn_from_failure(ch, gsn_forage, NULL); WAIT_STATE(ch, speed); return; } food = number_range(1, 10); if (food == 1) { sprintf(name, "barries"); sprintf(shortd, "barries"); sprintf(longd, "Someone has left behind some edible barries for you to eat.\n\r"); fv = 3; } if (food == 2) { sprintf(name, "roots"); sprintf(shortd, "roots"); sprintf(longd, "Someone has left behind some tasty looking roots to eat.\n\r"); fv = 2; } if (food == 3) { sprintf(name, "non-poisonous mushrooms"); sprintf(shortd, "non-poionous mushrooms"); sprintf(longd, "Someone has left behind some non-poisonous mushrooms for you to eat.\n\r"); fv = 3; } if (food == 4) { sprintf(name, "fresh grubs"); sprintf(shortd, "fresh grubs"); sprintf(longd, "Some ever so tasteful fresh grubs has been left here for all to enjoy.\n\r"); fv = 2; } if (food == 5) { sprintf(name, "deer meat"); sprintf(shortd, "left over deer meat"); sprintf(longd, "Someone has left behind some left over deet meat for you to enjoy.\n\r"); fv = 5; } if (food == 6) { sprintf(name, "small apples"); sprintf(shortd, "small apples"); sprintf(longd, "Someone has left behind a small assortment of apples for you to enjoy.\n\r"); fv = 3; } if (food == 7) { sprintf(name, "fresh grapes"); sprintf(shortd, "some frash grapes"); sprintf(longd, "Someone has left behind a small pile of fresh grapes for you to enjoy.\n\r"); fv = 3; } if (food == 8) { sprintf(name, "honey"); sprintf(shortd, "fresh honey"); sprintf(longd, "Someone has left behind a small batch of fresh honey, how delightful!\n\r"); fv = 3; } if (food == 9) { sprintf(name, "eggs"); sprintf(shortd, "mystery eggs"); sprintf(longd, "Someone has left behind some eggs, eggs of what, who knows.\n\r"); fv = 3; } if (food == 10) { sprintf(name, "assorted fresh weeds"); sprintf(shortd, "assorted fresh weeds"); sprintf(longd, "Someone has left behind an assortment of fresh, edible weeds\n\r"); fv = 3; } } else { send_to_char("You cannot forage here, sorry.\n\r", ch); return; } ofood = create_object(get_obj_index(OBJ_VNUM_MUSHROOM), 1); STRFREE(ofood->name); STRFREE(ofood->short_descr); STRFREE(ofood->description); ofood->name = STRALLOC(name); ofood->short_descr = STRALLOC(shortd); ofood->description = STRALLOC(longd); ofood->value[0] = fv; if (get_ch_carry_number(ch) + (get_obj_number(ofood) / ofood->count) > can_carry_n(ch)) { obj_to_room(ofood, ch->in_room, ch); sprintf(name, "Your hands are full, just going to have to leave it on the ground.\n\r"); } else if (get_ch_carry_weight(ch) + (get_obj_weight(ofood) / ofood->count) > can_carry_w(ch)) { obj_to_room(ofood, ch->in_room, ch); sprintf(name, "You cannot carry the extra weight, leaving it on the ground.\n\r"); } else { obj_to_char(ofood, ch); strcpy(name, ""); } act(AT_GREEN, "$n gets on $s knees and starts to forage for food .... and finds $p", ch, ofood, NULL, TO_ROOM); act(AT_GREEN, "You get on your knees and start to forage for food .... and you find $p", ch, ofood, NULL, TO_CHAR); send_to_char(name, ch); WAIT_STATE(ch, speed); return; } else { do_forage(ch, ""); return; } } void do_cutpurse(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int percent; sh_int mastery, m; sh_int level; int amount; mastery = MASTERED(ch, gsn_cutpurse); level = POINT_LEVEL(LEARNED(ch, gsn_cutpurse), MASTERED(ch, gsn_cutpurse)); if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("Attempt a cutpurse on whom?\n\r", ch); return; } if (ms_find_obj(ch)) return; if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("That's pointless.\n\r", ch); return; } if (is_safe(ch, victim)) { set_char_color(AT_MAGIC, ch); send_to_char("A magical force interrupts you.\n\r", ch); return; } if (IS_IMMORTAL(victim)) { send_to_char("You cannot steal from immortals.\n\r", ch); bug("%s tried to steal from an immortal", ch->name); return; } if (xIS_SET(victim->act, ACT_PACIFIST)) /* Gorog */ { send_to_char("They are a pacifist - Shame on you!\n\r", ch); return; } if (wielding_skill_weapon(ch, 0) != 7) { send_to_char("You can only cutpurse if you are wielding a dagger like weapon.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_cutpurse]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_cutpurse, NULL); percent = 20+(level/2) + (IS_AWAKE(victim) ? 0 : 50) + UMIN(10, ((get_curr_lck(ch)-14)/2) + ((get_curr_dex(ch)-14)/2)); if (mastery < 3 && ch->position != POS_STANDING) percent = 0; else { if (ch->position == POS_BERSERK || ch->position == POS_AGGRESSIVE || ch->position == POS_FIGHTING || ch->position == POS_DEFENSIVE || ch->position == POS_EVASIVE) { if (mastery < 4) percent /= 2; } else percent = 0; } if (percent > 0) { if (mastery == 3) percent+=5; if (mastery == 4) percent+=10; } if (!IS_NPC(victim) && check_room_pk(ch) < 2) { send_to_char("You can only steal coins from players in noloot zones or higher.\n\r", ch); return; } if (!can_see(victim, ch)) percent+=20; percent = UMIN(95, percent); if (level < number_range(1, 100)) { /* * Failure. */ send_to_char("Oops...\n\r", ch); learn_from_failure(ch, gsn_cutpurse, victim); affect_strip(ch, gsn_invis); affect_strip(ch, gsn_mass_invis); affect_strip(ch, gsn_sneak); affect_strip(ch, gsn_stalk); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_INVISIBLE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); xREMOVE_BIT(ch->affected_by, AFF_STALK); m = 25+(mastery*10); if (number_range(1, 100) > m) { act(AT_ACTION, "$n tried to steal money from you!", ch, NULL, victim, TO_VICT); act(AT_ACTION, "$n tried to steal money from $N.", ch, NULL, victim, TO_NOTVICT); if (!IS_NPC(victim)) { if (legal_loot_coins(ch, victim)) { set_thief(ch, victim); } } else global_retcode = one_hit(victim, ch, TYPE_UNDEFINED, LM_BODY); } return; } if (IS_NPC(ch)) { amount = (int) (victim->gold * number_range(12, 16) / 100); } else { if (mastery == 4) amount = (int) (victim->gold * number_range(20, 25) / 100); else if (mastery == 3) amount = (int) (victim->gold * number_range(15, 20) / 100); else if (mastery == 2) amount = (int) (victim->gold * number_range(12, 16) / 100); else amount = (int) (victim->gold * number_range(8, 13) / 100); } if (amount <= 0) { send_to_char("You couldn't get any gold.\n\r", ch); learn_from_failure(ch, gsn_cutpurse, victim); return; } ch->gold += amount; victim->gold -= amount; ch_printf(ch, "Aha! You got %d gold coins.\n\r", amount); learn_from_success(ch, gsn_cutpurse, victim); return; } void do_grab(CHAR_DATA *ch, char *argument) { char arg1[MIL]; char arg2[MIL]; CHAR_DATA *victim; OBJ_DATA *obj; int percent; sh_int mastery; sh_int level; mastery = MASTERED(ch, gsn_grab); level = POINT_LEVEL(LEARNED(ch, gsn_grab), MASTERED(ch, gsn_grab)); argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (arg1[0] == '\0' || arg2[0] == '\0') { send_to_char("Grab what from whom?\n\r", ch); return; } if (ms_find_obj(ch)) return; if ((victim = get_char_room_new(ch, arg2, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("That's pointless.\n\r", ch); return; } if (is_safe(ch, victim)) { set_char_color(AT_MAGIC, ch); send_to_char("A magical force interrupts you.\n\r", ch); return; } if (IS_IMMORTAL(victim)) { send_to_char("You cannot steal from immortals.\n\r", ch); bug("%s tried to steal from an immortal", ch->name); return; } if (xIS_SET(victim->act, ACT_PACIFIST)) /* Gorog */ { send_to_char("They are a pacifist - Shame on you!\n\r", ch); return; } if (ch->position != POS_STANDING) { send_to_char("You can only grab an item if you are standing.\n\r", ch); return; } if (can_see(victim, ch)) { send_to_char("This will only work if the target cannot see you.\n\r", ch); return; } if (!IS_NPC(victim) && check_room_pk(ch) < 4) { send_to_char("You can only steal items from players in fulloot zones or higher.\n\r", ch); return; } if (xIS_SET(victim->act, ACT_GRABBED)) { send_to_char("Your target has already had an attempt made, he/she will not fall for it again.\n\r", ch); return; } if ((obj = get_obj_wear(victim, arg1)) == NULL) { send_to_char("You can't seem to find the object in question.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_steal]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_steal, NULL); percent = 20+(level/2) + (IS_AWAKE(victim) ? 0 : 50) + UMIN(10, ((get_curr_lck(ch)-14)/2) + ((get_curr_dex(ch)-14)/2)); if (mastery == 3) percent+=5; if (mastery == 4) percent+=10; percent = UMIN(95, percent); if (level < number_range(1, 100)) { /* * Failure. */ send_to_char("Oops...\n\r", ch); learn_from_failure(ch, gsn_grab, victim); affect_strip(ch, gsn_invis); affect_strip(ch, gsn_mass_invis); affect_strip(ch, gsn_sneak); affect_strip(ch, gsn_stalk); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_INVISIBLE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); xREMOVE_BIT(ch->affected_by, AFF_STALK); if (IS_NPC(victim)) xSET_BIT(victim->act, ACT_GRABBED); act(AT_ACTION, "$n tried to grab $p from you!", ch, obj, victim, TO_VICT); act(AT_ACTION, "$n tried to grab $p from $N.", ch, obj, victim, TO_NOTVICT); if (!IS_NPC(victim)) { if (legal_loot(ch, victim)) { set_thief(ch, victim); } } else { global_retcode = one_hit(victim, ch, TYPE_UNDEFINED, LM_BODY); } return; } if (!can_drop_obj(ch, obj) || IS_OBJ_STAT(obj, ITEM_INVENTORY) || IS_OBJ_STAT(obj, ITEM_PROTOTYPE) || obj->level > ch->level) { send_to_char("You can't manage to pry it away.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_NOGIVE)) { send_to_char("You cannot grab an item that is nogive, sorry.\n\r", ch); return; } if (IS_UNIQUE(ch, obj)) { send_to_char("You already have one, cannot grab another.\n\r", ch); return; } if (get_ch_carry_number(ch) + (get_obj_number(obj) / obj->count) > can_carry_n(ch)) { send_to_char("You have your hands full.\n\r", ch); return; } if (get_ch_carry_weight(ch) + (get_obj_weight(obj) / obj->count) > can_carry_w(ch)) { send_to_char("You can't carry that much weight.\n\r", ch); return; } separate_obj(obj); unequip_char(victim, obj); obj_from_char(obj); obj_to_char(obj, ch); learn_from_success(ch, gsn_grab, victim); adjust_favor(ch, 9, 1); affect_strip(ch, gsn_invis); affect_strip(ch, gsn_mass_invis); affect_strip(ch, gsn_sneak); affect_strip(ch, gsn_stalk); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_INVISIBLE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); xREMOVE_BIT(ch->affected_by, AFF_STALK); act(AT_ACTION, "You grab $p from $N.", ch, obj, victim, TO_CHAR); act(AT_ACTION, "$n grabs $p from you!", ch, obj, victim, TO_VICT); act(AT_ACTION, "$n grabs $p from $N.", ch, obj, victim, TO_NOTVICT); if (IS_NPC(victim)) xSET_BIT(victim->act, ACT_GRABBED); if (!IS_NPC(ch)) { if (legal_loot(ch, victim)) { set_thief(ch, victim); } } else global_retcode = one_hit(victim, ch, TYPE_UNDEFINED, LM_BODY); return; } void do_steal(CHAR_DATA * ch, char *argument) { char arg1[MIL]; char arg2[MIL]; CHAR_DATA *victim; OBJ_DATA *obj; int percent; sh_int mastery, m; sh_int level; mastery = MASTERED(ch, gsn_steal); level = POINT_LEVEL(LEARNED(ch, gsn_steal), MASTERED(ch, gsn_steal)); argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (arg1[0] == '\0' || arg2[0] == '\0') { send_to_char("Steal what from whom?\n\r", ch); return; } if (ms_find_obj(ch)) return; if ((victim = get_char_room_new(ch, arg2, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("That's pointless.\n\r", ch); return; } if (is_safe(ch, victim)) { set_char_color(AT_MAGIC, ch); send_to_char("A magical force interrupts you.\n\r", ch); return; } if (IS_IMMORTAL(victim)) { send_to_char("You cannot steal from immortals.\n\r", ch); bug("%s tried to steal from an immortal", ch->name); return; } /* Disabled stealing among players because of complaints naked avatars were running around stealing eq from equipped pkillers. -- Narn */ /* if ( check_illegal_psteal( ch, victim ) ) { send_to_char( "You can't steal from that player.\n\r", ch ); return; } */ /* if (!IS_NPC(ch) && !IS_NPC(victim)) { set_char_color(AT_IMMORT, ch); send_to_char("The gods forbid theft between players.\n\r", ch); return; } */ if (xIS_SET(victim->act, ACT_PACIFIST)) /* Gorog */ { send_to_char("They are a pacifist - Shame on you!\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_steal]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_steal, NULL); percent = 25+(level*2/3) + (IS_AWAKE(victim) ? 0 : 50) + UMIN(10, ((get_curr_lck(ch)-14)/2) + ((get_curr_dex(ch)-14)/2)); if (mastery < 3 && ch->position != POS_STANDING) percent = 0; else { if (ch->position == POS_BERSERK || ch->position == POS_AGGRESSIVE || ch->position == POS_FIGHTING || ch->position == POS_DEFENSIVE || ch->position == POS_EVASIVE) { if (mastery < 4) percent /= 2; } else percent = 0; } if (percent > 0) { if (mastery == 3) percent+=10; if (mastery == 4) percent+=20; } if (!can_see(victim, ch)) percent+=30; if (str_cmp(arg1, "coin") && str_cmp(arg1, "coins") && str_cmp(arg1, "gold")) { percent/=2; if (check_room_pk(ch) < 4 && !IS_NPC(victim)) { send_to_char("You can only steal items from players in fulloot zones or higher.\n\r", ch); return; } } else { if (check_room_pk(ch) < 2 && !IS_NPC(victim)) { send_to_char("You can only steal coins from players in noloot zones or higher.\n\r", ch); return; } } percent = UMIN(95, percent); if (level < number_range(1, 100)) { /* * Failure. */ send_to_char("Oops...\n\r", ch); learn_from_failure(ch, gsn_steal, victim); affect_strip(ch, gsn_invis); affect_strip(ch, gsn_mass_invis); affect_strip(ch, gsn_sneak); affect_strip(ch, gsn_stalk); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_INVISIBLE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); xREMOVE_BIT(ch->affected_by, AFF_STALK); m = 35+(mastery*15); if (number_range(1, 100) > m) { act(AT_ACTION, "$n tried to steal from you!", ch, NULL, victim, TO_VICT); act(AT_ACTION, "$n tried to steal from $N.", ch, NULL, victim, TO_NOTVICT); if (!IS_NPC(victim)) { if (legal_loot_coins(ch, victim)) { set_thief(ch, victim); } } else global_retcode = one_hit(victim, ch, TYPE_UNDEFINED, LM_BODY); } return; } if (!str_cmp(arg1, "coin") || !str_cmp(arg1, "coins") || !str_cmp(arg1, "gold")) { int amount; if (IS_NPC(ch)) { amount = (int) (victim->gold * number_range(1, 7) / 100); } else { if (mastery == 4) amount = (int) (victim->gold * number_range(3, 13) / 100); else if (mastery == 3) amount = (int) (victim->gold * number_range(1, 10) / 100); else if (mastery == 2) amount = (int) (victim->gold * number_range(1, 7) / 100); else amount = (int) (victim->gold * number_range(1, 5) / 100); } if (amount <= 0) { send_to_char("You couldn't get any gold.\n\r", ch); learn_from_failure(ch, gsn_steal, victim); return; } ch->gold += amount; victim->gold -= amount; ch_printf(ch, "Aha! You got %d gold coins.\n\r", amount); learn_from_success(ch, gsn_steal, victim); return; } if ((obj = get_obj_carry(victim, arg1)) == NULL) { send_to_char("You can't seem to find it.\n\r", ch); return; } if (!can_drop_obj(ch, obj) || IS_OBJ_STAT(obj, ITEM_INVENTORY) || IS_OBJ_STAT(obj, ITEM_PROTOTYPE) || obj->level > ch->level) { send_to_char("You can't manage to pry it away.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_NOGIVE)) { send_to_char("You cannot steal an item that is nogive, sorry.\n\r", ch); return; } if (IS_UNIQUE(ch, obj)) { send_to_char("You already have one, cannot steal another.\n\r", ch); return; } if (get_ch_carry_number(ch) + (get_obj_number(obj) / obj->count) > can_carry_n(ch)) { send_to_char("You have your hands full.\n\r", ch); return; } if (get_ch_carry_weight(ch) + (get_obj_weight(obj) / obj->count) > can_carry_w(ch)) { send_to_char("You can't carry that much weight.\n\r", ch); return; } separate_obj(obj); obj_from_char(obj); obj_to_char(obj, ch); if (!can_see(victim, ch)) level += 60; if (number_range(1, 100) > level/2) { act(AT_ACTION, "You steal $p from $N. It appears $N might of noticed", ch, obj, victim, TO_CHAR); act(AT_ACTION, "You feel like you are missing something.....", ch, obj, victim, TO_VICT); } else { act(AT_ACTION, "You steal $p from $N. It appears $N did not notice it.", ch, obj, victim, TO_CHAR); } learn_from_success(ch, gsn_steal, victim); adjust_favor(ch, 9, 1); return; } void do_assassinate(CHAR_DATA *ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; OBJ_DATA *obj; int percent; sh_int mastery; int level; mastery = MASTERED(ch, gsn_assassinate); level = POINT_LEVEL(LEARNED(ch, gsn_assassinate), MASTERED(ch, gsn_assassinate)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't do that right now.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't get close enough while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Assassinate whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("How can you sneak up on yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 7) { send_to_char("You can only assassinate with a dagger.\n\r", ch); return; } if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) { send_to_char("You are not wielding a weapon.\n\r", ch); return; } if (victim->fighting) { send_to_char("You can't assassinate someone who is in combat.\n\r", ch); return; } /* Can backstab a char even if it's hurt as long as it's sleeping. -Narn */ if (victim->hit < victim->max_hit && IS_AWAKE(victim)) { act(AT_PLAIN, "$N is hurt and suspicious ... you can't sneak up.", ch, NULL, victim, TO_CHAR); return; } percent = 5 + (level/3) + UMIN(10, ((get_curr_dex(ch)-14)/2) + ((get_curr_lck(ch)-14)/2)); if (can_see(victim, ch)) percent /= 3; percent -= (victim->max_hit - ch->max_hit) / 30; if (victim->max_hit >= 5000) percent = 0; else percent = URANGE(5, percent, 95); check_attacker(ch, victim); if (!IS_AWAKE(victim) || number_range(1, 100) <= percent) { learn_from_success(ch, gsn_assassinate, victim); act(AT_RED, "You slide behind $N and in a quick motion to slit $S throat. Blood pours EVERYWHERE!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n slides behind you and in a quick motion slitting your throat.", ch, NULL, victim, TO_VICT); act(AT_RED, "$n slides behind $N and in a quick motion to slit $S throat. Blood pours EVERYWHERE!", ch, NULL, victim, TO_NOTVICT); damage(ch, victim, 50, TYPE_HIT, DM_DEATH, LM_NECK); } else { act(AT_RED, "You slide behind $N and in a quick motion to slit $S throat, but you fail", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n slides behind you and in a quick motion to slit your throat, but fails.", ch, NULL, victim, TO_VICT); act(AT_RED, "$n slides behind $N and in a quick motion to slit $S throat, but fails.", ch, NULL, victim, TO_NOTVICT); learn_from_failure(ch, gsn_assassinate, victim); one_hit(ch, victim, TYPE_HIT, LM_BODY); } return; } void do_backstab(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; OBJ_DATA *obj; int percent; sh_int mastery; int level; mastery = MASTERED(ch, gsn_backstab); level = POINT_LEVEL(LEARNED(ch, gsn_backstab), MASTERED(ch, gsn_backstab)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't do that right now.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't get close enough while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Backstab whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("How can you sneak up on yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 7) { send_to_char("You can only backstab with a dagger.\n\r", ch); return; } if (ch->grip != GRIP_STAB) { send_to_char("You can only use backstab if you are gripping your dagger for a stab strike.\n\r", ch); return; } if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL) { send_to_char("You are not wielding a weapon.\n\r", ch); return; } if (victim->fighting) { send_to_char("You can't backstab someone who is in combat.\n\r", ch); return; } /* Can backstab a char even if it's hurt as long as it's sleeping. -Narn */ if (victim->hit < victim->max_hit && IS_AWAKE(victim)) { act(AT_PLAIN, "$N is hurt and suspicious ... you can't sneak up.", ch, NULL, victim, TO_CHAR); return; } percent = 40 + (level/2) + UMIN(10, (14-get_curr_dex(ch)) + (14-get_curr_lck(ch))); if (!can_see(victim, ch)) percent+=30; if (mastery == 4) percent=95; percent = UMIN(95, percent); check_attacker(ch, victim); if (!IS_AWAKE(victim) || number_range(1, 100) <= percent) { learn_from_success(ch, gsn_backstab, victim); global_retcode = one_hit(ch, victim, gsn_backstab, LM_BODY); adjust_favor(ch, 10, 1); check_illegal_pk(ch, victim); } else { learn_from_failure(ch, gsn_backstab, victim); global_retcode = damage(ch, victim, 0, gsn_backstab, 0, LM_BODY); ch->fight_timer = get_btimer(ch, -1, NULL); } return; } void do_rescue(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; CHAR_DATA *fch; int percent; int level; int adiff = 0; int aggroc, aggrov; AGGRO_DATA *aggro; aggroc = aggrov = -1; level = POINT_LEVEL(LEARNED(ch, gsn_rescue), MASTERED(ch, gsn_rescue)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_BERSERK)) { send_to_char("You aren't thinking clearly...\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Rescue whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("How about fleeing instead?\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (!IS_NPC(ch) && IS_NPC(victim)) { send_to_char("They don't need your help!\n\r", ch); return; } if (!ch->fighting) { send_to_char("Too late...\n\r", ch); return; } if ((fch = who_fighting(victim)) == NULL) { send_to_char("They are not fighting right now.\n\r", ch); return; } if (who_fighting(victim) == ch) { send_to_char("Just running away would be better...\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_BERSERK)) { send_to_char("Stepping in front of a berserker would not be an intelligent decision.\n\r", ch); return; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } if (IS_NPC(victim->fighting->who)) { for (aggro = victim->fighting->who->first_aggro; aggro; aggro = aggro->next) { if (aggro->ch == victim) aggrov = aggro->value; if (aggro->ch == ch) aggroc = aggro->value; } adiff = URANGE(-20, (aggrov - aggroc)/3, 30); } percent = 10 + URANGE(-3, (get_curr_lck(ch) - 14)/2, 3) + URANGE(-3, (get_curr_lck(victim) - 14)/2, 3); percent += URANGE(1, level/3, 25); percent -= adiff; percent = URANGE(5, percent, 70); if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_rescue]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_rescue, NULL); if (number_range(1, 100) > percent) { send_to_char("You fail the rescue.\n\r", ch); act(AT_SKILL, "$n tries to rescue you!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "$n tries to rescue $N!", ch, NULL, victim, TO_NOTVICT); learn_from_failure(ch, gsn_rescue, victim); return; } act(AT_SKILL, "You rescue $N!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n rescues you!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "$n moves in front of $N!", ch, NULL, victim, TO_NOTVICT); learn_from_success(ch, gsn_rescue, victim); adjust_favor(ch, 8, 1); if (aggrov > aggroc) { for (aggro = victim->fighting->who->first_aggro; aggro; aggro = aggro->next) { if (aggro->ch == ch) aggro->value = aggrov+1; } } stop_fighting(fch, FALSE); stop_fighting(victim, FALSE); if (ch->fighting) stop_fighting(ch, FALSE); set_fighting(ch, fch); set_fighting(fch, ch); return; } //Take up less space, put all the normal checks in here -- Xerves int check_battle_skills(CHAR_DATA *ch, CHAR_DATA *victim, sh_int usgn) { if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return 0; } if (IS_NPC(ch) || ch->pcdata->ranking[usgn] <= 0) { send_to_char("You better leave the martial arts to those who have the knowledge.\n\r", ch); return 0; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return 0; } return 1; } int get_limb_location args((int limb)); //Similar to one_hit, checks to make sure you hit, adds bonuses int check_combat_hit(CHAR_DATA *ch, CHAR_DATA *victim, int dam, int at, int wear, int usgn) { sh_int victim_ac = 0; sh_int armor_ac = 0; sh_int weapon_ac = 0; int block = 0; sh_int tohit, mastery, hnum, percent, holder; OBJ_DATA *eq; OBJ_DATA *wield; OBJ_DATA *damobj; sh_int dameq; int miss = 0; int counter = 0; sh_int mry, pv, tol, lvl; int suc = 0; int limb; OBJ_DATA *shield; int cond; int noarmor = 0; holder = -1; mry = MASTERED(ch, usgn); pv = LEARNED(ch, usgn); lvl = POINT_LEVEL(pv, mry); tol = 2+lvl/6; blockdam = 0; if (wear == WEAR_HEAD) limb = LM_HEAD; else if (wear == WEAR_NECK) limb = LM_NECK; else if (wear == WEAR_ARM_R) limb = LM_RARM; else if (wear == WEAR_ARM_L) limb = LM_LARM; else if (wear == WEAR_LEG_R) limb = LM_RLEG; else if (wear == WEAR_LEG_L) limb = LM_LLEG; else limb = LM_BODY; if ((eq = get_eq_char(victim, wear)) == NULL) { if (IS_NPC(victim)) { armor_ac = victim->armor; weapon_ac += tol; if (victim->armor == 0) noarmor = 1; if (wear == WEAR_HEAD) armor_ac += 2; else if (wear == WEAR_NECK) armor_ac += 3; } else armor_ac = 0; } else { if (at == GRIP_BASH) { armor_ac = eq->value[0]; weapon_ac += tol; } else if (at == GRIP_STAB) { armor_ac = eq->value[2]; weapon_ac += tol; } else if (at == GRIP_SLASH) { armor_ac = eq->value[1]; weapon_ac += tol; } } if (armor_ac == 0) noarmor = 1; if (eq) cond = eq->value[3]; else cond = 1000*victim->hit/victim->max_hit; if ((wield = get_eq_char(ch, WEAR_WIELD)) != NULL) { if (IS_OBJ_STAT(wield, ITEM_MONKWEAPON)) { if (at == GRIP_BASH) weapon_ac += wield->value[7]; if (at == GRIP_SLASH) weapon_ac += wield->value[8]; if (at == GRIP_STAB) weapon_ac += wield->value[9]; } } if (armor_ac > 0) { armor_ac -= (3 -(cond / 251)); if (armor_ac < 1) armor_ac = 1; } victim_ac = armor_ac - weapon_ac; //negative is a better to hit //negative is a better to hit /* if you can't see what's coming... */ if (!can_see(ch, victim)) victim_ac += 1; if (!can_see(victim, ch)) victim_ac -= 1; tohit = get_hit_or_miss(ch, victim, victim_ac, at, limb, noarmor, NULL, -1); if ((shield = get_eq_char(victim, WEAR_SHIELD)) != NULL && IS_AWAKE(victim)) { int spoints = POINT_LEVEL(GET_POINTS(victim, gsn_shieldblock, 0, 1), GET_MASTERY(victim, gsn_shieldblock, 0, 1)); if (spoints > 0 && number_range(1, 100) <= UMIN(95, (UMIN(15, URANGE(-20, victim->apply_shield, 20)/2))+ shield->value[2]+ (spoints/4))) { learn_from_success(victim, gsn_shieldblock, NULL); block = 1; } else { if (spoints > 0) learn_from_failure(victim, gsn_shieldblock, NULL); } } else if (victim->apply_shield > 0) { if (number_range(1, 100) <= URANGE(-20, victim->apply_shield, 20)) block = 1; } if (tohit == DM_MISS || block) //miss or block { /* Miss. */ miss = 1; } dam += str_app[get_curr_str(ch)].todam; //Strength Bonus if (wield) { if (IS_OBJ_STAT(wield, ITEM_MONKWEAPON)) { dam += number_range(wield->value[1], wield->value[2]); } } if (dam <= 3) { if (number_range(1, 5) == 1) suc = 1; } else if (dam <= 6) { if (number_range(1, 3) == 1) suc = 1; } else if (dam <= 10) { if (number_range(1, 2) == 1) suc = 1; } else { suc = 1; } if (miss != 1) { dam -= URANGE(-6, victim->apply_stone, 6); dam -= URANGE(-4, victim->apply_hardening, 4); if (victim->apply_hardening > 0) check_aff_learn(victim, "bracing", 0, ch, 1); if (!IS_NPC(victim) && victim->pcdata->learned[gsn_krundi_style] > 0) { int level; level = POINT_LEVEL(LEARNED(victim, gsn_krundi_style), MASTERED(victim, gsn_krundi_style)); level = number_range(level*3, level*4); level += 100; level = URANGE(100, level, 600); dam -= level/100; level = level % 100; if (number_range(1, 100) <= level) { dam--; } learn_from_success(victim, gsn_krundi_style, ch); } dam = UMAX(1, dam); } //Calculated fightstyle damage if (miss != 1 && suc) { dam = get_fightingstyle_dam(victim, dam, ch, 0, 1); dam = get_fightingstyle_dam(ch, dam, victim, 1, 1); } else { dam = get_fightingstyle_dam(victim, dam, ch, 0, 0); dam = get_fightingstyle_dam(ch, dam, victim, 1, 0); } if (!IS_NPC(ch) && ch->pcdata->learned[gsn_concentration] > 0) { int dam1, dam2, level; level = POINT_LEVEL(LEARNED(ch, gsn_concentration), MASTERED(ch, gsn_concentration)); mastery = MASTERED(ch, gsn_concentration); dam1 = level/15; if (mastery == 6) hnum = number_range(35, 30); else if (mastery == 5) hnum = number_range(30, 25); else if (mastery == 4) hnum = number_range(18, 25); else if (mastery == 3) hnum = number_range(10, 17); else if (mastery == 2) hnum = number_range(5, 10); else hnum = number_range(1, 5); dam2 = (int) (dam * hnum / 150); if (dam1 < dam2) dam += dam1; else dam += dam2; if (miss != 1 && suc) learn_from_success(ch, gsn_concentration, victim); } if (!IS_NPC(ch) && ch->pcdata->learned[gsn_enhanced_damage] > 0) { int dam1, dam2, level; level = POINT_LEVEL(LEARNED(ch, gsn_enhanced_damage), MASTERED(ch, gsn_enhanced_damage)); mastery = MASTERED(ch, gsn_enhanced_damage); dam1 = level/10; if (mastery == 6) hnum = number_range(35, 30); else if (mastery == 5) hnum = number_range(30, 25); else if (mastery == 4) hnum = number_range(18, 25); else if (mastery == 3) hnum = number_range(10, 17); else if (mastery == 2) hnum = number_range(5, 10); else hnum = number_range(1, 5); dam2 = (int) (dam * hnum / 100); if (dam1 < dam2) dam += dam1; else dam += dam2; if (miss != 1 && suc) learn_from_success(ch, gsn_enhanced_damage, victim); } if (!IS_NPC(ch) && ch->pcdata->learned[gsn_deadly_accuracy] > 0) { int dam1, dam2, level; level = POINT_LEVEL(LEARNED(ch, gsn_deadly_accuracy), MASTERED(ch, gsn_deadly_accuracy)); mastery = MASTERED(ch, gsn_deadly_accuracy); dam1 = level/15; if (mastery == 6) hnum = number_range(35, 30); else if (mastery == 5) hnum = number_range(30, 25); else if (mastery == 4) hnum = number_range(18, 25); else if (mastery == 3) hnum = number_range(10, 17); else if (mastery == 2) hnum = number_range(5, 10); else hnum = number_range(1, 5); dam2 = (int) (dam * hnum / 150); if (dam1 < dam2) dam += dam1; else dam += dam2; if (miss != 1 && suc) learn_from_success(ch, gsn_deadly_accuracy, victim); } if (!IS_AWAKE(victim)) dam *= 2; if (!IS_NPC(victim) && victim->pcdata->learned[gsn_counter] > 0 && victim->pcdata->ranking[gsn_counter] > 0 && !xIS_SET(victim->act, PLR_COUNTER)) { percent = number_range(1, 10000); mastery = MASTERED(ch, gsn_counter); if (mastery == 6) hnum = number_range(220, 200); else if (mastery == 5) hnum = number_range(180, 160); else if (mastery == 4) hnum = number_range(135, 150); else if (mastery == 3) hnum = number_range(90, 105); else if (mastery == 2) hnum = number_range(50, 90); else hnum = number_range(20, 45); if (victim->pcdata->tier > 1) holder = holder + 200; if (victim->pcdata->caste > 5) holder = holder + 100; holder += 100 * (get_curr_dex(victim) - get_curr_dex(ch)); holder += 50 * (get_curr_lck(victim) - get_curr_lck(ch)); holder += 100 * (get_curr_str(victim) - get_curr_str(ch)); if (percent < holder) { counter = 1; learn_from_success(victim, gsn_counter, ch); } } if (dam <= 0) dam = 1; /* immune to damage */ if (dam == -1) { return 0; } if(xIS_SET(victim->act, ACT_UNDEAD)) { if(!wield || (wield && !xIS_SET(wield->extra_flags, ITEM_BLESS) && !xIS_SET(wield->extra_flags, ITEM_SANCTIFIED))) { return 0; } if(xIS_SET(wield->extra_flags, ITEM_BLESS) && wield->bless_dur > 0) { if (dam) wield->bless_dur -= 1; if(xIS_SET(wield->extra_flags, ITEM_BLESS) && wield->bless_dur <= 0) { xTOGGLE_BIT(wield->extra_flags, ITEM_BLESS); act(AT_MAGIC, "Your $p stops glowing...\n\r", ch, wield, NULL, TO_CHAR); } } } if(xIS_SET(victim->act, ACT_LIVING_DEAD)) { if(!wield || (wield && !xIS_SET(wield->extra_flags, ITEM_BLESS) && !xIS_SET(wield->extra_flags, ITEM_SANCTIFIED))) { dam = dam / 2; } if(wield && (xIS_SET(wield->extra_flags, ITEM_BLESS) || xIS_SET(wield->extra_flags, ITEM_SANCTIFIED))) { dam = dam * 2; } if(wield && xIS_SET(wield->extra_flags, ITEM_BLESS) && wield->bless_dur > 0) { if (dam) wield->bless_dur -= 1; if(xIS_SET(wield->extra_flags, ITEM_BLESS) && wield->bless_dur <= 0) { xTOGGLE_BIT(wield->extra_flags, ITEM_BLESS); act(AT_MAGIC, "Your $p stops glowing...\n\r", ch, wield, NULL, TO_CHAR); } } } /* Counter Attack Check -- Xerves 8/25/99 */ if (counter == 1) { damage(victim, ch, dam, TYPE_HIT, DM_COUNTER, LM_BODY); return 0; } if (!block && (tohit == DM_HIT || tohit == DM_CRITICAL || tohit == DM_SLICEDLIMB)) { /* damage eq */ dameq = get_limb_location(limb); damobj = get_eq_char(victim, dameq); if (damobj) { if (number_range(1, 100) > (50 + (get_obj_resistance(damobj, victim) * 5/2))) { set_cur_obj(damobj); damage_obj(damobj, victim, 0, dam); } } } damobj = NULL; // Weapon deteriates over time... if (wield && (tohit == DM_HIT || tohit == DM_CRITICAL || tohit == DM_SLICEDLIMB)) { damobj = wield; if (damobj) { if (number_range(1, 100) > (40 + (get_obj_resistance(damobj, ch) * 3))) { set_cur_obj(damobj); damage_obj(damobj, ch, 0, dam); } } } if (block) { damobj = get_eq_char(victim, WEAR_SHIELD); if (damobj) { set_cur_obj(damobj); damage_obj(damobj, ch, 0, dam); } } if (tohit == DM_DEATH) return 5000; //Critical attack else if (block == 1) { blockdam = dam; return -1; } else if (tohit == DM_MISS) return 0; else { if (tohit > 200) return (tohit-100)*dam*100; dam = dam*(tohit-100) / 100; dam += URANGE(-15, ch->apply_sanctify, 15); dam += URANGE(-10, ch->apply_manaburn, 10); if (ch->apply_manaburn > 0 && skill_lookup("arrowcatch") > 0 && LEARNED(ch, skill_lookup("arrowcatch")) > 0) learn_from_success(ch, skill_lookup("arrowcatch"), victim); if (tohit > -300 && dam <= 0) dam = 0; return dam; } return 1; } CHAR_DATA *get_battle_target(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim = NULL; victim = who_fighting(ch); if ((victim = get_char_room_new(ch, argument, 1)) != NULL) return victim; else if ((victim = who_fighting(ch)) != NULL) return victim; else return NULL; } //Below are the 20 combat skills, enjoy -- Xerves void do_roundhouse(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_SLASH; usgn = gsn_roundhouse; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = pv; dam = check_combat_hit(ch, victim, dam, at, WEAR_HEAD, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_HEAD); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_HEAD); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_HEAD); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_HEAD); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_HEAD); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_HEAD); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_spinkick(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_SLASH; usgn = gsn_spinkick; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 3 + lvl * 30 / 100; dam = check_combat_hit(ch, victim, dam, at, WEAR_HEAD, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_HEAD); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_HEAD); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_HEAD); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_HEAD); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_HEAD); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_HEAD); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_tornadokick(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_BASH; usgn = gsn_tornadokick; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 5 + lvl*40/100; dam = check_combat_hit(ch, victim, dam, at, WEAR_HEAD, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_HEAD); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_HEAD); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_HEAD); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_HEAD); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_HEAD); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_HEAD); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_niburo(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_BASH; usgn = gsn_niburo; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 7 + lvl * 55/100; dam = check_combat_hit(ch, victim, dam, at, WEAR_HEAD, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_HEAD); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_HEAD); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_HEAD); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_HEAD); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_HEAD); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_HEAD); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_neckpinch(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_STAB; usgn = gsn_neckpinch; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = pv+1; dam = check_combat_hit(ch, victim, dam, at, WEAR_NECK, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_NECK); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_NECK); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_NECK); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_NECK); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_NECK); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_NECK); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_neckchop(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_SLASH; usgn = gsn_neckchop; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 3 + lvl * 35 / 100; dam = check_combat_hit(ch, victim, dam, at, WEAR_NECK, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_NECK); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_NECK); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_NECK); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_NECK); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_NECK); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_NECK); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_neckrupture(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_STAB; usgn = gsn_neckrupture; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 5 + lvl * 45/ 100; dam = check_combat_hit(ch, victim, dam, at, WEAR_NECK, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_NECK); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_NECK); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_NECK); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_NECK); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_NECK); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_NECK); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_emeru(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_STAB; usgn = gsn_emeru; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 7 + lvl * 60 / 100; dam = check_combat_hit(ch, victim, dam, at, WEAR_NECK, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_NECK); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_NECK); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_NECK); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_NECK); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_NECK); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_NECK); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_elbowjab(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; char arg[MIL]; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type int wtype; int limb; sh_int dam; at = GRIP_STAB; usgn = gsn_elbowjab; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which arm do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_ARM_R; limb = LM_RARM; } else { wtype = WEAR_ARM_L; limb = LM_LARM; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = pv; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_NECK); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_NECK); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_NECK); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_NECK); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_NECK); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_NECK); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_elbowstab(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_STAB; usgn = gsn_elbowstab; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which arm do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_ARM_R; limb = LM_RARM; } else { wtype = WEAR_ARM_L; limb = LM_LARM; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 3 + lvl * 27/100; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_elbowbreak(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_BASH; usgn = gsn_elbowbreak; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which arm do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_ARM_R; limb = LM_RARM; } else { wtype = WEAR_ARM_L; limb = LM_LARM; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 5 + lvl*37/100; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_amberio(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_SLASH; usgn = gsn_amberio; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which arm do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_ARM_R; limb = LM_RARM; } else { wtype = WEAR_ARM_L; limb = LM_LARM; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 7 + lvl*52/100; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_sidekick(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_BASH; usgn = gsn_sidekick; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which leg do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_LEG_R; limb = LM_RLEG; } else { wtype = WEAR_LEG_L; limb = LM_LLEG; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = pv; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_kneestrike(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_BASH; usgn = gsn_kneestrike; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which leg do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_LEG_R; limb = LM_RLEG; } else { wtype = WEAR_LEG_L; limb = LM_LLEG; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 3 + lvl * 28/100; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_kneecrusher(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_SLASH; usgn = gsn_kneecrusher; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which leg do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_LEG_R; limb = LM_RLEG; } else { wtype = WEAR_LEG_L; limb = LM_LLEG; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 5 + lvl*38/100; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_lembecu(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type char arg[MIL]; int wtype; int limb; sh_int dam; at = GRIP_BASH; usgn = gsn_lembecu; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); argument = one_argument(argument, arg); victim = get_battle_target(ch, arg); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; if (str_cmp(argument, "right") && str_cmp(argument, "left")) { send_to_char("Which LEG do you want to strike?.\n\r", ch); return; } if (!str_cmp(argument, "right")) { wtype = WEAR_LEG_R; limb = LM_RLEG; } else { wtype = WEAR_LEG_L; limb = LM_LLEG; } ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 7 + lvl*53/100; dam = check_combat_hit(ch, victim, dam, at, wtype, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, limb); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, limb); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, limb); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, limb); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, limb); else global_retcode = damage(ch, victim, dam, usgn, 0, limb); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_blitz(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_BASH; usgn = gsn_blitz; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = pv; dam = check_combat_hit(ch, victim, dam, at, WEAR_BODY, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_BODY); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_BODY); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_BODY); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_BODY); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_BODY); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_BODY); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_spear(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_BASH; usgn = gsn_spear; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 3 + lvl * 25 / 100; dam = check_combat_hit(ch, victim, dam, at, WEAR_BODY, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_BODY); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_BODY); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_BODY); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_BODY); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_BODY); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_BODY); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_ribpuncture(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_STAB; usgn = gsn_ribpuncture; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 5 + lvl*35/100; dam = check_combat_hit(ch, victim, dam, at, WEAR_BODY, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_BODY); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_BODY); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_BODY); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_BODY); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_BODY); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_BODY); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_timmuru(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; sh_int lvl; //Point_level sh_int mry; //Mastery sh_int pv; //Points sh_int usgn; //Gn of the skill sh_int at; //Attack type sh_int dam; at = GRIP_SLASH; usgn = gsn_timmuru; mry = MASTERED(ch, usgn); pv = UMIN(13, LEARNED(ch, usgn)); lvl = UMIN(80, POINT_LEVEL(LEARNED(ch, usgn), MASTERED(ch, usgn))); victim = get_battle_target(ch, argument); if (!victim) { send_to_char("Your target is not here.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (ch == victim) { send_to_char("Targetting yourself is not a wise idea.\n\r", ch); return; } //Checks the normal stuff to see if they can attack if (check_battle_skills(ch, victim, usgn) == 0) return; ch->fight_timer += get_btimer(ch, usgn, NULL); if (can_use_skill(ch, number_percent()-((mry-1)*10), usgn)) { learn_from_success(ch, usgn, victim); dam = 7 + lvl*50/100; dam = check_combat_hit(ch, victim, dam, at, WEAR_BODY, usgn); if (dam == 5000) global_retcode = damage(ch, victim, 50, usgn, DM_DEATH, LM_BODY); else if (dam == -1) global_retcode = damage(ch, victim, dam, usgn, DM_BLOCK, LM_BODY); else if (dam == 0) global_retcode = damage(ch, victim, 0, usgn, DM_MISS, LM_BODY); else if (dam <= -2) global_retcode = damage(ch, victim, dam*-1, usgn, DM_SLICEDLIMB, LM_BODY); else if (dam >= 20000) global_retcode = damage(ch, victim, dam/10000, usgn, DM_CRITICAL, LM_BODY); else global_retcode = damage(ch, victim, dam, usgn, 0, LM_BODY); } else { learn_from_failure(ch, usgn, victim); global_retcode = damage(ch, victim, 0, usgn, 0, -1); } return; } void do_nervepinch(CHAR_DATA *ch, char *argument) { int level; CHAR_DATA *victim = NULL; int chance = 0; AFFECT_DATA af; level = POINT_LEVEL(LEARNED(ch, gsn_nervepinch), MASTERED(ch, gsn_nervepinch)); if (argument[0] != '\0') { if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not here.\n\r", ch); return; } } if (!victim && !ch->fighting) { send_to_char("Syntax: nervepinch <target>\n\r", ch); send_to_char("Note: You do not have to specify a target if you are fighting.\n\r", ch); return; } if (!check_twohand_shield(ch)) return; if (!victim) victim = ch->fighting->who; if (victim == ch) { send_to_char("Pinching yourself is not a good idea you idiot.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_NERVEPINCH)) { send_to_char("Your victim is already in pain from a nervepinch, adding to it will not help.\n\r", ch); return; } if (!victim->fighting) chance += 15; if (!can_see(victim, ch)) chance += 20; chance += URANGE(-4, (14 - get_curr_int(victim))*2, 4); chance += URANGE(-4, (14 - get_curr_dex(victim))*2, 4); chance += level/2; chance = URANGE(1, chance, 60); if (victim->max_hit > 1000) chance/=2; if (victim->max_hit > 5000) chance/=2; if (victim->max_hit > 10000) chance/=4; chance = URANGE(1, chance, 60); if (number_range(1, 100) <= chance) { act(AT_RED, "$n quickly strikes $N with a deadly nervepinch. $N starts to twitch in pain!", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "You quickly strike at $N with a deadly nervepinch. $N twiches in pain, success!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n quickly strikes at you with a deadly nervepinch. A horribly pain shoots down your spine!", ch, NULL, victim, TO_VICT); af.type = gsn_nervepinch; af.duration = 2+level/3; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = meb(AFF_NERVEPINCH); affect_join(victim, &af); learn_from_success(ch, gsn_nervepinch, victim); if (ch->fighting) ch->fight_timer = skill_table[gsn_kickdirt]->beats; else WAIT_STATE(ch, skill_table[gsn_kickdirt]->beats*2); if (victim->fighting) victim->fight_timer *= 2; else set_fighting(victim, ch); return; } else { act(AT_GREEN, "$n quickly strikes $N with a deadly nervepinch, but $N quickly evades it.", ch, NULL, victim, TO_NOTVICT); act(AT_GREEN, "You quickly strike at $N with a deadly nervepinch, but $N quickly evades it.", ch, NULL, victim, TO_CHAR); act(AT_GREEN, "$n quickly strikes at you with a deadly nervepinch, but you quickly evades it.", ch, NULL, victim, TO_VICT); learn_from_failure(ch, gsn_nervepinch, victim); if (ch->fighting) ch->fight_timer = skill_table[gsn_kickdirt]->beats; else WAIT_STATE(ch, skill_table[gsn_kickdirt]->beats*2); if (!victim->fighting) set_fighting(victim, ch); return; } } //Attempt to cure poison or weaken void do_cleansing(CHAR_DATA *ch, char *argument) { int level; int succ = 0; int weaken = (skill_lookup("weaken")); if (!is_affected(ch, gsn_poison) && !is_affected(ch, weaken)) { send_to_char("You need to be affected by poison or weaken to use this.\n\r", ch); return; } level = POINT_LEVEL(LEARNED(ch, gsn_cleansing), MASTERED(ch, gsn_cleansing)); act(AT_GREEN, "$n closes $s eyes and starts to chant for spiritual cleansing.", ch, NULL, NULL, TO_ROOM); act(AT_GREEN, "You close your eyes and start to chant for spiritual cleansing.", ch, NULL, NULL, TO_CHAR); level += URANGE(-4, get_curr_wis(ch) - 14, 6); level = URANGE(3, level, 90); if (number_range(1, 100) > level) { act(AT_DGREEN, "You are unable to pull up enough energy to cleanse your body.", ch, NULL, NULL, TO_CHAR); learn_from_failure(ch, gsn_cleansing, NULL); WAIT_STATE(ch, skill_table[gsn_cleansing]->beats*2); return; } if (is_affected(ch, gsn_poison)) { affect_strip(ch, gsn_poison); act(AT_BLUE, "You feel the poison being ripped from your body.", ch, NULL, NULL, TO_CHAR); ch->mental_state = URANGE(-100, ch->mental_state, -10); learn_from_success(ch, gsn_cleansing, NULL); succ = 1; } if (is_affected(ch, weaken)) { affect_strip(ch, weaken); act(AT_BLUE, "You feel the weakening in your bones start to lift.", ch, NULL, NULL, TO_CHAR); ch->mental_state = URANGE(-100, ch->mental_state, -10); if (succ == 0) learn_from_success(ch, gsn_cleansing, NULL); } WAIT_STATE(ch, skill_table[gsn_cleansing]->beats*2); return; } void do_daze(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; AFFECT_DATA af; int chance; int level; bool fail; level = POINT_LEVEL(LEARNED(ch, gsn_daze), MASTERED(ch, gsn_daze)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (IS_NPC(ch) || ch->pcdata->ranking[gsn_daze] <= 0) { send_to_char("You better leave the martial arts to those who are skilled.\n\r", ch); return; } if (!ch->fighting) { send_to_char("You can only use this during the heat of battle.\n\r", ch); return; } if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { victim = ch->fighting->who; } if (is_safe(ch, victim)) { send_to_char("You cannot daze that target.\n\r", ch); return; } check_illegal_pk(ch, victim); check_attacker(ch, victim); if (!IS_NPC(ch) && ch->move < ch->max_move / 10) { set_char_color(AT_SKILL, ch); send_to_char("You are far too tired to do that.\n\r", ch); return; /* missing return fixed March 11/96 */ } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } ch->fight_timer = get_btimer(ch, gsn_daze, NULL); fail = FALSE; chance = ris_save(victim, level, RIS_PARALYSIS); if (chance == 1000) fail = TRUE; chance = 5+chance/4; if (!IS_NPC(ch) && !IS_NPC(victim)) chance -= sysdata.stun_plr_vs_plr; else chance -= sysdata.stun_regular; chance += ((get_curr_dex(victim) + get_curr_str(victim)) - (get_curr_dex(ch) + get_curr_str(ch))) * 3; chance += victim->saving_para_petri; chance = URANGE(5, chance, 35); if (!fail) { if (number_range(1, 100) > chance) fail = TRUE; } if (!fail) { learn_from_success(ch, gsn_daze, victim); /* DO *NOT* CHANGE! -Thoric */ if (!IS_NPC(ch)) { if (MASTERED(ch, gsn_daze) == 4) ch->move -= ch->max_move / 20; else ch->move -= ch->max_move / 15; } ch->fight_timer = skill_table[gsn_daze]->beats; act(AT_SKILL, "$N smashes into you, leaving you dazed!", victim, NULL, ch, TO_CHAR); act(AT_SKILL, "You smash into $N, leaving $M dazed!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n smashes into $N, leaving $M dazed!", ch, NULL, victim, TO_NOTVICT); if (!IS_AFFECTED(victim, AFF_PARALYSIS)) { af.type = gsn_daze; af.location = APPLY_ARMOR; af.modifier = -2; af.duration = 4+(MASTERED(ch, gsn_stun)); af.bitvector = meb(AFF_PARALYSIS); affect_to_char(victim, &af); update_pos(victim); } start_hating(victim, ch); start_hunting(victim, ch); } else { ch->fight_timer = skill_table[gsn_daze]->beats; if (!IS_NPC(ch)) { if (MASTERED(ch, gsn_daze) == 4) ch->move -= ch->max_move / 30; else ch->move -= ch->max_move / 25; } learn_from_failure(ch, gsn_daze, victim); act(AT_SKILL, "$n charges at you trying to daze you, but you dodge out of the way.", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You try to daze $N, but $E dodges out of the way.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n charges at $N trying to daze $M, but keeps going right on past.", ch, NULL, victim, TO_NOTVICT); start_hating(victim, ch); start_hunting(victim, ch); } return; } void do_stun(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; AFFECT_DATA af; int chance; int level; bool fail; level = POINT_LEVEL(LEARNED(ch, gsn_stun), MASTERED(ch, gsn_stun)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (!IS_NPC(ch) && ch->pcdata->ranking[gsn_stun] <= 0) { send_to_char("You better leave the martial arts to those who are skilled.\n\r", ch); return; } if (!ch->fighting || !ch->fighting->who) { send_to_char("You can only use this during the heat of battle.\n\r", ch); return; } if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { victim = ch->fighting->who; } if (is_safe(ch, victim)) { send_to_char("You cannot stun that target.\n\r", ch); return; } check_illegal_pk(ch, victim); check_attacker(ch, victim); if (!IS_NPC(ch) && ch->move < ch->max_move / 10) { set_char_color(AT_SKILL, ch); send_to_char("You are far too tired to do that.\n\r", ch); return; /* missing return fixed March 11/96 */ } if (!IS_NPC(ch) && HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } ch->fight_timer = get_btimer(ch, gsn_stun, NULL); fail = FALSE; chance = ris_save(victim, level, RIS_PARALYSIS); if (chance == 1000) fail = TRUE; chance = 15+chance/4; if (!IS_NPC(ch) && !IS_NPC(victim)) chance -= sysdata.stun_plr_vs_plr; else chance -= sysdata.stun_regular; chance += ((get_curr_dex(victim) + get_curr_str(victim)) - (get_curr_dex(ch) + get_curr_str(ch))) * 3; chance += victim->saving_para_petri; chance = URANGE(5, chance, 45); if (!fail) { if (number_range(1, 100) > chance) fail = TRUE; } if (!fail) { learn_from_success(ch, gsn_stun, victim); /* DO *NOT* CHANGE! -Thoric */ if (!IS_NPC(ch)) { if (MASTERED(ch, gsn_stun) == 4) ch->move -= ch->max_move / 20; else ch->move -= ch->max_move / 15; } ch->fight_timer = skill_table[gsn_stun]->beats; act(AT_SKILL, "$N smashes into you, leaving you stunned!", victim, NULL, ch, TO_CHAR); act(AT_SKILL, "You smash into $N, leaving $M stunned!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n smashes into $N, leaving $M stunned!", ch, NULL, victim, TO_NOTVICT); if (!IS_AFFECTED(victim, AFF_PARALYSIS)) { af.type = gsn_stun; af.location = APPLY_ARMOR; af.modifier = -4; af.duration = 4+(MASTERED(ch, gsn_stun)*3/2); if (IS_NPC(ch)) af.duration = 2+MASTERED(ch, gsn_stun); af.bitvector = meb(AFF_PARALYSIS); affect_to_char(victim, &af); update_pos(victim); } start_hating(victim, ch); start_hunting(victim, ch); } else { ch->fight_timer = skill_table[gsn_stun]->beats; if (!IS_NPC(ch)) { if (MASTERED(ch, gsn_stun) == 4) ch->move -= ch->max_move / 30; else ch->move -= ch->max_move / 25; } learn_from_failure(ch, gsn_stun, victim); act(AT_SKILL, "$n charges at you screaming, but you dodge out of the way.", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You try to stun $N, but $E dodges out of the way.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n charges screaming at $N, but keeps going right on past.", ch, NULL, victim, TO_NOTVICT); start_hating(victim, ch); start_hunting(victim, ch); } return; } /* * Disarm a creature. * Caller must check for successful attack. * Check for loyalty flag (weapon disarms to inventory) for pkillers -Blodkai */ void disarm(CHAR_DATA * ch, CHAR_DATA * victim) { OBJ_DATA *obj, *tmpobj; char buf[MSL]; int level; int trigger; if ((obj = get_eq_char(victim, WEAR_WIELD)) == NULL) return; if ((tmpobj = get_eq_char(victim, WEAR_DUAL_WIELD)) != NULL && number_bits(1) == 0) obj = tmpobj; if (get_eq_char(ch, WEAR_WIELD) == NULL && number_bits(1) == 0) { learn_from_failure(ch, gsn_disarm, victim); return; } if (IS_NPC(ch) && !can_see_obj(ch, obj) && number_bits(1) == 0) { learn_from_failure(ch, gsn_disarm, victim); return; } if (HAS_WAIT(ch)) { return; } if (check_grip(ch, victim)) { learn_from_failure(ch, gsn_disarm, victim); return; } if (IS_OBJ_STAT(obj, ITEM_NODISARM)) { sprintf(buf, "%s has a nodisarm object", victim->name); if (get_trust(ch) > LEVEL_HI_IMM) level = get_trust(ch); else level = LEVEL_HI_IMM; log_string_plus(buf, LOG_COMM, level); return; } trigger = MOBtrigger; MOBtrigger = TRUE; act(AT_SKILL, "&G$n &R****[&G&WDISARMS&R]****&G you!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "&GYou &R****[&G&WDISARM&R]****&G $N!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n disarms $N!", ch, NULL, victim, TO_NOTVICT); MOBtrigger = trigger; learn_from_success(ch, gsn_disarm, victim); if (obj == get_eq_char(victim, WEAR_WIELD) && (tmpobj = get_eq_char(victim, WEAR_DUAL_WIELD)) != NULL) tmpobj->wear_loc = WEAR_WIELD; if ((!IS_NPC(victim) && victim->pcdata->quest && victim->pcdata->quest->questarea == victim->in_room->area) || (IS_OBJ_STAT(obj, ITEM_NOGIVE)) || (IS_OBJ_STAT(obj, ITEM_NODROP))) { unequip_char(victim, obj); obj->wear_loc = -1; } else { unequip_char(victim, obj); obj->wear_loc = -1; obj_from_char(obj); obj_to_room(obj, victim->in_room, victim); } return; } void do_disarm(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; OBJ_DATA *obj; int percent; sh_int points; points = POINT_LEVEL(LEARNED(ch, gsn_disarm), MASTERED(ch, gsn_disarm)); points /= 2; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (IS_NPC(ch) || ch->pcdata->ranking[gsn_disarm] <= 0) { send_to_char("You don't know how to disarm opponents.\n\r", ch); return; } if (get_eq_char(ch, WEAR_WIELD) == NULL) { send_to_char("You must wield a weapon to disarm.\n\r", ch); return; } if ((victim = who_fighting(ch)) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if ((obj = get_eq_char(victim, WEAR_WIELD)) == NULL) { send_to_char("Your opponent is not wielding a weapon.\n\r", ch); return; } ch->fight_timer = get_btimer(ch, gsn_disarm, NULL); percent = points + URANGE(-5, get_curr_lck(ch)-get_curr_lck(victim), 5); percent = percent + URANGE(-5, get_curr_str(ch)-get_curr_str(victim), 5); percent = URANGE(1, percent, 45); if (!can_see_obj(ch, obj)) percent /= 2; if (number_range(1, 100) <= percent) disarm(ch, victim); else { send_to_char("You failed.\n\r", ch); learn_from_failure(ch, gsn_disarm, victim); } return; } /* * Trip a creature. * Caller must check for successful attack. */ void trip(CHAR_DATA * ch, CHAR_DATA * victim) { int chance; if (IS_AFFECTED(victim, AFF_FLYING) || IS_AFFECTED(victim, AFF_FLOATING)) return; if (HAS_WAIT(ch)) { return; } chance = 50-((get_curr_str(victim)-14)*2)-((get_curr_dex(victim)-14)*3)-((get_curr_lck(victim)-14)); chance = URANGE(15, chance, 85); if (victim->mount) { chance /= 3; if (IS_AFFECTED(victim->mount, AFF_FLYING) || IS_AFFECTED(victim->mount, AFF_FLOATING)) return; if (number_range(1, 100) <= chance) { act(AT_SKILL, "$n trips your mount and you fall off!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You trip $N's mount and $N falls off!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n trips $N's mount and $N falls off!", ch, NULL, victim, TO_NOTVICT); xREMOVE_BIT(victim->mount->act, ACT_MOUNTED); victim->mount = NULL; if (victim->fighting) { victim->fight_timer+=2; } else { WAIT_STATE(victim, 2 * PULSE_VIOLENCE); victim->position = POS_RESTING; } return; } else { act(AT_SKILL, "$n attempts to trip your mount but it does not budge!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You attempt to trip $N's mount but it will not budge!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n attempts to trip $N's mount but it will not budge!", ch, NULL, victim, TO_NOTVICT); } } else { if (number_range(1, 100) <= chance) { act(AT_SKILL, "$n trips you and you go down!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You trip $N and $N goes down!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n trips $N and $N goes down!", ch, NULL, victim, TO_NOTVICT); if (victim->fighting) { victim->fight_timer+=2; } else { WAIT_STATE(victim, 2 * PULSE_VIOLENCE); victim->position = POS_RESTING; } } else { act(AT_SKILL, "$n attempts to trip you but fails!", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You attempt to trip $N but you fail!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n attempts to trip $N but fails!", ch, NULL, victim, TO_NOTVICT); } } return; } void do_begging(CHAR_DATA * ch, char *argument) { int level; CHAR_DATA *victim; int chance; level = POINT_LEVEL(LEARNED(ch, gsn_begging), MASTERED(ch, gsn_begging)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (IS_NPC(ch) || ch->pcdata->ranking[gsn_begging] <= 0) { send_to_char("You don't know how to beg.\n\r", ch); return; } if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not here for you to beg from.\n\r", ch); return; } if (xIS_SET(victim->act, ACT_AGGRESSIVE)) { send_to_char("Your target doesn't look very friendly, begging is not a good idea.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_HIDE) || IS_AFFECTED(ch, AFF_INVISIBLE) || IS_AFFECTED(ch, AFF_STALK)) { send_to_char("You can only beg if you are visible.\n\r", ch); return; } if (!IS_NPC(victim)) { send_to_char("You can only use this on NPCs, if you want to beg from players use say.\n\r", ch); return; } if (IS_ACT_FLAG(victim, ACT_MOUNTSAVE)) { send_to_char("You mount doesn't look very interested in helping you out.\n\r", ch); return; } if (victim->race >= MAX_PC_RACE) { send_to_char("You can only beg from humanoid NPCs.\n\r", ch); return; } if (ch->position != POS_STANDING) { send_to_char("You have to be standing to beg.\n\r", ch); return; } chance = 30 + (level/2); chance -= victim->begatt; if (xIS_SET(victim->act, ACT_PACIFIST)) chance /=2; WAIT_STATE(ch, skill_table[gsn_begging]->beats*2); if (number_range(1, 100) > chance) { learn_from_failure(ch, gsn_begging, victim); victim->begatt++; if (!xIS_SET(victim->act, ACT_PACIFIST)) { if (number_range(1, 100) > UMIN(95, 45+(level/2))) { act(AT_RED, "$n tries to beg for some money from $N, but $N decides $n should DIE instead!", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "You try to beg for some money from $N, but $N decides you should DIE instead!", ch, NULL, victim, TO_CHAR); one_hit(victim, ch, TYPE_HIT, LM_BODY); return; } } act(AT_RED, "$n tries to beg for some money from $N, but $N refuses to give $n any money.", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "You try to beg for some money from $N, but $N refuses to give you any money.", ch, NULL, victim, TO_CHAR); return; } else { learn_from_success(ch, gsn_begging, victim); victim->begatt++; ch->gold += URANGE(2, number_range(2+level/6, 5+level/6), 15); act(AT_RED, "$n tries to beg for some money from $N and $N gives $n a few coins.", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "You try to beg for some money from $N and $N gives you a few coins.", ch, NULL, victim, TO_CHAR); return; } } char *const insult_target[4] = { "mother", "father", "family", "lover" }; char *const insult_fun[18] = { "a useless tool", "a giant failure", "a nasty cesspool", "a filthy maggot", "a scorge", "a scar on humanity", "a worthless f**k", "a stupid f**k", "a giant pile of lard", "an eyesore", "a bastard", "a waste of space", "a fairy's b***h", "uglier than a troll", "another stupid fool", "a bastard child", "the stupidest motherf****r on this earth", "a son of a b***h" }; void do_insult(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; int level; int chance; char buf[MSL]; int x; int y; if (check_npc(ch)) return; if (argument[0] != '\0') { if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not here.\n\r", ch); return; } } else { if (!ch->fighting || !ch->fighting->who) { send_to_char("You need to be fighting to insult someone.\n\r", ch); return; } victim = ch->fighting->who; } if (!victim->fighting) { send_to_char("You can only taunt a target that is fighting.\n\r", ch); return; } if (!IS_NPC(victim)) { send_to_char("Save the smack for the say and chat channels ok.\n\r", ch); return; } x = number_range(0, 4); y = number_range(0, 17); if (x == 4) { sprintf(buf, "$n calls $N %s", insult_fun[y]); act(AT_RED, buf, ch, NULL, victim, TO_ROOM); sprintf(buf, "You call $N %s", insult_fun[y]); act(AT_RED, buf, ch, NULL, victim, TO_CHAR); } else { sprintf(buf, "$n calls $N's %s %s", insult_target[x], insult_fun[y]); act(AT_RED, buf, ch, NULL, victim, TO_ROOM); sprintf(buf, "You call $N's %s %s", insult_target[x], insult_fun[y]); act(AT_RED, buf, ch, NULL, victim, TO_CHAR); } ch->fight_timer = 2; level = POINT_LEVEL(LEARNED(ch, gsn_insult), MASTERED(ch, gsn_insult)); chance = 50 + (level * 5 / 6); if (get_curr_int(victim) <= 14) chance += 20; else if (get_curr_int(victim) <= 16) chance += 10; else if (get_curr_int(victim) <= 18) chance -= 10; else if (get_curr_int(victim) <= 20) chance -= 30; else if (get_curr_int(victim) <= 22) chance -= 60; else if (get_curr_int(victim) <= 24) chance -= 90; else chance = 0; if (number_range(1, 100) <= chance) { learn_from_success(ch, gsn_insult, victim); adjust_aggression_list(victim, ch, 0, 2, gsn_insult); } else learn_from_failure(ch, gsn_insult, victim); return; } void do_pick(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *gch; OBJ_DATA *obj; EXIT_DATA *pexit; int x, y, z; sh_int percent; int level; TOWN_DATA *town; level = POINT_LEVEL(LEARNED(ch, gsn_pick_lock), MASTERED(ch, gsn_pick_lock)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Pick what?\n\r", ch); return; } if (ms_find_obj(ch)) return; if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } WAIT_STATE(ch, skill_table[gsn_pick_lock]->beats*2); /* look for guards */ for (gch = ch->in_room->first_person; gch; gch = gch->next_in_room) { if (IN_SAME_ROOM(gch, ch) && IS_NPC(gch) && IS_AWAKE(gch)) { act(AT_PLAIN, "$N is standing too close to the lock.", ch, NULL, gch, TO_CHAR); return; } } percent = 35 + (level*2/3) + (14-get_curr_lck(ch)); if (number_range(1, 100) > percent) { send_to_char("You failed.\n\r", ch); learn_from_failure(ch, gsn_pick_lock, NULL); /* for ( gch = ch->in_room->first_person; gch; gch = gch->next_in_room ) { if ( IS_NPC(gch) && IS_AWAKE(gch) && xIS_SET(gch->act, ACT_GUARDIAN ) ) one_hit( gch, ch, TYPE_UNDEFINED ); } */ return; } if ((pexit = find_door(ch, arg, TRUE)) != NULL) { /* 'pick door' */ /* ROOM_INDEX_DATA *to_room; *//* Unused */ EXIT_DATA *pexit_rev; if (!IS_SET(pexit->exit_info, EX_CLOSED)) { send_to_char("It's not closed.\n\r", ch); return; } if (pexit->key < 0) { send_to_char("It can't be picked.\n\r", ch); return; } if (!IS_SET(pexit->exit_info, EX_LOCKED)) { send_to_char("It's already unlocked.\n\r", ch); return; } if (IS_SET(pexit->exit_info, EX_PICKPROOF)) { send_to_char("You failed.\n\r", ch); learn_from_failure(ch, gsn_pick_lock, NULL); check_room_for_traps(ch, TRAP_PICK | trap_door[pexit->vdir]); return; } REMOVE_BIT(pexit->exit_info, EX_LOCKED); send_to_char("*Click*\n\r", ch); act(AT_ACTION, "$n picks the $d.", ch, NULL, pexit->keyword, TO_ROOM); learn_from_success(ch, gsn_pick_lock, NULL); adjust_favor(ch, 9, 1); /* pick the other side */ if ((pexit_rev = pexit->rexit) != NULL && pexit_rev->to_room == ch->in_room) { REMOVE_BIT(pexit_rev->exit_info, EX_LOCKED); } check_room_for_traps(ch, TRAP_PICK | trap_door[pexit->vdir]); return; } if ((obj = get_obj_here(ch, arg)) != NULL) { /* 'pick object' */ if (obj->item_type != ITEM_CONTAINER) { send_to_char("That's not a container.\n\r", ch); return; } if (!IS_SET(obj->value[1], CONT_CLOSED)) { send_to_char("It's not closed.\n\r", ch); return; } if (obj->value[2] < 0) { send_to_char("It can't be unlocked.\n\r", ch); return; } if (!IS_SET(obj->value[1], CONT_LOCKED)) { send_to_char("It's already unlocked.\n\r", ch); return; } if (IS_SET(obj->value[1], CONT_PICKPROOF)) { send_to_char("You failed.\n\r", ch); learn_from_failure(ch, gsn_pick_lock, NULL); check_for_trap(ch, obj, TRAP_PICK, NEW_TRAP_PICK); return; } separate_obj(obj); REMOVE_BIT(obj->value[1], CONT_LOCKED); send_to_char("*Click*\n\r", ch); act(AT_ACTION, "$n picks $p.", ch, obj, NULL, TO_ROOM); learn_from_success(ch, gsn_pick_lock, NULL); adjust_favor(ch, 9, 1); check_for_trap(ch, obj, TRAP_PICK, NEW_TRAP_PICK); return; } x = ch->coord->x; y = ch->coord->y; if (IN_WILDERNESS(ch) && is_valid_movement(&x, &y, arg, ch)) { if (map_sector[ch->map][x][y] != SECT_LDOOR) { send_to_char("There is no locked door in that direction.\n\r", ch); return; } town = find_town(x, y, ch->map); if (!town) { bug("do_pick: %s at %d %d has picked a door that does not belong to a town.", ch->name, x, y); } else { for (z = 0; z <= 99; z++) { if (town->doorstate[4][z] > 0) { if (town->doorstate[5][z] == x && town->doorstate[6][z] == y && town->doorstate[7][z] == ch->map) { town->doorstate[0][z] = 1; write_kingdom_file(town->kingdom); break; } } } if (z == 100) { bug("do_open: %s at %d %d in town %s has found a door not belonging to that town", ch->name, x, y, town->name); } } send_to_char("*Click*\n\r", ch); act(AT_ACTION, "$n picks the door to the $d.", ch, NULL, arg, TO_ROOM); map_sector[ch->map][x][y] = SECT_LDOOR; return; } ch_printf(ch, "You see no %s here.\n\r", arg); return; } //Allows you to climb over walls depending on what is on the otherside. Does not allow //allow moving into "bad" sectors or into roofed areas. As soon as one is encountered //it fails. If you cannot get past the layers of walls you cannot climb in either. //--Xerves void do_climbwall(CHAR_DATA *ch, char *argument) { int x = ch->coord->x; int y = ch->coord->y; int cnt=0; int level; TOWN_DATA *town; if (argument[0] == '\0') { send_to_char("Syntax: climbwall [direction]\n\r", ch); return; } if (!is_valid_movement(&x, &y, argument, ch)) return; if (ch->position != POS_STANDING) { send_to_char("You have to be standing to climb over a wall.\n\r", ch); return; } if (map_sector[ch->map][x][y] != SECT_WALL && map_sector[ch->map][x][y] != SECT_DWALL && map_sector[ch->map][x][y] != SECT_NBWALL && map_sector[ch->map][x][y] != SECT_DOOR && map_sector[ch->map][x][y] != SECT_CDOOR && map_sector[ch->map][x][y] != SECT_LDOOR) { send_to_char("There is not a wall in that direction.\n\r", ch); return; } level = POINT_LEVEL(LEARNED(ch, gsn_gag), MASTERED(ch, gsn_gag)); for (;;) { if (cnt++ > 2+(level/10)) { send_to_char("There is simply too much wall for you to climb in that direction.\n\r", ch); return; } town = find_town(x, y, ch->map); if (map_sector[ch->map][x][y] != SECT_WALL && map_sector[ch->map][x][y] != SECT_DWALL && map_sector[ch->map][x][y] != SECT_NBWALL && map_sector[ch->map][x][y] != SECT_DOOR && map_sector[ch->map][x][y] != SECT_CDOOR && map_sector[ch->map][x][y] != SECT_LDOOR && (!town || (town && town->usedpoint[x - town->startx+30][y - town->starty+30] == 0))) { if (!sect_show[(int)map_sector[ch->map][x][y]].canpass) { send_to_char("There is a nopass sector in your wall that direction.\n\r", ch); return; } //Looks to be a free sector lets jump in it if (40+level > number_range(1, 100)+(cnt-2)*15) { send_to_char("You carefully crawl up the wall and land SUCCESSFULLY on the other side.\n\r", ch); ch->coord->x = x; ch->coord->y = y; update_objects(ch, x, y, ch->map); if (ch->rider) { act(AT_WHITE, "$n successfully climbs over the wall with you on $s back.", ch, NULL, ch->rider, TO_VICT); ch->rider->coord->x = x; ch->rider->coord->y = y; do_look(ch->rider, "auto"); update_objects(ch->rider, x, y, ch->map); } do_look(ch, "auto"); learn_from_success(ch, gsn_climbwall, NULL); return; } else { send_to_char("You attempt to climb the wall but you end up falling off it instead!.\n\r", ch); WAIT_STATE(ch, 20); learn_from_failure(ch, gsn_climbwall, NULL); damage(ch, ch, number_range(5, 10), TYPE_UNDEFINED, 0, -1); return; } } else { if (!is_valid_movement(&x, &y, argument, ch)) return; } } } //Removes the gag affect if you happen to have a handy knife around void do_cutgag(CHAR_DATA *ch, char *argument) { OBJ_DATA *obj; if (argument[0] == '\0') { send_to_char("Syntax: cutgag <object>\n\r", ch); send_to_char("Syntax: cutgag none\n\r", ch); return; } if (IS_NPC(ch)) { send_to_char("Not for NPCS!.\n\r", ch); return; } if (ch->position <= POS_SLEEPING) { send_to_char("You need to be fighting/standing/mounted/resting to remove a gag.\n\r", ch); return; } if (!IS_AFFECTED(ch, AFF_GAGGED)) { send_to_char("Your aren't gagged, no real reason to do that now is there?", ch); return; } if ((obj = get_obj_carry(ch, argument)) == NULL) { if (!str_cmp(argument, "none")) ; else { send_to_char("You cannot seem to find the object in your inventory.\n\r", ch); return; } } if (obj && !IS_OBJ_STAT(obj, ITEM_GAGREMOVE)) { send_to_char("That cannot be used to remove gags.\n\r", ch); return; } affect_strip(ch, gsn_gag); if (obj) { act(AT_WHITE, "$n pulls out $p and cuts the gag off.", ch, obj, NULL, TO_NOTVICT); act(AT_WHITE, "You pull out $p and cut the gag off.", ch, obj, NULL, TO_CHAR); } else { act(AT_WHITE, "$n works franticly to remove the gag.", ch, NULL, NULL, TO_NOTVICT); act(AT_WHITE, "You work franticly to remove the gag.", ch, NULL, NULL, TO_CHAR); } if (!ch->fighting) { if (obj) WAIT_STATE(ch, 1); else WAIT_STATE(ch, 8); } else { if (obj) ch->fight_timer = 1; else ch->fight_timer = 8; } } void do_gag(CHAR_DATA * ch, char *argument) { AFFECT_DATA af; CHAR_DATA *victim; int level; int fighting=0; char arg1[MIL]; OBJ_DATA *obj; if (argument[0] == '\0') { send_to_char("Syntax: gag <object> <target>\n\r", ch); return; } argument = one_argument(argument, arg1); level = POINT_LEVEL(LEARNED(ch, gsn_gag), MASTERED(ch, gsn_gag)); if (IS_NPC(ch)) { send_to_char("Not for NPCS!.\n\r", ch); return; } if (ch->position != POS_STANDING && ch->position != POS_EVASIVE && ch->position != POS_DEFENSIVE && ch->position != POS_FIGHTING && ch->position != POS_AGGRESSIVE) { send_to_char("You can only use this if you are standing, or fighting no higher than aggressive style.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (!ch->fighting) fighting = 1; if ((obj = get_obj_carry(ch, arg1)) == NULL) { send_to_char("You cannot seem to find the object in your inventory.\n\r", ch); return; } if (obj->item_type != ITEM_GAG) { send_to_char("You cannot use that to gag someone!\n\r", ch); return; } if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not here with you.\n\r", ch); return; } if (IS_AFFECTED(victim, AFF_GAGGED)) { send_to_char("Your target is already gagged, no use in doing it twice!", ch); return; } if (IS_ACT_FLAG(victim, ACT_PACIFIST)) { send_to_char("Target is pacifist, cannot do that now!\n\r", ch); return; } if (is_safe(ch, victim)) return; if (!IS_NPC(victim) && !IS_NPC(ch) && get_trust(victim) >= LEVEL_IMMORTAL) { send_to_char("Sorry, you cannot gag immortals.\n\r", ch); return; } separate_obj(obj); if (number_range(1, 100) <= (10+(fighting*40)+UMIN(50, level * 2 / 3))) { //success act(AT_WHITE, "$n pulls out $p and shoves it in $N's mouth to shut $M up.", ch, obj, victim, TO_NOTVICT); act(AT_WHITE, "You pull out $p and shove it in $N's mouth to shut $M up.", ch, obj, victim, TO_CHAR); act(AT_WHITE, "$n pulls out $p and shoves it in your mouth to shut you up.", ch, obj, victim, TO_VICT); af.type = gsn_gag; af.duration = 5+UMIN(12, level/6); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = meb(AFF_GAGGED); affect_to_char(victim, &af); if (ch->fighting) ch->fight_timer = 5 - UMIN(2, level/30); else WAIT_STATE(ch, 5 - UMIN(2, level/30)); learn_from_success(ch, gsn_gag, victim); obj_from_char(obj); extract_obj(obj); if (IS_NPC(victim) && !victim->fighting) one_hit(victim, ch, TYPE_HIT, LM_BODY); } else { act(AT_WHITE, "$n pulls out $p and tries to gag $N but fails.", ch, obj, victim, TO_NOTVICT); act(AT_WHITE, "You pull out $p and try to gag $N but fail.", ch, obj, victim, TO_CHAR); act(AT_WHITE, "$n pulls out $p and tries to gag you but fails", ch, obj, victim, TO_VICT); if (ch->fighting) ch->fight_timer = 7 - UMIN(2, level/30); else WAIT_STATE(ch, 7 - UMIN(2, level/30)); learn_from_failure(ch, gsn_gag, victim); obj_from_char(obj); extract_obj(obj); if (IS_NPC(victim) && !victim->fighting) one_hit(victim, ch, TYPE_HIT, LM_BODY); } } void get_wilderness_move(CHAR_DATA *ch, int dir) { if (dir == 0) do_north(ch, ""); else if (dir == 1) do_east(ch, ""); else if (dir == 2) do_south(ch, ""); else if (dir == 3) do_west(ch, ""); else if (dir == 6) do_northeast(ch, ""); else if (dir == 7) do_northwest(ch, ""); else if (dir == 8) do_southeast(ch, ""); else if (dir == 9) do_southwest(ch, ""); } void do_stalk(CHAR_DATA * ch, char *argument) { AFFECT_DATA af; sh_int level; int dir; level = POINT_LEVEL(LEARNED(ch, gsn_stalk), MASTERED(ch, gsn_stalk)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if ((dir = get_door(argument)) == -1) { send_to_char("Stalk in WHAT direction?\n\r", ch); return; } if (!IN_WILDERNESS(ch) && !(get_exit(ch->in_room, dir))) { send_to_char("You cannot go that direction.\n\r", ch); return; } ch_printf(ch, "You attempt to stalk silently %s\n\r", argument); affect_strip(ch, gsn_stalk); af.type = gsn_stalk; af.duration = 10+level/2; af.location = APPLY_NONE; af.modifier = level; af.bitvector = meb(AFF_STALK); affect_to_char(ch, &af); if (IN_WILDERNESS(ch)) { get_wilderness_move(ch, dir); } else move_char(ch, get_exit(ch->in_room, dir), 0); return; } void do_sneak(CHAR_DATA * ch, char *argument) { AFFECT_DATA af; sh_int level; sh_int mastery; mastery = MASTERED(ch, gsn_sneak) * 20; mastery = mastery - 60; level = POINT_LEVEL(LEARNED(ch, gsn_sneak), MASTERED(ch, gsn_sneak)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } send_to_char("You attempt to move silently.....\n\r", ch); affect_strip(ch, gsn_sneak); if (can_use_skill(ch, number_percent() - mastery, gsn_sneak)) { send_to_char("You feel you have the ability to move secretly now...\n\r", ch); af.type = gsn_sneak; af.duration = 600+level*6; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = meb(AFF_SNEAK); affect_to_char(ch, &af); learn_from_success(ch, gsn_sneak, ch); } else learn_from_failure(ch, gsn_sneak, ch); return; } void do_hide(CHAR_DATA * ch, char *argument) { sh_int mastery; mastery = MASTERED(ch, gsn_hide) * 20; mastery = mastery - 60; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (!IS_NPC(ch) && !is_nighttime() && LEARNED(ch, gsn_lightprawl) <= 0) { send_to_char("You can only hide during the day if you have knowledge of lightprawl.\n\r", ch); return; } send_to_char("You attempt to hide....\n\r", ch); if (IS_AFFECTED(ch, AFF_HIDE)) xREMOVE_BIT(ch->affected_by, AFF_HIDE); if (ch->race == RACE_FAIRY) { xSET_BIT(ch->affected_by, AFF_HIDE); if (ch->pcdata->learned[gsn_hide] > 0) learn_from_success(ch, gsn_hide, ch); return; } if (can_use_skill(ch, number_percent() - mastery, gsn_hide)) { xSET_BIT(ch->affected_by, AFF_HIDE); learn_from_success(ch, gsn_hide, ch); } else learn_from_failure(ch, gsn_hide, ch); return; } /* * Contributed by Alander. */ void do_visible(CHAR_DATA * ch, char *argument) { affect_strip(ch, gsn_invis); affect_strip(ch, gsn_mass_invis); affect_strip(ch, gsn_sneak); affect_strip(ch, gsn_stalk); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_INVISIBLE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); xREMOVE_BIT(ch->affected_by, AFF_STALK); send_to_char("Ok.\n\r", ch); return; } void do_recall(CHAR_DATA * ch, char *argument) { ROOM_INDEX_DATA *location; CHAR_DATA *opponent; location = NULL; if (IS_NPC(ch)) return; if (!IS_NPC(ch) && ch->pcdata->caste < 2) location = get_room_index(5644); if (!IS_NPC(ch) && ch->pcdata->clan) location = get_room_index(ch->pcdata->clan->recall); /* Hometown code - Xerves */ /* Replaced with Kingdom, pretty much the same damn thing -- Xerves 12/99 */ if (!location && ch->pcdata->town) location = get_room_index(OVERLAND_SOLAN); if (!location) location = get_room_index(ROOM_VNUM_TEMPLE); if (!str_cmp(argument, "rolen")) location = get_room_index(ROOM_VNUM_TEMPLE); if (!location) { send_to_char("You are completely lost.\n\r", ch); return; } if (ch->in_room == location && location->vnum != OVERLAND_SOLAN) return; if (ch->pcdata->town && location->vnum == OVERLAND_SOLAN && ch->coord->x == ch->pcdata->town->recall[0] && ch->coord->y == ch->pcdata->town->recall[1] && ch->map == ch->pcdata->town->recall[2]) return; if (ch->fighting) { send_to_char("You cannot recall during a battle now, flee.\n\r", ch); return; } if (xIS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)) { send_to_char("For some strange reason... nothing happens.\n\r", ch); return; } if (in_hellmaze(ch)) { send_to_char("The only way out of the maze from hell is death or reaching the end.\n\r", ch); return; } if (get_timer(ch, TIMER_RECENTFIGHT) >= 1) { send_to_char("Your blood is pumping too much to do this at this time.\n\r", ch); return; } if (IS_AFFECTED(ch, AFF_CURSE)) { send_to_char("You are cursed and cannot recall!\n\r", ch); return; } if (xIS_SET(ch->act, PLR_GAMBLER)) { send_to_char("You cannot recall while you are gambling!\n\r", ch); return; } if (ch->ship) { send_to_char("You cannot recall while on a ship.\n\r", ch); return; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } if ((opponent = who_fighting(ch)) != NULL) { if (number_bits(1) == 0 || (!IS_NPC(opponent) && number_bits(3) > 1)) { WAIT_STATE(ch, 4); ch_printf(ch, "You failed!\n\r"); return; } ch_printf(ch, "You recall from combat!\n\r"); stop_fighting(ch, TRUE); } act(AT_ACTION, "$n disappears in a swirl of smoke.", ch, NULL, NULL, TO_ROOM); ch->coord->x = ch->coord->y = ch->map = -1; REMOVE_ONMAP_FLAG(ch); if (ch->on) { ch->on = NULL; ch->position = POS_STANDING; } if (ch->position != POS_STANDING && ch->position != POS_RIDING) { ch->position = POS_STANDING; } char_from_room(ch); char_to_room(ch, location); if (location->vnum == OVERLAND_SOLAN) { ch->coord->x = ch->pcdata->town->recall[0]; ch->coord->y = ch->pcdata->town->recall[1]; ch->map = ch->pcdata->town->recall[2]; SET_ONMAP_FLAG(ch); if (ch->mount) { char_from_room(ch->mount); char_to_room(ch->mount, location); ch->mount->coord->x = ch->coord->x; ch->mount->coord->y = ch->coord->y; ch->mount->map = ch->map; SET_ONMAP_FLAG(ch->mount); do_look(ch->mount, "auto"); } if (!IS_NPC(ch) && ch->pcdata->pet) { char_from_room(ch->pcdata->pet); char_to_room(ch->pcdata->pet, location); ch->pcdata->pet->coord->x = ch->coord->x; ch->pcdata->pet->coord->y = ch->coord->y; ch->pcdata->pet->map = ch->map; SET_ONMAP_FLAG(ch->pcdata->pet); do_look(ch->pcdata->pet, "auto"); } if (!IS_NPC(ch) && ch->pcdata->mount && !ch->mount) { char_from_room(ch->pcdata->mount); char_to_room(ch->pcdata->mount, location); ch->pcdata->mount->coord->x = ch->coord->x; ch->pcdata->mount->coord->y = ch->coord->y; ch->pcdata->mount->map = ch->map; SET_ONMAP_FLAG(ch->pcdata->mount); do_look(ch->pcdata->mount, "auto"); } if (ch->rider) { char_from_room(ch->rider); char_to_room(ch->rider, location); ch->rider->coord->x = ch->coord->x; ch->rider->coord->y = ch->coord->y; ch->rider->map = ch->map; SET_ONMAP_FLAG(ch->rider); update_objects(ch->rider, ch->rider->map, ch->rider->coord->x, ch->rider->coord->y); do_look(ch->rider, "auto"); } if (ch->riding) { char_from_room(ch->riding); char_to_room(ch->riding, location); ch->riding->coord->x = ch->coord->x; ch->riding->coord->y = ch->coord->y; ch->riding->map = ch->map; SET_ONMAP_FLAG(ch->riding); update_objects(ch->riding, ch->riding->map, ch->riding->coord->x, ch->riding->coord->y); do_look(ch->riding, "auto"); } } else { if (ch->mount) { ch->mount->coord->x = ch->mount->coord->y = ch->mount->map = -1; REMOVE_ONMAP_FLAG(ch->mount); char_from_room(ch->mount); char_to_room(ch->mount, location); update_objects(ch->mount, ch->mount->map, ch->mount->coord->x, ch->mount->coord->y); do_look(ch->mount, "auto"); } if (ch->pcdata->pet) { ch->pcdata->pet->coord->x = ch->pcdata->pet->coord->y = ch->pcdata->pet->map = -1; REMOVE_ONMAP_FLAG(ch->pcdata->pet); char_from_room(ch->pcdata->pet); char_to_room(ch->pcdata->pet, location); do_look(ch->pcdata->pet, "auto"); } if (ch->pcdata->mount && !ch->mount) { ch->pcdata->mount->coord->x = ch->pcdata->mount->coord->y = ch->pcdata->mount->map = -1; REMOVE_ONMAP_FLAG(ch->pcdata->mount); char_from_room(ch->pcdata->mount); char_to_room(ch->pcdata->mount, location); do_look(ch->pcdata->mount, "auto"); } if (ch->rider) { ch->rider->coord->x = ch->rider->coord->y = ch->rider->map = -1; REMOVE_ONMAP_FLAG(ch->rider); char_from_room(ch->rider); char_to_room(ch->rider, location); do_look(ch->rider, "auto"); } if (ch->riding) { ch->riding->coord->x = ch->riding->coord->y = ch->riding->map = -1; REMOVE_ONMAP_FLAG(ch->riding); char_from_room(ch->riding); char_to_room(ch->riding, location); do_look(ch->riding, "auto"); } } update_objects(ch, ch->map, ch->coord->x, ch->coord->y); act(AT_ACTION, "$n appears in the room.", ch, NULL, NULL, TO_ROOM); do_look(ch, "auto"); return; } void do_aid(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int percent; int mastery; mastery = MASTERED(ch, gsn_aid) * 15; mastery = mastery - 60; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Aid whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (IS_NPC(victim)) /* Gorog */ { send_to_char("Not on mobs.\n\r", ch); return; } if (ch->mount) { send_to_char("You can't do that while mounted.\n\r", ch); return; } if (victim == ch) { send_to_char("Aid yourself?\n\r", ch); return; } if (victim->position > POS_STUNNED) { act(AT_PLAIN, "$N doesn't need your help.", ch, NULL, victim, TO_CHAR); return; } if (victim->hit <= -6) { act(AT_PLAIN, "$N's condition is beyond your aiding ability.", ch, NULL, victim, TO_CHAR); return; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } percent = number_percent() - (get_curr_lck(ch) - 13); if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_aid]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_aid, NULL); if (!can_use_skill(ch, percent + mastery, gsn_aid)) { send_to_char("You fail.\n\r", ch); learn_from_failure(ch, gsn_aid, victim); return; } act(AT_SKILL, "You aid $N!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n aids $N!", ch, NULL, victim, TO_NOTVICT); learn_from_success(ch, gsn_aid, victim); adjust_favor(ch, 8, 1); if (victim->hit < 1) victim->hit = 1; update_pos(victim); act(AT_SKILL, "$n aids you!", ch, NULL, victim, TO_VICT); return; } //Allow a PC to give another PC a ride....Be scared of the hobbit totting //ogres void do_piggyback(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("You can't find that here.\n\r", ch); return; } if (ch->mount) { send_to_char("Might be a good idea to dismount whatever you are on right now.\n\r", ch); return; } if (victim->rider) { send_to_char("Your target already has a rider.\n\r", ch); return; } if (ch->riding) { send_to_char("You are already hitching a ride.\n\r", ch); return; } if (!IS_NPC(victim) && xIS_SET(victim->act, PLR_NORIDERS)) { send_to_char("Your target would crush you like a peanut if you even attempted.\n\r", ch); return; } if (IS_NPC(victim) && !xIS_SET(victim->act, ACT_ALLOWRIDE)) { send_to_char("You cannot piggyback that mob.\n\r", ch); return; } if (victim->position < POS_STANDING) { send_to_char("Your target must be standing.\n\r", ch); return; } if (victim->position == POS_FIGHTING || victim->fighting) { send_to_char("Your mount is moving around too much.\n\r", ch); return; } if (get_ch_carry_weight(ch)+ ch->weight > can_carry_w(victim)) { send_to_char("You weight too much for your target to carry.\n\r", ch); return; } ch->riding = victim; victim->rider = ch; /* Take away Hide + Sneak */ if (IS_AFFECTED(ch, AFF_STALK)) { xREMOVE_BIT(ch->affected_by, AFF_STALK); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); affect_strip(ch, gsn_stalk); act(AT_SKILL, "You appear from the shadows amd jump on $N's back.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n appears from the shadows and jumps on the back of $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n appears from the shadows and then jumps on YOUR BACK.", ch, NULL, victim, TO_VICT); } else if (IS_AFFECTED(ch, AFF_HIDE) && IS_AFFECTED(ch, AFF_SNEAK)) { xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); act(AT_SKILL, "You stop sneaking, appear from the shadows, and then jump on $N's back.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n stops sneaking, appears from the shadows, and jumps on the back of $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n stops sneaking, appears from the shadows, and then jumps on YOUR BACK.", ch, NULL, victim, TO_VICT); } else if (IS_AFFECTED(ch, AFF_HIDE)) { xREMOVE_BIT(ch->affected_by, AFF_HIDE); act(AT_SKILL, "You appear from the shadows amd jump on $N's back.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n appears from the shadows and jumps on the back of $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n appears from the shadows and then jumps on YOUR BACK.", ch, NULL, victim, TO_VICT); } else if (IS_AFFECTED(ch, AFF_SNEAK)) { xREMOVE_BIT(ch->affected_by, AFF_SNEAK); act(AT_SKILL, "You stop sneaking and then jump on $N's back.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n stops sneaking and jumps on the back of $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n stops sneaking and then jumps on YOUR BACK.", ch, NULL, victim, TO_VICT); } else { act(AT_SKILL, "You jump on the back of $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n skillfully jumps on the back of $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n jumps on YOUR BACK.", ch, NULL, victim, TO_VICT); } ch->position = POS_RIDING; return; } void do_mount(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; if (ch->mount) { send_to_char("You're already mounted!\n\r", ch); return; } if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("You can't find that here.\n\r", ch); return; } if (!IS_NPC(victim) || !xIS_SET(victim->act, ACT_MOUNTABLE)) { send_to_char("You can't mount that!\n\r", ch); return; } if (ch->riding) { send_to_char("You need to be not riding someone to use mount.\n\r", ch); return; } if (xIS_SET(victim->act, ACT_MOUNTED)) { send_to_char("That mount already has a rider.\n\r", ch); return; } if (victim->position < POS_STANDING) { send_to_char("Your mount must be standing.\n\r", ch); return; } if (victim->position == POS_FIGHTING || victim->fighting) { send_to_char("Your mount is moving around too much.\n\r", ch); return; } if (xIS_SET(victim->act, ACT_MOUNTSAVE) && (ch->pcdata->mount == NULL)) { send_to_char("Only the owner can mount this one.\n\r", ch); return; } if (xIS_SET(victim->act, ACT_MOUNTSAVE) && (ch->pcdata->mount != victim)) { send_to_char("Only the owner can mount this one.\n\r", ch); return; } if (get_ch_carry_weight(ch) > can_carry_w(victim)) { send_to_char("Your mount thinks you weight a bit too much to try that.\n\r", ch); return; } xSET_BIT(victim->act, ACT_MOUNTED); ch->mount = victim; /* Take away Hide + Sneak */ if (IS_AFFECTED(ch, AFF_STALK)) { xREMOVE_BIT(ch->affected_by, AFF_STALK); xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); affect_strip(ch, gsn_stalk); act(AT_SKILL, "You appear from the shadows to mount $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n appears from the shadows and skillfully mounts $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n appears from the shadows to mounts you.", ch, NULL, victim, TO_VICT); } else if (IS_AFFECTED(ch, AFF_HIDE) && IS_AFFECTED(ch, AFF_HIDE)) { xREMOVE_BIT(ch->affected_by, AFF_HIDE); xREMOVE_BIT(ch->affected_by, AFF_SNEAK); act(AT_SKILL, "You stop sneaking and appear from the shadows to mount $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n stops sneaking and appears from the shadows to skillfully mounts $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n stops sneaking and appears from the shadows to mounts you.", ch, NULL, victim, TO_VICT); } else if (IS_AFFECTED(ch, AFF_HIDE)) { xREMOVE_BIT(ch->affected_by, AFF_HIDE); act(AT_SKILL, "You appear from the shadows to mount $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n appears from the shadows and skillfully mounts $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n appears from the shadows to mounts you.", ch, NULL, victim, TO_VICT); } else if (IS_AFFECTED(ch, AFF_SNEAK)) { xREMOVE_BIT(ch->affected_by, AFF_SNEAK); act(AT_SKILL, "You stop sneaking and mount $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n stops sneaking and skillfully mounts $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n stops sneaking and mounts you.", ch, NULL, victim, TO_VICT); } else { act(AT_SKILL, "You mount $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n skillfully mounts $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n mounts you.", ch, NULL, victim, TO_VICT); } ch->position = POS_MOUNTED; return; } void do_toss(CHAR_DATA *ch, char *argument) { int dam; CHAR_DATA *victim; char arg[MIL]; if (argument[0] == '\0') { send_to_char("Syntax: toss [soft/hard]\n\r", ch); send_to_char("Syntax: toss at <victim>\n\r", ch); return; } if (!ch->rider) { send_to_char("You have no one currently on your back to toss off.\n\r", ch); return; } argument = one_argument(argument, arg); if (!str_cmp(arg, "soft")) { act(AT_SKILL, "You gently toss $N off of his back and onto the ground.", ch, NULL, ch->rider, TO_CHAR); act(AT_SKILL, "$n gently tosses $N off of $s back and onto the ground.", ch, NULL, ch->rider, TO_NOTVICT); act(AT_SKILL, "$n gently tosses you off of $s back and onto the ground.", ch, NULL, ch->rider, TO_VICT); ch->rider->position = POS_STANDING; ch->rider->riding = NULL; ch->rider = NULL; return; } if (!str_cmp(arg, "hard")) { act(AT_SKILL, "You grab $N and toss $S with great velocity toward the ground.", ch, NULL, ch->rider, TO_CHAR); act(AT_SKILL, "$n grabs $N and tosses $S with great velocity toward the ground.", ch, NULL, ch->rider, TO_NOTVICT); act(AT_SKILL, "$n grabs you and tosses you with great velocity toward the ground.", ch, NULL, ch->rider, TO_VICT); dam = URANGE(-4, (get_curr_str(ch)-13)/2, 4)+5; ch->rider->position = POS_STANDING; ch->rider->riding = NULL; damage(ch->rider, ch->rider, dam, TYPE_UNDEFINED, 0, -1); ch->rider = NULL; return; } if (!str_cmp(arg, "at")) { if ((victim = get_char_room_new(ch, argument, 1)) == NULL) { send_to_char("Your target is not in the room with you.\n\r", ch); return; } if (is_safe(ch, victim)) { send_to_char("This room is safe from fighting, sorry.\n\r", ch); return; } if (!IS_NPC(victim) && !IS_NPC(ch) && get_trust(ch) >= LEVEL_IMMORTAL) { sprintf(log_buf, "%s: immortal attempting player murder of %s.", ch->name, victim->name); log_string_plus(log_buf, LOG_NORMAL, LEVEL_ADMIN); send_to_char("Sorry, you cannot murder players.\n\r", ch); return; } if (!IS_NPC(victim) && !IS_NPC(ch) && get_trust(victim) >= LEVEL_IMMORTAL) { sprintf(log_buf, "%s: player attempted immortal murder of %s.", ch->name, victim->name); log_string_plus(log_buf, LOG_NORMAL, LEVEL_ADMIN); send_to_char("Sorry, you cannot murder immortals.\n\r", ch); return; } check_illegal_pk(ch, victim); check_attacker(ch, victim); act(AT_SKILL, "You are grabbed and thrown toward $N, this cannot be good!", ch->rider, NULL, victim, TO_CHAR); act(AT_SKILL, "$n is promply thrown from $s riding position toward $N. Look out!", ch->rider, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n is being thrown toward you, stupid little bastards!.", ch->rider, NULL, victim, TO_VICT); dam = URANGE(-4, (get_curr_str(ch)-13)/2, 4)+5; ch->rider->position = POS_STANDING; ch->rider->riding = NULL; damage(ch->rider, ch->rider, dam, TYPE_UNDEFINED, 0, -1); if (!char_died(ch->rider)) damage(ch->rider, victim, dam, TYPE_UNDEFINED, 0, -1); ch->rider = NULL; return; } do_toss(ch, ""); return; } void do_dismount(CHAR_DATA * ch, char *argument) { CHAR_DATA *victim; if (ch->riding) { act(AT_SKILL, "You jump off the back of $N.", ch, NULL, ch->riding, TO_CHAR); act(AT_SKILL, "$n skillfully jumps off the back of $N.", ch, NULL, ch->riding, TO_NOTVICT); act(AT_SKILL, "$n jumps of your back...about damn time!", ch, NULL, ch->riding, TO_VICT); ch->riding->rider = NULL; ch->riding = NULL; ch->position = POS_STANDING; return; } if ((victim = ch->mount) == NULL) { send_to_char("You're not mounted.\n\r", ch); return; } act(AT_SKILL, "You dismount $N.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n skillfully dismounts $N.", ch, NULL, victim, TO_NOTVICT); act(AT_SKILL, "$n dismounts you. Whew!", ch, NULL, victim, TO_VICT); xREMOVE_BIT(victim->act, ACT_MOUNTED); ch->mount = NULL; ch->position = POS_STANDING; return; } /**************************************************************************/ /* * Check for parry. */ int check_parry(CHAR_DATA * ch, CHAR_DATA *victim) { sh_int mastery; sh_int level; OBJ_DATA *aweapon; OBJ_DATA *vweapon; int aparry = 0, vparry = 0; int chance; mastery = MASTERED(victim, gsn_parry); level = POINT_LEVEL(LEARNED(victim, gsn_parry), MASTERED(victim, gsn_parry)); if (!IS_AWAKE(victim)) return FALSE; if (IS_NPC(victim) && !xIS_SET(victim->defenses, DFND_PARRY)) return FALSE; aweapon = get_eq_char(ch, WEAR_WIELD); vweapon = get_eq_char(victim, WEAR_WIELD); if (!vweapon && !IS_NPC(victim)) return FALSE; if (aweapon) { aparry = aweapon->value[13]; aparry += (get_curr_str(ch) - 14)/2; if (victim->position == POS_BERSERK) aparry *= 140/100; if (victim->position == POS_AGGRESSIVE) aparry *= 120/100; if (victim->position == POS_FIGHTING) aparry *= 100/100; if (victim->position == POS_DEFENSIVE) aparry *= 80/100; if (victim->position == POS_EVASIVE) aparry *= 60/100; } else if (!aweapon && IS_NPC(ch)) { aparry = URANGE(0, (get_curr_str(ch)-14)*2, 20); } if (vweapon) { vparry = vweapon->value[12]; vparry += (get_curr_dex(victim) - 14)/2; if (victim->position == POS_BERSERK) vparry *= 60/100; if (victim->position == POS_AGGRESSIVE) vparry *= 80/100; if (victim->position == POS_FIGHTING) vparry *= 100/100; if (victim->position == POS_DEFENSIVE) vparry *= 120/100; if (victim->position == POS_EVASIVE) vparry *= 140/100; } else if (!vweapon && IS_NPC(victim)) { vparry = URANGE(0, (get_curr_dex(victim)-14)*4, 40); } if (!IS_NPC(victim)) { vparry += number_range(level/3, level/4); } chance = vparry - aparry; //bug("v%d a%d t%d", vparry, aparry, chance); chance = chance * sysdata.parry_mod / 100; if (victim->morph) chance += victim->morph->parry; chance = URANGE(1, chance, 40); if (chance >= number_range(1, 100)) { //slight gain to dex, not as much as dodge... if (!IS_NPC(victim)) { int mdex = 1; int dex = victim->perm_dex; int bdex = 14 + race_table[victim->race]->dex_plus; if (sysdata.stat_gain <= 1) mdex = number_range(2,3); else if (sysdata.stat_gain <= 3) mdex = number_range(3,5); else if (sysdata.stat_gain >= 5) mdex = number_range(6,9); if (dex == bdex - 4) mdex *= 2; if (dex == bdex - 3) mdex *= 1.7; if (dex == bdex - 2) mdex *= 1.5; if (dex == bdex - 1) mdex *= 1.2; if (dex == bdex) mdex *= 1; if (dex == bdex + 1) mdex *= .85; if (dex == bdex + 2) mdex *= .7; if (dex == bdex + 3) mdex *= .6; if (dex == bdex + 4) mdex *= .4; if (dex == bdex + 5) mdex *= .3; if (dex == bdex + 6) mdex *= .275; if (dex == bdex + 7) mdex *= .25; if (dex == bdex + 8) mdex *= .225; if (dex > bdex + 8) //Base + 8 should be the max unless you screwed it up mdex = 0; else { if (mdex == 0) mdex = 1; } if (victim->perm_dex == (14 + race_table[victim->race]->dex_plus + race_table[victim->race]->dex_range + get_talent_increase(victim, 2)) && victim->pcdata->per_dex >= 3000 && mdex > 0) mdex = 0; victim->pcdata->per_dex += mdex; if (victim->pcdata->per_dex > 10000) { victim->perm_dex++; send_to_char("&G***************************************\n\r", victim); send_to_char("&G*****You Gain 1 Point of Dexterity*****\n\r", victim); send_to_char("&G***************************************\n\r", victim); victim->pcdata->per_dex = 0; } } if (victim->position == POS_EVASIVE || (victim->position == POS_DEFENSIVE && mastery >= 3) || (victim->position == POS_FIGHTING && mastery >= 4) || IS_NPC(victim)) { if (!IS_NPC(victim) && !IS_SET(victim->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "You parry $n's attack.", ch, NULL, victim, TO_VICT); if (!IS_NPC(ch) && !IS_SET(ch->pcdata->flags, PCFLAG_GAG)) /* SB */ act(AT_SKILL, "$N parries your attack.", ch, NULL, victim, TO_CHAR); // act(AT_SKILL, "$N parries $n's attack.", ch, NULL, victim, TO_NOTVICT); learn_from_success(victim, gsn_parry, ch); return TRUE; //No damage } else { if (!IS_NPC(victim) && !IS_SET(victim->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "You partially deflect $n's attack with a parry.", ch, NULL, victim, TO_VICT); if (!IS_NPC(ch) && !IS_SET(ch->pcdata->flags, PCFLAG_GAG)) /* SB */ act(AT_SKILL, "$N partially deflect your attack with a parry.", ch, NULL, victim, TO_CHAR); // act(AT_SKILL, "$N partially deflect $n's attack with a parry.", ch, NULL, victim, TO_NOTVICT); learn_from_success(victim, gsn_parry, ch); } if (victim->position == POS_EVASIVE) return TRUE; //No damage if (victim->position == POS_DEFENSIVE) { if (mastery == 1) return 10; // 10 percent damage else if (mastery == 2) return 5; else return TRUE; } if (victim->position == POS_FIGHTING) { if (mastery == 1) return 20; else if (mastery == 2) return 15; else if (mastery == 3) return 10; else return TRUE; } if (victim->position == POS_AGGRESSIVE) { if (mastery == 1) return 30; else if (mastery == 2) return 25; else if (mastery == 3) return 20; else return 15; } if (victim->position == POS_BERSERK) { if (mastery == 1) return 50; else if (mastery == 2) return 45; else if (mastery == 3) return 40; else return 35; } } else return FALSE; return FALSE; } /* * Check for dodge. */ bool check_dodge(CHAR_DATA * ch, CHAR_DATA * victim, int limb) { int percent; int mdex; int bdex; int dex = victim->perm_dex; int empty = 0; sh_int mastery, level; OBJ_DATA *armor; int limbadd = 0; int hobbit; int tlevel; int diff; mastery = MASTERED(victim, gsn_dodge); level = POINT_LEVEL(LEARNED(victim, gsn_dodge), MASTERED(victim, gsn_dodge)); tlevel = POINT_LEVEL(LEARNED(victim, gsn_tumble), MASTERED(victim, gsn_tumble)); if (!IS_AWAKE(victim)) return FALSE; if (IS_NPC(victim)) { int chance = 0; if (!xIS_SET(victim->defenses, DFND_DODGE)) return FALSE; chance = URANGE(10, 15 + ((get_curr_dex(victim) - 14)*3), 35); if (number_range(1, 100) >= chance) return FALSE; else { if (!IS_NPC(victim) && !IS_SET(victim->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "You dodge $n's attack.", ch, NULL, victim, TO_VICT); if (!IS_NPC(ch) && !IS_SET(ch->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "$N dodges your attack.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$N dodges $n's attack.", ch, NULL, victim, TO_NOTVICT); return TRUE; } } if (!IS_NPC(victim) && victim->pcdata->learned[gsn_dodge] == 0) level = 0; if (limb == LM_HEAD) limbadd = 10; else if (limb == LM_NECK) limbadd = 15; else if (limb == LM_RARM || limb == LM_LARM) limbadd = 7; else if (limb == LM_RLEG || limb == LM_LLEG) limbadd = 3; else if (limb == LM_BODY) limbadd = -5; percent = 10 + URANGE(-12, (get_curr_dex(victim) - 15) * 2, 14) + URANGE(-6, get_curr_lck(victim) - 14, 7); percent += limbadd; diff = percent; if (victim->race == RACE_HOBBIT) hobbit = 2; else hobbit = 0; if ((armor = get_eq_char(victim, WEAR_HEAD)) == NULL) { empty++; percent += 3; } else { if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 1+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 2; else if (armor->value[5] == ASIZE_HEAVY) percent -= 4; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 7; } if ((armor = get_eq_char(victim, WEAR_NECK)) == NULL) { empty++; percent += 3; } else { if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 1+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 2; else if (armor->value[5] == ASIZE_HEAVY) percent -= 4; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 6; } if ((armor = get_eq_char(victim, WEAR_ARM_R)) == NULL) { empty++; percent += 3; } else { if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 1+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 3; else if (armor->value[5] == ASIZE_HEAVY) percent -= 5; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 8; } if ((armor = get_eq_char(victim, WEAR_ARM_L)) == NULL) { empty++; percent += 3; } else { if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 1+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 3; else if (armor->value[5] == ASIZE_HEAVY) percent -= 5; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 8; } if ((armor = get_eq_char(victim, WEAR_LEG_R)) == NULL) { empty++; percent += 3; } else { if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 1+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 3; else if (armor->value[5] == ASIZE_HEAVY) percent -= 6; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 9; } if ((armor = get_eq_char(victim, WEAR_LEG_L)) == NULL) { empty++; percent += 3; } else { if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 1+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 3; else if (armor->value[5] == ASIZE_HEAVY) percent -= 6; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 9; } if ((armor = get_eq_char(victim, WEAR_BODY)) == NULL) { empty++; percent += 5; } else { if (hobbit > 0) hobbit+=1; if (armor->value[5] == 0) { if (armor->pIndexData->value[5] == 0) { bug("%s on %s has an invalid v5 for armorsize", armor->name, victim->name); send_to_char("There is some problem with your armor, tell an immortal.\n\r", victim); } else armor->value[5] = armor->pIndexData->value[5]; } if (armor->value[5] == ASIZE_LEATHER) percent += 2+hobbit; else if (armor->value[5] == ASIZE_LIGHT) percent -= 1-hobbit; else if (armor->value[5] == ASIZE_MEDIUM) percent -= 4; else if (armor->value[5] == ASIZE_HEAVY) percent -= 8; else if (armor->value[5] == ASIZE_HEAVIEST) percent -= 12; } diff = percent - diff; if (diff > 0 && tlevel > 0) { percent += 1 + number_range(tlevel/5, tlevel/4); } if (!IS_NPC(ch)) { percent += race_table[ch->race]->dodge_bonus; } percent = percent * sysdata.dodge_mod / 100; if (victim->morph) percent += victim->morph->dodge; percent += number_range(level/4, level/3); percent = URANGE(1, percent, 50); if ((armor = get_eq_char(victim, WEAR_SHIELD)) != NULL) { percent = percent - UMAX(0, (armor->value[2] - 15)); percent = URANGE(1, percent, 75); } if (!IS_NPC(victim)) { if (percent <= 3) mdex = number_range(-2, -1); else if (percent <= 7) mdex = number_range(-1, 0); else if (percent <= 15) mdex = number_range(-1, 2); else if (percent <= 25) mdex = number_range(1, 2); else if (percent <= 40) mdex = number_range(2, 3); else if (percent <= 60) mdex = number_range(3, 5); else if (percent <= 80) mdex = number_range(5, 7); else mdex = number_range(7, 9); if (sysdata.stat_gain <= 3 && mdex > 0) mdex = number_range(150*mdex/100, 180*mdex/100); else if (sysdata.stat_gain >= 5 && mdex > 0) mdex = number_range(250*mdex/100, 300*mdex/100); //dex mods if (mdex > 0) { bdex = 14 + race_table[victim->race]->dex_plus; if (dex == bdex - 4) mdex *= 2; if (dex == bdex - 3) mdex *= 1.7; if (dex == bdex - 2) mdex *= 1.5; if (dex == bdex - 1) mdex *= 1.2; if (dex == bdex) mdex *= 1; if (dex == bdex + 1) mdex *= .85; if (dex == bdex + 2) mdex *= .7; if (dex == bdex + 3) mdex *= .6; if (dex == bdex + 4) mdex *= .4; if (dex == bdex + 5) mdex *= .3; if (dex == bdex + 6) mdex *= .275; if (dex == bdex + 7) mdex *= .25; if (dex == bdex + 8) mdex *= .225; if (dex > bdex + 8) //Base + 8 should be the max unless you screwed it up mdex = 0; else { if (mdex == 0) mdex = 1; } } else { bdex = 14 + race_table[victim->race]->dex_plus; if (dex == bdex - 4) mdex = 0; if (dex == bdex - 3) mdex *= .3; if (dex == bdex - 2) mdex *= .4; if (dex == bdex - 1) mdex *= .6; if (dex == bdex) mdex *= 1; if (dex == bdex + 1) mdex *= 1.2; if (dex == bdex + 2) mdex *= 1.4; if (dex == bdex + 3) mdex *= 1.6; if (dex == bdex + 4) mdex *= 1.8; if (dex == bdex + 5) mdex *= 2; } if (victim->perm_dex == (14 + race_table[victim->race]->dex_plus + race_table[victim->race]->dex_range + get_talent_increase(victim, 2)) && victim->pcdata->per_dex >= 3000 && mdex > 0) mdex = 0; if (victim->perm_dex == (14 + race_table[victim->race]->dex_plus - 5 + race_table[victim->race]->dex_range) && victim->pcdata->per_dex <= 3000 && mdex < 0) mdex = 0; victim->pcdata->per_dex += mdex; if (victim->pcdata->per_dex > 10000) { victim->perm_dex++; send_to_char("&G***************************************\n\r", victim); send_to_char("&G*****You Gain 1 Point of Dexterity*****\n\r", victim); send_to_char("&G***************************************\n\r", victim); victim->pcdata->per_dex = 0; } if (victim->pcdata->per_dex < 0) { victim->perm_dex--; send_to_char("&g***************************************\n\r", victim); send_to_char("&g*****You Lose 1 Point of Dexterity*****\n\r", victim); send_to_char("&g***************************************\n\r", victim); victim->pcdata->per_dex = 9999; } } if (xIS_SET(victim->act, PLR_DODGE)) return FALSE; if (number_range(1, 100) > percent) return FALSE; if (diff > 0 && tlevel > 0) { if (!IS_NPC(victim) && !IS_SET(victim->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "You tumble out of the way of $n's attack.", ch, NULL, victim, TO_VICT); if (!IS_NPC(ch) && !IS_SET(ch->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "$N tumbles away from your attack.", ch, NULL, victim, TO_CHAR); // act(AT_SKILL, "$N tumbles away from $n's attack.", ch, NULL, victim, TO_NOTVICT); learn_from_success(victim, gsn_tumble, ch); } else { if (!IS_NPC(victim) && !IS_SET(victim->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "You dodge $n's attack.", ch, NULL, victim, TO_VICT); if (!IS_NPC(ch) && !IS_SET(ch->pcdata->flags, PCFLAG_GAG)) act(AT_SKILL, "$N dodges your attack.", ch, NULL, victim, TO_CHAR); // act(AT_SKILL, "$N dodges $n's attack.", ch, NULL, victim, TO_NOTVICT); } learn_from_success(victim, gsn_dodge, ch); return TRUE; } void do_poison_weapon(CHAR_DATA * ch, char *argument) { OBJ_DATA *obj; OBJ_DATA *pobj; OBJ_DATA *wobj; char arg[MIL]; int percent; sh_int mastery, level; mastery = MASTERED(ch, gsn_poison_weapon) * 20; mastery = mastery - 70; level = POINT_LEVEL(LEARNED(ch, gsn_poison_weapon), MASTERED(ch, gsn_poison_weapon)); if (IS_NPC(ch) || ch->pcdata->ranking[gsn_poison_weapon] <= 0) { send_to_char("What do you think you are, a talented thief?\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("What are you trying to poison?\n\r", ch); return; } if (ch->fighting) { send_to_char("While you're fighting? Nice try.\n\r", ch); return; } if (ms_find_obj(ch)) return; if (!(obj = get_obj_carry(ch, arg))) { send_to_char("You do not have that weapon.\n\r", ch); return; } if (obj->item_type != ITEM_WEAPON) { send_to_char("That item is not a weapon.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_POISONED)) { send_to_char("That weapon is already poisoned.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_CLANOBJECT)) { send_to_char("It doesn't appear to be fashioned of a poisonable material.\n\r", ch); return; } /* Now we have a valid weapon...check to see if we have the powder. */ for (pobj = ch->first_carrying; pobj; pobj = pobj->next_content) { if (pobj->pIndexData->vnum == OBJ_VNUM_BLACK_POWDER) break; } if (!pobj) { send_to_char("You do not have the black poison powder.\n\r", ch); return; } /* Okay, we have the powder...do we have water? */ for (wobj = ch->first_carrying; wobj; wobj = wobj->next_content) { if (wobj->item_type == ITEM_DRINK_CON && wobj->value[1] > 0 && wobj->value[2] == 0) break; } if (!wobj) { send_to_char("You have no water to mix with the powder.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_poison_weapon]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_poison_weapon, NULL); percent = (number_percent() - ((get_curr_wis(ch) - 15)*5) - ((get_curr_dex(ch) - 15)*5) - ((get_curr_lck(ch) - 14)*5) - mastery); /* Check the skill percentage */ separate_obj(pobj); separate_obj(wobj); if (!can_use_skill(ch, percent, gsn_poison_weapon)) { set_char_color(AT_RED, ch); send_to_char("You failed and spill some on yourself. Ouch!\n\r", ch); set_char_color(AT_GREY, ch); damage(ch, ch, 3+level/2, gsn_poison_weapon, 0, -1); if (number_range(1, 5) == 1) //20 percent { AFFECT_DATA af; af.type = gsn_poison; af.duration = 60; af.location = APPLY_STR; af.modifier = -1; af.bitvector = meb(AFF_POISON); affect_join(ch, &af); ch->mental_state = URANGE(20, (ch->mental_state + 2), 100); send_to_char("You feel your skin start to swell, you have poisoned yourself!!!!!\n\r", ch); } act(AT_RED, "$n spills the poison all over!", ch, NULL, NULL, TO_ROOM); extract_obj(pobj); extract_obj(wobj); learn_from_failure(ch, gsn_poison_weapon, NULL); return; } separate_obj(obj); /* Well, I'm tired of waiting. Are you? */ act(AT_RED, "You mix $p in $P, creating a deadly poison!", ch, pobj, wobj, TO_CHAR); act(AT_RED, "$n mixes $p in $P, creating a deadly poison!", ch, pobj, wobj, TO_ROOM); act(AT_GREEN, "You pour the poison over $p, which glistens wickedly!", ch, obj, NULL, TO_CHAR); act(AT_GREEN, "$n pours the poison over $p, which glistens wickedly!", ch, obj, NULL, TO_ROOM); xSET_BIT(obj->extra_flags, ITEM_POISONED); obj->cost *= 2; /* Set an object timer. Don't want proliferation of poisoned weapons */ obj->timer = 5+level*2; if (IS_OBJ_STAT(obj, ITEM_GLOW)) obj->timer *= 1.3; if (IS_OBJ_STAT(obj, ITEM_MAGIC)) obj->timer *= 1.5; /* WHAT? All of that, just for that one bit? How lame. ;) */ act(AT_BLUE, "The remainder of the poison eats through $p.", ch, wobj, NULL, TO_CHAR); act(AT_BLUE, "The remainder of the poison eats through $p.", ch, wobj, NULL, TO_ROOM); extract_obj(pobj); extract_obj(wobj); learn_from_success(ch, gsn_poison_weapon, NULL); return; } void do_manatap(CHAR_DATA *ch, char *argument) { int level; int mana; int maxgain; level = POINT_LEVEL(LEARNED(ch, gsn_manatap), MASTERED(ch, gsn_manatap)); maxgain = UMAX(ch->max_mana * level / 120, level*35/10); if (IS_NPC(ch)) return; if (ch->position != POS_STANDING && ch->position != POS_SITTING && ch->position != POS_RESTING && ch->position != POS_MOUNTED) { send_to_char("You can only use this while standing, sitting, mounted, or resting.\n\r", ch); return; } if (IS_NPC(ch) || ch->pcdata->ranking[gsn_manatap] <= 0) { send_to_char("A skill such as this requires more magical ability than that of your skills.\n\r", ch); return; } if (ch->mana < ch->max_mana) { send_to_char("You can only tap mana when your mana is full.\n\r", ch); return; } if (ch->mana >= ch->max_mana + maxgain) { send_to_char("Your mana is maxed out, you cannot tap any more.\n\r", ch); return; } if (number_range(1, 100) <= (40+level/2)) { act(AT_MAGIC, "You tap your surroundings and gain additional mana.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n taps the surroundings area and gains additional mana.", ch, NULL, NULL, TO_CANSEE); mana = UMAX(5, level/2); if (ch->mana + mana >= (ch->max_mana + maxgain)) mana = ch->max_mana + maxgain - ch->mana; ch->mana+=mana; learn_from_success(ch, gsn_manatap, NULL); } else { act(AT_MAGIC, "You attempt to tap your surroundings for additional mana but fail.", ch, NULL, NULL, TO_CHAR); act(AT_MAGIC, "$n attempts to tap the surrounding area for additional mana but fails.", ch, NULL, NULL, TO_CANSEE); learn_from_failure(ch, gsn_manatap, NULL); } WAIT_STATE(ch, skill_table[gsn_manatap]->beats*2); } void do_scribe(CHAR_DATA * ch, char *argument) { OBJ_DATA *scroll; int sn; char buf1[MSL]; char buf2[MSL]; char buf3[MSL]; int mana; sh_int mastery; int fvnum; int points; int chance; int strength; points = POINT_LEVEL(LEARNED(ch, gsn_scribe), MASTERED(ch, gsn_scribe)); mastery = MASTERED(ch, gsn_scribe) * 25; mastery = mastery - 100; if (IS_NPC(ch)) return; if (IS_NPC(ch) || ch->pcdata->ranking[gsn_scribe] <= 0) { send_to_char("A skill such as this requires more magical ability than that of your skills.\n\r", ch); return; } if (argument[0] == '\0' || !str_cmp(argument, "")) { send_to_char("Scribe what?\n\r", ch); return; } if (ms_find_obj(ch)) return; if ((sn = find_spell(ch, argument, TRUE)) < 0) { send_to_char("You have not learned that spell.\n\r", ch); return; } if (skill_table[sn]->spell_fun == spell_null) { send_to_char("That's not a spell!\n\r", ch); return; } if (SPELL_FLAG(skill_table[sn], SF_NOSCRIBE)) { send_to_char("You cannot scribe that spell.\n\r", ch); return; } mana = IS_NPC(ch) ? 0 : skill_table[sn]->min_mana; if (MASTERED(ch, gsn_scribe) == 6) mana *= 3; else if (MASTERED(ch, gsn_scribe) == 5) mana = mana * 7 / 2; else if (MASTERED(ch, gsn_scribe) == 4) mana *= 4; else mana *= 5; if (!IS_NPC(ch) && ch->mana < mana) { send_to_char("You don't have enough mana.\n\r", ch); return; } if (MASTERED(ch, sn) < 4) { send_to_char("You can only scribe a spell that you have mastered.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 5 && MASTERED(ch, gsn_scribe) < 6) { send_to_char("You can only scribe a Tier 5 spell if you have a mastery of flawless in scribe.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 4 && MASTERED(ch, gsn_scribe) < 5) { send_to_char("You can only scribe a Tier 4 spell if you have a mastery of elite in scribe.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 3 && MASTERED(ch, gsn_scribe) < 4) { send_to_char("You can only scribe a Tier 3 spell if you have mastered scribe.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 2 && MASTERED(ch, gsn_scribe) < 3) { send_to_char("You can only scribe a Tier 2 spell if you at least an expert scribe.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 3 || skill_table[sn]->masterydiff[0] == 4 || skill_table[sn]->masterydiff[0] == 5) fvnum = OBJ_VNUM_SCROLL_SCRIBING_TIER3; else if (skill_table[sn]->masterydiff[0] == 2) fvnum = OBJ_VNUM_SCROLL_SCRIBING_TIER2; else fvnum = OBJ_VNUM_SCROLL_SCRIBING; for (scroll = ch->first_carrying; scroll; scroll = scroll->next_content) { if (scroll->pIndexData->vnum == fvnum && scroll->value[1] == -1) break; } if (!scroll) { send_to_char("You must have a blank scroll in your inventory to scribe it.\n\r", ch); return; } if ((scroll->value[1] != -1) && (scroll->pIndexData->vnum == fvnum)) { send_to_char("That scroll has already been inscribed.\n\r", ch); return; } if (!process_spell_components(ch, sn)) { learn_from_failure(ch, gsn_scribe, NULL); ch->mana -= (mana / 2); gain_mana_per(ch, NULL, mana/2); return; } chance = 15 + (points * 123 / 100); chance = URANGE(15, chance, 95); if (number_range(1, 100) > chance) { set_char_color(AT_MAGIC, ch); send_to_char("You failed.\n\r", ch); learn_from_failure(ch, gsn_scribe, NULL); ch->mana -= (mana / 2); gain_mana_per(ch, NULL, mana/2); return; } strength = SPOWER_MIN + (points/10) - ((skill_table[sn]->masterydiff[0]*2)-2); strength = URANGE(SPOWER_MIN, strength, SPOWER_GREATEST); chance = 1+ (points/10) + UMIN(5, get_curr_lck(ch)-14); if (number_range(1, 100) <= chance) { strength = SPOWER_GREATEST; send_to_char("&w&WYour magical blessing is so pure that you create a very powerful scroll!\n\r", ch); } scroll->value[5] = strength; scroll->value[1] = sn; scroll->value[0] = ch->level; sprintf(buf1, "%s scroll", skill_table[sn]->name); STRFREE(scroll->short_descr); scroll->short_descr = STRALLOC(aoran(buf1)); sprintf(buf2, "A glowing scroll inscribed '%s' lies in the dust.", skill_table[sn]->name); STRFREE(scroll->description); scroll->description = STRALLOC(buf2); sprintf(buf3, "scroll scribing %s", skill_table[sn]->name); STRFREE(scroll->name); scroll->name = STRALLOC(buf3); act(AT_MAGIC, "$n magically scribes $p.", ch, scroll, NULL, TO_ROOM); act(AT_MAGIC, "You magically scribe $p.", ch, scroll, NULL, TO_CHAR); learn_from_success(ch, gsn_scribe, NULL); ch->mana -= mana; gain_mana_per(ch, NULL, mana); } void do_brew(CHAR_DATA * ch, char *argument) { OBJ_DATA *potion; OBJ_DATA *fire; int sn; char buf1[MSL]; char buf2[MSL]; char buf3[MSL]; int mana; sh_int mastery; bool found; int fvnum; int points; int chance; int strength; points = POINT_LEVEL(LEARNED(ch, gsn_brew), MASTERED(ch, gsn_brew)); if (IS_NPC(ch)) return; if (IS_NPC(ch) || ch->pcdata->ranking[gsn_brew] <= 0) { send_to_char("A skill such as this requires more magical ability than that of your abilities.\n\r", ch); return; } if (argument[0] == '\0' || !str_cmp(argument, "")) { send_to_char("Brew what?\n\r", ch); return; } if (ms_find_obj(ch)) return; if ((sn = find_spell(ch, argument, TRUE)) < 0) { send_to_char("You have not learned that spell.\n\r", ch); return; } if (skill_table[sn]->spell_fun == spell_null) { send_to_char("That's not a spell!\n\r", ch); return; } if (SPELL_FLAG(skill_table[sn], SF_NOBREW)) { send_to_char("You cannot brew that spell.\n\r", ch); return; } mana = IS_NPC(ch) ? 0 : skill_table[sn]->min_mana; mastery = MASTERED(ch, gsn_brew); if (mastery == 6) mana *= 2; if (mastery == 5) mana = mana * 5 / 2; if (mastery == 4) mana *= 3; else mana *= 4; if (!IS_NPC(ch) && ch->mana < mana) { send_to_char("You don't have enough mana.\n\r", ch); return; } found = FALSE; for (fire = ch->in_room->first_content; fire; fire = fire->next_content) { if (fire->item_type == ITEM_FIRE) { found = TRUE; break; } } /* Masters don't need a fire */ if (!found && mastery != 4) { send_to_char("There must be a fire in the room to brew a potion.\n\r", ch); return; } if (MASTERED(ch, sn) < 4) { send_to_char("You can only brew a spell that you have mastered.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 5 && MASTERED(ch, gsn_brew) < 6) { send_to_char("You can only brew a Tier 3 spell if you have mastered brew.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 4 && MASTERED(ch, gsn_brew) < 5) { send_to_char("You can only brew a Tier 3 spell if you have mastered brew.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 3 && MASTERED(ch, gsn_brew) < 4) { send_to_char("You can only brew a Tier 3 spell if you have mastered brew.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 2 && MASTERED(ch, gsn_brew) < 3) { send_to_char("You can only brew a Tier 2 spell if you at least an expert brewer.\n\r", ch); return; } if (skill_table[sn]->masterydiff[0] == 3 || skill_table[sn]->masterydiff[0] == 4 || skill_table[sn]->masterydiff[0] == 5) fvnum = OBJ_VNUM_FLASK_BREWING_TIER3; else if (skill_table[sn]->masterydiff[0] == 2) fvnum = OBJ_VNUM_FLASK_BREWING_TIER2; else fvnum = OBJ_VNUM_FLASK_BREWING; for (potion = ch->first_carrying; potion; potion = potion->next_content) { if (potion->pIndexData->vnum == fvnum && potion->value[1] == -1) break; } if (!potion) { send_to_char("You must have an empty flask in your inventory to brew a potion.\n\r", ch); return; } mastery = mastery * 30; mastery = mastery - 120; chance = 15 + (points * 123 / 100); chance = URANGE(15, chance, 95); if ((potion->value[1] != -1) && (potion->pIndexData->vnum == fvnum)) { send_to_char("That's not an empty flask.\n\r", ch); return; } if (!process_spell_components(ch, sn)) { learn_from_failure(ch, gsn_brew, NULL); ch->mana -= (mana / 2); gain_mana_per(ch, NULL, mana/2); return; } if (number_range(1, 100) > chance) { set_char_color(AT_MAGIC, ch); send_to_char("You failed.\n\r", ch); learn_from_failure(ch, gsn_brew, NULL); ch->mana -= (mana / 2); gain_mana_per(ch, NULL, mana/2); return; } strength = SPOWER_MIN + (points/10) - ((skill_table[sn]->masterydiff[0]*2)-2); strength = URANGE(SPOWER_MIN, strength, SPOWER_GREATEST); chance = 1+ (points/10) + UMIN(5, get_curr_lck(ch)-14); if (number_range(1, 100) <= chance) { strength = SPOWER_GREATEST; send_to_char("&w&WYour magical blessing is so pure that you create a very powerful potion!\n\r", ch); } potion->value[5] = strength; potion->value[1] = sn; potion->value[0] = 0; sprintf(buf1, "%s potion", skill_table[sn]->name); STRFREE(potion->short_descr); potion->short_descr = STRALLOC(aoran(buf1)); sprintf(buf2, "A strange potion labelled '%s' sizzles in a glass flask.", skill_table[sn]->name); STRFREE(potion->description); potion->description = STRALLOC(buf2); sprintf(buf3, "flask potion %s", skill_table[sn]->name); STRFREE(potion->name); potion->name = STRALLOC(buf3); act(AT_MAGIC, "$n brews up $p.", ch, potion, NULL, TO_ROOM); act(AT_MAGIC, "You brew up $p.", ch, potion, NULL, TO_CHAR); learn_from_success(ch, gsn_brew, NULL); ch->mana -= mana; gain_mana_per(ch, NULL, mana); } bool check_grip(CHAR_DATA * ch, CHAR_DATA * victim) { int chance = 0; int percent = 0; sh_int mastery, level; mastery = MASTERED(victim, gsn_grip); level = POINT_LEVEL(LEARNED(victim, gsn_grip), MASTERED(victim, gsn_grip)); if (!IS_AWAKE(victim)) return FALSE; if (IS_NPC(victim) && !xIS_SET(victim->defenses, DFND_GRIP)) return FALSE; if (IS_NPC(victim)) chance = URANGE(5, level, 50); else { percent = 10+level*1.5; chance = (int) (percent / 3 * 2); } /* Consider luck+str as a factor */ chance += get_curr_lck(victim) - 14; chance += get_curr_str(victim) - get_curr_str(ch); chance = URANGE(5, chance, 85); if (number_range(1, 100) >= chance) { learn_from_failure(victim, gsn_grip, ch); return FALSE; } act(AT_SKILL, "You evade $n's attempt to disarm you.", ch, NULL, victim, TO_VICT); act(AT_SKILL, "$N holds $S weapon strongly, and is not disarmed.", ch, NULL, victim, TO_CHAR); learn_from_success(victim, gsn_grip, ch); return TRUE; } //Sort of like shove but a bit more nasty void do_drive(CHAR_DATA *ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; EXIT_DATA *pexit = NULL; int dir; int level; int nomove = 0; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } argument = one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Attempt to drive whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("Why would you want to do that to yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 3 || !get_eq_char(ch, WEAR_WIELD)) { send_to_char("You have to wielding a polearm to make use of this command..\n\r", ch); return; } if ((dir = get_truedir(argument)) == -1) { send_to_char("That is not a valid direction!\n\r", ch); return; } if (!IN_WILDERNESS(ch)) { ROOM_INDEX_DATA *to_room; if ((pexit = get_exit(ch->in_room, dir)) == NULL) { send_to_char("There's no exit in that direction.\n\r", ch); return; } else if (IS_SET(pexit->exit_info, EX_CLOSED) && (!IS_AFFECTED(victim, AFF_PASS_DOOR) || IS_SET(pexit->exit_info, EX_NOPASSDOOR))) { send_to_char("There's no exit in that direction.\n\r", ch); return; } to_room = pexit->to_room; if (xIS_SET(to_room->room_flags, ROOM_DEATH)) { send_to_char("You cannot drive someone into a deathtrap!.\n\r", ch); return; } } level = POINT_LEVEL(LEARNED(ch, gsn_drive), MASTERED(ch, gsn_drive))/2; level += 35; if (ch->position == POS_MOUNTED) level +=15; if (victim->position == POS_MOUNTED) level -=10; level += (get_curr_str(ch) - get_curr_str(victim))*2; check_attacker(ch, victim); if (number_range(1, 100) <= level) { learn_from_success(ch, gsn_drive, victim); global_retcode = one_hit(ch, victim, gsn_drive, LM_BODY); if (char_died(victim)) return; if (victim->position == POS_MOUNTED) { if (victim->mount) { xREMOVE_BIT(victim->mount->act, ACT_MOUNTED); victim->mount = NULL; } } victim->position = POS_STANDING; if (IN_WILDERNESS(ch)) { process_movement_value(victim, dir); if (IN_SAME_ROOM(ch, victim)) nomove = 1; } if (!IN_WILDERNESS(ch)) { if ((move_char(victim, get_exit(ch->in_room, dir), 0)) == rSTOP) nomove = 1; } if (!nomove) { act(AT_RED, "You drive into $N with your weapon and roll $M into another room.", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n drives into you with $s weapon and rolls you into another room.", ch, NULL, victim, TO_VICT); act(AT_RED, "$n drives into $N and rolls him into another room.", ch, NULL, victim, TO_NOTVICT); act(AT_RED, "$N drove into $n rolling him into this room with you!", victim, NULL, ch, TO_NOTVICT); } else { act(AT_RED, "You drive into $N with your weapon but there is nowhere for $M to go that way!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n drives into you with your weapon but there is nowhere for you to go that way!", ch, NULL, victim, TO_VICT); act(AT_RED, "$n drives into $N with your weapon but there is nowhere for $M to go that way!", ch, NULL, victim, TO_NOTVICT); } stop_fighting(victim, FALSE); if (IS_NPC(victim)) victim->fight_timer = 2 + MASTERED(ch, gsn_drive); else WAIT_STATE(victim, 4 + MASTERED(ch, gsn_drive)*2); } else { learn_from_failure(ch, gsn_drive, victim); act(AT_RED, "You drive into $N but $E refuses to budge.", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n drives into you but you refuse to budge.", ch, NULL, victim, TO_VICT); act(AT_RED, "$n drives into $N but $E refuses to budge.", ch, NULL, victim, TO_NOTVICT); global_retcode = one_hit(ch, victim, gsn_drive, LM_BODY); return; } } //pretty much is do_fire but with a room check/gsn addition void do_perfectshot(CHAR_DATA *ch, char *argument) { char arg[MIL]; CHAR_DATA *victim = NULL; OBJ_DATA *arrow; OBJ_DATA *bow; if ((bow = get_eq_char(ch, WEAR_MISSILE_WIELD)) == NULL) { send_to_char("But you are not wielding a missile weapon!!\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0' && ch->fighting == NULL) { send_to_char("Perform a perfect shot at whom or what?\n\r", ch); return; } if (!str_cmp(arg, "none") || !str_cmp(arg, "self") || victim == ch) { send_to_char("How exactly did you plan on firing at yourself?\n\r", ch); return; } if ((arrow = get_eq_char(ch, WEAR_NOCKED)) == NULL) { send_to_char("You are not holding a projectile!\n\r", ch); return; } if (arrow->item_type != ITEM_PROJECTILE) { send_to_char("You are not holding a projectile!\n\r", ch); return; } if (!str_cmp(arg, "target")) { if (ch->pcdata->aimtarget == NULL) { send_to_char("Your target does not exist anymore, sorry.\n\r", ch); return; } if (!IN_WILDERNESS(ch)) { send_to_char("Can only fire at a target out in the Wilderness.\n\r", ch); return; } victim = ch->pcdata->aimtarget; } else if (arg[0] == '\0') { if (ch->fighting == NULL) { send_to_char("Your target does not seem to exist anymore.\n\r", ch); return; } victim = ch->fighting->who; } else if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (!IN_SAME_ROOM(ch, victim)) { send_to_char("You can only use this command if you are in the same room as the target!\n\r", ch); return; } if (bow->value[7] != arrow->value[7]) { char *msg = "You have nothing to fire...\n\r"; send_to_char(msg, ch); return; } /* Add wait state to fire for pkill, etc... */ ch->fight_timer = get_btimer(ch, 1000, NULL); /* handle the ranged attack */ learn_from_success(ch, gsn_perfect_shot, victim); ranged_attack(ch, argument, bow, arrow, gsn_perfect_shot, 1); return; } void do_deshield(CHAR_DATA *ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; OBJ_DATA *shield; int level; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't deshield an individual while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Attempt to deshield the shield of whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("Why would you want to do that to yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 5 || !get_eq_char(ch, WEAR_WIELD)) { send_to_char("You have to wielding a staff to make use of this command..\n\r", ch); return; } if ((shield = get_eq_char(victim, WEAR_SHIELD)) == NULL) { send_to_char("Your target is not holding a shield.\n\r", ch); return; } level = POINT_LEVEL(LEARNED(ch, gsn_deshield), MASTERED(ch, gsn_deshield))*3/2; if (!victim->fighting) //If you aren't expecting it.... level+=50; level += (get_curr_str(ch) - 14)/2; level += get_curr_dex(ch) - get_curr_dex(victim)*3; check_attacker(ch, victim); if (number_range(1, 1000) <= level) { learn_from_success(ch, gsn_deshield, victim); ch->fight_timer = get_btimer(ch, gsn_deshield, NULL); act(AT_RED, "You lunge at $N's shield and manage to knock it out of $S grasp!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n lunges at your shield and manages to knock it out of your grasp!", ch, NULL, victim, TO_VICT); act(AT_RED, "$n lunges at $N's shield and manages to knock it out of $S grasp!", ch, NULL, victim, TO_NOTVICT); if ((!IS_NPC(victim) && victim->pcdata->quest && victim->pcdata->quest->questarea == victim->in_room->area) || (IS_OBJ_STAT(shield, ITEM_NOGIVE)) || (IS_OBJ_STAT(shield, ITEM_NODROP))) { unequip_char(victim, shield); shield->wear_loc = -1; } else { unequip_char(victim, shield); shield->wear_loc = -1; obj_from_char(shield); obj_to_room(shield, victim->in_room, victim); } if (!victim->fighting && IS_NPC(victim)) one_hit(victim, ch, TYPE_HIT, LM_BODY); } else { learn_from_failure(ch, gsn_deshield, victim); ch->fight_timer = get_btimer(ch, gsn_deshield, NULL); act(AT_RED, "You lunge at $N's shield, but cannot manage to knock it out of $S grasp!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n lunges at your shield, but cannot manage to knock it out of your grasp!", ch, NULL, victim, TO_VICT); act(AT_RED, "$n lunges at $N's shield, but cannot manage to knock it out of $S grasp!", ch, NULL, victim, TO_NOTVICT); if (!victim->fighting && IS_NPC(victim)) one_hit(victim, ch, TYPE_HIT, LM_BODY); } return; } void do_weaponbreak(CHAR_DATA *ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; OBJ_DATA *wield; OBJ_DATA *awield; int level; int percent; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't weaponbreak while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Attempt to break the weapon of whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("Why would you want to do that to yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 4 || !get_eq_char(ch, WEAR_WIELD)) { send_to_char("You have to wielding a blunt weapon to make use of this command..\n\r", ch); return; } if ((wield = get_eq_char(victim, WEAR_WIELD)) == NULL) { send_to_char("Your target is not wielding a weapon.\n\r", ch); return; } level = POINT_LEVEL(LEARNED(ch, gsn_weaponbreak), MASTERED(ch, gsn_weaponbreak)); if (!victim->fighting) level+=15; level += (get_curr_str(ch) - 14); check_attacker(ch, victim); percent = 200 + level*5; //first attempt to snap it in half, slight chance of execution compared to actual damage if (number_range(1, 10000) <= percent) { learn_from_success(ch, gsn_weaponbreak, victim); ch->fight_timer = get_btimer(ch, gsn_weaponbreak, NULL); act(AT_RED, "You swing wildly at $N's weapon and snap it into two!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n swings wildly at your weapon and snaps it into two!", ch, NULL, victim, TO_VICT); act(AT_RED, "$n swings wildly at $N's weapon and snaps it into two!", ch, NULL, victim, TO_NOTVICT); make_scraps(wield, victim); if ((wield =get_eq_char(victim, WEAR_DUAL_WIELD)) != NULL) { wield->wear_loc = WEAR_WIELD; } if (!victim->fighting && IS_NPC(victim)) one_hit(victim, ch, TYPE_HIT, LM_BODY); } level+= 10; if (number_range(1, 100) <= level/3*2) { int sdiff; int dam; learn_from_success(ch, gsn_weaponbreak, victim); ch->fight_timer = get_btimer(ch, gsn_weaponbreak, NULL); act(AT_RED, "You swing wildly at $N's weapon and manage only to damage it!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n swings wildly at your weapon and manages only to damage it!", ch, NULL, victim, TO_VICT); act(AT_RED, "$n swings wildly at $N's weapon and manages only to damage it!!", ch, NULL, victim, TO_NOTVICT); awield = get_eq_char(ch, WEAR_WIELD); sdiff = awield->value[3] - wield->value[3]; dam = URANGE(20, level*10 + sdiff*50, 1000); damage_obj(wield, ch, 0, dam); if (!victim->fighting && IS_NPC(victim)) one_hit(victim, ch, TYPE_HIT, LM_BODY); } else { learn_from_failure(ch, gsn_weaponbreak, victim); ch->fight_timer = get_btimer(ch, gsn_weaponbreak, NULL); act(AT_RED, "You swing wildly at $N's weapon and miss!", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n swings wildly at your weapon and misses!", ch, NULL, victim, TO_VICT); act(AT_RED, "$n swings wildly at $N's weapon and misses!", ch, NULL, victim, TO_NOTVICT); if (!victim->fighting && IS_NPC(victim)) one_hit(victim, ch, TYPE_HIT, LM_BODY); } return; } void do_powerslice(CHAR_DATA *ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int limb = 0; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } argument = one_argument(argument, arg); if (ch->mount) { send_to_char("You can't powerslice while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Attempt to slice off the arm of whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (!str_cmp(argument, "right")) limb = LM_RARM; if (!str_cmp(argument, "left")) limb = LM_LARM; if (limb == 0) { send_to_char("You need to select a limb to attempt to slice off\n\r", ch); return; } if (victim == ch) { send_to_char("Why would you want to do that to yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 2 || !get_eq_char(ch, WEAR_WIELD)) { send_to_char("You have to be wielding a sword to use this command.\n\r", ch); return; } if (ch->grip != GRIP_SLASH) { send_to_char("You need to be have a slash grip to use this skill.\n\r", ch); return; } check_attacker(ch, victim); global_retcode = one_hit(ch, victim, gsn_powerslice, limb); adjust_favor(ch, 10, 1); check_illegal_pk(ch, victim); return; } void do_pincer(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; OBJ_DATA *wield; OBJ_DATA *dual; int level; if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't pincer while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Pincer whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("Why would you want to do that to yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 1 || !get_eq_char(ch, WEAR_WIELD)) { send_to_char("You have to be dual wielding axes to use this command.\n\r", ch); return; } else { if ((dual = get_eq_char(ch, WEAR_DUAL_WIELD)) == NULL) { send_to_char("You have to be dual wielding axes to use this command.\n\r", ch); return; } else { wield = get_eq_char(ch, WEAR_WIELD); dual->wear_loc = WEAR_WIELD; wield->wear_loc = WEAR_DUAL_WIELD; if (wielding_skill_weapon(ch, 0) != 1) { send_to_char("You have to be dual wielding axes to use this command.\n\r", ch); wield->wear_loc = WEAR_WIELD; dual->wear_loc = WEAR_DUAL_WIELD; return; } wield->wear_loc = WEAR_WIELD; dual->wear_loc = WEAR_DUAL_WIELD; } } level = 30; level += POINT_LEVEL(LEARNED(ch, gsn_pincer), MASTERED(ch, gsn_pincer))/2; level += (get_curr_lck(ch) - 14)/2; check_attacker(ch, victim); if (number_range(1, 100) <= level) { learn_from_success(ch, gsn_pincer, victim); act(AT_RED, "You pince $N together with your axes", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n pinces you together with $s axes", ch, NULL, victim, TO_VICT); global_retcode = one_hit(ch, victim, gsn_pincer, LM_BODY); adjust_favor(ch, 10, 1); check_illegal_pk(ch, victim); } else { learn_from_failure(ch, gsn_pincer, victim); act(AT_RED, "You try to pince $N together with your axes but fail", ch, NULL, victim, TO_CHAR); act(AT_RED, "$n tries to pinces you together with $s axes but fails", ch, NULL, victim, TO_VICT); global_retcode = one_hit(ch, victim, TYPE_HIT, LM_BODY); adjust_favor(ch, 10, 1); check_illegal_pk(ch, victim); } return; } void do_kick_back(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int percent; int level; level = POINT_LEVEL(LEARNED(ch, gsn_kick_back), MASTERED(ch, gsn_kick_back)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't kick back while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Kick back whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("Why would you want to do that to yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 2) { send_to_char("You can only use a sword to do a kickback.\n\r", ch); return; } if (ch->grip == GRIP_BASH) { send_to_char("Have to be using slash or stab grips to use kickback.\n\r", ch); return; } percent = 35+ UMIN(15, ((get_curr_str(ch) - get_curr_str(victim))*2) + ((get_curr_lck(ch) - get_curr_lck(victim)))); percent += level*2/3; if (victim->fighting && victim->fighting->who == ch) percent -=30; percent = URANGE(5, percent, 95); check_attacker(ch, victim); if (number_range(1, 100) <= percent) { learn_from_success(ch, gsn_kick_back, victim); global_retcode = one_hit(ch, victim, gsn_kick_back, LM_BODY); adjust_favor(ch, 10, 1); check_illegal_pk(ch, victim); } else { learn_from_failure(ch, gsn_kick_back, victim); global_retcode = one_hit(ch, victim, TYPE_HIT, LM_BODY); check_illegal_pk(ch, victim); } return; } void do_circle(CHAR_DATA * ch, char *argument) { char arg[MIL]; CHAR_DATA *victim; int percent; int level; level = POINT_LEVEL(LEARNED(ch, gsn_circle), MASTERED(ch, gsn_circle)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } one_argument(argument, arg); if (ch->mount) { send_to_char("You can't circle while mounted.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Circle around whom?\n\r", ch); return; } if ((victim = get_char_room_new(ch, arg, 1)) == NULL) { send_to_char("They aren't here.\n\r", ch); return; } if (victim == ch) { send_to_char("How can you sneak up on yourself?\n\r", ch); return; } if (is_safe(ch, victim)) return; if (wielding_skill_weapon(ch, 0) != 7) { send_to_char("You can only circle with a dagger.\n\r", ch); return; } if (ch->grip != GRIP_STAB) { send_to_char("You can only use circle if you are gripping your dagger for a stab strike.\n\r", ch); return; } percent = 35+ UMIN(15, ((get_curr_dex(ch) - get_curr_dex(victim))*2) + ((get_curr_lck(ch) - get_curr_lck(victim)))); percent += level*2/3; if (victim->fighting && victim->fighting->who == ch) percent -=30; percent = URANGE(5, percent, 95); check_attacker(ch, victim); if (number_range(1, 100) <= percent) { learn_from_success(ch, gsn_circle, victim); global_retcode = one_hit(ch, victim, gsn_circle, LM_BODY); adjust_favor(ch, 10, 1); check_illegal_pk(ch, victim); } else { learn_from_failure(ch, gsn_circle, victim); global_retcode = one_hit(ch, victim, TYPE_HIT, LM_BODY); check_illegal_pk(ch, victim); } return; } //Kind of what bash use to do in stock, but made more useful in the new system. //Not quite as powerful as stun (not asleep), but it takes time to recover from //plus it should land a bit more than stun void do_bash(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int chance; int level; level = POINT_LEVEL(LEARNED(ch, gsn_bash), MASTERED(ch, gsn_bash)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (IS_NPC(ch) || ch->pcdata->ranking[gsn_bash] <= 0) { send_to_char("You better leave the martial arts to those who are skilled.\n\r", ch); return; } if ((victim = who_fighting(ch)) == NULL) { send_to_char("You aren't fighting anyone.\n\r", ch); return; } if (!IS_NPC(ch) && ch->move < ch->max_move / 15) { set_char_color(AT_SKILL, ch); send_to_char("You are far too tired to do that.\n\r", ch); return; /* missing return fixed March 11/96 */ } if (!ch->fighting) { send_to_char("You can only use this command in battle.\n\r", ch); return; } ch->fight_timer = get_btimer(ch, gsn_bash, NULL); chance = level/5*2; chance += (get_curr_str(ch) - get_curr_str(victim)) * 3; chance -= UMIN(((get_curr_dex(victim) - 14) *2), 16); chance += get_curr_lck(ch) - get_curr_lck(victim); chance = URANGE(1, chance, 50); if (number_range(1, 100) <= chance) { learn_from_success(ch, gsn_bash, victim); if (!IS_NPC(ch)) { if (MASTERED(ch, gsn_bash) == 4) ch->move -= ch->max_move / 30; else ch->move -= ch->max_move / 25; } victim->fight_timer += skill_table[gsn_bash]->beats + 3 + UMIN(level/10, 7); victim->fight_timer = UMIN(victim->fight_timer, 24); act(AT_SKILL, "$N bashes into you, leaving you dazed!", victim, NULL, ch, TO_CHAR); act(AT_SKILL, "You bash into $N, leaving $M dazed!", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n bashes into $N, leaving $M dazed!", ch, NULL, victim, TO_NOTVICT); } else { if (!IS_NPC(ch)) { if (MASTERED(ch, gsn_bash) == 4) ch->move -= ch->max_move / 40; else ch->move -= ch->max_move / 35; } learn_from_failure(ch, gsn_bash, victim); act(AT_SKILL, "$n charges at you shoulder first, but you dodge out of the way.", ch, NULL, victim, TO_VICT); act(AT_SKILL, "You try to bash $N, but $E dodges out of the way.", ch, NULL, victim, TO_CHAR); act(AT_SKILL, "$n charges shoulder first at $N, but keeps going right on past.", ch, NULL, victim, TO_NOTVICT); } return; } //Attempts to make the enemies in the room stop fighting with you, rather useful //against lower level mobs if you are in a hurry. Also removes the //aggro flags from mobs in actual areas (wilderness mobs, well they just //go away) void do_roar(CHAR_DATA *ch, char *argument) { int level; int chance; CHAR_DATA *victim; CHAR_DATA *next_victim; int succ = 0; level = POINT_LEVEL(LEARNED(ch, gsn_roar), MASTERED(ch, gsn_roar)); if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) { send_to_char("You can't concentrate enough for that.\n\r", ch); return; } if (IS_NPC(ch) || ch->pcdata->ranking[gsn_roar] <= 0) { send_to_char("You better leave the roaring to those who are skilled.\n\r", ch); return; } if (!ch->fighting) { send_to_char("You have to be fighting to use this command.\n\r", ch); return; } ch->fight_timer = get_btimer(ch, gsn_roar, NULL); for (victim = ch->in_room->first_person; victim; victim = next_victim) { next_victim = victim->next_in_room; if (!IN_SAME_ROOM(ch, victim)) continue; if (!victim->fighting) continue; if (!IS_NPC(victim)) continue; chance = level; chance -= victim->max_hit/5; //Won't work on any mob over 600 hp or so because of this chance -= (get_curr_int(victim) - 11)*2; chance -= (get_curr_str(victim) - 11)*2; chance += ch->max_hit/10; chance += (get_curr_str(ch) - 16)*2; if (number_range(1, 100) <= chance) { act(AT_RED, "$N cowers in fear from the mighty roar of $n", ch, NULL, victim, TO_ROOM); act(AT_RED, "Your mighty roar causes $N to cower in fear and cease fighting you!", ch, NULL, victim, TO_CHAR); succ++; if (IN_WILDERNESS(ch)) { stop_fighting(victim, FALSE); extract_char(victim, TRUE); } else { stop_fighting(victim, TRUE); stop_hating(victim); stop_hunting(victim); start_fearing(victim, ch); if (xIS_SET(victim->act, ACT_AGGRESSIVE)) { xREMOVE_BIT(victim->act, ACT_AGGRESSIVE); } } } else { act(AT_RED, "$n lets out a mighty roar but $N seems unimpressed", ch, NULL, victim, TO_ROOM); act(AT_RED, "You let out a mighty roar but $N seems not to care.", ch, NULL, victim, TO_CHAR); } } if (succ == 0) learn_from_failure(ch, gsn_roar, NULL); else learn_from_success(ch, gsn_roar, NULL); } /* Berserk and HitAll. -- Altrag */ void do_berserk(CHAR_DATA * ch, char *argument) { sh_int percent; AFFECT_DATA af; int level; level = POINT_LEVEL(LEARNED(ch, gsn_berserk), MASTERED(ch, gsn_berserk)); if (IS_AFFECTED(ch, AFF_BERSERK)) { send_to_char("Your rage is already at its peak!\n\r", ch); return; } percent = level+20; if (!ch->fighting) WAIT_STATE(ch, skill_table[gsn_berserk]->beats*2); else ch->fight_timer = get_btimer(ch, gsn_berserk, NULL); if (number_range(1, 100) > percent) { send_to_char("You couldn't build up enough rage.\n\r", ch); learn_from_failure(ch, gsn_berserk, ch); return; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } af.type = gsn_berserk; af.duration = number_range(level/2, level)+10; af.modifier = level; af.location = APPLY_NONE; af.bitvector = meb(AFF_BERSERK); affect_to_char(ch, &af); send_to_char("You start to lose control..\n\r", ch); learn_from_success(ch, gsn_berserk, ch); return; } /* External from fight.c */ ch_ret one_hit args((CHAR_DATA * ch, CHAR_DATA * victim, int dt, int limb)); void do_hitall(CHAR_DATA * ch, char *argument) { CHAR_DATA *vch; CHAR_DATA *vch_next; CHAR_DATA *mount = NULL; sh_int nvict = 0; OBJ_DATA *shield; sh_int nhit = 0; int pcount = 0; sh_int percent, level, mastery; mastery = MASTERED(ch, gsn_hitall); level = POINT_LEVEL(LEARNED(ch, gsn_hitall), mastery); if (is_room_safe(ch)) { send_to_char_color("&BA godly force prevents you.\n\r", ch); return; } if (!ch->in_room->first_person) { send_to_char("There's no one else here!\n\r", ch); return; } if (IS_SET(ch->in_room->area->flags, AFLAG_NOAREA)) { send_to_char("A mystical force in this area blocks your area attack.\n\r", ch); return; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } if ((shield = get_eq_char(ch, WEAR_SHIELD)) && IS_OBJ_STAT(shield, ITEM_TWOHANDED)) { send_to_char("Cannot use hitall while wearing a two-handed shield!\n\r", ch); return; } if (ch->position == POS_BERSERK) pcount = 2; if (ch->position == POS_AGGRESSIVE) pcount = 1; if (ch->position == POS_DEFENSIVE) pcount = -1; if (ch->position == POS_EVASIVE) pcount = -2; percent = URANGE(10, level*4/3+UMIN(get_curr_lck(ch)-14, 8), 95); act(AT_RED, "$n pulls back to attempt to hit everyone in the room!", ch, NULL, NULL, TO_ROOM); act(AT_RED, "You pull back and attempt to hit everyone in the room!", ch, NULL, NULL, TO_CHAR); for (vch = ch->in_room->first_person; vch; vch = vch_next) { vch_next = vch->next_in_room; if (ch->coord->x != vch->coord->x || ch->coord->y != vch->coord->y || ch->map != vch->map) continue; if (is_same_group(ch, vch) || !is_legal_kill(ch, vch) || !can_see(ch, vch) || is_safe(ch, vch)) continue; if (++nvict > UMAX(1, URANGE(1, level / 10, 7)+pcount)) break; check_illegal_pk(ch, vch); if (xIS_SET(vch->act, ACT_MOUNTSAVE)) mount = vch; if (number_range(1, 100) <= percent || nhit == 0) { nhit++; global_retcode = one_hit(ch, vch, TYPE_HIT, ch->grip); } else global_retcode = damage(ch, vch, 0, TYPE_HIT, 0, -1); /* Fireshield, etc. could kill ch too.. :>.. -- Altrag */ if (global_retcode == rCHAR_DIED || global_retcode == rBOTH_DIED || char_died(ch)) return; } if (!nvict) { send_to_char("There's no one else here!\n\r", ch); return; } if (nhit) { learn_from_success(ch, gsn_hitall, mount); if (nhit > 1) ch->fight_timer = URANGE(2, nhit * get_btimer(ch, -1, NULL) * (95-(level/4))/100, 48); //24 seconds should be plenty, ha ha else ch->fight_timer = get_btimer(ch, -1, NULL); } else { if (ch->fighting) ch->fight_timer = get_btimer(ch, -1, NULL); else WAIT_STATE(ch, 2*get_btimer(ch, -1, NULL)); learn_from_failure(ch, gsn_hitall, mount); } return; } bool check_illegal_psteal(CHAR_DATA * ch, CHAR_DATA * victim) { return FALSE; } void do_scan(CHAR_DATA * ch, char *argument) { ROOM_INDEX_DATA *was_in_room; EXIT_DATA *pexit; sh_int dir = -1; sh_int dist; sh_int max_dist = 6; sh_int mastery; mastery = MASTERED(ch, gsn_scan) * 30; mastery = mastery - 90; set_char_color(AT_ACTION, ch); if (IS_AFFECTED(ch, AFF_BLIND)) { send_to_char("Not very effective when you're blind...\n\r", ch); return; } if (ch->position <= POS_SLEEPING) { send_to_char("You cannot do that in your sleep.\n\r", ch); return; } if (ch->pcdata->learned[gsn_scan] <= 0 || ch->pcdata->ranking[gsn_scan] <= 0) { send_to_char("You are not skilled enough to use this skill.\n\r", ch); return; } if (ch->coord->x > -1 || ch->coord->y > -1 || ch->map > -1) { display_map(ch, 6000, 6000, 0); learn_from_success(ch, gsn_scan, NULL); return; } if (argument[0] == '\0') { send_to_char("Scan in a direction...\n\r", ch); return; } if ((dir = get_door(argument)) == -1) { send_to_char("Scan in WHAT direction?\n\r", ch); return; } was_in_room = ch->in_room; act(AT_GREY, "Scanning $t...", ch, dir_name[dir], NULL, TO_CHAR); act(AT_GREY, "$n scans $t.", ch, dir_name[dir], NULL, TO_ROOM); if (!can_use_skill(ch, number_percent() - mastery, gsn_scan)) { act(AT_GREY, "You stop scanning $t as your vision blurs.", ch, dir_name[dir], NULL, TO_CHAR); learn_from_failure(ch, gsn_scan, NULL); return; } mastery = MASTERED(ch, gsn_scan); if (IS_VAMPIRE(ch)) { if ((gethour() < 21 && gethour() > 5) && mastery < 4) { send_to_char("You have trouble seeing clearly through all the " "light.\n\r", ch); max_dist = 1; } } if ((pexit = get_exit(ch->in_room, dir)) == NULL) { act(AT_GREY, "You can't see $t.", ch, dir_name[dir], NULL, TO_CHAR); return; } max_dist = max_dist + (mastery - 2); if (mastery <= 2) max_dist--; for (dist = 1; dist <= max_dist;) { if (IS_SET(pexit->exit_info, EX_CLOSED)) { if (IS_SET(pexit->exit_info, EX_SECRET) || IS_SET(pexit->exit_info, EX_DIG)) act(AT_GREY, "Your view $t is blocked by a wall.", ch, dir_name[dir], NULL, TO_CHAR); else act(AT_GREY, "Your view $t is blocked by a door.", ch, dir_name[dir], NULL, TO_CHAR); break; } if (room_is_private(pexit->to_room) && ch->level < LEVEL_STAFF) /* Tracker1 */ { act(AT_GREY, "Your view $t is blocked by a private room.", ch, dir_name[dir], NULL, TO_CHAR); break; } if (xIS_SET(pexit->to_room->room_flags, ROOM_IMP) && ch->pcdata->caste < caste_Staff) { send_to_char("No peeking, for Staff only!\n\r", ch); break; } if (xIS_SET(pexit->to_room->room_flags, ROOM_MAP)) { send_to_char("Your view $t is stopped at the Wilderness.\n\r", ch); break; } char_from_room(ch); char_to_room(ch, pexit->to_room); set_char_color(AT_RMNAME, ch); send_to_char(ch->in_room->name, ch); send_to_char("\n\r", ch); show_list_to_char( ch->in_room->first_content, ch, FALSE, FALSE, eItemNothing ); show_char_to_char(ch->in_room->first_person, ch); switch (ch->in_room->sector_type) { default: dist++; break; case SECT_AIR: if (number_percent() < 80) dist++; break; case SECT_INSIDE: case SECT_FIELD: case SECT_UNDERGROUND: dist++; break; case SECT_FOREST: case SECT_CITY: case SECT_DESERT: case SECT_HILLS: dist += 2; break; case SECT_WATER_SWIM: case SECT_WATER_NOSWIM: dist += 3; break; case SECT_MOUNTAIN: case SECT_UNDERWATER: case SECT_OCEANFLOOR: dist += 4; break; } if (dist >= max_dist) { act(AT_GREY, "Your vision blurs with distance and you see no " "farther $t.", ch, dir_name[dir], NULL, TO_CHAR); break; } if ((pexit = get_exit(ch->in_room, dir)) == NULL) { act(AT_GREY, "Your view $t is blocked by a wall.", ch, dir_name[dir], NULL, TO_CHAR); break; } } char_from_room(ch); char_to_room(ch, was_in_room); learn_from_success(ch, gsn_scan, NULL); return; } // Like get_group_name, but will return Holy/Evil, used for do_study char *sp_get_group_name(int group) { if (group == 30) return "Holy and Evil"; else return get_group_name(group); } /* Allows PCs to learn spells embedded in object. Should prove interesting. - Samson 8-9-98 */ /* Added Int support based off of AD&D rules -- Xerves 7/3/99 */ void do_study(CHAR_DATA * ch, char *argument) /* study by Absalom */ { char arg[MIL]; OBJ_DATA *obj; int sn = 0; // int ls; int mastery; int group; one_argument(argument, arg); if (arg[0] == '\0') { send_to_char("Study what?\n\r", ch); return; } if ((obj = get_obj_carry(ch, arg)) == NULL) { send_to_char("You do not have that item.\n\r", ch); return; } if (obj->item_type != ITEM_SPELLBOOK) { send_to_char("You can only study spell books.\n\r", ch); return; } act(AT_MAGIC, "$n studies $p.", ch, obj, NULL, TO_ROOM); act(AT_MAGIC, "You study $p.", ch, obj, NULL, TO_CHAR); if (obj->item_type == ITEM_SPELLBOOK) { sn = obj->value[1]; mastery = obj->value[2]; group = skill_table[sn]->group[0]; mastery = URANGE(0, mastery, 4); if (mastery == 0) mastery = skill_table[sn]->masterydiff[0]; if (sn < 0 || sn >= MAX_SKILL || skill_table[sn]->spell_fun == spell_null) { bug("Do_study: bad sn %d.", sn); return; } //Put check in here to make sure they can learn it based off of group requirements if (ch->pcdata->learned[sn]) { send_to_char("You already know that spell!\n\r", ch); return; } if (skill_table[sn]->type != SKILL_SPELL) { send_to_char("You can only study books of magical learning.\n\r", ch); return; } ch->pcdata->ranking[sn] = 1; ch->pcdata->learned[sn] = 1; act(AT_MAGIC, "You have learned the spell $t!", ch, skill_table[sn]->name, NULL, TO_CHAR); act(AT_FIRE, "$p breaks down from constant use and becomes nothing but trash.", ch, obj, NULL, TO_CHAR); extract_obj(obj); return; } } /* * Basically the same guts as do_scan() from above (please keep them in * sync) used to find the victim we're firing at. -Thoric */ // moved to archery.c //CHAR_DATA *scan_for_victim( CHAR_DATA *ch, EXIT_DATA *pexit, char *name ) /* * Search inventory for an appropriate projectile to fire. * Also search open quivers. -Thoric */ // Moved to archery.c //OBJ_DATA *find_projectile( CHAR_DATA *ch, int type ) ch_ret spell_attack(int, int, CHAR_DATA *, void *); /* * Perform the actual attack on a victim -Thoric */ // Moved to archery.c //ch_ret ranged_got_target( CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *weapon, // OBJ_DATA *projectile, sh_int dist, sh_int dt, char *stxt, sh_int color ) /* * Generic use ranged attack function -Thoric & Tricops */ // Moved to archery.c //ch_ret ranged_attack( CHAR_DATA *ch, char *argument, OBJ_DATA *weapon, // OBJ_DATA *projectile, sh_int dt, sh_int range ) /* * Fire <direction> <target> * * Fire a projectile from a missile weapon (bow, crossbow, etc) * * Design by Thoric, coding by Thoric and Tricops. * * Support code (see projectile_hit(), quiver support, other changes to * fight.c, etc by Thoric. */ // Moved to archery.c //void do_fire( CHAR_DATA *ch, char *argument ) /* * Attempt to fire at a victim. * Returns FALSE if no attempt was made */ //moved to archery.c //bool mob_fire( CHAR_DATA *ch, char *name ) /* -- working on -- * Syntaxes: throw object (assumed already fighting) * throw object direction target (all needed args for distance * throwing) * throw object (assumed same room throw) void do_throw( CHAR_DATA *ch, char *argument ) { ROOM_INDEX_DATA *was_in_room; CHAR_DATA *victim; OBJ_DATA *throw_obj; EXIT_DATA *pexit; sh_int dir; sh_int dist; sh_int max_dist = 3; char arg[MIL]; char arg1[MIL]; char arg2[MIL]; argument = one_argument( argument, arg ); argument = one_argument( argument, arg1 ); argument = one_argument( argument, arg2 ); for ( throw_obj = ch->last_carrying; throw_obj; throw_obj = throw_obj=>prev_content ) { --- if ( can_see_obj( ch, throw_obj ) && ( throw_obj->wear_loc == WEAR_HELD || throw_obj->wear_loc == WEAR_WIELDED || throw_obj->wear_loc == WEAR_DUAL_WIELDED ) && nifty_is_name( arg, throw_obj->name ) ) break; ---- if ( can_see_obj( ch, throw_obj ) && nifty_is_name( arg, throw_obj->name ) break; } if ( !throw_obj ) { send_to_char( "You aren't holding or wielding anything like that.\n\r", ch ); return; } ---- if ( ( throw_obj->item_type != ITEM_WEAPON) { send_to_char("You can only throw weapons.\n\r", ch ); return; } ---- if (get_obj_weight( throw_obj ) - ( 3 * (get_curr_str(ch) - 15) ) > 0) { send_to_char("That is too heavy for you to throw.\n\r", ch); if (!number_range(0,10)) learn_from_failure( ch, gsn_throw ); return; } if ( ch->fighting ) victim = ch->fighting; else { if ( ( ( victim = get_char_room( ch, arg1 ) ) == NULL ) && ( arg2[0] == '\0' ) ) { act( AT_GREY, "Throw $t at whom?", ch, obj->short_descr, NULL, TO_CHAR ); return; } } }*/ void do_slice(CHAR_DATA * ch, char *argument) { OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *slice; bool found; MOB_INDEX_DATA *pMobIndex; char buf[MSL]; char buf1[MSL]; found = FALSE; if (IS_NPC(ch)) { send_to_char("Huh?\n\r", ch); return; } if (!IS_IMMORTAL(ch) && ch->pcdata->ranking[gsn_slice] <= 0) { send_to_char("You are not learned in this skill.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char("From what do you wish to slice meat?\n\r", ch); return; } if ((obj = get_eq_char(ch, WEAR_WIELD)) == NULL || (obj->value[3] != 1 && obj->value[3] != 2 && obj->value[3] != 3 && obj->value[3] != 11)) { send_to_char("You need to wield a sharp weapon.\n\r", ch); return; } if ((corpse = get_obj_here(ch, argument)) == NULL) { send_to_char("You can't find that here.\n\r", ch); return; } if (corpse->item_type != ITEM_CORPSE_NPC || corpse->value[3] < 75) { send_to_char("That is not a suitable source of meat.\n\r", ch); return; } if ((pMobIndex = get_mob_index((sh_int) - (corpse->value[2]))) == NULL) { bug("Can not find mob for value[2] of corpse, do_slice", 0); return; } if (get_obj_index(OBJ_VNUM_SLICE) == NULL) { bug("Vnum 24 not found for do_slice!", 0); return; } if (!can_use_skill(ch, number_percent(), gsn_slice) && !IS_IMMORTAL(ch)) { send_to_char("You fail to slice the meat properly.\n\r", ch); learn_from_failure(ch, gsn_slice, NULL); /* Just in case they die :> */ if (number_percent() + (get_curr_dex(ch) - 13) < 10) { act(AT_BLOOD, "You cut yourself!", ch, NULL, NULL, TO_CHAR); damage(ch, ch, number_range(2, 10), gsn_slice, 0, -1); } return; } slice = create_object(get_obj_index(OBJ_VNUM_SLICE), 0); sprintf(buf, "meat fresh slice %s", pMobIndex->player_name); STRFREE(slice->name); slice->name = STRALLOC(buf); sprintf(buf, "a slice of raw meat from %s", pMobIndex->short_descr); STRFREE(slice->short_descr); slice->short_descr = STRALLOC(buf); sprintf(buf1, "A slice of raw meat from %s lies on the ground.", pMobIndex->short_descr); STRFREE(slice->description); slice->description = STRALLOC(buf1); act(AT_BLOOD, "$n cuts a slice of meat from $p.", ch, corpse, NULL, TO_ROOM); act(AT_BLOOD, "You cut a slice of meat from $p.", ch, corpse, NULL, TO_CHAR); obj_to_char(slice, ch); corpse->value[3] -= 25; learn_from_success(ch, gsn_slice, NULL); return; } /*------------------------------------------------------------ * Fighting Styles - haus */ void do_style(CHAR_DATA * ch, char *argument) { char arg[MIL]; /* char buf[MIL]; int percent; */ if (IS_NPC(ch)) return; one_argument(argument, arg); if (arg[0] == '\0') { ch_printf_color(ch, "&wAdopt which fighting style? (current: %s&w)\n\r", ch->style == STYLE_BERSERK ? "&Rberserk" : ch->style == STYLE_DIVINE ? "&Ydivine" : ch->style == STYLE_WIZARDRY ? "&Ywizardry" : ch->style == STYLE_AGGRESSIVE ? "&Raggressive" : ch->style == STYLE_DEFENSIVE ? "&Ydefensive" : ch->style == STYLE_EVASIVE ? "&Yevasive" : "standard"); return; } if (HAS_WAIT(ch)) { send_to_char("You are too busy in battle to do that.\n\r", ch); return; } if (!str_prefix(arg, "evasive") || !str_prefix(arg, "divine") || !str_prefix(arg, "wizardry")) { int erank = 0; char styleb[15]; int astyle = 0; char buf[MSL]; if (ch->pcdata->ranking[gsn_style_evasive] <= 0 && ch->pcdata->ranking[gsn_style_divine] <= 0 && ch->pcdata->ranking[gsn_style_wizardry] <= 0) { send_to_char("You have not yet learned enough to fight evasively.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, 4); else ch->fight_timer = 2; if (!str_prefix(arg, "evasive")) { erank = POINT_LEVEL(LEARNED(ch, gsn_style_evasive), MASTERED(ch, gsn_style_evasive)); sprintf(styleb, "evasive"); astyle = STYLE_EVASIVE; } if (!str_prefix(arg, "divine")) { erank = POINT_LEVEL(LEARNED(ch, gsn_style_divine), MASTERED(ch, gsn_style_divine)); sprintf(styleb, "divine"); astyle = STYLE_DIVINE; } if (!str_prefix(arg, "wizardry")) { erank = POINT_LEVEL(LEARNED(ch, gsn_style_wizardry), MASTERED(ch, gsn_style_wizardry)); sprintf(styleb, "wizardry"); astyle = STYLE_WIZARDRY; } if (number_percent() < erank + 40) { /* success */ if (ch->fighting) { ch->position = POS_EVASIVE; sprintf(buf, "$n changes stances to %s.", styleb); act(AT_ACTION, buf, ch, NULL, NULL, TO_ROOM); } ch->style = astyle;; sprintf(buf, "You change your stance to %s\n\r", styleb); send_to_char(buf, ch); return; } else { /* failure */ ch_printf(ch, "You nearly trip in a lame attempt to change your style to %s.\n\r", styleb); return; } } else if (!str_prefix(arg, "defensive")) { if (ch->pcdata->ranking[gsn_style_defensive] <= 0) { send_to_char("You have not yet learned enough to fight defensively.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, 4); else ch->fight_timer = 2; if (number_percent() < POINT_LEVEL(LEARNED(ch, gsn_style_defensive), MASTERED(ch, gsn_style_defensive)) + 40) { /* success */ if (ch->fighting) { ch->position = POS_DEFENSIVE; learn_from_success(ch, gsn_style_defensive, NULL); act(AT_ACTION, "$n moves into a defensive posture.", ch, NULL, NULL, TO_ROOM); } ch->style = STYLE_DEFENSIVE; send_to_char("You adopt a defensive fighting style.\n\r", ch); return; } else { /* failure */ send_to_char("You nearly trip in a lame attempt to adopt a defensive fighting style.\n\r", ch); return; } } else if (!str_prefix(arg, "standard")) { if (ch->pcdata->ranking[gsn_style_standard] <= 0) { send_to_char("You have not yet learned enough to fight in the standard style.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, 4); else ch->fight_timer = 2; if (number_percent() < POINT_LEVEL(LEARNED(ch, gsn_style_standard), MASTERED(ch, gsn_style_standard)) + 40) { /* success */ if (ch->fighting) { ch->position = POS_FIGHTING; learn_from_success(ch, gsn_style_standard, NULL); act(AT_ACTION, "$n switches to a standard fighting style.", ch, NULL, NULL, TO_ROOM); } ch->style = STYLE_FIGHTING; send_to_char("You adopt a standard fighting style.\n\r", ch); return; } else { /* failure */ send_to_char("You nearly trip in a lame attempt to adopt a standard fighting style.\n\r", ch); return; } } else if (!str_prefix(arg, "aggressive")) { if (ch->pcdata->ranking[gsn_style_aggressive] <= 0) { send_to_char("You have not yet learned enough to fight aggressively.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, 4); else ch->fight_timer = 2; if (number_percent() < POINT_LEVEL(LEARNED(ch, gsn_style_aggressive), MASTERED(ch, gsn_style_aggressive)) + 40) { /* success */ if (ch->fighting) { ch->position = POS_AGGRESSIVE; learn_from_success(ch, gsn_style_aggressive, NULL); act(AT_ACTION, "$n assumes an aggressive stance.", ch, NULL, NULL, TO_ROOM); } ch->style = STYLE_AGGRESSIVE; send_to_char("You adopt an aggressive fighting style.\n\r", ch); return; } else { /* failure */ send_to_char("You nearly trip in a lame attempt to adopt an aggressive fighting style.\n\r", ch); return; } } else if (!str_prefix(arg, "berserk")) { if (ch->pcdata->ranking[gsn_style_berserk] <= 0) { send_to_char("You have not yet learned enough to fight as a berserker.\n\r", ch); return; } if (!ch->fighting) WAIT_STATE(ch, 4); else ch->fight_timer = 2; if (number_percent() < POINT_LEVEL(LEARNED(ch, gsn_style_berserk), MASTERED(ch, gsn_style_berserk)) + 40) { /* success */ if (ch->fighting) { ch->position = POS_BERSERK; learn_from_success(ch, gsn_style_berserk, NULL); act(AT_ACTION, "$n enters a wildly aggressive style.", ch, NULL, NULL, TO_ROOM); } ch->style = STYLE_BERSERK; send_to_char("You adopt a berserk fighting style.\n\r", ch); return; } else { /* failure */ send_to_char("You nearly trip in a lame attempt to adopt a berserk fighting style.\n\r", ch); return; } } send_to_char("Adopt which fighting style?\n\r", ch); return; } /* New check to see if you can use skills to support morphs --Shaddai */ bool can_use_skill(CHAR_DATA * ch, int percent, int gsn) { bool check = FALSE; int suc; suc = 1; if (!IS_NPC(ch)) { if ((percent + skill_table[gsn]->difficulty * 5) > (85 + (ch->pcdata->learned[gsn]*5))) suc = 0; } if (!IS_NPC(ch) && ((ch->pcdata->learned[gsn] < 1 || ch->pcdata->learned[gsn] > MAX_SKPOINTS) || (ch->pcdata->ranking[gsn] < 1 || ch->pcdata->ranking[gsn] > MAX_RANKING))) return FALSE; if (IS_NPC(ch) && percent < 85) check = TRUE; else if (suc == 1) check = TRUE; else if (ch->morph && ch->morph->morph && ch->morph->morph->skills && ch->morph->morph->skills[0] != '\0' && is_name(skill_table[gsn]->name, ch->morph->morph->skills) && percent < 85) check = TRUE; if (ch->morph && ch->morph->morph && ch->morph->morph->no_skills && ch->morph->morph->no_skills[0] != '\0' && is_name(skill_table[gsn]->name, ch->morph->morph->no_skills)) check = FALSE; return check; } /* * Cook was coded by Blackmane and heavily modified by Shaddai */ void do_cook(CHAR_DATA * ch, char *argument) { OBJ_DATA *food, *fire; char arg[MIL]; char buf[MSL]; sh_int level; level = POINT_LEVEL(LEARNED(ch, gsn_cook), MASTERED(ch, gsn_cook)); one_argument(argument, arg); if (IS_NPC(ch) || ch->pcdata->ranking[gsn_cook] <= 0) { send_to_char("That skill is beyond your understanding.\n\r", ch); return; } if (arg[0] == '\0') { send_to_char("Cook what?\n\r", ch); return; } if (ms_find_obj(ch)) return; if ((food = get_obj_carry(ch, arg)) == NULL) { send_to_char("You do not have that item.\n\r", ch); return; } if (food->item_type != ITEM_COOK) { send_to_char("How can you cook that?\n\r", ch); return; } if (food->value[2] > 2) { send_to_char("That is already burnt to a crisp.\n\r", ch); return; } for (fire = ch->in_room->first_content; fire; fire = fire->next_content) { if (fire->item_type == ITEM_FIRE) break; } if (!fire) { send_to_char("There is no fire here!\n\r", ch); return; } if (number_percent() > level+35) { food->timer = food->timer / 2; food->value[0] = 0; food->value[2] = 3; act(AT_MAGIC, "$p catches on fire burning it to a crisp!\n\r", ch, food, NULL, TO_CHAR); act(AT_MAGIC, "$n catches $p on fire burning it to a crisp.", ch, food, NULL, TO_ROOM); sprintf(buf, "a burnt %s", food->pIndexData->name); STRFREE(food->short_descr); food->short_descr = STRALLOC(buf); sprintf(buf, "A burnt %s.", food->pIndexData->name); STRFREE(food->description); food->description = STRALLOC(buf); return; } if (number_percent() > level +55) { food->timer = food->timer * 3; food->value[2] += 2; act(AT_MAGIC, "$n overcooks a $p.", ch, food, NULL, TO_ROOM); act(AT_MAGIC, "You overcook a $p.", ch, food, NULL, TO_CHAR); sprintf(buf, "an overcooked %s", food->pIndexData->name); STRFREE(food->short_descr); food->short_descr = STRALLOC(buf); sprintf(buf, "An overcooked %s.", food->pIndexData->name); STRFREE(food->description); food->description = STRALLOC(buf); } else { food->timer = food->timer * 4; food->value[0] *= 2; act(AT_MAGIC, "$n roasts a $p.", ch, food, NULL, TO_ROOM); act(AT_MAGIC, "You roast a $p.", ch, food, NULL, TO_CHAR); sprintf(buf, "a roasted %s", food->pIndexData->name); STRFREE(food->short_descr); food->short_descr = STRALLOC(buf); sprintf(buf, "A roasted %s.", food->pIndexData->name); STRFREE(food->description); food->description = STRALLOC(buf); food->value[2]++; } learn_from_success(ch, gsn_cook, NULL); } //restores limbs, used at a mob, cost is based on health void do_restorelimbs(CHAR_DATA *ch, char *argument) { CHAR_DATA *mob; int cost; char buf[MSL]; /* Search for an act_healer */ for (mob = ch->in_room->first_person; mob; mob = mob->next_in_room) { if (IS_NPC(mob) && xIS_SET(mob->act, ACT_RESTORELIMBS)) break; } if (mob == NULL) { send_to_char("You can't do that here.\n\r", ch); return; } cost = (20+ch->max_hit) * ch->max_hit *.4; if (argument[0] == '\0') { sprintf(buf, "It will cost you %d to restore a limb. Choices for limbs are: rarm larm rleg lleg", cost); do_say(mob, buf); return; } sprintf(buf, "It will cost you %d to restore a limb.", cost); if (!str_cmp(argument, "rarm")) { if (ch->con_rarm != -1) { do_say(mob, "You can only restore broken limbs."); return; } if (ch->gold < cost) { do_say(mob, buf); return; } ch->gold -= cost; ch->con_rarm = 100; act(AT_WHITE, "$N waves $S hands around and restores $n's right arm.", ch, NULL, mob, TO_ROOM); act(AT_WHITE, "$N waves $S hands around and restores your right arm.", ch, NULL, mob, TO_CHAR); return; } if (!str_cmp(argument, "larm")) { if (ch->con_larm != -1) { do_say(mob, "You can only restore broken limbs."); return; } if (ch->gold < cost) { do_say(mob, buf); return; } ch->gold -= cost; ch->con_larm = 100; act(AT_WHITE, "$N waves $S hands around and restores $n's left arm.", ch, NULL, mob, TO_ROOM); act(AT_WHITE, "$N waves $S hands around and restores your left arm.", ch, NULL, mob, TO_CHAR); return; } if (!str_cmp(argument, "rleg")) { if (ch->con_rleg != -1) { do_say(mob, "You can only restore broken limbs."); return; } if (ch->gold < cost) { do_say(mob, buf); return; } ch->gold -= cost; ch->con_rleg = 100; act(AT_WHITE, "$N waves $S hands around and restores $n's right leg.", ch, NULL, mob, TO_ROOM); act(AT_WHITE, "$N waves $S hands around and restores your right leg.", ch, NULL, mob, TO_CHAR); return; } if (!str_cmp(argument, "lleg")) { if (ch->con_lleg != -1) { do_say(mob, "You can only restore broken limbs."); return; } if (ch->gold < cost) { do_say(mob, buf); return; } ch->gold -= cost; ch->con_lleg = 100; act(AT_WHITE, "$N waves $S hands around and restores $n's left leg.", ch, NULL, mob, TO_ROOM); act(AT_WHITE, "$N waves $S hands around and restores your left leg.", ch, NULL, mob, TO_CHAR); return; } do_restorelimbs(ch, ""); return; } /* Healer, for lower levels and just for fun -- Xerves */ void do_heal(CHAR_DATA * ch, char *argument) { CHAR_DATA *mob; char arg[MIL]; int cost, sn; SPELL_FUN *spell; char *words; /* Search for an act_healer */ for (mob = ch->in_room->first_person; mob; mob = mob->next_in_room) { if (IS_NPC(mob) && xIS_SET(mob->act, ACT_HEALER)) break; } if (mob == NULL) { send_to_char("You can't do that here.\n\r", ch); return; } one_argument(argument, arg); if (arg[0] == '\0') { /* display price list */ act(AT_PLAIN, "$N says 'I offer the following spells:'", ch, NULL, mob, TO_CHAR); send_to_char("\n &Rlight: &Ccure light wounds &Y200 gold\n\r", ch); send_to_char(" &Rserious: &Ccure serious wounds &Y300 gold\n\r", ch); send_to_char(" &Rcritical: &Ccure critical wounds &Y400 gold\n\r", ch); send_to_char(" &Rheal: &Chealing spell &Y1000 gold\n\r", ch); send_to_char(" &Rblind: &Ccure blindness &Y1200 gold\n\r", ch); send_to_char(" &Rpoison: &Ccure poison &Y1200 gold\n\r", ch); send_to_char(" &Rcurse: &Cremove curse &Y2500 gold\n\r", ch); send_to_char(" &Rsanctuary: &Csanctuary &Y5000 gold\n\r", ch); send_to_char(" &Rstrength: &Ckindred strength &Y4000 gold\n\r", ch); send_to_char(" &Rdexterity: &Cslink &Y4000 gold\n\r", ch); send_to_char(" &Rwisdom: &Csagacity &Y4000 gold\n\r", ch); send_to_char(" &Rint: &Cdragon wit &Y4000 gold\n\r", ch); send_to_char(" &Rcon: &Ctrollish vigor &Y4000 gold\n\r", ch); send_to_char(" &Rarmor: &Carmor &Y2000 gold\n\r", ch); send_to_char(" &Rshield: &Cshield &Y2500 gold\n\r", ch); send_to_char(" &Rrefresh: &Crestore movement &Y500 gold\n\r", ch); send_to_char(" &Rmana: &Crestore mana &Y800 gold\n\n\r", ch); send_to_char(" &c&wType heal <type> to be healed.\n\r", ch); return; } if (!str_cmp(arg, "light")) { spell = spell_smaug; sn = skill_lookup("cure light"); words = "judicandus dies"; cost = 200; } else if (!str_cmp(arg, "serious")) { spell = spell_smaug; sn = skill_lookup("cure serious"); words = "judicandus gzfuajg"; cost = 300; } else if (!str_cmp(arg, "critical")) { spell = spell_smaug; sn = skill_lookup("cure critical"); words = "judicandus qfuhuqar"; cost = 400; } else if (!str_cmp(arg, "heal")) { spell = spell_smaug; sn = skill_lookup("heal"); words = "pzar"; cost = 1000; } else if (!str_cmp(arg, "blind")) { spell = spell_cure_blindness; sn = skill_lookup("cure blindness"); words = "judicandus noselacri"; cost = 1200; } else if (!str_cmp(arg, "poison")) { spell = spell_cure_poison; sn = skill_lookup("cure poison"); words = "judicandus sausabru"; cost = 1200; } else if (!str_cmp(arg, "curse")) { spell = spell_remove_curse; sn = skill_lookup("remove curse"); words = "candussido judifgz"; cost = 2500; } else if (!str_cmp(arg, "mana")) { spell = NULL; sn = -1; words = "energizer"; cost = 800; } else if (!str_cmp(arg, "refresh")) { spell = spell_smaug; sn = skill_lookup("refresh"); words = "candusima"; cost = 500; } else if (!str_cmp(arg, "sanctuary")) { spell = spell_smaug; sn = skill_lookup("sanctuary"); words = "heliamheldra"; cost = 5000; } else if (!str_cmp(arg, "strength")) { spell = spell_smaug; sn = skill_lookup("kindred strength"); words = "stremdupha"; cost = 4000; } else if (!str_cmp(arg, "wisdom")) { spell = spell_smaug; sn = skill_lookup("sagacity"); words = "wifda"; cost = 4000; } else if (!str_cmp(arg, "dexterity")) { spell = spell_smaug; sn = skill_lookup("slink"); words = "zooooom"; cost = 4000; } else if (!str_cmp(arg, "int")) { spell = spell_smaug; sn = skill_lookup("dragon wit"); words = "knofdapiel"; cost = 4000; } else if (!str_cmp(arg, "con")) { spell = spell_smaug; sn = skill_lookup("trollish vigor"); words = "skupfta"; cost = 4000; } else if (!str_cmp(arg, "armor")) { spell = spell_smaug; sn = skill_lookup("armor"); words = "feskunda"; cost = 2000; } else if (!str_cmp(arg, "shield")) { spell = spell_smaug; sn = skill_lookup("shield"); words = "rayoprot"; cost = 2500; } else { act(AT_PLAIN, "$N says ' Type 'heal' for a list of spells.'", ch, NULL, mob, TO_CHAR); return; } if (cost > ch->gold) { act(AT_PLAIN, "$N says 'You do not have enough gold for my services.'", ch, NULL, mob, TO_CHAR); return; } WAIT_STATE(ch, PULSE_VIOLENCE); ch->gold -= cost; act(AT_PLAIN, "$n utters the words '$T'.", mob, NULL, words, TO_ROOM); if (spell == NULL) { ch->mana += dice(10, 5); if (ch->mana > ch->max_mana) ch->mana = ch->max_mana; send_to_char("A warm glow passes through you.\n\r", ch); return; } if (sn == -1) return; spell(sn, mob->level, mob, ch); }