EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Archive::Development (https://www.eqemulator.org/forums/forumdisplay.php?f=621)
-   -   EXP modifier patch (https://www.eqemulator.org/forums/showthread.php?t=7366)

kaldec 05-20-2003 06:06 PM

EXP modifier patch
 
This is my first attempt at modifying the code, so please go easy on me. :)

This is just a bit of code to allow admins to modify the amount of EXP earned, AAEXP earned, and the EXP bonus for each additional member of the group. If this is something people want, I'd like to expand it to include Quest EXP vs. Mob EXP, death penalties, mob stats and other balancing issues as well. All of these would be controlled through table entries so that admins could make some balance changes without deciphering the source and recompiling.

The current entries are all controlled through the variables table
  • GroupEXPBonus = EXP modifier for each member of group (default = .1)

    EXPMod = EXP earned multiplier in GetEXP (default = 1.0)

    AAXPMod = AAXP earned multiplier in GetEXP (default = 1.0)
Anyway here's a diff against the zone directory vs 0.4.4-DR1.

I'm not much of a C++ programmer, and do development on Linux so I'm not making any promises. Any feedback or other project ideas are welcome.


Code:

diff -uBb ../Source/zone/client.cpp zone/client.cpp
--- ../Source/zone/client.cpp  2003-05-14 15:28:39.000000000 -0500
+++ zone/client.cpp    2003-05-20 14:27:24.000000000 -0500
@@ -1048,9 +1048,9 @@
 
 void Client::AddEXP(int32 add_exp) {
        int32 add_aaxp = (int32)((float)add_exp * ((float)((float)pp.perAA) / 100
.0f));
-      int32 exp = GetEXP() + (add_exp - add_aaxp);
+      int32 exp = GetEXP() + (int32)(zone->GetEXPMod() * (add_exp - add_aaxp));
 
-      int32 aaexp = GetAAXP() + add_aaxp;
+      int32 aaexp = GetAAXP() + (int32)(zone->GetAAXPMod() * add_aaxp);
        SetEXP(exp, aaexp, false);
        // FIXME!      int32 add_aaxp = (int32)((float)add_exp * ((float)pp.perA
A / 100.0f));
        // FIXME!      SetEXP(GetEXP() + (add_exp - add_aaxp), GetAAXP() + add_a
axp, false);
diff -uBb ../Source/zone/groups.cpp zone/groups.cpp
--- ../Source/zone/groups.cpp  2003-05-14 15:28:38.000000000 -0500
+++ zone/groups.cpp    2003-05-20 20:15:18.000000000 -0500
@@ -201,7 +201,7 @@
        {
                        if(members[i]->GetLevel() > maxlevel)
                                maxlevel = members[i]->GetLevel();
-                      groupexp += exp/10;
+                      groupexp += (uint32)(exp * zone->GetGroupEXPBonus());
                        membercount++;
                }
        }
diff -uBb ../Source/zone/zone.cpp zone/zone.cpp
--- ../Source/zone/zone.cpp    2003-05-14 15:28:38.000000000 -0500
+++ zone/zone.cpp      2003-05-20 20:14:30.000000000 -0500
@@ -93,6 +93,7 @@
        if (!zone->LoadZoneCFG(zone->GetShortName(), true)) // try loading the zo
ne name...
                zone->LoadZoneCFG(zone->GetFileName()); // if that fails, try the
 file name, then load defaults
        char tmp[10];
+      char *tmp2;
        PlayerProfile_Struct* pp;
        int char_num = 0;
        unsigned long* lengths;
@@ -136,6 +137,20 @@
                }
                mysql_free_result(result);
                }
+
+      // Set default value for EXP modifiers
+      zone->EXPMod = (double)1;
+        zone->GroupEXPBonus = 0.1;
+        zone->AAXPMod = (double)1;
+
+      // Look for database entries and use them if they exist
+      if (database.GetVariable("EXPMod", tmp, 9))
+              zone->EXPMod = strtod((const char*)tmp, &tmp2);
+      if (database.GetVariable("GroupEXPBonus", tmp, 9))
+              zone->GroupEXPBonus = strtod((const char*)tmp, &tmp2);
+      if (database.GetVariable("AAXPMod", tmp, 9))
+              zone->AAXPMod = strtod((const char*)tmp, &tmp2);
+
        //g_LogFile.write("AI LEVEL set to %d\n",iAILevel);
        petition_list.ClearPetitions();
        petition_list.ReadDatabase();
diff -uBb ../Source/zone/zone.h zone/zone.h
--- ../Source/zone/zone.h      2003-05-14 15:28:39.000000000 -0500
+++ zone/zone.h 2003-05-20 14:28:01.000000000 -0500
@@ -132,6 +132,11 @@
        bool    IsCityTakeable() { return citytakeable; }
        int16  CityGuardRace(int32 zoneID);
 
+
+      double  GetGroupEXPBonus() { return GroupEXPBonus; }
+      double  GetEXPMod()        { return EXPMod; }
+      double  GetAAXPMod()      { return AAXPMod; }
+
        void    weatherProc();
        void    weatherSend();
        time_t  weather_timer;
@@ -164,6 +169,10 @@
        float  psafe_x, psafe_y, psafe_z;
        int32  pMaxClients;
 
+      double  GroupEXPBonus;
+      double  EXPMod;
+      double  AAXPMod;
+     
        bool    staticzone;
        bool    gottime;

Kaldec

Sterbla 05-20-2003 11:40 PM

If quest XP can be done then would it be possible to make it worthwhile to quest for XP?

This was one of the biggest flaws in EQ...most quests except epics are way too bothersome comparing risk vs. reward and the XP rewarded is close to non-existant at most, making XP groups and boss-killing a lot more rewarding than questing.

Having quests give a lot of XP would make them more appealing.

Trumpcard 05-21-2003 01:05 AM

I think its a great idea.

If you make sure values set at 1 make it look like it does today, I'll merge it in.

Any change that makes a paramter tunable without needing to be recompiled is a valuable addition. That way you can speed up/slow down progression on your server without going through to much pain.

kaldec 05-21-2003 02:42 AM

Sounds good.

I'll see if I can figure out how to separate questing and fighting tonight, and run some tests.

Monrezz 05-21-2003 05:21 AM

The XP bonus's for groups are as follows:

2 person group - 2% total bonus.
3 person group - 6% total bonus.
4 person group - 10% total bonus.
5 person group - 14% total bonus.
6 person group - 20% total bonus.

Don't know if this is possible in the GroupEXPBonus though, not had a look at it.

kaldec 05-21-2003 07:11 PM

I apologize for not linking to something this large, I'll do so in the future. I did update the diff against a new CVS grab tonight.

I've implemented the following variables that can be included in the variables table as double values (i..e 3.0, .04, 13.0, ...):

NPCEXPMod: Multiple for exp gained from killing NPCs (default=1.0)

PCEXPMod: Multiple for exp gained from killing PCs (default=1.0)

QuestEXPMod: Multiple for exp gained from quests (both systems) (default=1.0)

AAXPMod: Multiple for AAXP gained by any means (default=1.0)

GroupEXPBonus: Group EXP bonus per member (default=.1)

EXPPenaltyMod: Modifier to EXP lost upon death (default=1.0)

If these fields are added to the variables table, the value set will be used, otherwise the default value will be used. I've verified that the default value is setup correctly in the absence of these fields. I've also verified that the default values for NPCEXPMod, QuestEXPMod, and EXPPenaltyMod do not affect the end results of those actions. The changes were the same in all cases, so I didn't go to the trouble of setting up a second account to test the GroupEXPBonus.

Some things to consider when using this:

* The NPCEXPMod and PCEXPMod are applied before a chunk of EXP is passed to a group instead of being applied to each individuals gain, I'm not sure what if any difference this makes.

* The default setting for the GroupEXP bonus was a static 100% person. My modifier simply replaces that, so you can't do a sliding bonus with it. It would be fairly straightforward to setup the sliding bonus and then apply my modifier to it so 2/6/10... could be 4/12/20 or 1/3/5.

* AAEXP is applied at the last minute so it will compound any other EXP bonuses.


Finally, there looked to be a couple of logic bugs in the Client:Death method in attack.cpp:844

Code:

SetEXP((int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*800\
0 > 0)? (int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*8000) : 1,GetAAXP(\
));

The result of the initial '>' operation is being cast to a int32. I assume that the intention was to cast the number being compared to 0, so I updated the line to do this.

A few lines below when calculating a bonus EXP loss for guildwar servers, the same thing occurs. In addtion, there is a discrepency between the loss of EXP being tested and the loss being applied. I didn't update this value, but it seems likely that it should be.

Code:

SetEXP((int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*120\
00 > 0)? (int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*8000) : 1,GetAAXP\
());


Code:

diff -uBb ../van-5-20/zone/attack.cpp zone/attack.cpp
--- ../van-5-20/zone/attack.cpp 2003-05-21 20:36:19.000000000 -0500
+++ zone/attack.cpp    2003-05-21 20:58:20.000000000 -0500
@@ -839,23 +839,25 @@
 
        d->type = attack_skill;
        d->unknownds016 = pp.bind_point_zone;
-      int32 exploss = (int32)(GetLevel()*((float)GetLevel()/18)*8000);
+      int32 exploss = (int32)(zone->GetEXPPenaltyMod()*GetLevel()*((float)GetLevel()/18)*8000);
        if (GetLevel() > 9 && !IsBecomeNPC() && !GetGM() && GetEXP() >= 0 && (other == 0 || !other->IsClient()))
-              SetEXP((int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*8000 > 0)? (int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*8000) : 1,GetAAXP());
+              SetEXP(((int32)(GetEXP() - exploss) > 0)? (int32)(GetEXP() - exploss) : 1,GetAAXP());
        entity_list.QueueClients(this, &app);
 #ifdef GUILDWARS
        if(other != 0 && other->IsClient() && IsAttackAllowed(other) && other != this)
        {
        if (GetLevel() > 9 && GetLevelCon(other->GetLevel()) == CON_GREEN)
-              SetEXP((int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*12000 > 0)? (int32)(GetEXP() - GetLevel()*((float)GetLevel()/18)*8000) : 1,GetAAXP());
+        // Kaldec: There was a weird imbalance here a test involving 12000 and then execution involving 8000, I've replaced the 8000 with exploss, although
+        //        I have a feeling it should have been changed to 12000 to match the test.
+              SetEXP(((int32)(GetEXP() - (zone->GetEXPPenaltyMod()*GetLevel()*((float)GetLevel()/18)*12000)) > 0)? (int32)(GetEXP() - exploss) : 1,GetAAXP());
 
                char msg[400];
                sprintf(msg,"%s:%i:%i:%i",zone->GetShortName(),GuildDBID(),other->CastToClient()->GuildDBID(),other->GetHP());
                database.InsertNewsPost(1,name,other->GetName(),2,msg);
                if (other->CastToClient()->isgrouped && entity_list.GetGroupByClient(other->CastToClient()) != 0)
-                      entity_list.GetGroupByClient(other->CastToClient())->SplitExp((uint32)(level*level*325*3.5f), GetLevel());
+                      entity_list.GetGroupByClient(other->CastToClient())->SplitExp((uint32)(zone->GetPCEXPMod()*level*level*325*3.5f), GetLevel());
                else if(other->GetLevelCon(GetLevel()) != CON_GREEN)
-                      other->CastToClient()->AddEXP((uint32)(level*level*350*3.5f));
+                      other->CastToClient()->AddEXP((uint32)(zone->GetPCEXPMod()*level*level*350*3.5f));
        }
 #endif
        if(IsBecomeNPC() == true)
@@ -864,9 +866,9 @@
 
                {
                        if (other->CastToClient()->isgrouped && entity_list.GetGroupByMob(other) != 0)
-                              entity_list.GetGroupByMob(other->CastToClient())->SplitExp((uint32)(level*level*75*3.5f), GetLevel());
+                              entity_list.GetGroupByMob(other->CastToClient())->SplitExp((uint32)(zone->GetPCEXPMod()*level*level*75*3.5f), GetLevel());
                        else
-                              other->CastToClient()->AddEXP((uint32)(level*level*75*3.5f)); // Pyro: Comment this if NPC death crashes zone
+                              other->CastToClient()->AddEXP((uint32)(zone->GetPCEXPMod()*level*level*75*3.5f)); // Pyro: Comment this if NPC death crashes zone
                        //hate_list.DoFactionHits(GetNPCFactionID());
                }
        }
@@ -1324,18 +1326,18 @@
        {
                if (killer->CastToClient()->isgrouped && entity_list.GetGroupByClient(killer->CastToClient()) != 0)
 #ifdef GUILDWARS
-                      entity_list.GetGroupByClient(killer->CastToClient())->SplitExp((uint32)(level*level*175*3.5f), GetLevel());
+                      entity_list.GetGroupByClient(killer->CastToClient())->SplitExp((uint32)(zone->GetNPCEXPMod()*level*level*175*3.5f), GetLevel());
 #else
-                      entity_list.GetGroupByClient(killer->CastToClient())->SplitExp((uint32)(level*level*75*3.5f), GetLevel());
+                      entity_list.GetGroupByClient(killer->CastToClient())->SplitExp((uint32)(zone->GetNPCEXPMod()*level*level*75*3.5f), GetLevel());
 #endif
                else
        {
            if (killer->GetLevelCon(GetLevel()) != CON_GREEN && MerchantType == 0)
            {
 #ifdef GUILDWARS
-                          killer->CastToClient()->AddEXP((uint32)(level*level*200*3.5f));
+                          killer->CastToClient()->AddEXP((uint32)(zone->GetNPCEXPMod()*level*level*200*3.5f));
 #else
-                          killer->CastToClient()->AddEXP((uint32)(level*level*75*3.5f)); // Pyro: Comment this if NPC death crashes zone
+                          killer->CastToClient()->AddEXP((uint32)(zone->GetNPCEXPMod()*level*level*75*3.5f)); // Pyro: Comment this if NPC death crashes zone
 #endif
            }
                }
diff -uBb ../van-5-20/zone/client.cpp zone/client.cpp
--- ../van-5-20/zone/client.cpp 2003-05-21 20:36:19.000000000 -0500
+++ zone/client.cpp    2003-05-21 20:06:22.000000000 -0500
@@ -1050,7 +1050,7 @@
        int32 add_aaxp = (int32)((float)add_exp * ((float)((float)pp.perAA) / 100.0f));
        int32 exp = GetEXP() + (add_exp - add_aaxp);
 
-      int32 aaexp = GetAAXP() + add_aaxp;
+      int32 aaexp = GetAAXP() + (int32)(zone->GetAAXPMod() * add_aaxp);
        SetEXP(exp, aaexp, false);
        // FIXME!      int32 add_aaxp = (int32)((float)add_exp * ((float)pp.perAA / 100.0f));
        // FIXME!      SetEXP(GetEXP() + (add_exp - add_aaxp), GetAAXP() + add_aaxp, false);
diff -uBb ../van-5-20/zone/groups.cpp zone/groups.cpp
--- ../van-5-20/zone/groups.cpp 2003-05-21 20:36:19.000000000 -0500
+++ zone/groups.cpp    2003-05-21 20:06:22.000000000 -0500
@@ -201,7 +201,7 @@
        {
                        if(members[i]->GetLevel() > maxlevel)
                                maxlevel = members[i]->GetLevel();
-                      groupexp += exp/10;
+                      groupexp += (uint32)(exp * zone->GetGroupEXPBonus());
                        membercount++;
                }
        }
diff -uBb ../van-5-20/zone/parser.cpp zone/parser.cpp
--- ../van-5-20/zone/parser.cpp 2003-05-21 20:36:19.000000000 -0500
+++ zone/parser.cpp    2003-05-21 20:06:22.000000000 -0500
@@ -816,7 +816,7 @@
                        }
                        else if (strstr(strlwr(arglist[0]),"exp")) {
                                if (mob->IsClient())
-                                      mob->CastToClient()->AddEXP(atoi(arglist[1]));
+                                      mob->CastToClient()->AddEXP((uint32)(zone->GetQuestEXPMod() * atoi(arglist[1])));
                        }
                        else if (strstr(strlwr(arglist[0]),"level")) {
                                if (mob->IsClient())
diff -uBb ../van-5-20/zone/WesQuests.cpp zone/WesQuests.cpp
--- ../van-5-20/zone/WesQuests.cpp      2003-05-21 20:36:19.000000000 -0500
+++ zone/WesQuests.cpp  2003-05-21 20:06:22.000000000 -0500
@@ -348,7 +348,7 @@
                        ps = true;
                }
                else if (strstr(command,"EXP") != NULL) {
-                      this->AddEXP (atoi(sep.arg[1]));
+                      this->AddEXP((uint32)(zone->GetQuestEXPMod() * atoi(sep.arg[1])));
                        ps = true;
                }
                else if (strstr(command,"LEVEL") != NULL) {
diff -uBb ../van-5-20/zone/zone.cpp zone/zone.cpp
--- ../van-5-20/zone/zone.cpp  2003-05-21 20:36:19.000000000 -0500
+++ zone/zone.cpp      2003-05-21 21:02:07.000000000 -0500
@@ -137,6 +137,7 @@
                }
                mysql_free_result(result);
                }
+      zone->LoadZoneCustomizations();
        zone->LoadZoneDoors(zone->GetShortName());
        //g_LogFile.write("AI LEVEL set to %d\n",iAILevel);
        petition_list.ClearPetitions();
@@ -184,6 +185,37 @@
        UpdateWindowTitle();
 }
 
+void Zone::LoadZoneCustomizations()
+{

+  char tmp[10];
+  char *tmp2;

+  // Set default value for EXP modifiers
+  NPCEXPMod    = (double)1;
+  PCEXPMod      = (double)1;
+  QuestEXPMod  = (double)1;
+  GroupEXPBonus = 0.1;
+  AAXPMod      = (double)1;
+  EXPPenaltyMod = (double)1;
+
+  // Look for database entries and use them if they exist
+  if (database.GetVariable("NPCEXPMod", tmp, 9))
+    NPCEXPMod = strtod((const char*)tmp, &tmp2);
+  if (database.GetVariable("PCEXPMod", tmp, 9))
+    PCEXPMod = strtod((const char*)tmp, &tmp2);
+  if (database.GetVariable("QuestEXPMod", tmp, 9))
+    QuestEXPMod = strtod((const char*)tmp, &tmp2);
+  if (database.GetVariable("GroupEXPBonus", tmp, 9))
+    GroupEXPBonus = strtod((const char*)tmp, &tmp2);
+  if (database.GetVariable("AAXPMod", tmp, 9))
+    AAXPMod = strtod((const char*)tmp, &tmp2);
+  if (database.GetVariable("EXPPenaltyMod", tmp, 9))
+    EXPPenaltyMod = strtod((const char*)tmp, &tmp2);

+}
+
+
 void Zone::LoadZoneDoors(const char* zone)
 {
 printf("Loading zones doors...");
diff -uBb ../van-5-20/zone/zone.h zone/zone.h
--- ../van-5-20/zone/zone.h    2003-05-21 20:36:19.000000000 -0500
+++ zone/zone.h 2003-05-21 21:03:07.000000000 -0500
@@ -77,12 +77,13 @@
        inline const float&    safe_z()                { return psafe_z; }
        inline const int32& GetMaxClients() { return pMaxClients; }
 
+      void  LoadZoneCustomizations();
        void    LoadZoneDoors(const char* zone);
 
        int32  CountSpawn2();
        ZonePoint* GetClosestZonePoint(float x, float y, float z, const char* to_name);
        ZonePoint* GetClosestZonePoint(float x, float y, float z, int32 to);
-      SpawnGroupList* spawn_group_list;
+SpawnGroupList* spawn_group_list;
 
        bool RemoveSpawnEntry(uint32 spawngroupid);
        bool RemoveSpawnGroup(uint32 in_id);
@@ -123,6 +124,13 @@
        void    SetDate(int16 year, int8 month, int8 day, int8 hour, int8 minute);
        void    SetTime(int8 hour, int8 minute);
 
+      double  GetGroupEXPBonus() { return GroupEXPBonus; }
+      double  GetNPCEXPMod()    { return NPCEXPMod; }
+      double  GetPCEXPMod()      { return PCEXPMod; }
+      double  GetQuestEXPMod()  { return QuestEXPMod; }
+      double  GetAAXPMod()      { return AAXPMod; }
+      double  GetEXPPenaltyMod() { return EXPPenaltyMod; }
+
        void    weatherProc();
        void    weatherSend();
        time_t  weather_timer;
@@ -176,6 +184,13 @@
        float  psafe_x, psafe_y, psafe_z;
        int32  pMaxClients;
 
+      double  GroupEXPBonus;
+      double  NPCEXPMod;
+      double  PCEXPMod;
+      double  QuestEXPMod;
+      double  AAXPMod;
+      double  EXPPenaltyMod;
+
        bool    staticzone;
        bool    gottime;


Trumpcard 05-22-2003 12:35 AM

Diff files would be easier to post, rather than cut/pastes of diff output. They would also be easier to apply to the code. Looks good though!

fnemo 05-22-2003 05:06 AM

when do you merge this to the cvs trumpcard ? ^^;

Trumpcard 05-22-2003 05:10 AM

When I can get it merged in...

Bigpull 05-22-2003 10:45 PM

Not to totaly rain on the parade but, shouldn't some of this stuff be class dependant also =)

Monrezz 05-23-2003 03:52 AM

NO!







:twisted:
:lol:

killspree 05-23-2003 10:00 AM

There aren't class modifiers anymore. :p

killspree 06-04-2003 10:16 PM

For anyone that hasn't heard, there are group bonus changes on test and will be going live on june 11th - these are substantial exp bonus changes, not sure if folks want to add them into the emu, but they range from 20-80% now, I'm not sure on the exact numbers, but those are for a 2 to 5 person group - the 6th person of the group is basically a free person, they don't detract any from the exp.

So each person in the group would get exp in a full group like it was a 5 person group.

monkboy 06-05-2003 01:08 AM

Exp modifiers
 
As pointed out, there's no class modifyier for exp anymore.. however, there is race modifiers. If I recall correctly, Iksars got a 20% racial experience penalty, to make up for their increased regen/innate AC bonus..

IARivinwise 06-11-2003 12:03 AM

Trolls I believe have that same penalty. I may be able to find a list of racial experience penalties.


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

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