|
|
 |
 |
 |
 |
|
 |
 |
|
 |
 |
|
 |
|
Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum) |
 |
|
 |

10-06-2008, 11:57 PM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
OOC Regen Enable/Disable
As a quick idea for a feature request I think that it might be good to have an option to disable the OOC Regen on an NPC. This could either be done by a setting in the NPC_Types table or even better would be via a quest command that could enable or disable it on the fly.
Here is the code that sets the OOC Regen. To disable it, we would just need to add in another check in the if statement to see if the NPC should use the OOC Regen bonus or not. If we were just making a setting in the NPC_Types table, then this could just check that setting in the table. But, if there was a way to make a quest command to change it on the fly, I think it would be best, but am not sure exactly how to do it. Maybe setting a new field in the NPC_Types table and then make a command that can change that field in real time to turn it on or off.
npc.cpp
Code:
sint32 OOCRegen = 0;
if(RuleI(NPC, OOCRegen) > 0){
OOCRegen += GetMaxHP() * RuleI(NPC, OOCRegen) / 100;
}
|
 |
|
 |

10-07-2008, 12:28 AM
|
Demi-God
|
|
Join Date: May 2007
Posts: 1,032
|
|
don't we allready have a rule which set mobs OCC regen? If I set it to 0 - won't that work as disabled?
UPDATE: Ah I see - you want this to be done on the fly. could be usefull
PS: Its about time we add PLAYER OOC regeneration =)
|
 |
|
 |

10-07-2008, 12:39 AM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
Ya, that too does sound like a fun idea! Though, I would think it would need to be a bit more complex and scale up per level, but shouldn't be too hard to figure out a simple equation. I will see if I can write a rule or 2 for Player OOC regen. Maybe having 1 for the regen amount and another for level scaling. So, you could have it regen a level 1 character to full HPs in 15 seconds, but a level 70 character might take 1 minute or something if you wanted it to scale. Of course with an option to turn both off and use normal regen rates. That should be pretty easy code to write.
But, I would still like to see some ideas for how to disable OOC Regen on NPCs on the fly. There are only a few cases where I would want this, but for some advanced events, the fast OOC regen rates make the event harder to setup properly. For example, if you have a fight that once the NPC gets to 50% health, it goes ABH and whipes the aggro list and then players are supposed to do something else before the mob goes back to normal fight mode.
|
 |
|
 |
 |
|
 |

10-07-2008, 01:11 AM
|
Demi-God
|
|
Join Date: May 2007
Posts: 1,032
|
|
Quote:
Originally Posted by trevius
Ya, that too does sound like a fun idea! Though, I would think it would need to be a bit more complex and scale up per level, but shouldn't be too hard to figure out a simple equation. I will see if I can write a rule or 2 for Player OOC regen. Maybe having 1 for the regen amount and another for level scaling. So, you could have it regen a level 1 character to full HPs in 15 seconds, but a level 70 character might take 1 minute or something if you wanted it to scale. Of course with an option to turn both off and use normal regen rates. That should be pretty easy code to write.
.
|
yeah we prabobly want low lev folks to have almost no down time , but high end people should invest into some potions anyway (too bad we don't have Food the way its done in EQ2. If you never played EQ2, there food/drink are not just for keeping your char fed, they actualy give you mana/hp reg Out of COmbat over time and stats (regen effect halted during combat). Which makes far more sence than eq1 food which gives stats when it sits in your bag and does nothing- which result in evertone buying SINGLE best food/drink they can find and then force feeding themselves with junk food. In EQ2 you get stats/effect from food AFTER you eat it. Would be nice if our food/drink could be made the same way. It will also encourage people to seek and consume best food they can find for faster OCC regen. Note however that in EQ2 you don't have meditation and essentialy you do not realy regenerate mana during combat unless you have effecst like Clarity or +mana regen items. WHich is good cuase ecounters based on a chalange of defeating a mob with LIMITED mana/hp rather than relaying on your mana reg bonus, but once combat is over you have almost no down time (with good food/drink))
In main time, the OOC regen for players could be soemthing like (5+Level) per tick as a base with a Rule seting this from 100% and up (setting it to 0% will effectivly turn it to off)
|
 |
|
 |
 |
|
 |

01-02-2009, 04:41 PM
|
Fire Beetle
|
|
Join Date: Apr 2007
Posts: 1
|
|
Quote:
Originally Posted by trevius
Ya, that too does sound like a fun idea! Though, I would think it would need to be a bit more complex and scale up per level, but shouldn't be too hard to figure out a simple equation. I will see if I can write a rule or 2 for Player OOC regen. Maybe having 1 for the regen amount and another for level scaling. So, you could have it regen a level 1 character to full HPs in 15 seconds, but a level 70 character might take 1 minute or something if you wanted it to scale. Of course with an option to turn both off and use normal regen rates. That should be pretty easy code to write.
|
I didn't read all the way through the thread, but I think if a person would like to do out of combat regens without messing with the code, they could simply create new spells to be used as a clicky that uses the make fragile effect. This way they get nice OOC regens but lose them when aggresive action is taken. Kinda like the level 10 discipline Focused Will.
Just an idea, but I think I'm going to implement this on my server.
|
 |
|
 |

01-03-2009, 06:12 PM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
Ya, that would work ok on individual servers to setup custom stuff for regen. But, that isn't exactly the point of this thread. The point is for a rule so admins can setup out of combat regen for characters. It is actually almost all complete, but I need to add IsEngaged() back to the emu for it to work properly. I would also need to work out a few minor things with aggro from healing and maybe some other stuff. Other than that, it is pretty much all ready to go. I got side-tracked working on some other stuff, so I never finished this. Hopefully I will get some time soon to get OOC regen finished.
|
 |
|
 |

10-07-2008, 01:30 AM
|
Developer
|
|
Join Date: Mar 2007
Location: Ohio
Posts: 648
|
|
Quote:
Originally Posted by ChaosSlayer
PS: Its about time we add PLAYER OOC regeneration =)
|
Just a random thought, but couldn't we do this with player quests? Start a timer when out of combat, stop it while in combat, and when the timer comes up, either cast a spell, #heal, etc.
As far as per-mob Out of Combat regen, I think the best way to handle this might be to set this in the Mob class (make it sint32 oocregen or something like that), have it default to whatever the rule is set to, and make a function, say SetOOCRegen, to change it. Then, just wrap it into the quest code so you can trigger it via quest. That way, you can execute it on sub EVENT_SPAWN if you want it on by default instead of setting it in the database, and change it whenever/wherever you want. I think this should just about do it:
In zone/mob.h, around line 928, add
Code:
sint16 hp_regen;
sint16 mana_regen;
sint32 oocregen; //Out of Combat Regen, % per tick
void SetOOCRegen(sint32 newoocregen) {oocregen = newoocregen;}
In zone/mob.cpp, around line 29, add
Code:
#include "map.h"
#include "StringIDs.h"
#include "../common/rulesys.h"
and around line 206, add
Code:
hp_regen = in_hp_regen;
mana_regen = in_mana_regen;
oocregen = RuleI(NPC, OOCRegen); //default Out of Combat Regen
Then we just need to get it into the quests. I think this should do it:
in zone/perl_mob.cpp, around line 5569, add
Code:
XS(XS_Mob_SetOOCRegen); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_SetOOCRegen)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: Mob::SetOOCRegen(THIS, newoocregen)");
{
Mob * THIS;
sint32 newoocregen = (sint32)SvIV(ST(1));
if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Mob *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type Mob");
if(THIS == NULL)
Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
THIS->SetOOCRegen(newoocregen);
}
XSRETURN_EMPTY;
}
and around line 5813, add
Code:
newXSproto(strcpy(buf, "ClearFeignMemory"), XS_Mob_ClearFeignMemory, file, "$");
newXSproto(strcpy(buf, "SetOOCRegen"), XS_Mob_SetOOCRegen, file, "$$");
Now, you can change it using $Mob->SetOOCRegen(0). If you decide to try it out, let me know how it works.
Last edited by AndMetal; 10-07-2008 at 09:32 AM..
|
 |
|
 |
 |
|
 |

10-07-2008, 04:09 AM
|
Developer
|
|
Join Date: Mar 2007
Location: Ohio
Posts: 648
|
|
I just tried to compile the changes, and it looks like I didn't work the function correctly. If you put it around line 401 & add inline:
Code:
inline virtual void SetHP(sint32 hp) { if (hp >= max_hp) cur_hp = max_hp; else cur_hp = hp;}
bool ChangeHP(Mob* other, sint32 amount, int16 spell_id = 0, sint8 buffslot = -1, bool iBuffTic = false);
inline void SetOOCRegen(sint32 newoocregen) {oocregen = newoocregen;}
int MonkSpecialAttack(Mob* other, int8 skill_used);
void TryBackstab(Mob *other);
it should compile fine (I did verify this).
Of course, I also forgot the most important part: adding the check on whether or not to calculate OOC regen:
in zone/npc.cpp, around line 558, change
Code:
sint32 OOCRegen = 0;
if(oocregen > 0){ //should pull from Mob class
OOCRegen += GetMaxHP() * oocregen / 100;
}
//Lieka Edit: Fixing NPC regen. NPCs should regen to full during a set duration, not based on their HPs. Increase NPC's HPs by % of total HPs / tick.
if((GetHP() < GetMaxHP()) && !IsPet()) {
if(!IsEngaged() && oocregen > 0) //NPC out of combat
SetHP(GetHP() + hp_regen + OOCRegen);
else
SetHP(GetHP()+hp_regen);
} else if(GetHP() < GetMaxHP() && GetOwnerID() !=0) {
if(!IsEngaged()) //pet
SetHP(GetHP()+hp_regen+bonus+(GetLevel()/5));
else
SetHP(GetHP()+hp_regen+bonus);
} else
SetHP(GetHP()+hp_regen);
Verified that compiles also, just need to see if/how it works (if at all, lol).
|
 |
|
 |
 |
|
 |

10-07-2008, 05:27 AM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
I think that code looks really good accept I don't think you want this:
npc.cpp
Code:
//Lieka Edit: Fixing NPC regen. NPCs should regen to full during a set duration, not based on their HPs. Increase NPC's HPs by % of total HPs / tick.
if((GetHP() < GetMaxHP()) && !IsPet()) {
if(!IsEngaged() && oocregen > 0) //NPC out of combat
SetHP(GetHP() + hp_regen + OOCRegen);
Because with that set, NPCs wouldn't regen at all out combat even with their natural regen setting unless oocregen was set. I think you would need to check which is higher and use that instead. Maybe something like this:
Code:
//Lieka Edit: Fixing NPC regen. NPCs should regen to full during a set duration, not based on their HPs. Increase NPC's HPs by % of total HPs / tick.
if((GetHP() < GetMaxHP()) && !IsPet()) {
if(!IsEngaged()) {//NPC out of combat
if(hp_regen > OOCRegen)
SetHP(GetHP() + hp_regen);
else
SetHP(GetHP() + OOCRegen);
} else
SetHP(GetHP()+hp_regen);
} else if(GetHP() < GetMaxHP() && GetOwnerID() !=0) {
if(!IsEngaged()) //pet
SetHP(GetHP()+hp_regen+bonus+(GetLevel()/5));
else
SetHP(GetHP()+hp_regen+bonus);
} else
SetHP(GetHP()+hp_regen);
if(GetMana() < GetMaxMana()) {
SetMana(GetMana()+mana_regen+bonus);
}
I think that should work for almost any scenario. The only thing I can think of that might be worth considering would be a way to make an NPC stop regening completely when out of combat but still regen while in combat by the amount set in the npc_types table. But, if you absolutely had to do that, you could still do it via current quest commands fairly easily when needed.
|
 |
|
 |
 |
|
 |

10-07-2008, 06:53 AM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
I am not sure if the IsEngaged() check works for players, but if so, I think this code might work for character OOC regen:
client_process.cpp
Code:
void Client::DoHPRegen() {
if(GetHP() < GetMaxHP()) { //Don't do HP regen if HPs are full
int32 level=GetLevel();
int32 oochpregen = 0;
int8 oocwaittime = 0;
sint32 normal_regen = LevelRegen();
sint32 item_regen = itembonuses.HPRegen;
sint32 spell_regen = spellbonuses.HPRegen;
sint32 total_regen = normal_regen + item_regen + spell_regen;
if(IsEngaged()) {
oochpregen = 0;
oocwaittime = 0;
}
if(IsCasting() && RuleB(Character, OOCRegenCastCheck)) {
oochpregen = 0;
oocwaittime = 0;
} else {
if(oocwaittime >= RuleI(Character, OOCRegenWaitTicks)) {
oochpregen += GetMaxHP() * RuleI(Character, OOCHPRegen) / 100;
oochpregen -= level / RuleI(Character, MaxLevel) * oochpregen * RuleI(Character, OOCRegenLevelScale) / 100;
} else
oocwaittime = oocwaittime++;
}
total_regen = ((total_regen * RuleI(Character, HPRegenMultiplier)) / 100) + oochpregen;
SetHP(GetHP() + total_regen);
SendHPUpdate();
}
}
void Client::DoManaRegen() {
if(GetMana() < GetMaxMana()) { //Don't do mana regen if mana is full
int32 level=GetLevel();
int32 regen = 0;
int8 oocwaittime = 0;
int32 oocmanaregen = 0;
if(IsEngaged()) {
oocmanaregen = 0;
oocwaittime = 0;
}
if(IsCasting() && RuleB(Character, OOCRegenCastCheck)) {
oocmanaregen = 0;
oocwaittime = 0;
} else {
if(oocwaittime >= RuleI(Character, OOCRegenWaitTicks)) {
oocwaittime = oocwaittime++;
oocmanaregen += GetMaxMana() * RuleI(Character, OOCManaRegen) / 100;
oocmanaregen -= level / RuleI(Character, MaxLevel) * oocmanaregen * RuleI(Character, OOCRegenLevelScale) / 100;
} else
oocwaittime = oocwaittime++;
}
if (IsSitting() ||(GetHorseId() != 0)) { //this should be changed so we dont med while camping, etc...
if(HasSkill(MEDITATE)) {
medding = true;
regen = (((GetSkill(MEDITATE)/10)+(level-(level/4)))/4)+4;
regen += spellbonuses.ManaRegen + itembonuses.ManaRegen;
CheckIncreaseSkill(MEDITATE, -10);
}
else
regen = 2+spellbonuses.ManaRegen+itembonuses.ManaRegen+(level/5);
}
else {
medding = false;
regen = 2+spellbonuses.ManaRegen+itembonuses.ManaRegen+(level/5);
}
//AAs
regen += GetAA(aaMentalClarity) + GetAA(aaBodyAndMindRejuvenation);
regen = ((regen * RuleI(Character, ManaRegenMultiplier)) / 100) + oocmanaregen;
SetMana(GetMana() + regen);
SendManaUpdatePacket();
}
}
ruletypes.h
Code:
RULE_INT ( Character, OOCHPRegen, 0) //Regens this % of HPs per tick if not engaged with a mob (Disabled = 0)
RULE_INT ( Character, OOCManaRegen, 0) //Regens this % of Mana per tick if not engaged with a mob (Disabled = 0)
RULE_INT ( Character, OOCRegenLevelScale, 0) //OOC Regen will scale down per level (0 = scaling disabled, 1 = least scaling, 100 = most)
RULE_INT ( Character, OOCRegenWaitTicks, 0) //OOC Regen will wait this many ticks after combat before starting Out of Combat Regen
RULE_BOOL ( Character, OOCRegenCastCheck, false) //OOC Regen will be stopped if player is casting and this rule is set to true
Note that setting OOCRegenLevelScale to 100 will make it so that a max level character will not get any OOC Regen bonus at all, but a level 1 will still get almost the full bonus and as they level up the bonus will get less and less.
Optional SQL
Code:
Insert into rule_values values (0, 'Character:OOCHPRegen', 0);
Insert into rule_values values (0, 'Character:OOCManaRegen', 0);
Insert into rule_values values (0, 'Character:OOCRegenLevelScale', 0);
Insert into rule_values values (0, 'Character:OOCRegenWaitTicks', 0);
Insert into rule_values values (0, 'Character:OOCRegenCastCheck', false);
I will try this out and post back on how this and the code AndMetal posted work if at all 
Last edited by trevius; 11-16-2008 at 04:15 PM..
|
 |
|
 |
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 11:05 AM.
|
|
 |
|
 |
|
|
|
 |
|
 |
|
 |