EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=590)
-   -   Fix For Excessive Item Proc Rates (https://www.eqemulator.org/forums/showthread.php?t=22164)

WildcardX 12-24-2006 01:23 PM

Fix For Excessive Item Proc Rates
 
I have corrected the excessive proc rates for weapons. Here is my unified diff for this fix:

Code:

diff -u c:\temp\old/attack.cpp c:\temp\new/attack.cpp
--- c:\temp\old/attack.cpp        2006-12-19 20:11:56.000000000 -0600
+++ c:\temp\new/attack.cpp        2006-12-24 19:09:51.429597200 -0600
@@ -2175,18 +2175,29 @@
                if(!aug)
                        continue;
               
-                if (IsValidSpell(aug->Proc.Effect)
-                        && (aug->Proc.Type == ET_CombatProc)) {
-                        if (MakeRandomFloat(0, 1) < ProcChance) {        // 255 dex = 0.084 chance of proc. No idea what this number should be really.
-                                if(aug->Proc.Level > ourlevel) {
+                if (IsValidSpell(aug->Proc.Effect) && (aug->Proc.Type == ET_CombatProc))
+                {
+                        double MRF = MakeRandomFloat(0, 1);
+                        LogFile->write(EQEMuLog::Debug, "Mob::TryWeaponProc() - 1 - ProcChance = %f and MRF = %f", ProcChance, MRF);
+
+                        if (MRF < ProcChance)
+                        {        // 255 dex = 0.084 chance of proc. No idea what this number should be really.
+                                if(aug->Proc.Level > ourlevel)
+                                {
                                        Mob * own = GetOwner();
+                                       
                                        if(own != NULL) {
                                                own->Message_StringID(13,PROC_PETTOOLOW);
-                                        } else {
+                                        }
+                                        else
+                                        {
                                                Message_StringID(13,PROC_TOOLOW);
                                        }
-                                } else {
+                                }
+                                else
+                                {
                                        ExecWeaponProc(aug->Proc.Effect, on);
+                                        LogFile->write(EQEMuLog::Debug, "Mob::TryWeaponProc() - 1 - Weapon proc executed.");
                                }
                        }
                }
@@ -2200,24 +2211,61 @@
        GetProcChances(ProcBonus, ProcChance);
       
        //give weapon a chance to proc first.
-        if(weapon != NULL) {
-                if (IsValidSpell(weapon->Proc.Effect) && (weapon->Proc.Type == ET_CombatProc)) {
-                        float WPC = (weapon->ProcRate/100.0f) + ProcChance;
-                        if (MakeRandomFloat(0, 1) < WPC) {        // 255 dex = 0.084 chance of proc. No idea what this number should be really.
-                                if(weapon->Proc.Level > ourlevel) {
+        if(weapon != NULL)
+        {
+                if (IsValidSpell(weapon->Proc.Effect) && (weapon->Proc.Type == ET_CombatProc))
+                {
+                        int WeaponProcRate = weapon->ProcRate;
+                        float WPC = WeaponProcRate/100.0f;
+                        double MRF = MakeRandomFloat(0, 1);
+                        float NormalProcRate = 0.10;                        // TODO: This setting should be configurable by server op
+                        float WeightedProcRate = 0;
+
+                        WPC = WPC + ProcChance;
+
+                        if(WPC < 0)
+                        {
+                                // multiply for decreaed percentage from normal
+                                float TempWPC = fabs(WPC);
+
+                                WeightedProcRate = NormalProcRate * TempWPC;
+                        }
+                        else
+                        {
+                                // divide for increased percentage on top of normal
+                                if(WPC != 0)
+                                        WeightedProcRate = NormalProcRate / WPC;
+                                else
+                                        WPC = -1;
+                        }
+
+                        LogFile->write(EQEMuLog::Debug, "Mob::TryWeaponProc() - 2 - WPR = %f and MRF = %f", WeightedProcRate, MRF);
+                       
+                        if (MRF < WeightedProcRate)
+                        {
+                                if(weapon->Proc.Level > ourlevel)
+                                {
                                        mlog(COMBAT__PROCS, "Tried to proc (%s), but our level (%d) is lower than required (%d)", weapon->Name, ourlevel, weapon->Proc.Level);
                                        Mob * own = GetOwner();
-                                        if(own != NULL) {
+                                        if(own != NULL)
+                                        {
                                                own->Message_StringID(13,PROC_PETTOOLOW);
-                                        } else {
+                                        }
+                                        else
+                                        {
                                                Message_StringID(13,PROC_TOOLOW);
                                        }
-                                } else {
+                                }
+                                else
+                                {
                                        mlog(COMBAT__PROCS, "Attacking weapon (%s) successfully procing spell %d (%.2f percent chance)", weapon->Name, weapon->Proc.Effect, ProcChance*100);
                                        ExecWeaponProc(weapon->Proc.Effect, on);
+                                        LogFile->write(EQEMuLog::Debug, "Mob::TryWeaponProc() - 2 - Weapon proc executed.");
                                        return;
                                }
-                        } else {
+                        }
+                        else
+                        {
                                mlog(COMBAT__PROCS, "Attacking weapon (%s) did no proc (%.2f percent chance).", weapon->Name, ProcChance*100);
                        }
                }
diff -u c:\temp\old/item_struct.h c:\temp\new/item_struct.h
--- c:\temp\old/item_struct.h        2006-10-26 19:43:16.000000000 -0500
+++ c:\temp\new/item_struct.h        2006-12-24 11:29:05.281250000 -0600
@@ -153,7 +153,7 @@
                sint16  CastTime;        // Cast Time for clicky effects, in milliseconds
        };
        //uint32        Unk061;
-        uint32        ProcRate;
+        int32        ProcRate;
        sint8        CombatEffects;                // PoP: Combat Effects +
        sint8        Shielding;                // PoP: Shielding %
        sint8        StunResist;                // PoP: Stun Resist %

NOTE: There are a couple issues. #1. I have hard coded a variable called "NormalProcRate" at 10%. This guides the percentage for a successful proc rate for the whole server. I am leaving for a Christmas vacation Tuesday morning so I don't have time right now to set code to make this variable configurable by the server op. I will do so when I get back next week. For now, know this is hard coded and you can change it, but then you have to re-compile. #2. I noticed there are a lot of variables that are declared as "unit32" that are filled from columns from the item's table which are signed integers. This has the potential for lots of problems such as unstable behavior. At some point in near future, this should probably be changed to reflect the data types used in the database. For the patch I have listed above, I have declared the "procrate" column variable as a "int32" since that is what the data is from the database.

Enjoy and Happy Holidays!

John Adams 12-27-2006 06:18 AM

Quote:

Originally Posted by WildcardX
#2. I noticed there are a lot of variables that are declared as "unit32" that are filled from columns from the item's table which are signed integers.

Nice work as always, WildcardX. Thanks, and I hope your holiday was splendid. I wanted to comment (sorta sidetracky) about the int comparisons throughout the Emulator source. I get tons of "warnings" about atoi conversions or any int comparisons between types. I don't know enough to know if it causes actual problems, or just warns 1000's of times during a compile. I do know you can turn those warnings off, but why? I'd rather panic each compile. :)

If I knew what to change, and how it would effect the functionality, I could help fix these conversion warnings. Ok, back to your topic. Sorry.


All times are GMT -4. The time now is 08:26 PM.

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