EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Support::Windows Servers (https://www.eqemulator.org/forums/forumdisplay.php?f=587)
-   -   Mob difficulty isnt scaling with character (https://www.eqemulator.org/forums/showthread.php?t=35666)

sorvani 09-05-2012 10:25 PM

but he had pretty pictures!

Akkadius 09-05-2012 10:30 PM

http://threadbombing.com/data/media/3/love_my_nuts.jpg

demonstar55 09-05-2012 11:07 PM

Quote:

Originally Posted by cavedude (Post 212162)
As for combat, my own parses has shown there is a considerable difference between PC Live and EQMac. Basically, on EQMac the NPCs hit you more often and harder at all levels using toons with comparable stats/equipment. Live is what we are emulating, so that is going to be our model.

That is because AC Soft Caps changed with the release of SoD I believe. Plate went from 300 AC Soft Cap to 600 and the over cap return was tweaked for all classes too.

Cowboy6534 09-06-2012 09:52 AM

I found the problem last night and I no longer have this problem on my server. parse graphs for my server reflect what I have posted for live and eqmac...

Caryatis 09-06-2012 10:53 AM

So the options were completely rewrite the emu source or spend a night making changes locally? lol

cavedude 09-06-2012 12:07 PM

Quote:

Originally Posted by Cowboy6534 (Post 212322)
I found the problem last night and I no longer have this problem on my server. parse graphs for my server reflect what I have posted for live and eqmac...

Would you mind sharing what you did? Was it rules as I suggested?

Cowboy6534 09-06-2012 11:10 PM

It was a rewrite of the following code that is found in

if(RuleB(Combat, UseIntervalAC))
damage = (max_dmg+eleBane);
else
damage = MakeRandomInt((min_dmg+eleBane),(max_dmg+eleBane)) ;

and not a changing of settings.

Yes cavedude I will share the code with you. I want to make a special case for raid mobs or if you want to do that after I show you the code thats fine. A column to npc_types called isRaid will need to be added to check and see if its a raid target because they operate differently as far as this goes than normal mobs.

Edit: since you know all of the eqemu code better than me you might see a better way to check for raid target than what I suggested with a new column. I was thinking along the lines of the new isQuest column.

jsr 09-07-2012 04:08 AM

Personally I'd just use the existing fields.. e.g. if you want them to hit harder give them higher combat stats :)

An easy way to do this is to create a separate table with all the NPC_ID's for 'raid mobs'. Then you can run a query with an = or join on the NPC_ID.. For example,
Code:

update npc_types set npc_types.atk = 2 billion, npc_types.accuracy = 3 billion where npc_types.id = raidmobs.id
would give 2 billion attack and 3 billion accuracy to mobs whose ID you've put in your raidmobs table.

I use something similar to balance non-boss mobs by their level.

chrsschb 09-07-2012 08:50 AM

The hell with all this fancy mumbo-jumbo, I just let the raid mob beat the shit out of me for a few hours while I fine tune his stats :D

Cowboy6534 09-07-2012 08:59 AM

Code:

if(RuleB(Combat, UseIntervalAC)) {
               
                int32 con = GetLevelCon(GetLevel());
               
                        int32 randDmg = MakeRandomInt(0,99); // (0,99) because we want 100%
                        int32 min = 0;
                        int32 mid = 0;
                        int32 mid2 = 0;
                        int32 mid3 = 0;
                        int32 mid4 = 0;
                        int32 mid5 = 0;
                       
                        switch (con) {
                                case CON_RED: {
                                        min = 19; // 20% of the time hit for min dmg
                                        mid = 59; // 40% of the time hit for everything between min and max
                                        }
                                        break;
                                case CON_YELLOW: {
                                        min = 29;
                                        mid = 57;
                                        mid2 = 75;                // we want half of our mid to be divided by 2 to smooth out our curve but we dont want it to be too intense on our yellow mobs
                                        }                                  // as we get lower in con we want it to be even more of a slope start from left high going to right low on a graph.
                                        break;                         
                                case CON_WHITE: {
                                        min = 39;
                                        mid = 59;
                                        mid2 = 79;
                                        }
                                        break;
                                case CON_BLUE: {
                                        min = 49;
                                        mid = 61;
                                        mid2 = 73;
                                        mid3 = 85;
                                        }
                                        break;
                                case CON_LIGHTBLUE: {
                                        min = 57;
                                        mid = 65;
                                        mid2 = 73;
                                        mid3 = 81;
                                        mid4 = 89;
                                        }
                                        break;
                                default: {
                                        min = 65;
                                        mid2 = 73;
                                        mid3 = 81;
                                        mid4 = 89;
                                        mid5 = 97;
                                        }
                                        break;                               
                                }
                                if (randDmg <= min)
                                        damage = (min_dmg+eleBane);
                                else if (randDmg <= mid)
                                        damage = MakeRandomInt((min_dmg+eleBane+1),(max_dmg+eleBane-1));
                                else if (randDmg <= mid2)
                                        damage = MakeRandomInt ((min_dmg+eleBane+1),(max_dmg+eleBane-1))/2;
                                else if (randDmg <= mid3)
                                        damage = MakeRandomInt ((min_dmg+eleBane+1),(max_dmg+eleBane-1))/2.5;
                                else if (randDmg <= mid4)
                                        damage = MakeRandomInt ((min_dmg+eleBane+1),(max_dmg+eleBane-1))/3;
                                else if (randDmg <= mid5)
                                        damage = MakeRandomInt ((min_dmg+eleBane+1),(max_dmg+eleBane-1))/3.5;                                       
                                else
                                        damage = (max_dmg+eleBane);
                                }

As you can see the CON_RED is what current raid mobs would fall in and probably be fine but any old raid mobs wouldnt behave right because they would fall into the lower categories and would be much easier. So a seperate raid check would need to be added and its own case. So far this is working out great on my server. The only problem ive run into besides raid mobs is that all of the low level mobs on EQEMU have the wrong min max in the tables. Currently lvl1 mobs that are not in tutorialb hit for a max of 2 per the table. When I log into live into innothule swamp the decaying skeletons hit me for a max of 6 unless they hold a wep in which case it is 8 or 10 depending on the weapon they hold. So I have started to go back and readjust all of the npc min max to reflect live.

Edit: I commented out the current code in my attack.cpp starting at line 1870 and end at line 1874 then pasted the above at line 1875.

Cowboy6534 09-07-2012 09:03 AM

And obviously this values I just made up with what I have seen from all of the parses I have done. They need to be fine tuned to really get it right. I stopped at dividing the mid by 5 at green con because I think that if you go any more you would defeat the purpose of AC. Right now though you dont get hit for continue top end without a ton of AC and if you have a ton AC you still get hit hard on occasion. The most testing I have done so far has been in CoM and EJ with a 50monk wearing gear only from kunark and classic. So far I am not getting completely owned like normal and I still have to stop and bw to keep fighting like it should be for dark blue and light blue mobs. If I use a fungi I have to do this less. Or just wait a bit for the regen to do it. Much like my experiences on live eqmac and p99.

Cowboy6534 09-07-2012 09:21 AM

For the raid check I was thinking of something along the lines of

if(RuleB(Combat, UseIntervalAC) && raid check) {.....

copy paste the rest and then that could be adjusted to what you want raid mobs to reflect =)

jsr 09-07-2012 09:57 AM

Assuming I am reading this right, this will get screwy when mobs have a relatively high min hit. For argument's sake consider a green mob, that hits for 50-100 damage

65% of the time it hits for 50 (unmitigated)
8 % of the time it hits for 25-50 (unmitigated)
8% of the time it hits for 20-40 (unmitigated)
8% of the time it hits for 16-33 (unmitigated)
8% of the time it hits for 14-28 (unmitigated)

In all the latter cases, the max hit is at or below min hit. Once damage is calculated by this code it will go through the mitigation function. At which point damage will be set to min_hit (as it is lower than min_hit). So the final result will be a 97% chance for any green mob with comparably high min_hit a to hit for minimum.

Feel free to correct me if I've missed something.

Cowboy6534 09-07-2012 10:15 AM

I see what you're saying but at the same time I know of no mobs with a min hit of 50 that their max hit is only 100 or their min_hit multiplied by 2 to get the max_hit. Most of the time the max is x4 or more than what the min is. So if you had some custom mobs on your server that had only a dmg range of minx2 for max this could be a problem. But just looking through the npc_types, min_hit max_hit, nothing is set at a multiplier of x2 from min to max. Except like I said the level one mobs in the classic zones. In which case they aren't even what live is currently and need to be adjusted to reflect live.

Edit: Also these values are not set in stone. They can be adjusted to anything you want them to be.

Cowboy6534 09-07-2012 10:18 AM

And yes you want green mobs hitting for minimum almost always except for raid mobs.

Unless you have gray con on your server then gray can be made the default and green can adjusted accordingly.

Cowboy6534 09-07-2012 10:24 AM

The code below this.
Code:

                //check if we're hitting above our max or below it.
                if((min_dmg+eleBane) != 0 && damage < (min_dmg+eleBane)) {
                        mlog(COMBAT__DAMAGE, "Damage (%d) is below min (%d). Setting to min.", damage, (min_dmg+eleBane));
                    damage = (min_dmg+eleBane);
                }
                if((max_dmg+eleBane) != 0 && damage > (max_dmg+eleBane)) {
                        mlog(COMBAT__DAMAGE, "Damage (%d) is above max (%d). Setting to max.", damage, (max_dmg+eleBane));
                    damage = (max_dmg+eleBane);
                }

Can be adjusted so that it falls into the fall /3.5

And actually this calculation can just be added into the end of the if statements in the switch case.

jsr 09-07-2012 10:25 AM

Although it affects mobs with a lower ratio to a lesser degree, it's still a significant degree. It's also not part of your design and works against the concept of having brackets which you set. I only chose the green example because it had the most brackets. The figures look bad for other /con's as well.
At the 50% ratio: (over 4400 mobs)
yellow mobs hit minimum 50% of the time.
white mobs hit for minimum 70% of the time.

At 40% ratio, these figures drop by a few % rather than a lot of %.


I /coded over 4000 examples of mobs that have a 50% or higher ratio of mindmg to maxdmg, but edited them out on second thought ;) Over 14,000 mobs have 30% or higher ratios.. this is not an insignificant number.

Don't let it stop you tinkering, but you might want to rethink the solution.

Cowboy6534 09-07-2012 10:28 AM

But I believe that even if it reverts to a default of 50 unmitigated it will still be fine since by the time you run into a mob with a min or 50 your ac calculations will take over and it should still keep the same curve.

What do you think cavedude? Honestly so far I haven't had any problems but that doesn't mean there aren't any.

jsr 09-07-2012 10:33 AM

You misunderstand me - it reverts to min_hit AFTER the mitigation from AC.

Cowboy6534 09-07-2012 10:34 AM

Yeah thats fine. If you go into SoF at lvl90 on live you dont get hit for 1 dmg you frequently get hit for their min if you have max aas and if you dont just straight up avoid or block their dmg. Again these values can be adjusted.

This switch case can be made into a function and then you could add more checks like if the mob has a ratio of .5 or more to follow a different case.

Cowboy6534 09-07-2012 10:35 AM

Quote:

Originally Posted by jsr (Post 212351)
You misunderstand me - it reverts to min_hit AFTER the mitigation from AC.

Where is that in the attack.cpp?

jsr 09-07-2012 10:38 AM

use this query to get the ratio's;

Code:

select id, name, maxdmg, mindmg, mindmg/maxdmg as ratio from npc_types where (mindmg/maxdmg) > 0.2
You can change 0.2 to whatever suits.

jsr 09-07-2012 10:42 AM

Quote:

Originally Posted by Cowboy6534 (Post 212353)
Where is that in the attack.cpp?


Search for meleemitigation. IMO it's where you should be looking if you want to tweak mitigation code. Not to discourage you, but what you're doing at the moment is called a hack job :)

Cowboy6534 09-07-2012 10:43 AM

If you remove my code and go with standard and you have a green mob that hits your for min and then you mitigated that down to below the min and then some other check say well its below min so just bring it back up doesnt that defeat the purpose of the ac check?

jsr 09-07-2012 10:50 AM

No, the way it works is that a mob hits for maxdmg, and then AC and other mitigation factors are pitted against attack to push damage down towards minimum. There are 20 different values that a mob can hit for on live, so the function looks at mindmg and maxdmg of a mob, works out the 18 values in between, and then the outcome of mitigation vs attack determines which of the 20 possible values is the final damage outcome.

jsr 09-07-2012 11:20 AM

FYI it appears that there are now at least 30 values on live.

Furniture 11-05-2012 05:21 PM

Any word on a fix for this or if Cowboy's code is good enough?

Furniture 11-05-2012 05:23 PM

I also have an issue that it seems npc's arent ever missing swings.

lerxst2112 11-05-2012 05:46 PM

Quote:

Originally Posted by Furniture (Post 213994)
Any word on a fix for this or if Cowboy's code is good enough?

You are free to apply any patches to your own server if you like.

game 01-12-2013 11:29 PM

This issue has been resolved on the Sleeper server - tests have shown AC to play a much larger role in overall combat damage.

http://epicemu.com/forum/ac-new-dama...ing-code-tests

wtbmacestun 03-03-2014 09:12 AM

wtbmacestun = cowboy6534 ... just cant remember the pw to log into that account atm... anyway if anyone wants it I have the code we used on kegz server. I posted it in another thread but felt i would elaborate more in my own thread.

So basically when I started out on this little adventure to fix ac kegz didnt really have any interest until i found where in the code the actual problem was. The first implementation of it was what i posted here which did not work. The one that ended up working was kegz idea and it worked great.

First what I found was that in this section of code no matter what happened before this section dmg was static to min and max. None of the previous code influence the dmg being done, or rather, mitigation wasnt being applied from a characters AC.

Code:

if(RuleB(Combat, UseIntervalAC)) {                       
                        //int8 leveldif = ((other->GetLevel()) - (this->GetLevel())); // //AC Damage Reduction Level Diff - Kegz @ EpicEmu.com
                        damage = ((max_dmg+eleBane) - (otherac * acdiv/100.0f)); //AC Damage Reduction - Kegz @ EpicEmu.com
                }
                else {
                        //float acdiv2 = 0.25;
                        //int otherac = other->GetAC();
                        //damage = ((max_dmg+eleBane) - (otherac * acdiv2/100.0f));
                        damage = ((max_dmg+eleBane) - (otherac * acdiv/100.0f));
                }               

                //check if we're hitting above our max or below it.
                if((min_dmg+eleBane) != 0 && damage < (min_dmg+eleBane)) {
                        mlog(COMBAT__DAMAGE, "Damage (%d) is below min (%d). Setting to min.", damage, (min_dmg+eleBane));
                    //damage = (min_dmg+eleBane);
                        damage = ((min_dmg+eleBane) - (otherac * acdiv/100.0f));
                }
                if((max_dmg+eleBane) != 0 && damage > (max_dmg+eleBane)) {
                        mlog(COMBAT__DAMAGE, "Damage (%d) is above max (%d). Setting to max.", damage, (max_dmg+eleBane));
                    //damage = (max_dmg+eleBane);
                        damage = ((max_dmg+eleBane) - (otherac * acdiv/100.0f));
                }

If you look at whats commented out, youll see the normal ac code. What kegz added was the acdiv/100.0f . now in the other forum post I made, I had stated that I thought he had acdiv set to 20 and actually he had it set to 2. So basically 2% of your ac reduces the dmg you are being hit by. The way its coded is to take it off of the min and max. That is where all the parses that showed an actual difference came from. And actually the last time I had talked to him he said he had turned it up a bit but never told me what he set it to. Shortly after that he shutdown epicemu. But before doing so he gave me the code and then decided to post it on the epicemu github. When he originally tested the code he used velious gear as part of a parse but it was in a zone and level range where that much ac would never be possible so it was on the low side. I would assume 2.5 to 3.5 is where it ended up but youll need to test that out yourself.

If this never makes it in the main build it would have truly have been a waste for us to fix this. Seeing as he shut is server down and I am not in the position to run one myself atm. Although I am still constantly thinking about how to fix things on the server that isnt there any more.... As far as I know my monk weight fix still isnt implemented which is sad... Also all the hate that I received when I first brought this up made me not want to share with this community for a long time... But now that his project is gone and I have nothing to work towards again I thought I would share here.

I have a few ideas on how to bring back the Iksar ac bonus that was removed from live a long time ago. Which can be made into a database option for servers that want it and servers that dont. The ac fix should not be made an option though. Its gone on long enough that AC has been broken. If you have any questions let me know.

Yummy 03-03-2014 05:05 PM

Quote:

Originally Posted by wtbmacestun (Post 228630)
wtbmacestun = cowboy6534 ...

If this never makes it in the main build it would have truly have been a waste for us to fix this. Seeing as he shut is server down and I am not in the position to run one myself atm. Although I am still constantly thinking about how to fix things on the server that isnt there any more.... As far as I know my monk weight fix still isnt implemented which is sad... Also all the hate that I received when I first brought this up made me not want to share with this community for a long time... But now that his project is gone and I have nothing to work towards again I thought I would share here.

I have a few ideas on how to bring back the Iksar ac bonus that was removed from live a long time ago. Which can be made into a database option for servers that want it and servers that dont. The ac fix should not be made an option though. Its gone on long enough that AC has been broken. If you have any questions let me know.

cowboy6534,

Your post/code is very much appreciated. I have been feeling at lower levels game play was off. You have provided me with some ideas as to where to look and, potentially, tweak things. Thank you.

I am not sure how to say this, but here goes. The fact you reconciled the treatment by a minority of individuals for your use of less than ideal word choices--yes, you could have been a bit more sensitive, shows emotional maturity. I suspect others, quite possibly the majority, such as myself visit as guests and have been lurking about for *many* years and appreciate your efforts. I try to learn from the behavior of others and when criticized, see it as an opportunity to learn from the experience. I, believe, you did just that. You did good.

Best wishes :-D

wtbmacestun 03-03-2014 09:50 PM

The exact line you want to look at in the attack.cpp is 1866. This is under the void npc::attack. The void mod::meleemitigation does nothing to actually mitigate dmg being done. If you want to test this out like we did. Change the min and max to static numbers for all mobs and youll see just that.

Yummy 03-03-2014 09:54 PM

Thank you. I will.

wtbmacestun 04-17-2014 06:34 AM

I recently revised this code a bit if anyone is interested I thought i would share.

Code:

if(RuleB(Combat, UseIntervalAC)) {
                        damage = ((max_dmg+eleBane);
                }
                else {
                        damage = MakeRandomInt((min_dmg+eleBane) - (otherac * acdiv/100.0f),(max_dmg+eleBane) - (otherac * acdiv/100.0f));
                }               

                //check if we're hitting above our max or below it.
                if((min_dmg+eleBane) != 0 && damage < (min_dmg+eleBane)) {
                        mlog(COMBAT__DAMAGE, "Damage (%d) is below min (%d). Setting to min.", damage, (min_dmg+eleBane));
                        damage = ((min_dmg+eleBane) - (otherac * acdiv/100.0f));
                }
                if((max_dmg+eleBane) != 0 && damage > (max_dmg+eleBane)) {
                        mlog(COMBAT__DAMAGE, "Damage (%d) is above max (%d). Setting to max.", damage, (max_dmg+eleBane));
                        damage = (max_dmg+eleBane);
                }

NOTE: This code makes it so that if a mob rolls max hit it would land and anything below max hit would be mitigated. Now for raid targets since they are multiple levels
above the tank they would hit for max like normal keeping the dmg high and the encounters hard. But for none raid targets as long as they arent red it would allow
ac to do what it needs to do to.

What this does is take a % of your ac and reduces each hit by that percent. So if you have it set at 2 it would be dmg = max dmg - the persons ac who is being hit * 2/100

or for example

dmg=20-100*2/100
dmg=20-200/100
dmg=20-2
dmg=18

moofta 04-17-2014 09:00 AM

Some interesting points on AC from a Sony dev in this post http://www.eqemulator.org/forums/sho...624#post229624

I realise it doesn't cover all of the different checks in combat, but I though it pertinent to this discussion.

wtbmacestun 05-01-2014 01:43 PM

Yes, that is good information. Thank you.


All times are GMT -4. The time now is 07:33 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.