View Full Version : OOC Regen Enable/Disable
trevius
10-06-2008, 11:57 PM
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
sint32 OOCRegen = 0;
if(RuleI(NPC, OOCRegen) > 0){
OOCRegen += GetMaxHP() * RuleI(NPC, OOCRegen) / 100;
}
ChaosSlayer
10-07-2008, 12:28 AM
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 =)
trevius
10-07-2008, 12:39 AM
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.
ChaosSlayer
10-07-2008, 01:11 AM
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)
AndMetal
10-07-2008, 01:30 AM
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
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
#include "map.h"
#include "StringIDs.h"
#include "../common/rulesys.h"
and around line 206, add
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
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
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.
AndMetal
10-07-2008, 04:09 AM
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:
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
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).
trevius
10-07-2008, 05:27 AM
I think that code looks really good accept I don't think you want this:
npc.cpp
//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:
//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.
trevius
10-07-2008, 06:53 AM
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
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+(le vel/5);
}
else {
medding = false;
regen = 2+spellbonuses.ManaRegen+itembonuses.ManaRegen+(le vel/5);
}
//AAs
regen += GetAA(aaMentalClarity) + GetAA(aaBodyAndMindRejuvenation);
regen = ((regen * RuleI(Character, ManaRegenMultiplier)) / 100) + oocmanaregen;
SetMana(GetMana() + regen);
SendManaUpdatePacket();
}
}
ruletypes.h
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
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 :)
trevius
10-07-2008, 08:44 AM
Good and bad news!
The code I wrote for player OOC HP and Mana regen does work, but it doesn't seem to actually check if you are engaged or not. So, the !IsEngaged check isn't working. If someone knows how to check that for players, then it should be able to be added and get this code working right away. It did compile just fine, but the way it is now, it will regen at the OOC rates whether you are engaged or not.
The good news is that AndMetal's code with my modifications works perfectly! Here is an example quest that I tested and that works exactly as intended:
#OOC Regen Test
sub EVENT_SAY {
if ($text=~ /Hail/i){
quest::say("I can set the OOC regen rates to 0, 5, 10, or 20. Just ask for the number and I will set it right now.");}
if ($text=~ /^0$/i ){
$npc->SetOOCRegen(0);
quest::say("Setting OOC Regen to 0");}
if ($text=~ /5/i){
$npc->SetOOCRegen(5);
quest::say("Setting OOC Regen to 5");}
if ($text=~ /10/i){
$npc->SetOOCRegen(10);
quest::say("Setting OOC Regen to 10");}
if ($text=~ /20/i){
$npc->SetOOCRegen(20);
quest::say("Setting OOC Regen to 20");}
}
Using this quest, I was able to set the regen rates in real time while the mob was out of combat. If it is set to 0, the NPC will regen at whatever normal amount it is set to from the npc_types table. If it is in combat, the OOC code will not effect it at all. Note that it won't set the OOC higher than a certain amount. I tried setting it to 50 and it was the same as setting it to 0, so there may be some kind of cap.
Andrew80k
10-07-2008, 10:36 AM
PC OOC regen on live is done like so:
Take total mana pool and divide it by 30. That gives you three minutes to go to full mana from 0. There are 30 "ticks" in 3 minutes. Nice thing is it scales based on the size of the mana pool.
ChaosSlayer
10-07-2008, 12:09 PM
Trev, for players you would prabobly need to check if player is on any mob hate list.
Andrew80k, 3 min for any player of any lev to get to FM is bad imho, it would be better for gameplay if high lev player ooc downtime would stil be greater than for low lev player. But I guess if we figure out player occ regen at all, the rules can handle the rest
Andrew80k
10-07-2008, 12:11 PM
Chaos, I think you'd be surprised at how long 3 minutes is in game. But indeed a rule for that would handle it. It's just a matter of figuring out the formula and applying the rule.
ChaosSlayer
10-07-2008, 12:35 PM
Chaos, I think you'd be surprised at how long 3 minutes is in game. But indeed a rule for that would handle it. It's just a matter of figuring out the formula and applying the rule.
considering that i used to sit on my but for 15-20 min back on live -3 min gona be a breeze =)
i havent played on eq1 when they implemented OCC regen, but on EQ2 under lev 5 you regenerate from almost 0 (hp and mana) to full in about 30 seconds, but it starts to slow down as you level (the numbers of hp and mana pool on eq2 are MUCH larger however. My lev 35 druid had like 2k hp and 4k mana and that was considered poor). I think at lev 80 it takes like 10 min.
But thats what hp/mn regene foods are for
ANorher thing that on eq2 there is no meditation (not during combat not ever) all classes melee or caster all regen hp and mana at same rate in and out of combat (not counting buffs and items of course)
trevius
10-07-2008, 05:12 PM
Woah, they put OOC regen on live? LOL, they might actually be getting smarter :P
Either way, with the rule, you will be able to easily turn it on or off, or adjust the rate you want them to regen at. By setting the rule to 1, you would regen 1% per tick. So, if you wanted to regen from 0 to full in 3 minutes, you would just take 180/6 = 30, so 30 ticks, and if you set your rules to 3 (3 X 30 = 90), it would be pretty close to 3 minutes to regen full HPs or Mana. I think it is nice to have the option to enable/disable and increase/decrease the OOC Regen rates.
As for the code to check if they are engaged, I see in command.cpp from the latest SVN that it uses:
c->IsEngaged()
To check something with Feign Death (I don't have the code handy right now to post the exact line).
I tried using something like that, but I don't know how to define "c" properly. I think if I could figure out how to do that, that it should probably work. Maybe something like this:
if(c->IsEngaged())
oochpregen = 0;
else
oochpregen += GetMaxHP() * RuleI(Character, OOCHPRegen) / 100;
I think that looks about right, but I would need someone to help me to define "c" so that it worked like it does in command.cpp. I am still a noob lol.
ChaosSlayer
10-07-2008, 05:26 PM
Woah, they put OOC regen on live? LOL, they might actually be getting smarter :P
Either way, with the rule, you will be able to easily turn it on or off, or adjust the rate you want them to regen at. By setting the rule to 1, you would regen 1% per tick. So, if you wanted to regen from 0 to full in 3 minutes, you would just take 180/6 = 30, so 30 ticks, and if you set your rules to 3 (3 X 30 = 90), it would be pretty close to 3 minutes to regen full HPs or Mana. I think it is nice to have the option to enable/disable and increase/decrease the OOC Regen rates.
yeah they added it 1 or 2 expansiosn ago (after Aniversary package i think)
Note important thing to allow a rule to set diffirent scaling for OCC regen, cuase just setting it at % rate would make OOC regen identical (in time) for all levels and all mana pools.
where my originaly proposed formula 5+level would slow down as you go up, to leave some room to force people to buy potions (which is good for economy)
another good thing would be be a rule to turn OFF meditation =)
The logical reason for this that if you have OOC regen, then casters also havign bonsu from meditation will get MASSIVE and unfair advantage over melees (specialy since in Emu you don't need to sit down to meditate - which means all the time figth goes on- you still meditating at full speed)
trevius
10-07-2008, 09:55 PM
It took me a while to figure out how to make a good scaling system that will work on any server no matter what the maximum level is, but I think I finally got it.
I edited the code in my post above and added the new level scaling code into it. Now, if someone can tell me how to check if the character is out of combat, I think we can get this in and tested and into the SVN right away :)
I wasn't originally planning to use it on my server, but now I think it could actually be pretty cool. So, I will at least try it out and see how players like it. Just need that out of combat check to finalize it :)
The way the scaling works is you set this rule:
RuleI(Character, OOCRegenLevelScale)
in the rule_values table to be anything from 0 to 100. Then, this is an idea of what will happen:
0 = OOC Regen Level Scaling is disabled - OOC Regen will default to whatever the rules are set to
1 = Barely any OOC Regen Level Scaling - This wouldn't hardly be noticeable if at all for any level
50 = At level 1, the HPs would regen at almost exactly the rate that the OOCRegen rules are set to. At max level, they would regen at 50% of that rate
100 = Most extreme scaling to where max level almost gives no OOC regen bonus at all, but at level 1 they get almost exactly the full OOCRegen rates. And in the middle, they would get about 50% of the regen rates.
I think this leaves alot of options to adjust OOC regen for almost any server. The only other way to break it down any better would be to make individual level range settings for it, but I really don't think that is necessary.
ChaosSlayer
10-07-2008, 10:11 PM
0 = OOC Regen Level Scaling is disabled - OOC Regen will default to whatever the rules are set to
1 = Barely any OOC Regen Level Scaling - This wouldn't hardly be noticeable if at all for any level
50 = At level 1, the HPs would regen at almost exactly the rate that the OOCRegen rules are set to. At max level, they would regen at 50% of that rate
100 = Most extreme scaling to where max level almost gives no OOC regen bonus at all, but at level 1 they get almost exactly the full OOCRegen rates. And in the middle, they would get about 50% of the regen rates.
just to clarify. When you say
"100 = Most extreme scaling to where max level almost gives no OOC regen bonus at all"
you mean that:
the increase in regen as you level is small (like say 25 per tick at 50, which only grows to say 26 at a 100m by which time your mana pool/hp prabobly 5x times as large),
and NOT that your regen per tick gets smaller as you level up? =)
in otherwords you ment to say (i presume)
"Most extreme scaling to where max level almost gives no OOC regen bonus GROWTH at all"
in other words if you gain more regen you gain very little, but it does not become smaller than on previosu level =)
trevius
10-07-2008, 11:12 PM
Sort of, but I think you are making it more complex than it is.
When you set OOC regen, it is in increments of 1% per tick. So, you could set your OOCRegen to a minimum of 1% per tick, which would mean to go from 0 to 100% at any level would take exactly (100 / 1 * 6 = 600 seconds) 10 minutes. If you have OOC Regen set to 2%, then it would take (100 / 2 * 6 = 300 seconds) 5 minutes and so on. It is regening a % of your total hps no matter what gear or buffs you have on.
The scaling works by subtracting a percentage from the OOC regen. Depending on the rule setting and the level of the character and the max level set for the server, your regen could scale in a wide variety of ways. It checks your level against the max level setting for the server, so if you are level 1 and the server goes to level 50, you are 2% of the max level. If you were level 25 on the same server, you would be 50% of the max level. And, if you were level 50, you would be 100% of max level.
Now that it has your percentage, it can then multiply that number with the scaling rule. So, if your scaling rule is set to 50, then it will multiply your level percentage (explained above) with 0.50 (scale rule setting / 100). Using the level 50 max level explained above, and having a level 1 character, the math for this rule would look like this:
0.02 * 0.50 = 0.01
So, it then multiplies the OOCRegen by 0.01 and subtracts that total from your current OOCRegen per tick. So, it would only subtract a very small amount.
But, if you were level 50 in this same scenario, the math would look like this:
1 * 0.50 = 0.50
And when it multiplies that with your OOCRegen and subtracts it, you end up regening half as fast as you were at level 1. So, a level 1 might take 5 minutes to regen from 0 to 100, but a level 50 would take 10 minutes to regen from 0 to 100.
If your scaling rule is set to 100, then you will regen at almost the full OOC regen at level 1, but it will scale down so that by the time you get to max level, you will not regen any extra at all from OOCRegen.
I did make a slight mistake in what I said in that line you quoted though, it should have been this:
"Most extreme scaling to where max level gives no OOC regen bonus at all"
Ok, so maybe I just made it even more complex than you made it lol. But at least this is accurate. And the system should work perfectly and be easy to understand if you try it out a little once it is finalized.
ChaosSlayer
10-07-2008, 11:46 PM
well, basing it off a % may have an inherited flaw where at some point you level from say lev 69 to 70 and suddenly your regen drops DOWN , and i don't mean by % but by actual hp/mana per tick. and that should not happen. - you shoudl nto loose any regen as you level up. The could be no growth, or very little growth, or dimishing growth, but it should not go backwords.
for exmaple, let say for levels 1, 10, 25 and 50 your ooc regen coudl be like this:
no growth at all : 5 , 5, 5, 5 (it starst at 5 per tick mn or hp and it stays there)
small growth: 5, 6,7,8 (your regen growth but VERY slowly - and as you udnerstand 5 at lev 1 is MASSIVE while 8 at 50 is almost nothing compared to yoru mana/hp pool)
fast growth: 5, 10, 20, 40 (regen rapidly rising in atempt to catch up with your mana/hp pool)
any of the above are valid, but the actual ammount regen per tick should be becoming smaller
another important point- try NOT to base the final formula of the MAX level cap allowed. As server developes and people start rising max level cap to add more content, the previously set up rule values will no longer match up and would have to be recalculated every time
a simple build for formula imho is following: you set the formula in actual ammount of mn or hp per tick rather in %, AND a growth rate.
For exmaple:
Rule 1: (base regen per tick) - let say 5
Rule 2: (growth per level) - this one can be set in decimals for exmaple 0.25
(or in other words it grows by +1 each 4 levels)
What thsi means: thsi means that at any given level your regen is 5+(level-1)*0.25
so at level 50 your regen is 5+50*0.25=17.5 per tick.
Whenever this number is suficient compared to your mana/hp pool is a whoel diffirent matter AND admin can tune this up either altering the BASE or the Growth
alternatively setting the to say 2 gives you +2 extra mana per level, so at lev 50 your regen becomes 5+50*5=255 per tick =)
so its rather simple AND whats important- no involvement of max lev cap =)
trevius
10-08-2008, 12:51 AM
LOL, you are completely misunderstanding the point here :P
The system you describe is already in place as their is already a level based HP regen increase hard coded into the system to match EQLive. The current system will scale up as you level, but since it matches the old live system, this is for HP regen in or out of combat. It is also a very small regen increase which is barely noticeable at all.
Then, items and buffs/bonuses/AAs get factored into your total HP regen. This is slightly better, but again, it works the same if you are in combat or out of combat. With enough HPs, you could still be waiting 20+ minutes to fully regen HPs or Mana.
A while back, a rule was added so that you could increase the total character regen by a multiplier. The rules are HPRegenMultiplier and ManaRegenMultiplier and they start at a default of 100, but you can set them up or down to increase/decrease the in/out of combat regen rates. So, lets say you get 10 natural regen on your character and you have an item that gives +10, and also a buff that gives +10, your total would be 30HP regen per tick. These rules will multiply that amount times the percent you set the rule to. Since it is set to 100 by default, 100% of 30 is still 30. But, if you set it to 50%, then 30 is reduced to 15. Or, if you set it to 200%, then 30 becomes 60 per tick. Using these rules, you can quickly adjust regen rates and they will still scale based on levels/AA/Gear/Buffs. The flaw with doing this is that it not only increases out of combat regen, but also in combat regen. So, if you set it really high, your players will regen quick while out of combat, but they will also regen very fast while fighting mobs.
My new rules only deal with out of combat regen. Let's forget about the scaling for now so I can explain the basics of it. The whole point of OOC regen is to make it so players can regen quickly to recover from a fight and start a new fight without having to wait for 20 minutes to regen. So, obviously you want them to regen at a faster rate than the normal HP regen total. To do this, we just set the rule to whatever % we want players to regen per tick. So, 1% would take 100 ticks to regen to full, which is 6(seconds)X100 = 600 seconds AKA 10 minutes. If you set it to regen 20% per tick, then it would be 100/20=5, so 5 ticks. And 5 ticks = 30 seconds, so they would regen from 0% to 100% in 30 seconds. It doesn't matter what level they are, anyone will regen at that exact rate when they are not in combat.
By scaling per level, I am talking about making regen times take longer as you level. So the idea is that regening from 0 to 100% at level 1 might only take 30 seconds, but at level 70 you could set the scaling to regen them to full in 30 seconds, or 60 seconds, or 5 minutes, or whatever you want the max level regen time to take. So low levels could regen to full very quickly, but you could set high levels to take longer to regen to 100% if you wanted it to be that way. By disabling the scaling system, a level 1 would regen in the exact time it takes a level 70 to regen from 0 to 100%.
You are also misunderstanding the max level portion of the code. It pulls that level from your rules, so it doesn't matter what your server has the max level set to, it will work exactly the same on every server. You could have max level of 10, or max level of 200 and still have exactly the same options and flexibility. So, do not worry at all about the math getting thrown off by custom servers, because it won't be. I spent a couple of hours figuring out the exact math so that it will work flawlessly in all scenarios. The equation is fairly simple now that I have it figured out, but actually creating that equation was pretty tough.
I am not sure how I can explain this to you any better than I already have. It took me a while to figure out how to do it, so it might be a little tough to grasp. But, once you get a chance to test it out, I think you will understand and agree that it works well :)
ChaosSlayer
10-08-2008, 01:13 AM
Trev - you missunderstanding me =)
I am TOO talking ONLY about OOC regen =) (for hp and mana)
A while back, a rule was added so that you could increase the total character regen by a multiplier. The rules are HPRegenMultiplier and ManaRegenMultiplier and they start at a default of 100, but you can set them up or down to increase/decrease the in/out of combat regen rates. So, lets say you get 10 natural regen on your character and you have an item that gives +10, and also a buff that gives +10, your total would be 30HP regen per tick. These rules will multiply that amount times the percent you set the rule to. Since it is set to 100 by default, 100% of 30 is still 30. But, if you set it to 50%, then 30 is reduced to 15. Or, if you set it to 200%, then 30 becomes 60 per tick. Using these rules, you can quickly adjust regen rates and they will still scale based on levels/AA/Gear/Buffs. The flaw with doing this is that it not only increases out of combat regen, but also in combat regen. So, if you set it really high, your players will regen quick while out of combat, but they will also regen very fast while fighting mobs.
yes it was a significant problem when it come to tunign encounters since I had to choose between smaller downtimes and much easier ecounters. At the end I put it back to 100% and give players long recast healing/mana potions to be used during down time
The diffirence is that I am proposing to set the values for it in actual numbers rather than in % of total pool
So the idea is that regening from 0 to 100% at level 1 might only take 30 seconds, but at level 70 you could set the scaling to regen them to full in 30 seconds, or 60 seconds, or 5 minutes, or whatever you want the max level regen time to take. So low levels could regen to full very quickly, but you could set high levels to take longer to regen to 100% if you wanted it to be that way. By disabling the scaling system, a level 1 would regen in the exact time it takes a level 70 to regen from 0 to 100%.
I am talking about the same thing =)
But again where you would want to put say X=2% of mana pool, I want to put X=25 mana per tick
regading the max lev cap - the problem is NOT what your lev cap is. the problem that cap may change at any given time and then your OOC regen bonus granted by the formula will be thrown off
For exmaple: my server goes live with max lev cap of 75... 3 month later I add new zones and raise cap to 90
If your formula uses max lev cap anywhere in calculation- the whole formula just started to produce DIFFIRENT results for the same levels than it was before.
in other words your if your formual is something like: Z=X+Y*K, where ANY of the variables is a max level cap, the moment lev cap changes, your result for say lev 28 is now complitly diffirent value
trevius
10-08-2008, 01:48 AM
The only time that max level comes into play is with scaling. And assuming that most people wouldn't want to completely disable OOC regen at max level, if you raise your level cap, just raise the scaling rate as well to compensate for the difference.
If you were concerned with having the same OOC regen rates for levels even if your max level changes, all you have to do is adjust the scaling to match your new max level.
So, say your max level is 50, your scaling is currently set to 50%, and your OOC Regen is set to 20%. In this case, a level 1 would take exactly 30 seconds to regen from 0 to 100%, a level 25 would take exactly 45 seconds to regen from 0 to 100% and a level 50 would take exactly 1 minute to regen from 0 to 100. Now, say you upped your max level to 75, then you would just need to lower your scaling to compensate for that.
It sounds like all you want to do is add an extra OOC regen bonus based solely on level. Maybe characters get + 1 regen per level. So, level 10 would get +10 and level 50 would get +50 and so on. Or maybe it scales it so that it is diminishing returns the higher level you get so that it isn't a steady increase. Basically, this could be done by making OOC versions of HPRegenMultiplier and ManaRegenMultiplier. But, by doing it this way, people with more mana and hps will have to wait longer than people with less. And in order to make the OOC even work like it should, which IMO means it recovers much quicker than normal regen, you would have to set your OOC regen multiplier to be pretty high. And then you would have Items, AAs, Buffs etc all making that system a bit of a nightmare if they factored in. The multiplier could be done before those checks happen, which would avoid that. Either way, it seems like if you wanted a balanced perfectly scaling custom system, you would need to just build the whole thing manually in the source code.
If you or someone wants to write the code to do it exactly the way you want it, then feel free. But, I just don't think there would really be enough of a reason to use it over the one I just made :P And keep in mind that the more rules and math we add in to common checks, the more load it puts on the server. Customizing is good, but efficiency is also go. There needs to be a balance of what is worth doing and what is not.
ChaosSlayer
10-08-2008, 02:53 AM
So, say your max level is 50, your scaling is currently set to 50%, and your OOC Regen is set to 20%. In this case, a level 1 would take exactly 30 seconds to regen from 0 to 100%, a level 25 would take exactly 45 seconds to regen from 0 to 100% and a level 50 would take exactly 1 minute to regen from 0 to 100. Now, say you upped your max level to 75, then you would just need to lower your scaling to compensate for that.
.
yes the this the excatly the recalculating problem I was poiting too - everytime I alter the max lev cap , I have to tune the other numbers to match with it. Given it won't happen very often but will happen eventualy in the long run (specialy on custom servers), and having to go back and rethink what the number should be with new effect kind of pains me. Thats why I propose than max lev cap is not made to be a part of the formula
But, by doing it this way, people with more mana and hps will have to wait longer than people with less
actualyl I see this as a positive side =) If you got yourself a large ass mana pool (more than the average for the level) - you don't get to regenerate it for free =)
And then you would have Items, AAs, Buffs etc all making that system a bit of a nightmare if they factored in
the regen items and buffs SHOULD NOT be part of OOC regen multypliers.
The OOC should be calculated by itself (based on level and/or total pool) and effects from items and buffs added in on top of that unmodified. (since they work In and Out of combat, its alreday a huge bonus to the player that he gets active in combat regen from them)
Either way, it seems like if you wanted a balanced perfectly scaling custom system, you would need to just build the whole thing manually in the source code.
hey my whole system is 2 lines long =)
as I propose before you have 2 Rule variable: Base and Growth.
The only thing you add in code is
Final regen = Final regen + (Base+level*Growth) =)
yes it does not been based on your total mana/hp pool, but I guess its just my view on this is diffirent =) I simply don't see a legit reason why say a lev 65 wizard with 5k mana should regain mana faster than another lev 65 wizard with 4k mana pool. (yes they regain at equal % rate BUT the actual ammount of mana gained per tick will be HIGHER for the guy with larger mana pool, which result in person with lots +mana also gets EXTRA free mana regen on top of that, which is IMHo unfair advatange. Large mana pool- simply means more mana, not more mana per tick)
and then when you start talking actual mob killing vs downtime- the guy with larger pool nto only has more mana during combat - he also has smaller downtime to regain same ammount of mana.
So if your rate is say 1% per tick.
Wizard with 4k pool will regain 2k mana in 5 minutes, whiel wizard with 5k pool will regain 2.5k mana in SAME 5 min. Now let say you need 2k mana to solo mob X. First wizard can solo mob X every 5 min, 2nd wizard can solo same mob every 5min AND get extra 500 mana on top of that, so over course of 25 min wizard B can solo an additional mob. NOT becuase he has superior regeneration (via buffs or items) but becuase he mana pool is larger, which IMHO is wrong.
This approach leads to that +mana items/buffs automaticly outweight +mana regen items/buffs, since the gain from % based OOC regen is MASSIVE compared to what +regen item/buffs can give you.
This will lead to players ONLY going after +mana(or +hp) items/buffs rather than +regen items/buffs, which usualy (if you take LIVE - MUCH rare and harder to obtain)
thats why I belive why OOC should not be based of your pool size
trevius
10-08-2008, 06:44 AM
I can understand some of your points, but I think the benefits of one system would outweigh the other. And I really don't see much of a reason to have both systems that could ultimately be so similar.
If anyone knows how the system works on EQLive, maybe we should try to emulate that, since that is what the emulator team normally tries to shoot for. I know in games like WoW and others that I have played that have OOC Regen, they all appear to be % based as far as I can tell.
Downtime in games is probably one of the more annoying things out of anything. It has been reduced to a minimum in all modern MMOs and apparently even EQLive has it reduced now. There really is no positive side about making someone wait 20+ minutes for their mana to regen to 100%. You will notice that many custom server have CH and Regain Mana clickies on something like a 2 minute or so timer to remove the downtime from EQ. I think that makes a huge difference in the enjoyability of the game.
From what you are saying, it seems like you think that players with considerably better gear should get penalized for having that better gear. They get more downtime the better their gear is. Yes, they will regen more mana in the same amount of time as someone with lesser gear/manapool using my system, but their gear is much better, so why shouldn't they? You mentioned a scenario with a wizard that has better gear than another getting an extra kill more than the lesser geared one every now and then. Shouldn't that be how it works? Shouldn't casters with better gear be able to kill more then ones with lesser gear?
Using your system and increasing a base HP regen rate by a multiplier would mean that you are making all casters equal no matter how nice their gear is. Let say a wizard with 10k mana has 50 mana per tick from items/spells/buffs and natural regen. That means it would take them 200 ticks (20 minutes) to regen to full mana. So, if you want to get that to a reasonable timeframe, you would probably want to lower that to take 5 minutes max. So, to get 10k mana in 5 minutes you would need to have a bonus of 150 mana per tick + the 50 normal regen mentioned above to equal 200 per tick. Already, that 50 per regen from having good AAs, items, buffs is only making a minimal difference. The, factor in that a lesser wizard of the same level with 5k mana would still get at least 20 regen without even having great buffs/AAs/items to add more regen. So, even though the more powerful wizard has much better items and has spent much more time on their character, they only have a very small increase (15%) in OOC Regen per tick.
With your idea, these 10k and 5k mana wizards would both be almost equal. They would both have almost the same downtime to kill ratio. And in this case, the powerful wizard has 2X as nice gear as the other! The 10k wizard should be getting considerably more kills IMO.
The more you up that multiplier, the less important the other bonuses are from buffs/AAs/Gear in both systems. And in order to set what I would consider OOC regen, you would want it to increase HPs much faster than the base + bonuses, which means that no matter what, during non-combat the bonuses are going to be less important and not much of a factor in either system. The main point for having +bonuses for mana and regen when you have OOC Regen is for regen during fights. OOC Regen will basically take over when not in combat.
If 2 people group together, they should have the same downtime IMO. I wouldn't want one wizard with 5k mana to have to wait 2X as long for the other wizard with 10K mana that they are grouped with to get to full so they can start their next encounter. And, I wouldn't want a raid that is ready to fight to have to wait a few more minutes so their uber cleric can get to full even though everyone else is full already.
The main point of OOC Regen is to reduce downtime. There are no in combat benefits to having OOC Regen other than less time between fights. If a group is pulling steady pulls, I don't think they should have to stop for 20 minutes every few pulls so that the casters can regen. I also don't think that casters should be less useful in groups or raids than melee. By having a decent OOC Regen rate, it lets them maintain mana so they can help with every pull instead of doing a few pulls and then going AFK for 10 minutes while they regen.
As for adjusting the max level effecting OOC Regen, I think it is a very minimal issue if at all. If you really care about making sure that all levels remain the exact same regen rates and you have scaling enabled, then you can easily adjust the scale rule. But, in most cases, even custom servers aren't going to be increasing their max level by more than 5 or at most 10 at a time. If your server is jumping from level 50 max to level 100 max, then you got more issues than regen rates to worry about :P And, if they are only adding 5 levels, the difference for mid levels would be minimal and hardly noticeable. And, it isn't like you have to retune all mid level encounters because OOC Regen rates changed. It only effects out of combat, so it really doesn't matter.
You could easily write your code yourself and submit it to the server code submissions if you like. But again, I really don't see any reason to have more than 1 system for this. I imagine that most servers that would even use it would have it set so high that it wouldn't really matter how it was being done. I plan to try setting my OOC Regen rates at 10% per tick with a 50% scale, so a level 1 will regen to full in 1 minute max and a level 75 will regen to full in 2 minutes max.
Both systems would work to yield similar results. I don't see much of a point to draw out a big debate on the subject unless someone has some enlightening information that should point one way or another. My code is all done with the exception of 1 piece, so I am not going to rewrite it. I really only care to finish the code by figuring out how to check if the player is in combat or not.
You guys seriously talk too much, we'll put something in.
trevius
10-08-2008, 07:04 AM
LOL, honestly it would probably take me all of 10 minutes to write the code that he wants and just add it to the code that I wrote so you can use either type of out of combat regen. But, since HPs are constantly being updated, I am concerned that the extra calculations for extra rules will just make more potential server performance impact. Ya, 2 extra rules and an equation probably isn't bad, but Chaos wants rules for every little thing lol :P They would start to add up quickly and take a toll on performance at some point. I have been looking into increasing server performance where possible, and adding 2 systems to do essentially the same thing is a bit redundant. As soon as I get this done, at least there will be a flexible option for OOC Regen. I don't know if there really needs to be 2 separate OOC Regen systems considering we made it this long without any. And if people don't like the one I made, we can always change it at any point. :P
Here is the post from this thread with the code that I have written so far:
http://www.eqemulator.net/forums/showpost.php?p=157898&postcount=8
It is all done beside getting the IsEngaged check to work to see if the player is in combat or not.
ChaosSlayer
10-08-2008, 11:59 AM
Hehe KLS is right =)
Anyway, Trev,
Shouldn't casters with better gear be able to kill more then ones with lesser gear?
the word "gear" is too vague for this specific case. YES they should, but you need to be specific what gear you refering to:
If you playing a warrior- you can go for for STR to do more damage , kill enemies faster and take less dmg in the process OR go for AC items to get hit for less dmg to begin with, but then your fights will last longer since your DPS is lower. Each has pros and cons depending on specific encounters
Same thing happens when you look at the 2 wizards- one wizard went for +mana items while another went for +mana regen items.
The first wizard should have larger mana pool, while 2nd wizard should have faster mana recovery. The first wizard can put out far more spell dmg in combat before he runs OOM, while 2nd wizard can last longer while fight goes on for a while (liek a raid fight).
When you putting OOC regen on pool % bases - you bluring this diffirence in char gear customization away. :cool:
In either case - the debates help find the "golden middle" :D
ChaosSlayer
10-08-2008, 12:10 PM
Oh Trev we forgeting one more- OOC Endurance Regeneration =)
Congdar
10-08-2008, 02:47 PM
it seems the svn version no longer uses the hate list for clients unless they are charmed. it was probably part of the fix to the feign death bug. this means that IsEngaged() would only work on a charmed client or a npc
trevius
10-09-2008, 05:24 AM
The bot command in the command.cpp uses this code:
if(c->IsEngaged() || c->GetFeigned())
{
c->Message(15, "You can't summon bots while you are engaged or feigned.");
return;
}
Which is why I thought it would work. If it doesn't work for players, then it seems like that code won't work properly.
Congdar
10-09-2008, 08:59 AM
Yes, i'm finding that there is lots of code that works in the eqemulator.net source tree that doesn't work in the svn source tree. I'm working to update the bot source for svn as fast as I can.
trevius
10-12-2008, 06:17 PM
Does anyone know how to do a check to see if a player has aggro on any NPC? The closest thing I can find is IsOnHateList(), but that looks to only work if you check it for a particular NPC. Basically, I just want to know if a player has any aggro at all, similar to the NPC IsEngaged() check. Or, would it be possible to make an IsEngaged() check for clients or maybe expand the command to work for either? It would also have to be able to know if they are in PVP combat or not. Maybe if they have PVP on, the OOC regen would be disabled or something.
Once this part gets figured out, I can finish the code, test it and add it to the SVN.
Here is the post with the current code I have for the OOC Regen for players:
http://www.eqemulator.net/forums/showpost.php?p=157898&postcount=8
Note that I also made it so that it only does HP/Mana updates if the HPs/Mana are less than max HPs/Mana. I did test that and I don't see any weird issues with not sending them every tick if they are full. If anyone knows a reason why it should always send them, let me know. This is just another attempt to help reduce unneeded bandwidth utilization. It seems like there are many things being sent and overlapping that shouldn't be and they are generating much more traffic than we actually need to use to do everything flawlessly.
steve
10-12-2008, 07:02 PM
The way OOC regen works on Live, that is, when a character is not in combat, their hp/mana goes into super-regen mode.
After a character has finished combat, has no NPCs agro on them, and has no detrimental effects casted on them, they enter the 30 second 'wait time'. As long as the character does not re-engage an NPC, their hp/mana will regen completely, from 0% to 100% in 3 minutes. This scales with their hp/mana pool, so it does not matter if they have 5k mana or 15k mana. After 3 minutes, they will be completely full.
OOC regen does exist in raid zones, but I do not recall the 'wait time' before it kicks in. I think it may be 15 minutes, but might be as high as 30 minutes.
trevius
10-13-2008, 04:19 AM
Ok, I added in a wait time setting so you can set a rule to define how many ticks you want it to wait before OOC Regen starts working after the character leaves combat. So, if you wanted it to wait 30 seconds before starting OOC Regen, you should be able to set this to 4. The first 6 seconds is automatically added by the timer between ticks after you leave combat. I think it will work properly.
Here is the edited post with the current code:
http://www.eqemulator.net/forums/showpost.php?p=157898&postcount=8
Still just need the in combat check for clients to finalize this code.
trevius
10-13-2008, 06:33 PM
Added another rule to the code to allow admins to chose if they want player casting to stop OOC Regen or not. This will stop OOC regen if a player is casting buffs or a nuke or anything else.
Once the engaged check is working, this system should be pretty robust lol.
ChaosSlayer
10-13-2008, 06:36 PM
so what was wrong with using Feign Death like approach? or does FD simply erased hate lists?
trevius
10-13-2008, 07:56 PM
That FD check was in the Bots code and it has since been removed and replaced. It was actually checking if they were FD or if they were engaged before it would allow a bot to be summoned. Apparently the IsEngaged check has been changed so that it doesn't work for players anymore. I am not sure why.
AndMetal
10-14-2008, 02:22 PM
For some reason I thought something was changed with the client hate list, but I may have misread something (discussion (http://www.eqemulator.net/forums/showthread.php?t=25856)), because I can't find it being mentioned specifically (or in the changelogs, etc).
Looking through the code, Mob::IsEngaged checks to see if the hate_list, tucked in the protected portion of the Mob class in zone/mob.h, IsEmpty() (defined in hate_list.cpp). At that point, it basically iterates through the hate list to see if there are any hate values > -1.
There is a function, Mob::PrintHateListToClient (which basically points to HateList::PrintToClient) that's used by the #hatelist command that we might be able to use to debug it. I'm still running the base version of 1129, and I'm able to see my (client) hate list fine.
On a somewhat related note, the current SVN source doesn't wipe the client's hate list after you have successfully feigned and then waited the 2 min for the aggro to clear, at least as far as I can tell. As a result, you could still be considered Engaged if a mob you were killing is still alive, you feigned, & its hate list is wiped, so it no longer knows about you. You should be able to do this:
in zone/client_process.cpp, around line 626, add
// EverHood Feign Death 2 minutes and zone forgets you
if (forget_timer.Check()) {
forget_timer.Disable();
entity_list.ClearZoneFeignAggro(this);
WhipeHateList(); //wipe the client's hate list
Message(0,"Your enemies have forgotten you!");
}
I'm pretty sure WhipeHateList (sic) should be able to inherit from the Mob class, although if not, we may need to rework it a little.
In any case, if anyone has a chance to check the client/bot hate lists to see what's going on, maybe we can get to the bottom of this.
So_1337
10-14-2008, 02:44 PM
I'm still running the base version of 1129, and I'm able to see my (client) hate list fine.
The change came in Revision 38:
==10/03/2008
KLS: Hate list will no longer work for non ai controlloed player characters.
The problem had been that the client was maintaining a hate list that would never be wiped unless the mob on it was killed or the player camped/zoned. This was what was causing feign death to pull zone-wide trains. Since removing the hatelist from players, it's been corrected, though it has had other issues (such as breaking the mob fleeing code; they originally checked the client hatelist to see if there were other mobs with them).
My guess is that that may be what IsEngaged was calling on, and it's no longer there.
Congdar
10-14-2008, 03:00 PM
attack.cpp Mob::AddToHateList
if(IsClient() && !IsAIControlled())
return;
This is where the hate_list is used for the client... only if the client is charmed and aicontrolled.
trevius
10-14-2008, 05:48 PM
I think we can set IsEngaged() back to the way it was before and simply add in the whipehatelist code that AndMetal posted to fix the FD issue. The IsEngaged() check being available for clients is just too useful to remove it to fix FD. I am pretty sure that the fix AndMetal posted above will correct it. I will try it out tonight along with my OOC Regen code using the old IsEngaged() check by removing the check that Congdar posted. I think that will resolve some of the issues we are having right now with other code.
trevius
10-15-2008, 05:05 AM
Finally, by reverting IsEngaged() back to allowing it to work on clients, I was able to get OOC Regen working almost perfectly. The only thing that isn't currently working 100% as intended is the wait timer. And by adding the WhipeHateList() to the FD forget timer, it should fix the issues with FD as well even with IsEngaged() being reverted back. Much thanks for AndMetal, So_1337 and Congdar for figuring that stuff out :D
zone/attack.cpp in Mob::AddToHateList remove:
if(IsClient() && !IsAIControlled())
return;
zone/client_process.cpp, around line 626, add the RED line
// EverHood Feign Death 2 minutes and zone forgets you
if (forget_timer.Check()) {
forget_timer.Disable();
entity_list.ClearZoneFeignAggro(this);
WhipeHateList(); //wipe the client's hate list
Message(0,"Your enemies have forgotten you!");
}
zone/client_process.cpp remove:
void Client::DoHPRegen() {
sint32 normal_regen = LevelRegen();
sint32 item_regen = itembonuses.HPRegen;
sint32 spell_regen = spellbonuses.HPRegen;
sint32 total_regen = normal_regen + item_regen + spell_regen;
total_regen = (total_regen * RuleI(Character, HPRegenMultiplier)) / 100;
SetHP(GetHP() + total_regen);
SendHPUpdate();
}
void Client::DoManaRegen() {
if (GetMana() >= max_mana)
return;
int32 level=GetLevel();
int32 regen = 0;
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+(le vel/5);
}
else {
medding = false;
regen = 2+spellbonuses.ManaRegen+itembonuses.ManaRegen+(le vel/5);
}
regen += GetAA(aaMentalClarity);
regen += GetAA(aaBodyAndMindRejuvenation);
regen = (regen * RuleI(Character, ManaRegenMultiplier)) / 100;
SetMana(GetMana() + regen);
SendManaUpdatePacket();
}
And replace it with this:
void Client::DoHPRegen() {
if(GetHP() < GetMaxHP()) { //Don't do HP regen if HPs are full
int32 level=GetLevel();
int32 oochpregen = 0;
int8 oocwaittime = oocwaittime++;
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;
} else {
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;
oocwaittime = RuleI(Character, OOCRegenWaitTicks);
}
}
}
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 = oocwaittime++;
int32 oocmanaregen = 0;
if(IsEngaged()) {
oocmanaregen = 0;
oocwaittime = 0;
} else {
if(IsCasting() && RuleB(Character, OOCRegenCastCheck)) {
oocmanaregen = 0;
oocwaittime = 0;
} else {
if(oocwaittime >= RuleI(Character, OOCRegenWaitTicks)) {
oocmanaregen += GetMaxMana() * RuleI(Character, OOCManaRegen) / 100;
oocmanaregen -= level / RuleI(Character, MaxLevel) * oocmanaregen * RuleI(Character, OOCRegenLevelScale) / 100;
oocwaittime = RuleI(Character, OOCRegenWaitTicks);
}
}
}
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+(le vel/5);
}
else {
medding = false;
regen = 2+spellbonuses.ManaRegen+itembonuses.ManaRegen+(le vel/5);
}
//AAs
regen += GetAA(aaMentalClarity)
+ GetAA(aaBodyAndMindRejuvenation)
+ GetAA(aaExpansiveMind);
regen = ((regen * RuleI(Character, ManaRegenMultiplier)) / 100) + oocmanaregen;
SetMana(GetMana() + regen);
SendManaUpdatePacket();
}
}
I have tested this and once I get the wait timer working, I will add it to the SVN so anyone can enable it with the new rules or just leave it disabled as it is by default. It could actually get added as-is, but I don't think the wait timer will be that hard to fix. I am just not sure why the code I have set for it isn't working. It seems that no matter what I set the wait timer rule to, it always starts regen on the first tick after a fight is over.
If anyone knows of a reason why this shouldn't be added, please let me know!
Moved this thread to Development::Development since it is nearly final and not really a request anymore.
Derision
10-15-2008, 06:09 AM
I looked at reverting the change in Mob::AddToHateList when I was looking at fixing the Flee code. I added code to Feign Death, Rogue Escape and Bard Fading Memories to wipe the clients hate list, but I found a problem, so I backed that out.
Depending on timing, you can have a situation where a mob starts to cast an offensive spell on the player, a Rogue hits 'Escape', clears it's hatelist and then the spell still lands on the player and the mob is added back to the player's hate list, even though the mob no longer hates the player.
As I say, it purely depends on the timing of a mob casting and the player hitting Escape, or Fading Memories and probably won't happen often, but it is something to be aware of.
trevius
10-15-2008, 06:28 AM
It worked that way on Live too though :)
I played a rogue on live and using escape while something was casting on you would break hide/sneak and also add you back to their hate list. So unless something has changed since I played, I think that would be perfectly acceptable and intended. I am not sure even with changing how IsEngaged works that a spell being cast on you won't cause aggro after you escape or fade. It should at the very least break your hide/sneak.
Maybe you can put those changes back in unless someone else thinks it should work any differently.
Congdar
10-15-2008, 08:53 AM
on Live it is like that, but is it like that here? if the spell lands after fd or fm it should break fd and fm and add to both mob and client hate lists... i think here it may only add to the clients hate list and not actually break fd and fm.
So_1337
10-15-2008, 09:00 AM
That's right, Congdar. This wouldn't be an issue except for the fact that melee overflow was only occurring and pulling full zone trains based upon what was on the client's hatelist. I'd advocate putting the client hatelists back in if the issue were solved somehow, but it seems to be causing more trouble than it's worth for the time.
And yes, currently if you FD while a spell is being cast, it will hit you and nothing will happen. On Live, your FD would be broken and mobs would continue to attack you. AEs hitting you would have the same effect, they didn't have to be targeted spells.
trevius
10-15-2008, 05:31 PM
If WhipeHateList() is added for escape, fading memories and FD, I think it will work exactly the way it does on live. FD won't pull full zone trains if the client hate list is wiped after they get the forgotten about you message.
The only case where I think it could still be an issue is if someone FDs and a mob walks back to it's spawn point. That is supposed to clear FD if it worked like live. But, if the issue is that the client hate list still exists when that happens, we can just add another WhipeHateList() there so it catches both player and NPC hate lists. I know I have seen the code for NPCs returning to their spawn point after they leave combat somewhere, but I can't find it atm. I will put the code here if/when I find it.
Congdar
10-15-2008, 06:39 PM
I just wanted throw out a couple of thoughts I was having about this.
Do memblur spell effects have this problem? How do those spells handle the hate lists?
What other memblur, fd, fade, etc. type effects should we consider before implementing this code?
trevius
10-15-2008, 06:52 PM
Actually yes, I am pretty sure Memblur spells do have this problem lol. I just happened to be looking into something else last night and noticed the effect for memblur only wiping the hate list for NPCs. Which should mean that Memblur works for the first time currently in SVN since the hate lists were removed from players. But I posted a fix for it to work (I think it should anyway) even with hate lists being added to players as well as NPCs. So, that should resolve that issue and one other Memblur issue too I hope.
http://www.eqemulator.net/forums/showthread.php?t=26528
Funny that you posted this shortly after I posted that Memblur fix lol.
Congdar
10-15-2008, 07:05 PM
heh, that is funny. i don't remember reading that post, but I must have since it was making my brain itch about the same thing.
I have no problem bringing back hate lists for clients but:
1) If a npc loses all hate on a client the client should clear that npc from their table as well.
2) 1 can't apply if the client is computer controlled.
trevius
10-16-2008, 05:30 PM
I am still trying to figure out why the wait timer setting isn't working.
So far, I have only seen 1 other issue with this that needs to be resolved before it could be submitted. For some reason heals and buffs are not causing OOC Regen to stop, so healers basically have unlimited mana in fights. I figure I can find out why in the heal aggro code.
Andrew80k
10-16-2008, 05:48 PM
In live buffs don't cause you to gain agro IIRC. I'll have to verify that. Heals definitely should though.
trevius
10-16-2008, 06:53 PM
I know for sure that buffs used to cause aggro when I played Live. Rune procs were one of the better aggro generators. Also, if you cast a buff on a noobie while they were killing something, you would take faction hits when it died.
It isn't really buffs that I am so worried about, it is mostly heals. But HP buffs could be used as heals, so buffs should really cause hate too.
ChaosSlayer
10-16-2008, 08:03 PM
I know for sure that buffs used to cause aggro when I played Live. Rune procs were one of the better aggro generators. Also, if you cast a buff on a noobie while they were killing something, you would take faction hits when it died.
It isn't really buffs that I am so worried about, it is mostly heals. But HP buffs could be used as heals, so buffs should really cause hate too.
when someone killing dervishes in comons asked my druid for SoW I always waited till they stop fighting to cast it - i valued my faction. yeah buffs should defently put you on hate list
steve
10-17-2008, 03:47 AM
On Live, when my druid heals my pet, he does not get any faction hits when the mob dies. I'm not sure if this is unique to healing pets though. Always bugged me because then I need to remember to cast something on the mob to get the faction hit.
Congdar
10-17-2008, 09:00 AM
On Live, when my druid heals my pet, he does not get any faction hits when the mob dies. I'm not sure if this is unique to healing pets though. Always bugged me because then I need to remember to cast something on the mob to get the faction hit.
Yes, my necro had to do at least one point of damage to get the faction hits while my pet defended me. I think that meant I also had to do at least one point of damage to get the exp as well.
trevius
10-18-2008, 05:10 PM
Probably a big reason for pets not getting faction hits is because I remember people going AFK with a pet up at the orcs in west commons so they could get FP faction so they could trade in NFP. Free AFK faction gains was probably a large reason to remove it from pets. Though, if you are healing the pet, you aren't AFK so you should really be able to get faction IMO.
Yathozemli
01-02-2009, 04:41 PM
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.
trevius
01-03-2009, 06:12 PM
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.
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.