198 lines
6.8 KiB
C
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;
|
|
}
|