Author Topic: Dragon age-like regeneration when in non-combat  (Read 676 times)

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« on: October 20, 2010, 01:53:38 am »


                Hi, im working on a total conversion using nwn for more than one year,

and i'm trying to make a system that works more and less like the dragon age system  to restore the hit points and spells when the players and henchmans are off combat

what is the most ellegant way to do this?


in my concept i'm thinking to create a pseudo heartbeat to fire each x seconds healing the player (the player lvl in hit points) per x seconds, and then restore the spells

the same happend to henchmans they restore their hit points off combat and also self ressurect if they fall in battle after the battle is over


so what is the most ellegant way to do this?




for those who wish to know my project is based on south america colonization using a fantasy feel
www.projetopindorama.blogspot.com
               
               

               


                     Modifié par rafhot, 20 octobre 2010 - 02:15 .
                     
                  


            

Legacy_Builder_Anthony

  • Hero Member
  • *****
  • Posts: 786
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #1 on: October 20, 2010, 04:22:53 am »


               The top portion of this script heals a pc 1 hp every 5 seconds,but it does it in combat and doesnt do it to hechmen.It was written by axe murder so its a good step in your direction.Maybe throw a call in there to see if the pc is in combat and then somehow hook it to the henchmen.Figure its a start.






#include "gs_inc_encounter"
#include "gs_inc_flag"
#include "gs_inc_worship"
#include "gs_inc_xp"
void HealOneHP( object oPC)
{ if( GetIsDead( oPC))
  { DeleteLocalInt( oPC, "Dying");
    SetLocalInt( oPC, "HealCounter", 5);
    return;
  }
  if( GetLocalInt( oPC, "Dying"))
  { SetLocalInt( oPC, "HealCounter", 14);
    return;
  }
  SetLocalInt( oPC, "HealCounter", GetLocalInt( oPC, "HealCounter") -1);
  if( GetLocalInt( oPC, "HealCounter") > 0) return;
  SetLocalInt( oPC, "HealCounter", 5);
  ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectHeal( 1), oPC);
}
void main()
{
    object oPC        = OBJECT_INVALID;
    object oArea      = OBJECT_INVALID;
    object oTarget    = OBJECT_INVALID;
    location lLocation;
    int nPreviousDay  = GetLocalInt(OBJECT_SELF, "GS_DAY");
    int nCurrentDay   = GetCalendarDay();
    int nPreviousHour = GetLocalInt(OBJECT_SELF, "GS_HOUR");
    int nCurrentHour  = GetTimeHour();
    int nRound        = GetLocalInt(OBJECT_SELF, "GS_ROUND") + 1;
    int nTimestamp    = gsTIGetActualTimestamp();
    ExecuteScript("x3_mod_def_hb",OBJECT_SELF);
    ExecuteScript("pgs_mod_heartbea",OBJECT_SELF);//player guild system
    //per day
    if (nPreviousDay != nCurrentDay)
    {
        //process deities presence
        gsWOProcessPresence();
        SetLocalInt(OBJECT_SELF, "GS_DAY", nCurrentDay);
    }
    //per hour
    if (nPreviousHour != nCurrentHour)
    {
        //process deities power
        gsWOProcessPower();
        oPC = GetFirstPC();
        while (GetIsObjectValid(oPC))
        {
            if (! GetIsDM(oPC) &&
                GetLocalInt(oPC, "GS_ENABLED") &&
                ! gsFLGetAreaFlag("OVERRIDE_STATE", oPC))
            {
                if (GetLocalInt(oPC, "GS_ACTIVE"))
                {
                    //experience bonus
                    if (! gsFLGetAreaFlag("OVERRIDE_DEATH", oPC))
                        gsXPApply(oPC, gsPCGetRolePlay(oPC));
                    DeleteLocalInt(oPC, "GS_ACTIVE");
                }
                else
                {
                    AssignCommand(oPC, PlayAnimation(ANIMATION_LOOPING_PAUSE_TIRED, 1.0, 3600.0));
                }
                //state
                AssignCommand(oPC, gsSTProcessState());
            }
            oPC = GetNextPC();
        }
        SetCampaignInt("GS_SYSTEM", "TIMESTAMP", nTimestamp);
        SetLocalInt(OBJECT_SELF, "GS_HOUR", nCurrentHour);
    }
    //per 5 rounds
    if (nRound > 4)
    {
        oPC    = GetFirstPC();
        nRound = 0;
        while (GetIsObjectValid(oPC))
        {
            if (! GetIsDM(oPC) &&
                GetLocalInt(oPC, "GS_ENABLED"))
            {
                //encounter
                oArea = GetArea(oPC);
                if (GetIsObjectValid(oArea) &&
                    ! GetLocalInt(oArea, "GS_ENCOUNTER"))
                {
                    gsENSpawnByChance(oArea);
                    SetLocalInt(oArea, "GS_ENCOUNTER", TRUE);
                }
            }
            oPC = GetNextPC();
        }
    }
    SetLocalInt(OBJECT_SELF, "GS_ROUND", nRound);
    SetLocalInt(OBJECT_SELF, "GS_TIMESTAMP", nTimestamp);
    //per round
    oPC = GetFirstPC();
    while (GetIsObjectValid(oPC))
    {
        HealOneHP( oPC);
        oArea     = GetArea(oPC);
        if (GetIsObjectValid(oArea))
        {
            SetLocalInt(oArea, "GS_TIMESTAMP", nTimestamp);
            DeleteLocalInt(oArea, "GS_ENCOUNTER");
        }
        if (! GetIsDM(oPC) &&
            GetLocalInt(oPC, "GS_ENABLED") == TRUE)
        {
            //state animation
            AssignCommand(oPC, gsSTPlayAnimation());
        }
        //activity
        lLocation = GetLocation(oPC);
        if (GetLocalLocation(oPC, "GS_LOCATION") != lLocation)
        {
            SetLocalLocation(oPC, "GS_LOCATION", lLocation);
            SetLocalInt(oPC, "GS_ACTIVE", TRUE);
        }
        oPC       = GetNextPC();
    }
}
               
               

               


                     Modifié par Builder_Anthony, 20 octobre 2010 - 03:25 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #2 on: October 20, 2010, 04:30:21 am »


               Definitely don't use a pseudo for this - stuff like this is what the module heartbeat is perfect for. Just loop all pcs and heal them whatever amount you like.



Funky
               
               

               
            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #3 on: October 20, 2010, 04:35:44 am »


               do you think the heartbeat event dont will bring too much overhead to my module?



i was seaching some others ways to do this  and found the subdual damage to my henchmans



whats the performance difference beteween the heartbeat event and a pseudo-heartbeat for the system im in need?



i can code it by myself but i need to learn the optimal way to implement it
               
               

               
            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #4 on: October 20, 2010, 06:23:23 am »


               i have did it in the heartbeat event to see it in action and works fine for a singleplayer test, now i must see how much overhead it will take on multiplayer  here my test code from on heartbeat event:

object oJogador=GetFirstPC();

     if ( GetIsInCombat(oJogador) == FALSE  ) //IF IS NOT IN COMBAT EXECUTE...
       {
         if( GetCurrentHitPoints(oJogador) < GetMaxHitPoints(oJogador))
            {
               ApplyEffectToObject(DURATION_TYPE_INSTANT,SupernaturalEffect(EffectHeal(GetSkillRank(SKILL_HEAL) / 5 + GetHitDice(oJogador) )),oJogador); //AT EACH 5 POINTS IN HEAL SKILL THE PLAYER HEALS +1 PLUS HER LVL


                  if( GetCurrentHitPoints(oJogador) == GetMaxHitPoints(oJogador))  //IF HP AT MAX EXECUTE ONLY ONCE THIS ONE TO RESTORE FEATS AND SPELLS
                       {
                        ForceRest(oJogador);
                        }
               }
        }
               
               

               


                     Modifié par rafhot, 20 octobre 2010 - 05:55 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #5 on: October 20, 2010, 08:46:48 am »


               The heartbeat just to do that, would be completely negligible - you won't notice it. In fact, it's lower overhead than the pseudo, which would be roughly 5 times the overhead, give or take. I'm a big fan of pseudos, but heartbeats have their place. You can find posts on the old bioboards weighing when to use pseudos and when not to. Generally, heartbeats are fine, so long as you use them intelligently. It's when people put costly code in them that they pose a potential for lag, but that's potentially true of any script.



As for your code, assuming you add the GetNextPC call for multiplayer, you should be fine. Note that forceresting like that will wipe effects that are running - could be annoying to players.



Funky
               
               

               
            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #6 on: October 20, 2010, 06:46:45 pm »


               thanks so much for the explanations funky, i already have setup now the heartbeat for the players and henchmans

now im in need to make a concept for the death system to be more and less like dragon age

if the henchmans die in battle and the player still stand after battle,  when is in non combat  the henchmans get up with 1 hit points

and the same for the player if the player dies but any henchman still standing after the batlte
the player get up with 1 hit points




what is the best way to do this? still the heartbeat event? should i use subdual damage or normal damage?
               
               

               


                     Modifié par rafhot, 20 octobre 2010 - 05:54 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #7 on: October 20, 2010, 08:11:13 pm »


               The 'best' way to do that depends a great deal on what you value - simplicity is good, as is understandability, as well as more obvious things like keeping overhead down. A very simple way to do it would be to add an else to your heartbeat to match the GetIsInCombatCheck, but that would wind up looping the players henchmen every heartbeat. It would still probably be negligible, but if you do enough things like that, you wind up with lag. On the other hand, if you're not worried about it, because you know what else you'll need to do, and nothing else involves much overhead on the heartbeat, that might still be the 'best' way, because of its sipmlicity.

A slightly more complex way, and the way I'd probably use, is to add a check to the monster's death script. You'd check the area around its killers for other creatures hostile to the killer (if the killer is a pc), and if none were found, loop the pc's henchmen, raising them. Sounds simple enough, but you'd need to make sure that all the monsters death scripts had the code. If you're using custom death scripts, that could be an obstacle.

I always use normal damage when setting hitpoints back to where they were on client reentry. Acaos actually hacked the engine on HG to produce additional damage types (sacred, vile, psionic, ectoplasmic, and internal) and we STILL don't use subdual damage for anything. I'm not even sure how or if it works, frankly, though I know bioware at least has some consts floating around for it. Here, though, just use EffectResurrection, and if memory serves, that will bring them back with one hitpoint - res spells have to heal on top of that.

Funky
               
               

               


                     Modifié par FunkySwerve, 20 octobre 2010 - 07:16 .
                     
                  


            

Legacy_Builder_Anthony

  • Hero Member
  • *****
  • Posts: 786
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #8 on: October 20, 2010, 09:21:11 pm »


               The script i posted is used in mod hearbeat.Youll also not want to heal the pc or henchmen if hes dead or dying.
               
               

               
            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #9 on: October 20, 2010, 09:40:33 pm »


               Funky: thanx again, i will try to implement in both ways and test and post back here


Anthony: i'm trying to make a system to work more and less like in dragon age

when the henchmans die and the combat is over and the player still alive the henchmans will wake up.
the same happends to player if player dies and henchmans are still alive on combat over the player wake up. 
if everybody dies in combat then the load game screen apears and you go back to the last saved game

i think nwn2 have a similar system to this too
               
               

               


                     Modifié par rafhot, 20 octobre 2010 - 08:41 .
                     
                  


            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #10 on: October 20, 2010, 10:34:41 pm »


               i have tested first by the heartbeat event adding more one if to my old code

its worked fine for a single player campaing but i dont know how it will work for a muliplayer section playing the campaing

now i will do the reverse to the player wake up the henchman in the henchman heartbeat event

heres the updated code:

(since i hate paste the code with broken formatation here i uploaded to code paste viwer page)

http://paste.bradley...?paste_id=57694
               
               

               


                     Modifié par rafhot, 20 octobre 2010 - 09:40 .
                     
                  


            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #11 on: October 21, 2010, 02:57:40 am »


               well, in the reverse method i dont know yet how to prevent my henchman to leave my party when he dies



how to do this?

im using those scripts to my henchmans



OnBlocked=x0_ch_hen_block

OnDamaged=x0_ch_hen_damage

OnDeath=x2_hen_death

OnConversation=x0_ch_hen_conv

OnDisturbed=x0_ch_hen_distrb

OnCombatRoundEnd=x0_ch_hen_combat

OnHeartbeat=x0_ch_hen_heart

OnPhysicalAttacked=x0_ch_hen_attack

OnPerception=x0_ch_hen_percep

OnRested=x0_ch_hen_rest

OnSpawn=x0_ch_hen_spawn

OnSpellCast=x2_hen_spell

OnUserDefined=x0_ch_hen_usrdef



               
               

               
            

Legacy_Magical Master

  • Jr. Member
  • **
  • Posts: 82
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #12 on: October 21, 2010, 03:39:11 pm »


               As Funky said but I'm not sure you noticed, forcing a rest will remove all current buffs.  Which is no big deal to a fighter, but will likely annoy a mage or cleric to no end (unless you've removed 90% of buffs or something in your mod).
               
               

               
            

Legacy_rafhot

  • Jr. Member
  • **
  • Posts: 58
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #13 on: October 21, 2010, 04:52:48 pm »


               i have working on a total conversion, its another magic system, not d&d/d20 ruleset



the spells and regen are ok now

my trouble now its about the henchmans  i need my player character  wakeup a dead henchman when is not in combat....



but im unable to find how to set my henchman in my party even when he's dead ( when henchmans die he leaves my party) and i cant handle this

anyone knows a way to make then stay in the party even when dead?

or another way to me deal with then
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Dragon age-like regeneration when in non-combat
« Reply #14 on: October 21, 2010, 10:19:31 pm »


               Why do you need to prevent the henchman from leaving the party? And why do this in the henchman's heartbeat, when you already have a heartbeat running this script? It seems to me all you need is some way of finding the henchman - does looping GetHenchman with an incrementing count not work if they're dead? Never having used henchman that needed to survive death, I have no idea, but even if that's the case, you can just set a localobject on the pc with the henchman as the object, or find some other way as marking them out as a henchman in a way you could easily access from the heartbeat - typically this means a variable of one kind or another.



Funky