Aller au contenu

Photo

Dragon age-like regeneration when in non-combat


  • Veuillez vous connecter pour répondre
22 réponses à ce sujet

#1
rafhot

rafhot
  • Members
  • 34 messages
 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 .


#2
Builder_Anthony

Builder_Anthony
  • Members
  • 450 messages
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 .


#3
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
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

#4
rafhot

rafhot
  • Members
  • 34 messages
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

#5
rafhot

rafhot
  • Members
  • 34 messages
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 .


#6
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
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

#7
rafhot

rafhot
  • Members
  • 34 messages
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 .


#8
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
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 .


#9
Builder_Anthony

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

#10
rafhot

rafhot
  • Members
  • 34 messages
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 .


#11
rafhot

rafhot
  • Members
  • 34 messages
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 .


#12
rafhot

rafhot
  • Members
  • 34 messages
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




#13
Magical Master

Magical Master
  • Members
  • 91 messages
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).

#14
rafhot

rafhot
  • Members
  • 34 messages
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

#15
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
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

#16
rafhot

rafhot
  • Members
  • 34 messages
the gethenchman only work if the henchmans are in the party (and when they dead they leave the party)

i dont have experience on use setlocalobjects yet, but i remeber the defualt oc henchmans come with a item token to stay in player inventory (it is something related?)

i know how to use setlocalint and strings but i cant figure how i can use it to this problem yet too.

can you make some changes in my code that may open my mind ?
heres the link of the most recent changes 
http://paste.bradley...?paste_id=58005

thnx

Modifié par rafhot, 22 octobre 2010 - 07:02 .


#17
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
Not sure if this is of any help, but if you can get a hold of the NWN2 version of the OC death scripts, they work exactly as you are wanting. A "dead" party member (of any sort) will go down when out of hit points. When the fight is over, all "dead" members will get back up with 1 hp. Might give you some insight at to how to go about it.

#18
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
If I remember right, Shadowlords, Dreamcatcher, and Demon campaigns also use the same system.

#19
Mudeye

Mudeye
  • Members
  • 126 messages
I think SoU henchmen do something like that too. They go to 1 hit point and become unconscious. You have a certain amount of time to heal them. That might be a fit for what you want.

#20
rafhot

rafhot
  • Members
  • 34 messages
i will take a look on SoU oc, im also redownloading the adam miller modules to check

and i dont have nwn2 to check those scripts. can you _Knightmare_ paste the code here?



Thanks

#21
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Use this in the henchman heartbeat - you may have to edit it in, but that shouldn't be too hard. I haven't compiled this, but it should work, barring a typo somewhere:

void main() {
    object oMaster;
    if (GetIsDead(OBJECT_SELF)) {

        oMaster = GetLocalObject(OBJECT_SELF, "Master");
        if (GetIsObjectValid(oMaster) && !GetIsInCombat(oMaster)  && !GetIsDead(oMaster)) {
            effect eRes = EffectResurrection();
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eRes, OBJECT_SELF);
        }

    } else {

        oMaster = GetLocalObject(OBJECT_SELF, "Master");
        if (!GetIsObjectValid(oMaster)) {
            oMaster = GetMaster(OBJECT_SELF);
            if (GetIsObjectValid(oMaster))
                SetLocalObject(OBJECT_SELF, "Master", oMaster);
        }

        //add any other stuff you want to happen to henchman while alive here
    }
}

Basically, it checks while the npc is alive for their master, and stores them as a local for later reference. Please note that this is not a robust script - it doesn't provide, for example, with a way for the npc to switch masters. It just does the bare minimum of what you asked. Myself, I would normally only set the "Master" local once, in another event, but it's still fairly low overhead, and I'm trying to keep it simple so that you can see how local objects are used.

Funky

#22
ffbj

ffbj
  • Members
  • 593 messages
I did something similar, but it does not do henchmen. Just a simple PC transversal on hb that does 2 hits/rd as long as the PC is not in combat and up to 50% of the PC hits. That is it will ony heal the PC up to 50% of their total hits. For me and many other players they get the first 3 or 4 rounds of free healing and then rest or take a potion or use bandages anyway. I like it though since it represents the recovery of the body when not exerting itself in combat, or being wounded, and it is a nice clue that you are out pacing the foes you are fleeing as you start getting healed on the run, no  longer flagged as being in combat, which has saved my characters life a few times. I also use the hb for the recovery of fatigue at the same rate and to the same level: 50% of total fatigue just not being in combat.

Modifié par ffbj, 22 octobre 2010 - 09:55 .


#23
rafhot

rafhot
  • Members
  • 34 messages
I have tried the funky code in henchman hearbeat but i discover that the heartbeat event of a dead henchman dont fire.
Im also have looked at Adam miller dreamcacher scripts and he uses the henchmans ondeath event to ressurect their henchmans.

i will try to make a fine tune based on his code now, heres the code for the ondeath henchman event:
http://paste.bradley...?paste_id=58199

in the dreamcatcher system the henchman wake up when the delaycomand reach 0, even if the battle isnt over

but i think using the loop to detect if are any hostile creature around a radius will solve this problem and the henchman only will wake up when theres no one creature around this radius, my fear now its about TMI and loops


Thanks

Modifié par rafhot, 23 octobre 2010 - 06:54 .