mud/lib/verbs/players/backstab.c
2020-09-06 05:43:07 -07:00

198 lines
6.8 KiB
C

/* Allows players to possibly backstab a targets
* created by Rush@Dead Souls
* Version: @(#) backstab.c 1.3@(#)
* Last Modified: 96/12/21
*/
#include <lib.h>
#include <position.h>
#include "damage_types.h"
#include "include/backstab.h"
inherit LIB_VERB;
static void create() {
verb::create();
SetVerb("backstab");
SetRules("LIV");
SetErrorMessage("Who do you want to backstab?");
SetHelp("Syntax: backstab <LIVING>\n\n"
"This sneaky attack allows more devious players to "
"backstab a specified target.");
}
mixed can_backstab_liv() {
if( !environment(this_player()) ) return 0;
if( this_player()->GetInCombat() )
return "You are too busy with combat!";
else return this_player()->CanManipulate();
}
mixed do_backstab_liv(object ob) {
object env;
if(!(env = environment(this_player()))) return 0;
if( this_player()->GetPosition() != POSITION_STANDING )
this_player()->eventStand();
if(!ob || !present(ob, env)) {
this_player()->eventPrint("Your hapless victim is no longer present.");
return 1;
}
this_player()->RemoveNonTargets(({ob}));
this_player()->eventPrint("%^RED%^You sneak up behind " +
ob->GetName() + "...%^RESET%^");
this_player()->SetAttack(ob, (:eventBackstab, this_player(), ob:));
return 1;
}
int eventBackstab(object backstabber, object target) {
object env;
float tmp;
int suprise;
object *weapons;
int numberOfWeapons;
int numberOfStabs;
int i;
if(!backstabber || !(env = environment(backstabber))) return 0;
if(!target || !present(target, env)) {
backstabber->eventPrint("Your hapless victim is no longer present.");
return 1;
}
tmp = backstabber->GetSkillLevel("stealth")*1.5;
tmp += backstabber->GetStatLevel("charisma")/2.0;
tmp += backstabber->GetStatLevel("luck")/3.0;
tmp += backstabber->GetMobility()/3.0;
tmp -= target->GetStatLevel("luck")/3.0;
tmp -= target->GetStatLevel("wisdom")/3.0;
tmp -= target->GetMobility()/5.0;
tmp *= 1.0;
if(tmp < 1.0) tmp = 1.0;
suprise = to_int(tmp);
backstabber->AddSkillPoints("stealth", to_int(suprise * 3.0));
backstabber->AddStaminaPoints(-(5 + random(5)));
moral_act(backstabber, target, -30);
if(suprise < random(100) || !present(target, environment(backstabber))) {
backstabber->eventPrint("%^RED%^" + target->GetName()
+ " evades your poorly executed backstab.%^RESET%^");
target->eventPrint("%^RED%^You easily dodge " + possessive_noun(backstabber)
+ " attempted backstab.%^RESET%^");
environment(backstabber)->eventPrint("%^RED%^" + target->GetName()
+ " dodges " + possessive_noun(backstabber) + " attempted backstab.%^RESET%^",
({backstabber, target}));
return 1;
}
weapons = backstabber->GetWielded();
numberOfWeapons = sizeof(weapons);
if(!numberOfWeapons) {
backstabber->eventPrint("%^RED%^You beat your fists ineffectively on "
+ possessive_noun(target) + " back.%^RESET%^");
target->eventPrint("%^RED%^Somebody beats ineffectively upon your back.%^RESET%^");
environment(backstabber)->eventPrint("%^RED%^" + backstabber->GetName()
+ " backstabs " + target->GetName() + " expertly... unfortunately "
+ nominative(backstabber) + " forgot " + possessive(backstabber) + " knives.%^RESET%^",
({backstabber, target}));
return 1;
}
numberOfStabs = 0;
for(i = 0; i < numberOfWeapons && target; i++)
numberOfStabs += eventStab(backstabber, target, weapons[i]);
if(!numberOfStabs) {
target->eventPrint("%^RED%^You dodge " + possessive_noun(backstabber)
+ " attempted backstab.%^RESET%^");
return 1;
}
backstabber->eventExecuteAttack(target);
return 1;
}
int eventStab(object backstabber, object target, object weapon) {
string weaponType;
int damage;
float x;
int percentDamage;
float adjustment;
int numberWielded;
if(!(weaponType = weapon->GetWeaponType())) return 0;
numberWielded = sizeof(backstabber->GetWielded());
x = weapon->GetClass() * 5.0;
x += backstabber->GetSkillLevel(weaponType + " attack")/1.0;
x += backstabber->GetStatLevel("strength")/2.0;
x += backstabber->GetStatLevel("luck")/3.0;
x += backstabber->GetMobility()/3.0;
if(numberWielded > 1) {
adjustment = backstabber->GetSkillLevel("multi-weapon") / (numberWielded / 2.0);
x *= adjustment/100.0;
}
x -= target->GetStatLevel("luck")/3.0;
x *= 0.5;
x = (x + random(x)) / 2.0;
if(weaponType != "knife") x = (x - 50.0) / 4.0;
if(x < 1.0) x = 0.0;
damage = target->eventReceiveDamage(backstabber,
weapon->GetDamageType(), to_int(x), 0, target->GetTorso());
if(damage > 0) {
weapon->eventReceiveDamage(BLUNT, damage, 0, target->GetTorso());
percentDamage = damage * 100 / target->GetMaxHealthPoints();
if(percentDamage < 1) percentDamage = 0;
}
else percentDamage = 0;
eventPrintDamage(backstabber, target, weapon, percentDamage);
backstabber->AddSkillPoints(weaponType + " attack", 7 + damage/10);
return 1;
}
int eventPrintDamage(object backstabber, object target, object weapon, int percentDamage) {
string adverb;
string myVerb;
string verb;
if(!percentDamage) {
backstabber->eventPrint("%^RED%^You fumble awkwardly with your "
+ strip_article(weapon->GetShort()) + ".%^RESET%^");
environment(backstabber)->eventPrint("%^RED%^" + backstabber->GetName()
+ " fumbles awkwardly with " + possessive(backstabber) + " "
+ strip_article(weapon->GetShort()) + ".%^RESET%^",
({backstabber, target}));
return 1;
}
if(percentDamage < 15) {
myVerb = "jab ";
verb = "jabs ";
adverb = "sharply ";
}
else if(percentDamage < 30) {
myVerb = "stab ";
verb = "stabs ";
adverb = "painfully ";
}
else {
myVerb = "slam ";
verb = "slams ";
adverb = "deep ";
}
backstabber->eventPrint("%^RED%^You " + myVerb + "your "
+ strip_article(weapon->GetShort()) + " " + adverb + "into "
+ possessive_noun(target) + " back.%^RESET%^");
target->eventPrint("%^RED%^Your back sears with pain as a " + weapon->GetWeaponType()
+ " " + verb + adverb + "into you.%^RESET%^");
environment(backstabber)->eventPrint("%^RED%^" + backstabber->GetName() + " "
+ verb + possessive(backstabber) + " " + strip_article(weapon->GetShort())
+ " " + adverb + "into " + possessive_noun(target) + " back.%^RESET%^",
({backstabber, target}));
return 1;
}