/* Converted to base command by Malik Sept 97 */ /* many + Taniwha, Manshoon, Baldrick and Wonderflug made this */ inherit "/std/commands/base_command"; #include "new_tweaks.h" int backstab_damage(object doer,object target, object weapon); void do_circle(object doer, object target, int dam); int sense_check(object doer, object target); void setup(){ set_command_name("backstab"); target_type = BACKSTAB_TYPE; sec_lockout = BACKSTAB_LOCKOUT; sec_lock_prop = BACKSTAB_LOCK_PROP; guilds = BACKSTAB_GUILDS; set_help_string( "Syntax: backstab <person>\n\n" "Backstab is based on your level and dexterity. " "Your victim has a chance of sensing the backstab and thus avoiding " "it based on his level, wisdom and intelligence. " "Wether you are successful or not, the victim will attack you.\n\n" "You need a piercing weapon to be able to backstab and you must be " "hidden.\nThe cost is level dependent.\n\n" "You may also backstab during a fight, provided someone " "is there to distract your opponent long enough for you " "to work your way behind them. In this case the cost is " "4 GP per round of circling that you need to do.\n\n" "Example\n> backstab merchant\n"); } /* setup() */ int backstab(string str, object obj){ return ::exec_command(str,obj); } /* backstab() */ int do_command(object target, object doer){ int i, cost, damage; object *weap; string wname, tname, dname; cost = doer->query_level(); cost = (cost > 24 ? 24 : cost); if(doer->query_gp() < cost){ tell_object(doer, "You're too tired to backstab again.\n"); return 1; } if(doer->query_level() < 10){ tell_object(doer,"You find yourself too unskilled to backstab.\n"); return 1; } weap = doer->query_weapons_wielded(); if(!sizeof(weap)){ tell_object(doer,"Your fingers aren't really sharp enough to " "backstab someone with.\n"); return 1; } damage = 0; for (i=0;i<sizeof(weap);i++){ if(weap[i]->query_attack_type() == 3) damage += backstab_damage(doer,target,weap[i]); else{ tell_object(doer,"It would be rather impossible to shove a "+ weap[i]->query_short()+" in someone's back.\n"); return 1; } } if (i>=sizeof(weap)) i=0; wname = weap[i]->query_short(); tname = target->query_short(); dname = doer->query_short(); if(already_attacking(doer,target) == 1){ do_circle(doer, target, damage); return 1; } if(already_attacking(doer,target) == 2){ tell_object(doer, "Wouldn't be a good idea to neglect your other " "attackers and backstab someone else.\n"); return 1; } doer->add_timed_property(sec_lock_prop,100,sec_lockout); if(sense_check(doer,target)){ tell_object(doer,"Oh bugger, "+tname+" seems to have sensed your " "intentions!\n"); command_cost(cost/3,doer); } else { // Fake event triggers, for "special" weapons - Radix for(i=0; i<sizeof(weap); i++) weap[i]->event_backstab(damage,doer,target); command_cost(cost,doer); command_damage(-damage,doer,target); tell_object(target,"You convulse in agony as "+dname+" places a "+ wname+" in your back!\nThat really did hurt!\n"); tell_room(environment(doer), tname+" convulses in agony as "+dname+ " places a"+wname+" in "+target->query_possessive()+" back!\n", ({ doer, target }) ); tell_object(doer,tname+" convulses in agony as you place a "+wname+ " in "+target->query_objective()+", and blood pours over your " "hands.\n"); } return 1; } /* do_command() */ void do_circle(object doer, object target, int dam){ object *alist; if(sizeof((alist = target->query_attacker_list())) < 2){ tell_object(doer, "There isn't anyone to distract your victim " "long enough for you to circle round.\n"); return ; } setup_hb_command(doer,3+random(3),({target,doer->query_hp(),dam})); tell_object(doer,"You begin to edge around " +target->query_cap_name()+".\n"); } /* do_circle() */ int hb_command(object doer, mixed params, int time){ if(!params[0] || environment(doer) != environment(params[0]) || already_attacking(doer, params[0]) != 1){ tell_object(doer, "Your victim seems to have left. Let the chase " "begin!\n"); call_out("end_hb_command", 0, doer); return 1; } if(doer->query_dead() || params[0]->query_dead()){ tell_object(doer, "You stop trying to circle your victim.\n"); call_out("end_hb_command", 0, doer); return 1; } if(doer->query_hp() != params[1] || params[0]->query_attackee() == doer || random(100) > 50+doer->query_level()+doer->query_dex() - params[0]->query_level()){ tell_object(doer, "Oh bugger. "+params[0]->query_cap_name()+ " seems to have noticed your intentions.\n"); tell_object(params[0], "Just in time you notice "+ doer->query_cap_name()+" trying to slip around behind you!\n"); params[0]->attack_by(doer); params[0]->set_concentrate(doer); call_out("end_hb_command", 0, doer); return 1; } if(!command_cost(4,doer)){ tell_object(doer, "You lose your patience..\nIn your haste you " "stumble and "+params[0]->query_cap_name()+" notices you!\n"); call_out("end_hb_command", 0, doer); return 1; } if(time != 1){ tell_object(doer, "You continue to work your way behind "+ params[0]->query_cap_name()+"..\n"); return 0; } command_damage(-params[2], doer, params[0]); tell_object(doer, "Seizing the moment, you plunge your weapon into "+ params[0]->query_cap_name()+"'s back.\n"+ params[0]->query_cap_name()+" spasms in pain.\n"); tell_object(params[0], "You spasm in pain as "+doer->query_cap_name()+ " plunges a long sharp object into your back.\nYou could have " "sworn "+doer->query_pronoun()+" was in front of you!\n"); tell_room(environment(doer), doer->query_cap_name()+" circles behind "+ params[0]->query_cap_name()+" and backstabs "+ params[0]->query_objective()+".\n", ({ params[0], doer }) ); params[0]->set_concentrate(doer); return 1; } /* hb_command() */ int sense_check(object doer,object target){ int sense; int moi; if(!doer->query_hide_shadow()) return 1; // Sensed if not hidden if(target->query_property("sense_life")) return 1; if(target->query_int() > target->query_wis() ) sense = target->query_int(); else sense = target->query_wis(); sense += target->query_level(); moi = doer->query_level() + doer->query_dex(); sense = random(sense); // Always SOME chance of being hit if (moi < sense) return 1; // You're sensed return 0; } /* sense_check() */ int backstab_damage(object doer,object target, object weapon){ int lvl; int dam; lvl = doer->query_level(); dam = doer->query_dex(); /* if (dam>20) dam = 20; // hmm, anyone out there with super dex? // Well, it won't help them, he he * Yes it will, Wonderflug */ dam += weapon->query_damage_roll(); if(lvl < 15) dam *= (2 + lvl/2); else dam *= (5 + lvl/3); dam /= 10; dam += random(dam); // Backstab surely needs random element // Baldrick's cap to max hp if (dam > doer->query_max_hp()) dam = doer->query_max_hp(); return(dam); } /* backstab_damage() */