9
« on: November 01, 2007, 02:24:10 pm »
hey all, this is my first post in the forums. i hope you're all doing fine.
i've made some kinda minor revisions to the stock combat.c file (mostly just commenting out sections and changing a few words and numbers).
i basically want melee combat to behave the same as weapons combat, in terms of hitrate and such (so i just made the numbers for chance match up), though i am looking to reduce the damage later. i really want to have pros/cons check against some armor class variable as opposed to the type + " defense" skill, but i left those in for now since i have no idea how to code that part yet. i also want hitpoints to be done just as one number as opposed to limbs, although i left "targetlimb" in some places because i wasn't sure how to swap it out/how to change the body/race files yet. it's hard working with just one file when it works in parallel with like 5 others...
so yea, tell me if you think this stuff would work, thanks!
/* /lib/combat.c
* from the Dead Souls LPC Library
* combat events and data
* created by Descartes of Borg 950124
* Version: @(#) combat.c 1.40@(#)
* Last modified: 96/11/17
*/
#include <lib.h>
#include <rounds.h>
#include <config.h>
#include <daemons.h>
#include <position.h>
#include <damage_types.h>
#include <function.h>
inherit LIB_RACE;
inherit LIB_CLASSES;
inherit LIB_COMBATMSG;
private int Wimpy, Dead;
private string WimpyCommand;
private static int cParalyzed, tNextRound;
private static string TargetLimb, Party;
private static object CurrentEnemy;
private static function fParalyzed, fNextRound;
private static object *Hostiles, *Enemies, *SpecialTargets, *NonTargets;
private static object *PriorEnemies;
string GetName();
mixed GetProperty(string key);
string array AddChannel(mixed val);
string array RemoveChannel(mixed val);
int eventForce(mixed args);
int eventExecuteAttack(mixed target);
int eventWeaponRound(mixed target, mixed val);
void eventWeaponAttack(object target, object weapon, int num);
int eventMeleeRound(mixed target, function f);
void eventMeleeAttack(object target, string limb);
int eventMagicRound(mixed target, function f);
int eventWimpy(int i);
static void create() {
race::create();
classes::create();
Hostiles = ({});
Enemies = ({});
NonTargets = ({});
CurrentEnemy = SpecialTargets = 0;
Party = 0;
fParalyzed = 0;
fNextRound = 0;
cParalyzed = 0;
tNextRound = ROUND_UNDEFINED;
Wimpy = 0.20;
WimpyCommand = "go out";
}
/* ***************** /lib/combat.c data functions ***************** */
varargs int GetMaxHealthPoints(string limb){
return race::GetMaxHealthPoints(limb);
}
int GetDead(){
return Dead;
}
int SetDead(int i){
if(!i) Dead = 0;
else Dead = 1;
return Dead;
}
object array GetEnemies() {
return Enemies;
}
int AddEnemy(object ob) {
if( !ob || (member_array(ob, Enemies) != -1) ) {
return 0;
}
if( !living(ob) ) {
return 0;
}
Enemies += ({ ob });
return 1;
}
int RemoveEnemy(object ob) {
if( !ob || (member_array(ob, Enemies) == -1) ) {
return 0;
}
Enemies -= ({ ob });
return 1;
}
object SetCurrentEnemy(object ob) {
if( !ob ) {
return (CurrentEnemy = 0);
}
if( !living(ob) ) {
return CurrentEnemy;
}
if( member_array(ob, Enemies) == -1 ) {
AddEnemy(ob);
}
return (CurrentEnemy = ob);
}
static object ResetCurrentEnemy() {
object array obs;
obs = filter(GetEnemies(), (: $1 && environment() == environment($1) :));
if( !sizeof(obs) ) {
return 0;
}
return SetCurrentEnemy(obs[random(sizeof(obs))]);
}
object GetCurrentEnemy() {
return CurrentEnemy;
}
private static void SortEnemies() {
if( !sizeof(Enemies = filter(Enemies, (: ($1 && living($1)) :))) ) {
Hostiles = ({});
CurrentEnemy = 0;
return;
}
Hostiles = (Hostiles & Enemies);
}
mixed *AddNonTargets(mixed val){
if(!arrayp(val)) val = ({ val });
foreach(object member in val){
if(member_array(member,NonTargets) == -1){
if(base_name(this_object()) != base_name(member)) NonTargets += ({ member });
}
}
return NonTargets;
}
mixed *RemoveNonTargets(mixed val){
if(!val) val = ({});
if(!arrayp(val)) val = ({ val });
if(!sizeof(val)){
NonTargets = ({});
return NonTargets;
}
foreach(object member in val){
if(member_array(member,NonTargets) != -1){
NonTargets -= ({ member });
}
}
return NonTargets;
}
object *GetNonTargets(){
return NonTargets;
}
int AddHostile(object ob) {
if( !ob || (member_array(ob, Hostiles) != -1) ) {
return 0;
}
if( !living(ob) ) {
return 0;
}
Hostiles += ({ ob });
return 1;
}
int RemoveHostile(object ob) {
if( !ob || (member_array(ob, Hostiles) == -1) ) {
return 0;
}
Hostiles -= ({ ob });
return 1;
}
object array GetHostiles() {
return Hostiles;
}
object array GetSpecialTarget() {
return SpecialTargets;
}
object array SetSpecialTarget(object *cibles) {
if(cibles) SpecialTargets = cibles;
return SpecialTargets;
}
varargs int SetParalyzed(int count, function f) {
if(count < 1) {
count = cParalyzed = 0;
fParalyzed = 0;
}
else {
fParalyzed = f;
cParalyzed = count;
}
return count;
}
int GetParalyzed() { return cParalyzed; }
int eventQuell(){
object *truced;
truced = get_livings(environment(this_object()));
if(sizeof(Enemies)) PriorEnemies = Enemies;
Enemies = ({});
AddNonTargets(truced);
return 1;
}
int eventUnQuell(){
object *truced;
truced = GetNonTargets();
if(sizeof(PriorEnemies)) Enemies += PriorEnemies;
if(sizeof(truced)) RemoveNonTargets(truced);
return 1;
}
string SetParty(string str) {
if( file_name(previous_object()) != PARTY_D ) return Party;
if( str ) AddChannel(str);
else RemoveChannel(Party);
return (Party = str);
}
string GetParty() {
return Party;
}
varargs int SetAttack(mixed target, function callback, int type) {
int i;
string *voibs = ({ "kill", "target", "smite", "waste", "hit", "attack" });
if( objectp(target) ) target = ({ target });
if( target ) {
if( member_array(this_object(), target) != -1 ) return 0;
if(sizeof(NonTargets) && member_array(query_verb(),voibs) != -1){
foreach(object individual in target){
if(member_array(individual,NonTargets) != -1){
NonTargets -= ({ individual });
}
}
}
else if(sizeof(NonTargets)){
foreach(object individual in target){
if(member_array(individual,NonTargets) != -1) target -= ({ individual });
}
if(!sizeof(target)) return 0;
}
if( !GetCurrentEnemy() ) call_out((: eventExecuteAttack :), 0, target);
i = sizeof(target);
while(i--) if( AddEnemy(target[i]) ) AddHostile(target[i]);
if(!sizeof(SpecialTargets) ) SpecialTargets = target;
else {
int spec_targ_here;
foreach(object t in SpecialTargets){
if(t && present(t->GetKeyName(),environment(this_player()))) spec_targ_here = 1;
}
if(!spec_targ_here) SpecialTargets = target;
}
}
fNextRound = callback;
tNextRound = (type || ROUND_UNDEFINED);
return 1;
}
int GetLevel() {
return classes::GetLevel();
}
int GetInCombat() {
return sizeof(filter(GetEnemies(),
(: $1 && (environment($1) == environment()) :)));
}
int GetBaseStatLevel(string stat) {
return race::GetBaseStatLevel(stat);
}
float SetWimpy(float wimpy) {
return (Wimpy = wimpy);
}
float GetWimpy() {
return Wimpy;
}
string SetWimpyCommand(string cmd) {
return (WimpyCommand = cmd);
}
string GetWimpyCommand() {
return WimpyCommand;
}
int GetMaxCarry() {
return race::GetMaxCarry();
}
//int GetMagicChance(int val) {
// val = GetStatLevel("intelligence")/2 + (3*val)/2;
// return val + GetLuck();
//}
//int GetMagicResistance() {
// int val = GetStatLevel("wisdom")/2 + (3*GetSkillLevel("magic defense"))/2;
//
// return val + GetLuck();
//}
//int GetCombatChance(int val) {
// val = val + random((val * GetMobility())/50);
// val = (val/(3- visibility()) + GetLuck());
// if( GetBlind() ) {
// return val/10;
// }
// else {
// return val;
// }
//}
//int GetDefenseChance(int val) {
// val = (val * GetMobility())/50;
// val = (val/(3- visibility()) + (GetLuck()/2));
// if( GetBlind() ) {
// return val/10;
// }
// else {
// return val;
// }
//}
//int GetCombatBonus(int level) {
// int diff = level - GetLevel();
//
// if( diff >= 6 && diff < 16 ) {
// return 4;
// }
// else if( diff >= 1 && diff < 6 ) {
// return 3;
// }
// else if( diff >= -9 && diff < 1 ) {
// return 2;
// }
// else if( diff >= -20 && diff < -9 ) {
// return 1;
// }
// else {
// return 0;
// }
//}
static int GetDamage(int power, string skill) {
int x = GetSkillLevel(skill);
if( power < 1 ) {
return 0;
}
else if( power > 100 ) {
power = 100;
}
if( x < 1 ) {
x = 1;
}
else if( x > 100 ) {
x = 100;
}
x = (x * (power/2 + random(power/2))/10);
x += (GetLuck()/2) + GetStatLevel("strength")/8;
if( x < 1 ) { // negative luck or cursed strength
return 1;
}
return x;
}
/*
int CanWeapon(object target, string type, int hands, int num) {
string limb = target->GetRandomLimb(TargetLimb);
int chance = (7*GetSkillLevel(type+" attack") +
3*GetStatLevel("coordination"))/10;
int div = 2;
int x, y;
if(hands > 1) {
if(GetSkillLevel("multi-hand")) {
chance = (chance/2) +
(GetSkillLevel("multi-hand")/75)*(chance/2);
}
else { /* If you are really strong you can use multihand a bit */
chance *= GetStatLevel("strength")/300;
div += (hands-1);
}
}
if(num > 1) {
if(GetSkillLevel("multi-weapon")) {
chance = (chance/2) +
(GetSkillLevel("multi-weapon")/75)*(chance/2);
}
else { /* If you are really coordinated you can use multiweap a bit */
chance *= GetStatLevel("coordination")/300;
div += (num-1);
}
}
chance = GetCombatChance(chance/div);
x = random(chance);
y = random(10);
if( x <= y ) {
if( x > y/2 ) {
TargetLimb = target->GetRandomLimb(0);
}
else {
TargetLimb = 0;
}
}
else {
TargetLimb = limb;
}
return chance;
}
*/
int CanWeapon(object target, string type, int hands, int num) {
int chance = (7*GetSkillLevel(type) + 3*GetStatLevel("dexterity"))/10;
chance = GetCombatChance(chance/2);
return chance;
}
/*
int CanMelee(object target) {
if(!this_object()->GetMelee()){
string limb = target->GetRandomLimb(TargetLimb);
int chance = ( 6*GetSkillLevel("melee attack") +
2*GetStatLevel("coordination") )/20;
int y = random(10);
int x;
chance = GetCombatChance(chance/3);
x = random(chance);
if( x <= y ) {
if( x > y/2 ) {
TargetLimb = target->GetRandomLimb(0);
}
else {
TargetLimb = 0;
}
}
else {
TargetLimb = limb;
}
return chance;
}
else {
string limb = target->GetRandomLimb(TargetLimb);
int chance = ( 7*GetSkillLevel("melee attack") +
3*GetStatLevel("coordination") )/10;
int y = random(10);
int x;
chance = GetCombatChance(chance/2);
x = random(chance);
if( x <= y ) {
if( x > y/2 ) {
TargetLimb = target->GetRandomLimb(0);
}
else {
TargetLimb = 0;
}
}
else {
TargetLimb = limb;
}
return chance;
}
}
*/
int CanMelee(object target) {
int chance = (7*GetSkillLevel("melee") + 3*GetStatLevel("dexterity"))/10;
chance = GetCombatChance(chance/2);
return chance;
}
static int Destruct() {
if( GetParty() ) PARTY_D->eventLeaveParty(this_object());
return 1;
}
/* ***************** /lib/combat.c events ***************** */
varargs int eventDie(mixed agent) {
object ob;
int x;
if(Dead) return 1;
Dead = 1;
x = race::eventDie(agent);
if( x != 1 ) {
return x;
}
foreach(ob in GetEnemies()) {
if( ob ) {
ob->eventEnemyDied(this_object());
}
}
environment()->eventLivingDied(this_object(), agent);
Enemies = ({});
flush_messages();
return 1;
}
int eventExecuteAttack(mixed target) {
object array weapons;
function f = fNextRound;
int type = tNextRound;
int position = GetPosition();
if(Dead) return 1;
if(target->GetDead()) return 1;
fNextRound = 0;
tNextRound = ROUND_UNDEFINED;
/*
if( position == POSITION_LYING || position == POSITION_SITTING &&
RACES_D->GetLimblessCombatRace(this_object()->GetRace()) != 1) {
if(this_object()->CanFly()) {
this_object()->eventFly();
}
else if(RACES_D->GetLimblessCombatRace(GetRace()) != 1){
eventPrint("You can't fight unless you are up!");
return 0;
}
}
if(this_object()->GetPacifist()) {
tell_object(this_object(),"As a pacifist, you choose not to fight.");
return 0;
}
*/
if( arrayp(target) ) {
if( !f || (functionp(f) & FP_OWNER_DESTED) ) {
return 0; /* built in only handles 1 targ */
}
target = filter(target, function(object ob) {
if( !ob ) {
return 0;
}
if( !ob->eventPreAttack(this_object()) ) {
return 0;
}
return 1;
});
if( !sizeof(target) ) {
return 0;
}
}
else if( !target->eventPreAttack(this_object()) ) {
return 0;
}
// this_object()->AddStaminaPoints(-1);
switch(type) {
case ROUND_UNDEFINED:
if( functionp(f) && !(functionp(f) & FP_OWNER_DESTED) ) {
return evaluate(f, target);
}
if( sizeof(weapons = GetWielded()) ) {
return eventWeaponRound(target, weapons);
}
else {
return eventMeleeRound(target, 0);
}
case ROUND_MAGIC:
return eventMagicRound(target, f);
case ROUND_MELEE:
return eventMeleeRound(target, functionp(f) ? f : 0);
case ROUND_WEAPON:
return eventWeaponRound(target, functionp(f) ? f : GetWielded());
case ROUND_OTHER:
if( functionp(f) && !(functionp(f) & FP_OWNER_DESTED) ) {
return evaluate(f);
}
else {
return 0;
}
default: return 0;
}
return 0;
}
int eventWeaponRound(mixed target, mixed val) {
object array weapons = 0;
function f = 0;
if(Dead) return 1;
if(target->GetDead()) return 1;
if( arrayp(val) ) {
weapons = val;
}
else if( functionp(val) && !(functionp(val) & FP_OWNER_DESTED) ) {
f = val;
}
else {
return 0;
}
if( f ) {
evaluate(f, target);
}
else {
int count = sizeof(weapons);
foreach(object weapon in weapons) {
if( !target ) {
break;
}
eventWeaponAttack(target, weapon, count);
}
}
return target->GetDying();
}
void eventWeaponAttack(object target, object weapon, int num){
string weapon_type = weapon->GetWeaponType();
int hands = weapon->GetHands();
int level = target->GetLevel();
int bonus = GetCombatBonus(level);
int power, pro, con;
if(Dead) return;
if(target->GetDead()) return;
if( target->GetDying() ) {
return;
}
pro = CanWeapon(target, weapon_type, hands, num);
power = random(pro);
con = target->GetDefenseChance(target->GetSkillLevel(weapon_type + " defense"));
if( !TargetLimb ) { // If the thing stood still, I still missed
eventTrainSkill(weapon_type, pro, 0, 0, bonus);
/* if( hands > 1 ) {
eventTrainSkill("multi-hand", pro, 0, 0, bonus);
}
if( num > 1 ) {
eventTrainSkill("multi-weapon", pro, 0, 0, bonus);
}
*/ SendWeaponMessages(target, -2, weapon, TargetLimb);
}
else if( !target->eventReceiveAttack(power, weapon_type, this_object()) ) {
// Target avoided the attack
eventTrainSkill(weapon_type, pro, con, 0, bonus);
/* if( hands > 1 ) {
eventTrainSkill("multi-hand", pro, con, 0, bonus);
}
if( num > 1 ) {
eventTrainSkill("multi-weapon", pro, con, 0, bonus);
}
*/ SendWeaponMessages(target, -1, weapon, TargetLimb);
}
else { // I hit, but how hard did I hit?
int damage_type, damage, weapon_damage, actual_damage, encumbrance;
encumbrance = this_object()->GetEncumbrance();
if(encumbrance > 20){
tell_object(this_object(),"You struggle to fight while carrying stuff.");
}
eventTrainSkill(weapon_type, pro*2, con, 1, bonus);
damage_type = weapon->GetDamageType();
damage = (weapon->eventStrike(target) * pro)/(GetLevel()*2);
damage = GetDamage(damage, weapon_type);
damage -= encumbrance;
if(damage < 0) damage = 0;
actual_damage = target->eventReceiveDamage(this_object(), damage_type,
damage, 0, TargetLimb);
if( actual_damage < 0 ) {
actual_damage = 0;
}
weapon_damage = damage - actual_damage;
if( weapon_damage > 0 ) {
weapon->eventReceiveDamage(this_object(), BLUNT, weapon_damage,
0, TargetLimb);
}
if( !target->GetDying() ) {
SendWeaponMessages(target, actual_damage, weapon, TargetLimb);
}
else {
eventPrint(possessive_noun(target) + " death is now on your "
"head.");
target->eventPrint(GetName() + " is your murderer.");
environment()->eventPrint(possessive_noun(target) +
" death is now on " +
possessive_noun(this_object())
+ " head.", ({ this_object(), target }));
}
}
}
/*
int eventMeleeRound(mixed target, function f) {
string array limbs = GetLimbs() - ({ GetTorso() });
int count = sizeof(limbs);
int attacks;
if(Dead) return 1;
if(target->GetDead()) return 1;
if( count < 2 ) {
if(RACES_D->GetLimblessCombatRace(this_object()->GetRace())){
limbs = GetLimbs();
count = sizeof(limbs);
}
else return 0;
}
if( !f || (functionp(f) & FP_OWNER_DESTED) ) {
attacks = 1 + random(GetSkillLevel("melee attack"))/30;
while( attacks-- ) {
if( target->GetDying() ) {
break;
}
eventMeleeAttack(target, limbs[random(count)]);
}
}
else {
evaluate(f, target, limbs[random(count)]);
}
return target->GetDying();
}
*/
int eventMeleeRound(mixed target, function f) {
int attacks;
if(Dead) return 1;
if(target->GetDead()) return 1;
if ( !f || (functionp(f) & FP_OWNER_DESTED) ) {
attacks = 1 + random(GetSkillLevel("melee"))/30;
while( attacks-- ) {
if( target->GetDying() ) {
break;
}
eventMeleeAttack(target, limbs[random(count)]);
}
}
else {
evaluate(f, target, limbs[random(count)]);
}
return target->GetDying();
}
void eventMeleeAttack(object target, string limb) {
int pro, con;
int chance;
if( target->GetDead() || Dead || target->GetDying() ) {
return;
}
/*
if(limb == "head" && this_object()->GetCanBite()) {
eventBite(target);
return;
}
*/
pro = CanMelee(target);
con = target->GetDefenseChance(target->GetSkillLevel("melee defense"));
chance = random(pro);
if( !TargetLimb ) { // I *really* missed
SendMeleeMessages(target, -2);
eventTrainSkill("melee attack", pro, 0, 0,
GetCombatBonus(target->GetLevel()));
}
else if( !target->eventReceiveAttack(chance, "melee", this_object()) ) {
// Enemy dodged my attack
SendMeleeMessages(target, -1);
eventTrainSkill("melee", pro, con, 0,
GetCombatBonus(target->GetLevel()));
}
else {
int x, encumbrance;
encumbrance = this_object()->GetEncumbrance();
if(encumbrance > 20){
tell_object(this_object(),"You struggle to fight while carrying stuff.");
}
// I hit, how hard?
eventTrainSkill("melee", pro, con, 1,
GetCombatBonus(target->GetLevel()));
if(this_object()->GetMelee()) x = GetDamage(3*chance/4, "melee");
else x = GetDamage(4*chance/20, "melee");
x -= encumbrance;
if(x < 0) x = 0;
x = target->eventReceiveDamage(this_object(), BLUNT, x, 0,
TargetLimb);
if( !target->GetDying() ) {
SendMeleeMessages(target, (x > 0) ? x : 0, TargetLimb);
}
else {
eventPrint(possessive_noun(target) + " death is now "
"on your head.");
target->eventPrint(GetName() + " is your murderer.");
environment()->eventPrint(possessive_noun(target) +
" death is now on " +
possessive_noun(this_object()) +
" head.", ({ this_object(), target }));
}
AddExperiencePoints(x / 2);
}
}
/*
int eventMagicRound(mixed target, function f) {
if(target->GetDead()) return 1;
evaluate(f, target);
return target->GetDying();
}
mixed eventBite(object target) {
int pro = CanMelee(target);
int con = target->GetDefenseChance(target->GetSkillLevel("melee defense"));
int x = random(pro);
if(target->GetDead()) return 1;
if( environment() != environment(target) ) {
eventPrint(target->GetName() + " has gone away.");
return 1;
}
if( TargetLimb ) {
if( target->eventReceiveAttack(x, "melee", this_object()) ) {
x = GetDamage(pro*2, "melee attack");
x = target->eventReceiveDamage(this_object(), BITE, x, 0,
TargetLimb);
if( x < 1 ) {
target->eventPrint(possessive_noun(this_object()) + " bite "
"is nothing more than a pinch.");
eventPrint("Your bite is nothing more than a pinch.");
environment()->eventPrint(possessive_noun(this_object()) +
" bite is nothing more than a "
"pinch.",
({ target, this_object() }));
}
else {
target->eventPrint(GetName() + " bites you in the " +
TargetLimb + "!");
eventPrint("You bite " + target->GetName() + " in the " +
TargetLimb + "!");
environment()->eventPrint(GetName() + " bites " +
target->GetName() + " in the " +
TargetLimb + "!",
({ target, this_object() }));
}
eventTrainSkill("melee attack", pro, con, 1,
GetCombatBonus(target->GetLevel()));
}
else {
target->eventPrint("You avoid " + possessive_noun(this_object()) +
" bite.");
eventPrint(target->GetName() + " avoids your bite.");
environment()->eventPrint(target->GetName() + " avoids " +
possessive_noun(this_object()) +
" bite.",
({ this_object(), target }));
eventTrainSkill("melee attack", pro, con, 0,
GetCombatBonus(target->GetLevel()));
}
}
else {
eventPrint("You flounder about like a buffoon.");
environment()->eventPrint(GetName() + " flounders about like a "
"buffoon.", this_object());
}
return 1;
}
*/
int eventPreAttack(object agent) {
if( agent == this_object() ) {
return 0;
}
if( environment()->GetProperty("no attack") ) {
return 0;
}
if( GetDying() ) {
return 0;
}
if( playerp(this_object()) && playerp(agent) && !PLAYER_KILL) {
if( !environment()->CanAttack( agent, this_object() ) ) {
return 0;
}
}
if( AddEnemy(agent) ) {
AddHostile(agent);
}
return 1;
}
varargs int eventReceiveAttack(int speed, string def, object agent) {
int x, pro, level, bonus;
if(Dead) return 0;
if( !agent ) {
agent = previous_object();
}
if( !living(agent) ) {
level = 1;
bonus = 1;
}
else {
level = agent->GetLevel();
bonus = GetCombatBonus(level);
}
if( AddEnemy(agent) ) {
AddHostile(agent);
}
/* if( def == "magic" ) {
pro = GetMagicResistance();
if( (x = random(pro)) > speed ) {
eventTrainSkill("magic defense", pro, speed, 1, bonus);
return 0;
}
else {
eventTrainSkill("magic defense", pro, speed, 0, bonus);
return 1;
}
}
*/
// else {
pro = GetDefenseChance(GetSkillLevel(def + " defense"));
x = random(pro = pro/2);
if( x > speed ) {
eventTrainSkill(def + " defense", pro, speed, 1, bonus);
return 0;
}
else {
eventTrainSkill(def + " defense", pro, speed, 0, bonus);
return 1;
}
// }
}
void eventKillEnemy(object ob) {
int level;
if( !ob ) return;
level = ob->GetLevel();
if(ob->GetCustomXP()) this_object()->AddExperiencePoints(ob->GetCustomXP());
else this_object()->AddExperiencePoints(level * 80);
if( member_array(ob, GetHostiles()) == -1 ) {
int x;
eventTrainSkill("murder", GetLevel(), level, 1,GetCombatBonus(level));
x = (int)ob->GetMorality();
if( x > 0 ) x = -x;
else if( GetMorality() > 200 ) x = 100;
else x = 0;
eventMoralAct(x);
}
}
void eventDestroyEnemy(object ob) {
int level;
if( !ob ) return;
level = ob->GetLevel();
if(ob->GetCustomXP()) this_object()->AddExperiencePoints(ob->GetCustomXP());
else this_object()->AddExperiencePoints(level * 80);
eventTrainSkill("faith", GetLevel(), level, 1, GetCombatBonus(level));
}
void eventEnemyDied(object ob) {
if( !ob ) return;
Enemies -= ({ ob });
Hostiles -= ({ ob });
if(!sizeof(SpecialTargets) || (!sizeof(Enemies) || !sizeof(Hostiles)))
NonTargets = ({});
}
varargs int eventReceiveDamage(mixed agent, int type, int x, int internal,
mixed limbs) {
int hp,encumbrance;
//tc("ok.","green");
encumbrance = this_object()->GetEncumbrance();
if(Dead) return 0;
if(encumbrance > 200){
if(GetInCombat()) tell_object(this_object(),"You try to dodge while weighed down.");
}
x = race::eventReceiveDamage(agent, type, x, internal, limbs);
if( !Wimpy ) return x;
if( (hp = GetHealthPoints()) < 1 ) return x;
if( Wimpy < percent(hp, GetMaxHealthPoints()) )
return x;
call_out((: eventWimpy :), 0);
return x;
}
/*
mixed eventTurn(object who) {
int defense;
if( !GetUndead() ) {
return 0;
}
if( GetProperty("no turn") ) {
if( !who ) {
return 0;
}
else {
int x = GetProperty("no turn");
environment(who)->eventPrint("The power of the undead "
"turns on " + who->GetName() +
".", who);
who->eventPrint("The power of the undead turns on you.");
if( x > random(100) + 1 ) {
who->eventDie(this_object());
}
else {
who->eventReceiveDamage(this_object(), MAGIC, random(50), 1);
}
return 0;
}
}
if( !who ) {
race::eventTurn(who);
return 1;
}
defense = GetMagicResistance();
if( who->GetSkillLevel("faith") < defense ) {
who->eventPrint("You writhe in pain.");
environment(who)->eventPrint(who->GetName() + " writhes in pain.",
who);
who->eventReceiveDamage(this_object(), MAGIC, random(defense), 1);
eventTrainSkill("magic defense", defense, who->GetSkillLevel("faith"),
1, GetCombatBonus(who->GetLevel()));
return 0;
}
race::eventTurn(who);
return 1;
}
*/
int eventWimpy(int i) {
object env = environment();
string dir, cmd;
if( !env || !GetInCombat() ) {
if(!i) return 0;
}
cmd = WimpyCommand || "go out";
if( (sscanf(cmd, "go %s", dir) && !((string)env->GetExit(dir))) ||
(sscanf(cmd, "enter %s", dir) && !((string)env->GetEnter(dir))) ) {
string *tmp;
tmp = filter((string *)environment()->GetExits(),
(: !((string)environment()->GetDoor($1)) :));
if( !sizeof(tmp) ) {
tmp = filter((string *)environment()->GetEnters(),
(: !((string)environment()->GetDoor($1)) :));
if( !sizeof(tmp) ) {
eventPrint("You need to escape, but you have nowhere to go!");
return 0;
}
cmd = "enter " + tmp[random(sizeof(tmp))];
}
else cmd = "go " + tmp[random(sizeof(tmp))];
}
return eventForce(cmd);
}
static void heart_beat() {
race::heart_beat();
if( GetSleeping() || GetDying() ) {
return;
}
if( cParalyzed > 0 ) {
cParalyzed--;
if( cParalyzed < 1 ) {
function f;
f = fParalyzed;
fParalyzed = 0;
if( functionp(f) && !(functionp(f) & FP_OWNER_DESTED) ) {
evaluate(f);
}
else {
eventPrint("You can move again.");
}
}
return;
}
if( sizeof(Enemies) ) {
SortEnemies();
foreach(object dude in Enemies){
if(member_array(dude,NonTargets) != -1){
RemoveEnemy(dude);
RemoveHostile(dude);
}
}
}
if( sizeof(Enemies) ) {
object ob;
SortEnemies();
if( SpecialTargets ) {
foreach(object target in SpecialTargets) {
if( objectp(SetCurrentEnemy(target)) ) {
break;
}
}
eventExecuteAttack(SpecialTargets);
SpecialTargets = 0;
}
else if( ob = ResetCurrentEnemy() ) {
eventExecuteAttack(ob);
}
}
else if( tNextRound != ROUND_UNDEFINED && functionp(fNextRound) ) {
function f;
f = fNextRound;
tNextRound = ROUND_UNDEFINED;
evaluate(f);
}
}
ps, i see some tabs in there now, so it might make spacing a little wonky... i'll replace those when i actually place them into ed. i havn't actually tested this yet as i wasn't sure if i was going in the right direction, and also i'm at work currently... so yea.
thanks for taking the time to read this over! and feedback is definitely appreciated.