Skip to content

Commit

Permalink
Fix food/drink to match live
Browse files Browse the repository at this point in the history
  • Loading branch information
mackal committed Sep 19, 2017
1 parent 9634bef commit 8c9b852
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 76 deletions.
5 changes: 5 additions & 0 deletions common/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,11 @@ enum {
#define SAYLINK_ITEM_ID 0xFFFFF


// consumption timers for food/drink here instead of rules because the client
// uses these. Times in ms.
#define CONSUMPTION_TIMER 46000
#define CONSUMPTION_MNK_TIMER 92000

/*
Developer configuration
Expand Down
2 changes: 1 addition & 1 deletion common/ruletypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ RULE_BOOL(Character, EnableDiscoveredItems, true) // If enabled, it enables EVEN
RULE_BOOL(Character, EnableXTargetting, true) // Enable Extended Targetting Window, for users with UF and later clients.
RULE_BOOL(Character, EnableAggroMeter, true) // Enable Aggro Meter, for users with RoF and later clients.
RULE_BOOL(Character, KeepLevelOverMax, false) // Don't delevel a character that has somehow gone over the level cap
RULE_INT(Character, FoodLossPerUpdate, 35) // How much food/water you lose per stamina update
RULE_INT(Character, FoodLossPerUpdate, 32) // How much food/water you lose per stamina update
RULE_INT(Character, BaseInstrumentSoftCap, 36) // Softcap for instrument mods, 36 commonly referred to as "3.6" as well.
RULE_BOOL(Character, UseSpellFileSongCap, true) // When they removed the AA that increased the cap they removed the above and just use the spell field
RULE_INT(Character, BaseRunSpeedCap, 158) // Base Run Speed Cap, on live it's 158% which will give you a runspeed of 1.580 hard capped to 225.
Expand Down
11 changes: 11 additions & 0 deletions zone/bonuses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ void Client::CalcBonuses()

if (GetMaxXTargets() != 5 + aabonuses.extra_xtargets)
SetMaxXTargets(5 + aabonuses.extra_xtargets);

// hmm maybe a better way to do this
int metabolism = spellbonuses.Metabolism + itembonuses.Metabolism + aabonuses.Metabolism;
int timer = GetClass() == MONK ? CONSUMPTION_MNK_TIMER : CONSUMPTION_TIMER;
timer = timer * (100 + metabolism) / 100;
if (timer != consume_food_timer.GetTimerTime())
consume_food_timer.SetTimer(timer);
}

int Client::CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat)
Expand Down Expand Up @@ -2503,6 +2510,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
new_bonus->MagicWeapon = true;
break;

case SE_Hunger:
new_bonus->hunger = true;
break;

case SE_IncreaseBlockChance:
if (AdditiveWornBonus)
new_bonus->IncreaseBlockChance += effect_value;
Expand Down
69 changes: 28 additions & 41 deletions zone/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ Client::Client(EQStreamInterface* ieqs)
hpupdate_timer(2000),
camp_timer(29000),
process_timer(100),
stamina_timer(40000),
consume_food_timer(60000),
consume_food_timer(CONSUMPTION_TIMER),
zoneinpacket_timer(1000),
linkdead_timer(RuleI(Zone,ClientLinkdeadMS)),
dead_timer(2000),
Expand Down Expand Up @@ -8591,64 +8590,52 @@ void Client::SetConsumption(int32 in_hunger, int32 in_thirst)

void Client::Consume(const EQEmu::ItemData *item, uint8 type, int16 slot, bool auto_consume)
{
if(!item) { return; }

/*
Spell Bonuses 2 digit form - 10, 20, 25 etc. (10%, 20%, 25%)
AA Bonus Ranks, 110, 125, 150 etc. (10%, 25%, 50%)
*/

float aa_bonus = ((float) aabonuses.Metabolism - 100) / 100;
float item_bonus = (float) itembonuses.Metabolism / 100;
float spell_bonus = (float) spellbonuses.Metabolism / 100;
if (!item)
return;

float metabolism_mod = 1 + spell_bonus + item_bonus + aa_bonus;
int increase = item->CastTime_ * 100;
if (!auto_consume) // force feeding is half as effective
increase /= 2;

Log(Logs::General, Logs::Food, "Client::Consume() Metabolism bonuses spell_bonus: (%.2f) item_bonus: (%.2f) aa_bonus: (%.2f) final: (%.2f)",
spell_bonus,
item_bonus,
aa_bonus,
metabolism_mod
);
if (increase < 0) // wasn't food? oh well
return;

if (type == EQEmu::item::ItemTypeFood) {
int hunger_change = item->CastTime_ * metabolism_mod;
hunger_change = mod_food_value(item, hunger_change);
increase = mod_food_value(item, increase);

if(hunger_change < 0)
return;
if (increase < 0)
return;

m_pp.hunger_level += hunger_change;
m_pp.hunger_level += increase;

Log(Logs::General, Logs::Food, "Consuming food, points added to hunger_level: %i - current_hunger: %i", hunger_change, m_pp.hunger_level);
Log(Logs::General, Logs::Food, "Consuming food, points added to hunger_level: %i - current_hunger: %i",
increase, m_pp.hunger_level);

DeleteItemInInventory(slot, 1, false);
DeleteItemInInventory(slot, 1, false);

if(!auto_consume) //no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name);
if (!auto_consume) // no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name);

Log(Logs::General, Logs::Food, "Eating from slot: %i", (int)slot);
Log(Logs::General, Logs::Food, "Eating from slot: %i", (int)slot);

}
else {
int thirst_change = item->CastTime_ * metabolism_mod;
thirst_change = mod_drink_value(item, thirst_change);
} else {
increase = mod_drink_value(item, increase);

if(thirst_change < 0)
return;
if (increase < 0)
return;

m_pp.thirst_level += thirst_change;
m_pp.thirst_level += increase;

DeleteItemInInventory(slot, 1, false);

Log(Logs::General, Logs::Food, "Consuming drink, points added to thirst_level: %i current_thirst: %i", thirst_change, m_pp.thirst_level);
Log(Logs::General, Logs::Food, "Consuming drink, points added to thirst_level: %i current_thirst: %i",
increase, m_pp.thirst_level);

if(!auto_consume) //no message if the client consumed for us
if (!auto_consume) // no message if the client consumed for us
entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name);

Log(Logs::General, Logs::Food, "Drinking from slot: %i", (int)slot);

}
Log(Logs::General, Logs::Food, "Drinking from slot: %i", (int)slot);
}
}

void Client::SendMarqueeMessage(uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, std::string msg)
Expand Down
1 change: 0 additions & 1 deletion zone/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,6 @@ class Client : public Mob
Timer hpupdate_timer;
Timer camp_timer;
Timer process_timer;
Timer stamina_timer;
Timer consume_food_timer;
Timer zoneinpacket_timer;
Timer linkdead_timer;
Expand Down
4 changes: 4 additions & 0 deletions zone/client_packet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
drakkin_tattoo = m_pp.drakkin_tattoo;
drakkin_details = m_pp.drakkin_details;

// we know our class now, so we might have to fix our consume timer!
if (class_ == MONK)
consume_food_timer.SetTimer(CONSUMPTION_MNK_TIMER);

/* If GM not set in DB, and does not meet min status to be GM, reset */
if (m_pp.gm && admin < minStatusToBeGM)
m_pp.gm = 0;
Expand Down
49 changes: 26 additions & 23 deletions zone/client_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,9 @@ bool Client::Process() {
DoEnduranceUpkeep();
}

if (consume_food_timer.Check()) {
m_pp.hunger_level = m_pp.hunger_level - 1;
m_pp.thirst_level = m_pp.thirst_level - 1;
}
// this is independent of the tick timer
if (consume_food_timer.Check())
DoStaminaHungerUpdate();

if (tic_timer.Check() && !dead) {
CalcMaxHP();
Expand All @@ -539,7 +538,6 @@ bool Client::Process() {
DoManaRegen();
DoEnduranceRegen();
BuffProcess();
DoStaminaHungerUpdate();

if (tribute_timer.Check()) {
ToggleTribute(true); //re-activate the tribute.
Expand Down Expand Up @@ -1834,32 +1832,37 @@ void Client::DoManaRegen() {
CheckManaEndUpdate();
}

void Client::DoStaminaHungerUpdate() {
if(!stamina_timer.Check())
return;

void Client::DoStaminaHungerUpdate()
{
auto outapp = new EQApplicationPacket(OP_Stamina, sizeof(Stamina_Struct));
Stamina_Struct* sta = (Stamina_Struct*)outapp->pBuffer;
Stamina_Struct *sta = (Stamina_Struct *)outapp->pBuffer;

Log(Logs::General, Logs::Food, "Client::DoStaminaHungerUpdate() hunger_level: %i thirst_level: %i before loss", m_pp.hunger_level, m_pp.thirst_level);
Log(Logs::General, Logs::Food, "Client::DoStaminaHungerUpdate() hunger_level: %i thirst_level: %i before loss",
m_pp.hunger_level, m_pp.thirst_level);

if (zone->GetZoneID() != 151) {
sta->food = m_pp.hunger_level > 6000 ? 6000 : m_pp.hunger_level;
sta->water = m_pp.thirst_level > 6000 ? 6000 : m_pp.thirst_level;
}
else {
if (zone->GetZoneID() != 151 && !GetGM()) {
int loss = RuleI(Character, FoodLossPerUpdate);
if (GetHorseId() != 0)
loss *= 3;

m_pp.hunger_level = EQEmu::Clamp(m_pp.hunger_level - loss, 0, 6000);
m_pp.thirst_level = EQEmu::Clamp(m_pp.thirst_level - loss, 0, 6000);
if (spellbonuses.hunger) {
m_pp.hunger_level = EQEmu::ClampLower(m_pp.hunger_level, 3500);
m_pp.thirst_level = EQEmu::ClampLower(m_pp.thirst_level, 3500);
}
sta->food = m_pp.hunger_level;
sta->water = m_pp.thirst_level;
} else {
// No auto food/drink consumption in the Bazaar
sta->food = 6000;
sta->water = 6000;
}

Log(Logs::General, Logs::Food,
"Client::DoStaminaHungerUpdate() Current hunger_level: %i = (%i minutes left) thirst_level: %i = (%i minutes left) - after loss",
m_pp.hunger_level,
m_pp.hunger_level,
m_pp.thirst_level,
m_pp.thirst_level
);
Log(Logs::General, Logs::Food,
"Client::DoStaminaHungerUpdate() Current hunger_level: %i = (%i minutes left) thirst_level: %i = (%i "
"minutes left) - after loss",
m_pp.hunger_level, m_pp.hunger_level, m_pp.thirst_level, m_pp.thirst_level);

FastQueuePacket(&outapp);
}
Expand Down
1 change: 1 addition & 0 deletions zone/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ struct StatBonuses {
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
int aura_slots;
int trap_slots;
bool hunger; // Song of Sustenance -- min caps to 3500
};

typedef struct
Expand Down
10 changes: 0 additions & 10 deletions zone/spell_effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3656,16 +3656,6 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
break;
}

case SE_Hunger: {
// this procedure gets called 7 times for every once that the stamina update occurs so we add
// 1/7 of the subtraction.
// It's far from perfect, but works without any unnecessary buff checks to bog down the server.
if (IsClient()) {
CastToClient()->m_pp.hunger_level += 5;
CastToClient()->m_pp.thirst_level += 5;
}
break;
}
case SE_Invisibility:
case SE_InvisVsAnimals:
case SE_InvisVsUndead: {
Expand Down

0 comments on commit 8c9b852

Please sign in to comment.