mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-14 20:12:26 +00:00
Fix food/drink to match live
This commit is contained in:
parent
9634bef7fc
commit
8c9b852586
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
@ -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; }
|
||||
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%)
|
||||
*/
|
||||
int increase = item->CastTime_ * 100;
|
||||
if (!auto_consume) // force feeding is half as effective
|
||||
increase /= 2;
|
||||
|
||||
float aa_bonus = ((float) aabonuses.Metabolism - 100) / 100;
|
||||
float item_bonus = (float) itembonuses.Metabolism / 100;
|
||||
float spell_bonus = (float) spellbonuses.Metabolism / 100;
|
||||
|
||||
float metabolism_mod = 1 + spell_bonus + item_bonus + aa_bonus;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
if(thirst_change < 0)
|
||||
return;
|
||||
|
||||
m_pp.thirst_level += thirst_change;
|
||||
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);
|
||||
|
||||
Log(Logs::General, Logs::Food, "Consuming drink, points added to thirst_level: %i current_thirst: %i", thirst_change, m_pp.thirst_level);
|
||||
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
|
||||
Log(Logs::General, Logs::Food, "Eating from slot: %i", (int)slot);
|
||||
|
||||
} else {
|
||||
increase = mod_drink_value(item, increase);
|
||||
|
||||
if (increase < 0)
|
||||
return;
|
||||
|
||||
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",
|
||||
increase, m_pp.thirst_level);
|
||||
|
||||
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)
|
||||
|
||||
@ -1458,7 +1458,6 @@ private:
|
||||
Timer hpupdate_timer;
|
||||
Timer camp_timer;
|
||||
Timer process_timer;
|
||||
Timer stamina_timer;
|
||||
Timer consume_food_timer;
|
||||
Timer zoneinpacket_timer;
|
||||
Timer linkdead_timer;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
@ -539,7 +538,6 @@ bool Client::Process() {
|
||||
DoManaRegen();
|
||||
DoEnduranceRegen();
|
||||
BuffProcess();
|
||||
DoStaminaHungerUpdate();
|
||||
|
||||
if (tribute_timer.Check()) {
|
||||
ToggleTribute(true); //re-activate the tribute.
|
||||
@ -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
|
||||
);
|
||||
"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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user