dsI/bin/
dsI/extra/creremote/
dsI/extra/mingw/
dsI/extra/wolfpaw/
dsI/fluffos-2.7-ds2.018/
dsI/fluffos-2.7-ds2.018/ChangeLog.old/
dsI/fluffos-2.7-ds2.018/Win32/
dsI/fluffos-2.7-ds2.018/compat/
dsI/fluffos-2.7-ds2.018/compat/simuls/
dsI/fluffos-2.7-ds2.018/testsuite/
dsI/fluffos-2.7-ds2.018/testsuite/clone/
dsI/fluffos-2.7-ds2.018/testsuite/command/
dsI/fluffos-2.7-ds2.018/testsuite/data/
dsI/fluffos-2.7-ds2.018/testsuite/etc/
dsI/fluffos-2.7-ds2.018/testsuite/include/
dsI/fluffos-2.7-ds2.018/testsuite/inherit/
dsI/fluffos-2.7-ds2.018/testsuite/inherit/master/
dsI/fluffos-2.7-ds2.018/testsuite/log/
dsI/fluffos-2.7-ds2.018/testsuite/single/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
dsI/fluffos-2.7-ds2.018/testsuite/u/
dsI/fluffos-2.7-ds2.018/tmp/
dsI/lib/cfg/
dsI/lib/cmds/common/
dsI/lib/cmds/creators/include/
dsI/lib/cmds/creators/include/SCCS/
dsI/lib/daemon/services/
dsI/lib/doc/
dsI/lib/domains/Ylsrim/
dsI/lib/domains/Ylsrim/adm/
dsI/lib/domains/Ylsrim/armour/
dsI/lib/domains/Ylsrim/broken/
dsI/lib/domains/Ylsrim/fish/
dsI/lib/domains/Ylsrim/meal/
dsI/lib/domains/Ylsrim/npc/
dsI/lib/domains/Ylsrim/virtual/
dsI/lib/domains/Ylsrim/weapon/
dsI/lib/domains/default/creator/
dsI/lib/domains/default/etc/
dsI/lib/domains/default/room/
dsI/lib/lib/comp/
dsI/lib/lib/lvs/
dsI/lib/lib/user/
dsI/lib/lib/virtual/
dsI/lib/obj/
dsI/lib/obj/include/
dsI/lib/realms/
dsI/lib/save/kills/a/
dsI/lib/save/kills/b/
dsI/lib/save/kills/f/
dsI/lib/save/kills/m/
dsI/lib/save/kills/q/
dsI/lib/save/kills/r/
dsI/lib/secure/cfg/
dsI/lib/secure/cfg/classes/
dsI/lib/secure/cfg/races/SCCS/
dsI/lib/secure/cmds/creators/include/
dsI/lib/secure/cmds/players/
dsI/lib/secure/cmds/players/include/
dsI/lib/secure/daemon/include/
dsI/lib/secure/lib/
dsI/lib/secure/lib/include/
dsI/lib/secure/lib/net/
dsI/lib/secure/lib/net/include/
dsI/lib/secure/lib/std/
dsI/lib/secure/obj/
dsI/lib/secure/obj/include/
dsI/lib/secure/save/
dsI/lib/spells/
dsI/lib/verbs/admins/include/
dsI/lib/verbs/common/
dsI/lib/verbs/common/include/
dsI/lib/verbs/creators/
dsI/lib/verbs/creators/include/
dsI/lib/verbs/players/include/SCCS/
dsI/lib/verbs/rooms/
dsI/lib/verbs/rooms/include/
dsI/lib/www/
dsI/v22.2b14/
dsI/win32/
/*  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 1;
}

mixed do_backstab_liv(object ob) {
  object env;
  
  if(!(env = environment(this_player()))) return 0;
  if( (int)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()->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 = (string)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 = (int)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;
}