Author Topic: DS combat  (Read 22308 times)

Offline Andras

  • Acquaintance
  • *
  • Posts: 15
    • View Profile
Re: DS combat
« Reply #30 on: January 24, 2010, 05:33:58 am »
what program do you use when you code to get line numbers?
I tried to add this, but didnt work. I guess I screwd up on some Lines.
and my english aint that great but "comment out" = //  // ?

Offline Andras

  • Acquaintance
  • *
  • Posts: 15
    • View Profile
Re: DS combat
« Reply #31 on: January 24, 2010, 06:54:31 am »
what program do you use when you code to get line numbers?
I tried to add this, but didnt work. I guess I screwd up on some Lines.
and my english aint that great but "comment out" = //  // ?

I downloaded a program and tried to enter it correctly, this time it was atleast more correct then befor.
But still the "Lines" didnt alway match the number said, so I guess I tried around alittle. But when I was done
I tried to start the mud. Cant logg in. alot of errors. When I tried to loggin with just the combat.c edited the
thing was the same, cant logg in. Maybe its DS3.0 fault?

Offline cratylus

  • Your favorite and best
  • Administrator
  • ***
  • Posts: 1024
  • Cratylus@Dead Souls <ds> np
    • View Profile
    • About Cratylus
Re: DS combat
« Reply #32 on: January 24, 2010, 07:39:46 am »
Quote
Maybe its DS3.0 fault?

You have not provided enough information to be able to know whether the problem is you or DS.

For example, I've no idea what this "program" you downloaded is.

I don't know what you're using as an editor to be able to help you find line numbers.

If you're saying that you downloaded someone's replacement for DS combat
(after all, that's the thread you're posting in), and tried to install it, and it doesn't work,
and you don't know why, then you're going to have to provide the person who coded
that replacement with enough information to be able to help you troubleshoot your problem.

It's worth noting that just because code appears on the forum on this site doesn't
mean it's been particularly thoroughly tested nor does it mean that it's officially
recommended or even unofficially supported. In particular, LPC code should
not be treated like Diku "snippets". Even code from one DS version may not
necessarily work on another, and you should not expect code to just be "drop
in compatible" except when explicitly labeled as such by the author, and even
then
I wouldn't trust the typical LPC coder's opinion on that.

No fense to anyone!

:)

-Crat
http://web.archive.org/web/20080212140425/http://se.linux.org/dokumentation/artiklar/kunskap/smartafragor
« Last Edit: January 24, 2010, 08:15:18 am by cratylus »

Offline Andras

  • Acquaintance
  • *
  • Posts: 15
    • View Profile
Re: DS combat
« Reply #33 on: January 24, 2010, 09:14:10 am »
I used "Geany" for the purpose of getting line numbers.

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
Re: DS combat
« Reply #34 on: January 25, 2010, 08:09:35 am »
There may be two sources of confusion here.

First, when I provided an instruction like

L123 change GetInCombat to GetCurrentEnemy

to edit the stock ds code, I meant that you should go to Line 123 and change the function name "GetInCombat" to "GetCurrentEnemy". This is because the stock ds function is still trying to use the old GetInCombat function, which is no longer there, because we removed it in step #1 (remove old combat.c). The "L123" that I refer to does not come from any program. It is just my shorthand notation for "line 123".

Second, the instructions provided, to convert a stock ds to my new combat, are for converting a version of ds, approximately ds2.5 to ds2.9. Those should all work by following my detailed instructions. However, since I posted this new combat code, Crat has made numerous changes to the ds lib.

A couple of nights ago, I installed my new combat code onto a brand new ds3.0. The instructions are a bit longer than the posted ones. I shall try to post the full instructions for conversion to ds3.0 sometime in the next 2 weeks.

-Detah

Offline Andras

  • Acquaintance
  • *
  • Posts: 15
    • View Profile
Re: DS combat
« Reply #35 on: January 26, 2010, 01:51:03 am »
ok, thanks for the info!

Offline HoriceGump

  • Acquaintance
  • *
  • Posts: 16
    • View Profile
Re: DS combat
« Reply #36 on: September 23, 2010, 12:54:04 am »
Hows the whole project going?  Got anywhere on making a conversion to ds3.0?

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
Re: DS combat
« Reply #37 on: October 14, 2010, 11:50:27 pm »
Updated Instructions to load my combat system into an out-of-the-box ds v3.0.

1) rename and move your stock combat.c to c:/ds/bin/combat.old

2) save the following as combat.c in /lib/
Code: [Select]
/*****************************************************************************
 * Barebones combat for Dead Souls lib                                       *
 * Author: Detah, with huge thanks to Silenus for design outline             *
 *   Thanks also to Cratylus and Raudhrskal for misc. advice                 *
 * Modified: Detah@Arcania 05-01-08                                          *
 * Modified: Detah@Arcania 09-30-08                                          *
 * Modified: Detah@Arcania 12-07-08                                          *
 * Modified: Detah@Arcania 01-29-09                                          *
 * to update after a change:                                                 *
 *   update /lib/combat.c                                                    *
 *   update -r /lib/creator.c                                                *
 *   update /domains/town/room/valley.c (testing room)                       *
 *   userload aura and any other tps                                         *
 *****************************************************************************/
#include <daemons.h>
inherit LIB_RACE;
inherit LIB_CLASSES;
inherit LIB_COMBATMSG;

static int rd;
int Dead, Wimpy;
private object *Enemies;        /* All enemies who you have ever attacked, not killed and are not calmed */
private object *LocalEnemies;   /* Those enemies in Enemies which are currently in attacker's env */
private object *CalmEnemies;    /* Storage area for Enemies during Calm, Quell, or any other StopCombat event */
private object CurrentEnemy;    /* This is the specific enemy which is targetted each round in melee */
int CombatRound(mixed target);
int ComputeToHit(object attacker, object target);
int ComputeDamage(object attacker, object target);
void DamageMessage(int dam, object target);
void ApplyDamage(int dam, object target);
int GetWimpy();
void Wimpy();
/*****************************************************************************
 * Create function                                                           *
 * Inputs: none                                                              *
 * Output: none                                                              *
 * initializes basic combat variables and starts the heartbeat function in   *
 * the current object                                                        *
 *****************************************************************************/
static void create() {
    race::create();
    rd=1;
    Dead=0; /*is this necessary, since its also in body.c create() */
Wimpy=20;
    Enemies=({});
    LocalEnemies=({});
    CalmEnemies=({});
    CurrentEnemy=0;
    set_heart_beat(1);
}

/*****************************************************************************
 * GetEnemy function                                                         *
 * Inputs: none                                                              *
 * Output: Enemies=all enemies in array                                      *
 * Returns an array of current targets/enemies                               *
 *****************************************************************************/
object array GetEnemies() {
    return Enemies;
}

object array GetLocalEnemies() {
return LocalEnemies;
}

object GetCurrentEnemy() {
return CurrentEnemy;
}

object array GetCalmEnemies() {
return CalmEnemies;
}

/*****************************************************************************
 * AddEnemy function                                                         *
 * Inputs: target=the current target                                         *
 * Output: none                                                              *
 * target info sent from attack verb, adds enemies who are not already in    *
 * the Enemies array                                                         *
 *****************************************************************************/
void AddEnemy(object target) {
    if(member_array(target, Enemies)==-1) {
      Enemies += ({target});
    }
}

void AddLocalEnemy(object target) {
if(member_array(target, LocalEnemies)==-1) {
      LocalEnemies += ({target});
    }
}

void AddCurrentEnemy(object target) {
if(CurrentEnemy == 0) {
      CurrentEnemy = target;
    }
}

void AddCalmEnemies(object target) {
if(member_array(target, CalmEnemies)==-1) {
    }
}

/*****************************************************************************
 * RemoveEnemy function                                                      *
 * Inputs: target=the current target                                         *
 * Output: none                                                              *
 * target info sent from attack verb, remove enemies who have died, exited   *
 * room, etc                                                                 *
 *****************************************************************************/
void RemoveEnemy(object target) {
    if(member_array(target, Enemies)!=-1) {
      Enemies -= ({target});
    }
}

void RemoveLocalEnemy(object target) {
    if(member_array(target, LocalEnemies)!=-1) {
      LocalEnemies -= ({target});
    }
}

void RemoveCurrentEnemy() {
    CurrentEnemy = 0;
}

void RemoveCalmEnemies(object target) {
    if(member_array(target, CalmEnemies)!=-1) {
      CalmEnemies -= ({target});
    }
}

/*****************************************************************************
 * SetAttack function                                                        *
 * Inputs: target=the current enemy                                          *
 * Output: none                                                              *
 * checks if attacked monster is already in Enemies array. if it is not then *
 * it gets added to Enemies for both combatants                              *
 *****************************************************************************/
void SetAttack(mixed target) {
    if(objectp(target)) target=({target}); /*converts trivial case object into an array for processing in general case arrayp below*/
    foreach(object ind in target) {        /*reads in all objs in array target and adds them to both combatants if not already present*/
      this_object()->AddEnemy(ind);
      ind->AddEnemy(this_object());
    }
}

/*****************************************************************************
 * Heartbeat function                                                        *
 * Inputs: none                                                              *
 * Output: none                                                              *
 * checks if there are enemies in the Enemies array, checks hit probability  *
 * function to hit, if a hit, applies damage with the eventReceiveDamage fun *
 *****************************************************************************/
void heart_beat() {
object attacker;
attacker=this_object();
Enemies -= ({0});
race::heart_beat();

    if(!clonep(this_object()) && !interactive(this_object())) return; /*prevents clones of combat.c from doing stuff*/
    if(member_array(CurrentEnemy, all_inventory(environment(attacker) ) )==-1 ) { rd=1; } /*resets rd counter if you leave the room*/
    /*Dead Clean Up*/
    if(sizeof(Enemies)) {                 /* There are enemies in Enemies */
      foreach(object ob in Enemies) {     /* If anything in Enemies is dead, remove it from Enemies, LocalEnemies and CurrentEnemy */
        if(ob->GetDead()) {
          RemoveCurrentEnemy();
          if(sizeof(LocalEnemies)) RemoveLocalEnemy(ob);
          RemoveEnemy(ob);
          if(sizeof(CalmEnemies)) RemoveCalmEnemies(ob);
        }
      }
    }
    LocalEnemies=Enemies & all_inventory(environment()); /*defines LocalEnemies*/
    if( sizeof(LocalEnemies)==0 ) CurrentEnemy=0;          /*if LocalEnemies is empty, then zero out CurrentEnemy*/
    if( sizeof(LocalEnemies) ) {
    if( member_array(CurrentEnemy, LocalEnemies) == -1 ) CurrentEnemy = LocalEnemies[0]; /*if CurrentEnemy is not an element of LocalEnemies, then change CurrentEnemy to the first enemy in LocalEnemies*/
      if(userp(this_object())) {                         /* Only the player generates the Round counter*/
        attacker->eventPrint("%^WHITE%^[%^RESET%^ RD: "+rd+"  HP: "+this_object()->GetHP()+"/"+this_object()->GetMaxHP()+" %^WHITE%^]%^RESET%^");
        if(this_object()->GetHP() < GetWimpy()) {  /* BEGIN wimpy */
          Wimpy();
        } /* END wimpy */
      }
      CombatRound(CurrentEnemy);
      rd++;
    }
}
 
/*****************************************************************************
 * CombatRound function                                                      *
 *   replaces eventExecuteAttack in DS stock                                 *
 * Inputs: target (should be an array)                                       *
 * Output: int 0/1 (success/failure)                                         *
 *****************************************************************************/
int CombatRound(object target) {
string damtype;
int dam;
object attacker;
attacker=this_object();
damtype=this_object()->GetWeaponType(); /*for use later when I make a complex tohit fun*/
Enemies -= ({0});

    if(ComputeToHit(attacker, CurrentEnemy)==0) {         /*missed*/
      attacker->eventPrint("You miss.");
      CurrentEnemy->eventPrint(GetName() + " misses you.");
      tell_room( environment(attacker), attacker->GetName() + " misses " + CurrentEnemy->GetName()+".", ({attacker, CurrentEnemy}) );
    } else {                                              /*hit*/
      dam=ComputeDamage(attacker, CurrentEnemy);
      ApplyDamage(dam, CurrentEnemy);
      DamageMessage(dam, CurrentEnemy);
    }
    return 1;
}

/*****************************************************************************
 * ComputerToHit = calculates probability and whether you hit this round     *
 * Inputs: attacker=current attacker                                         *
 *         target=current target                                             *
 * Output: 0=hit, 1=miss                                                     *
 * checks if an attack hits or misses                                        *
 *****************************************************************************/
int ComputeToHit(object attacker, object target) {
int h;
    h=50+attacker->GetStat("coordination")["points"];  /*overly simplified hitprob for now*/
    if(h<0) h=0;
    if(h>100) h=100;
    if(h>(1+random(100))) {
      return 1; /*hit*/
    }
    else {
      return 0; /*miss*/
    }
}

/*****************************************************************************
 * ComputeDamage function                                                    *
 * Inputs: attacker=the current attacker,                                    *
 *         target=current target of attack                                   *
 * Output: dam=damage of attack                                              *
 *****************************************************************************/
int ComputeDamage(object attacker, object target) {
    return to_int(1 + attacker->GetStat("strength")["points"]/10 );
}

/*****************************************************************************
 * ApplyDamage function                                                      *
 * Inputs: dam=damage done                                                   *
 *         target=current target of attack                                   *
 * Output: none                                                               *
 *****************************************************************************/
void ApplyDamage(int dam, object target) {
    target->AdjustHP(-dam, this_object());
}

/*****************************************************************************
 * DamageMessage function                                                    *
 * Inputs: dam=damage of attack                                              *
 *         target=current target of attack                                   *
 * Output: none                                                              *
 *****************************************************************************/
void DamageMessage(int dam, object target) {
string verb, verb2;
    if(target->GetDead() || this_object()->GetDead()) return;
    if(dam>29) { verb="bludgeon"; }
    else if(dam>19) { verb="smash"; verb2="smashes"; }
    else if(dam>9) { verb="crush"; verb2="crushes"; }
    else if(dam>4) { verb="whack"; verb2="whacks"; }
    else if(dam>2) { verb="poke"; verb2="pokes"; }
    else if(dam=2) { verb="graze"; verb2="grazes"; }
    else if(dam=1) { verb="tickle"; verb2="tickles"; }
    this_object()->eventPrint(sprintf( "You %s %s.", verb, target->GetName() ) );
    target->eventPrint(sprintf("%s %s you.", GetName(), verb2 ) );
    tell_room(environment(),sprintf("%s %s %s.", GetName(), verb2, target->GetName() ), ({ this_object(), target }));
}

int GetDead(){
    return Dead;
}

int SetDead(int i){
    if(i==1) Dead=1;
    else Dead = 0;
    return 1;
}

/* BEGIN Wimpy section */
int GetWimpy() {
    return Wimpy;
}

void SetWimpy(int x) {
    if(x < 0) Wimpy=0;
    if(x > this_object()->GetMaxHP()) write("You will always flee combat.");
    Wimpy=x;
}   


void Wimpy() {
string array exits;
int x;
    exits=environment(this_player())->GetExits();
    x=random(sizeof(exits));                                /*selects random exit among room's exits*/
    this_player()->eventPrint("You flee "+exits[x]+".\n");
    this_player()->eventForce(exits[x]);
}
/* END Wimpy section */

/*To maintain compatibility with living.c eventFollow()*/
static int Destruct() {
    /*if( GetParty() ) PARTY_D->eventLeaveParty(this_object());*/
    return 1;
}

int GetBaseStatLevel(string stat){
    return race::GetBaseStatLevel(stat);
}

varargs int eventDie(mixed agent){
    object ob, env = environment();
    int x;
    if(this_object()->GetGodMode()) return 0;

    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());
        }
    }
    Enemies = ({});
    flush_messages();
    return 1;
}


3) Save the following as hp.c and save into /cmds/players/hp.c
Code: [Select]
/****************************************************
 * HP command, shows HP and MaxHP                   *
 * Author: Detah@Arcania 02-04-09                   *
 * This file should reside in /cmds/players/        *
 ****************************************************/
#include <lib.h>
inherit LIB_DAEMON;

mixed cmd() {
    this_player()->eventPrint("%^YELLOW%^[%^RESET%^ HP: "+this_player()->GetHP()+"/"+this_player()->GetMaxHP()+" %^YELLOW%^]%^RESET%^");
    return 1;
}


update /cmds/players/hp.c
update /daemon/command.c

4) make the following changes
Code: [Select]
/verbs/players/attack.c
L102-3 in do_attack_lvs fun, change to
        if(member_array(this_player(),subobj->GetEnemies()) != -1 ) { 
/*        &&  member_array(subobj,this_player()->GetNonTargets()) == -1){*/

/lib/player.c
L98 comment out living::eventKillEnemy(ob); in eventKillEnemy()
L105 changed to set_heart_beat(1); in eventReconnect()
L249 comment out SetSpecialTarget( ({}) ); in eventRevive()
L264 add this_object()->AdjustHP(this_object()->GetMaxHP(), this_object()); at the base level (ie. not in an if) in eventRevive, so players HP are reset after death, before final function bracket
L315 changed to set_heart_beat(1); in Setup()

/lib/npc.c
L64 changed to set_heart_beat(1); in create()
L78 changed to set_heart_beat(1); in CheckEncounter()
L85-90 comment out if( sizeof(enemies = GetEnemyNames()) ){ section in CheckEncounter()
L134 change GetInCombat to GetCurrentEnemy in heart_beat()
L138 change GetInCombat to GetCurrentEnemy in heart_beat()
L157 change GetInCombat to GetCurrentEnemy in heart_beat()
L185 comment out the if(GetParty()) line in Destruct()
L287 comment out living::eventEnemyDied(ob); line in eventEnemyDied()

/lib/race.c
L337 change GetInCombat to GetCurrentEnemy in GetHeartRate()
L359 changed to set_heart_beat(1); in heart_beat()

/lib/living.c
L240 change GetInCombat to GetCurrentEnemy in direct_steal_wrd_from_liv()
L253 change GetInCombat to GetCurrentEnemy in indirect_steal_obj_from_liv()
L628 change GetInCombat to GetCurrentEnemy in eventSteal()

/lib/genetics.c
L117 add this_object()->ComputeMaxHP(); in SetStat() last line
         if(stat=="durability") this_object()->AdjustHP(this_object()->GetMaxHP()); in SetStat()

/lib/sentient.c
L447 change GetInCombat to GetCurrentEnemy in heart_beat()

/lib/body.c
L39 add private int HP, MaxHP, Dead, AC; to variable declare section
L59 add the follow to the prototype section after the variable declare section
    int GetHP();
    int GetMaxHP();
    void ComputeMaxHP();
    varargs int AdjustHP(int x, object source);
    void NaturalHealing();
    int GetAC();
    void ComputeAC();
L85 add to create()
    HP=0;
    Dead=0;
    AC=0;
L90 add to beginning of functions section:
GetHP() {
    return HP;
}
GetMaxHP() {
    return MaxHP;
}
ComputeMaxHP() {
    MaxHP=50+GetStatLevel("durability")*8;
}
/*****************************************************
 * AdjustHP fun                                      *
 * Inputs: HP adjustment, object that did the damage *
 * Output: none                                      *
 * Applies the hp adj to the living's current HP and *
 * checks whether HP are negative to set Death seq   *
 *****************************************************/
AdjustHP(int x, object source) {
    HP+=x;
    if( HP < 0 ) {
      if(!this_object()->GetDead()){
        call_out("eventDie", 0, source);
      }
    }
    return 1;
}
/***************************************************************
 * NaturalHealing fun                                          *
 * Inputs: none                                                *
 * Output: none                                                *
 * Increases HP by 1 every 20 seconds if HP are less than      *
 * than MaxHP. This requires the LastHeal variable declared at *
 * top, initialized in create() and reset in eventReconnect    *
 ***************************************************************/
NaturalHealing() {
    if( time() - LastHeal > 20 && HP < MaxHP ) {
  AdjustHP(1, this_object());
  LastHeal=time();
  this_object()->eventPrint("[ HP: "+HP+"/"+MaxHP+" ]"); /* either a simple tick prompt or just for testing */
    }
}

GetAC() {
    return AC;
}

ComputeAC() {
AC=0;
    foreach(object ob in all_inventory(this_object())) {
      if(ob->GetWorn()) {
        AC+=ob->GetACValue();
      }
    }
}

comment out L386-388 if(!stringp(hobbled section in heart_beat()
L390 add following to heart_beat() at end of fun before final bracket
if(Dead==0) {
NaturalHealing();
}
L490 change GetInCombat to GetCurrentEnemy in eventCheckHealing()
L528 change GetInCombat to GetCurrentEnemy in eventCheckHealing()
L1010 add ComputeAC(); in eventWear() before final return 1
/*BEGIN ArmorClass section*/
/lib/std/armor.c (/lib/std/base_armor.c in post ds2.11 libs)
L40 add private int ACValue; to beginning of variable declare section
L54 add to beginning of functions section
void SetACValue(int x) {
    ACValue=x;
}
int GetACValue() {
    if(!ACValue) ACValue=0;
    return ACValue;
}
/*END ArmorClass section*/
/lib/leader.c
L155 comment out whole fun eventPreAttack()

/lib/firearm.c
L287 change GetInCombat to GetCurrentEnemy in eventFire()

/lib/fishing.c
L50 change GetInCombat to GetCurrentEnemy in heart_beat()
L108 change GetInCombat to GetCurrentEnemy in CanCast()

/lib/magic.c
L16 change GetInCombat to GetCurrentEnemy in prototype section
L139 change GetInCombat to GetCurrentEnemy in eventPrepareCast()

/lib/lvs/position.c
L238-9 in eventLand() comment out
    if(stringp(hobbled(this_object()))) Position = POSITION_STANDING;
    else Position = POSITION_LYING;
L244-247 comment out if(!stringp(hobbled(this_object()))){ section in eventStand()

/cmds/creators/quell.c
L17 change GetInCombat to GetCurrentEnemy in cmd()

/domains/campus/npc/turret.c
L42 change GetInCombat to GetCurrentEnemy in eventShootDude()

/verbs/items/wear.c
L43 add this_object()->ComputeAC();  at end of do_wear_obj()


5) update /lib/body.c
update /lib/race.c
update /lib/combat.c
update /lib/player.c
update /lib/npc.c
update /lib/leader.c
update -r /lib/creator.c
reboot mud

Offline stanach

  • Acquaintance
  • *
  • Posts: 19
    • View Profile
Re: DS combat
« Reply #38 on: December 20, 2010, 02:43:47 pm »
Added you code to a Stock DS 3.0 and was able to get it put in with no problems! thanks for sharing the code.

Only thing I noticed is that the prompt still shows 500/500 but you get the tick showing you are healing 1/410 etc.

I would need to change what to reflect the new combat to make it read the hp's correctly in the prompt? or point me in the right direction to fix the prompt.

thanks,

Stanach

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
Re: DS combat
« Reply #39 on: December 29, 2010, 04:16:00 pm »
copy/pasted from my earlier post #24 in this thread:

All newly created characters after this point will automatically generate their HP and MaxHP appropriately. However, existing characters will have 0/0 HP/MaxHP. To correct this do
Code: [Select]
eval return this_player()->ComputeMaxHP();
or
Code: [Select]
eval return find_player("playername")->ComputeMaxHP();

You can also use
Code: [Select]
eval return this_player()->AdjustHP(100);
to increase the HP of any player at any time.

The AdjustHP function is the 'healing' function. For new characters, their HP and MaxHP will be correct when the characters are created. The default setting has HP and MaxHP equal to durability * 8 + 50. I just confirmed this on a new character.

Offline Io

  • Acquaintance
  • *
  • Posts: 44
    • View Profile
Re: DS combat
« Reply #40 on: February 09, 2011, 09:28:53 pm »
the prompt still seems to be wrong after ComputeMaxHP

typing 'hp' shows the correct numbers, but the prompt remains the old health system

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile
Re: DS combat
« Reply #41 on: February 10, 2011, 09:13:14 am »
The prompt is calling the function GetHealthPoints, which is referencing the variable HealthPoints. I did NOT remove HealthPoints nor any of its associated functions from the lib. Those are from the stock ds hp-system. If you want your prompt, sc, stat, etc command to reference the new combat HP system, then you will need to reference the GetHP() fun. This is a trivial mod.

Removing HealthPoints and all of its associated functions is not trivial.

PS. my apologies to stanach. I did not understand what your issue was. I think this is what you were trying to say also.