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
|
#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
|
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, 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, 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_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_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_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.
|
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)
|
if (GetMaxXTargets() != 5 + aabonuses.extra_xtargets)
|
||||||
SetMaxXTargets(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)
|
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;
|
new_bonus->MagicWeapon = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_Hunger:
|
||||||
|
new_bonus->hunger = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case SE_IncreaseBlockChance:
|
case SE_IncreaseBlockChance:
|
||||||
if (AdditiveWornBonus)
|
if (AdditiveWornBonus)
|
||||||
new_bonus->IncreaseBlockChance += effect_value;
|
new_bonus->IncreaseBlockChance += effect_value;
|
||||||
|
|||||||
@ -123,8 +123,7 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
hpupdate_timer(2000),
|
hpupdate_timer(2000),
|
||||||
camp_timer(29000),
|
camp_timer(29000),
|
||||||
process_timer(100),
|
process_timer(100),
|
||||||
stamina_timer(40000),
|
consume_food_timer(CONSUMPTION_TIMER),
|
||||||
consume_food_timer(60000),
|
|
||||||
zoneinpacket_timer(1000),
|
zoneinpacket_timer(1000),
|
||||||
linkdead_timer(RuleI(Zone,ClientLinkdeadMS)),
|
linkdead_timer(RuleI(Zone,ClientLinkdeadMS)),
|
||||||
dead_timer(2000),
|
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)
|
void Client::Consume(const EQEmu::ItemData *item, uint8 type, int16 slot, bool auto_consume)
|
||||||
{
|
{
|
||||||
if(!item) { return; }
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
int increase = item->CastTime_ * 100;
|
||||||
Spell Bonuses 2 digit form - 10, 20, 25 etc. (10%, 20%, 25%)
|
if (!auto_consume) // force feeding is half as effective
|
||||||
AA Bonus Ranks, 110, 125, 150 etc. (10%, 25%, 50%)
|
increase /= 2;
|
||||||
*/
|
|
||||||
|
|
||||||
float aa_bonus = ((float) aabonuses.Metabolism - 100) / 100;
|
if (increase < 0) // wasn't food? oh well
|
||||||
float item_bonus = (float) itembonuses.Metabolism / 100;
|
return;
|
||||||
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 (type == EQEmu::item::ItemTypeFood) {
|
if (type == EQEmu::item::ItemTypeFood) {
|
||||||
int hunger_change = item->CastTime_ * metabolism_mod;
|
increase = mod_food_value(item, increase);
|
||||||
hunger_change = mod_food_value(item, hunger_change);
|
|
||||||
|
|
||||||
if(hunger_change < 0)
|
if (increase < 0)
|
||||||
return;
|
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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
DeleteItemInInventory(slot, 1, false);
|
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);
|
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)
|
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 hpupdate_timer;
|
||||||
Timer camp_timer;
|
Timer camp_timer;
|
||||||
Timer process_timer;
|
Timer process_timer;
|
||||||
Timer stamina_timer;
|
|
||||||
Timer consume_food_timer;
|
Timer consume_food_timer;
|
||||||
Timer zoneinpacket_timer;
|
Timer zoneinpacket_timer;
|
||||||
Timer linkdead_timer;
|
Timer linkdead_timer;
|
||||||
|
|||||||
@ -1410,6 +1410,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
drakkin_tattoo = m_pp.drakkin_tattoo;
|
drakkin_tattoo = m_pp.drakkin_tattoo;
|
||||||
drakkin_details = m_pp.drakkin_details;
|
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 GM not set in DB, and does not meet min status to be GM, reset */
|
||||||
if (m_pp.gm && admin < minStatusToBeGM)
|
if (m_pp.gm && admin < minStatusToBeGM)
|
||||||
m_pp.gm = 0;
|
m_pp.gm = 0;
|
||||||
|
|||||||
@ -524,10 +524,9 @@ bool Client::Process() {
|
|||||||
DoEnduranceUpkeep();
|
DoEnduranceUpkeep();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consume_food_timer.Check()) {
|
// this is independent of the tick timer
|
||||||
m_pp.hunger_level = m_pp.hunger_level - 1;
|
if (consume_food_timer.Check())
|
||||||
m_pp.thirst_level = m_pp.thirst_level - 1;
|
DoStaminaHungerUpdate();
|
||||||
}
|
|
||||||
|
|
||||||
if (tic_timer.Check() && !dead) {
|
if (tic_timer.Check() && !dead) {
|
||||||
CalcMaxHP();
|
CalcMaxHP();
|
||||||
@ -539,7 +538,6 @@ bool Client::Process() {
|
|||||||
DoManaRegen();
|
DoManaRegen();
|
||||||
DoEnduranceRegen();
|
DoEnduranceRegen();
|
||||||
BuffProcess();
|
BuffProcess();
|
||||||
DoStaminaHungerUpdate();
|
|
||||||
|
|
||||||
if (tribute_timer.Check()) {
|
if (tribute_timer.Check()) {
|
||||||
ToggleTribute(true); //re-activate the tribute.
|
ToggleTribute(true); //re-activate the tribute.
|
||||||
@ -1834,32 +1832,37 @@ void Client::DoManaRegen() {
|
|||||||
CheckManaEndUpdate();
|
CheckManaEndUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::DoStaminaHungerUpdate() {
|
void Client::DoStaminaHungerUpdate()
|
||||||
if(!stamina_timer.Check())
|
{
|
||||||
return;
|
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_Stamina, sizeof(Stamina_Struct));
|
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) {
|
if (zone->GetZoneID() != 151 && !GetGM()) {
|
||||||
sta->food = m_pp.hunger_level > 6000 ? 6000 : m_pp.hunger_level;
|
int loss = RuleI(Character, FoodLossPerUpdate);
|
||||||
sta->water = m_pp.thirst_level > 6000 ? 6000 : m_pp.thirst_level;
|
if (GetHorseId() != 0)
|
||||||
}
|
loss *= 3;
|
||||||
else {
|
|
||||||
|
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
|
// No auto food/drink consumption in the Bazaar
|
||||||
sta->food = 6000;
|
sta->food = 6000;
|
||||||
sta->water = 6000;
|
sta->water = 6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(Logs::General, Logs::Food,
|
Log(Logs::General, Logs::Food,
|
||||||
"Client::DoStaminaHungerUpdate() Current hunger_level: %i = (%i minutes left) thirst_level: %i = (%i minutes left) - after loss",
|
"Client::DoStaminaHungerUpdate() Current hunger_level: %i = (%i minutes left) thirst_level: %i = (%i "
|
||||||
m_pp.hunger_level,
|
"minutes left) - after loss",
|
||||||
m_pp.hunger_level,
|
m_pp.hunger_level, m_pp.hunger_level, m_pp.thirst_level, m_pp.thirst_level);
|
||||||
m_pp.thirst_level,
|
|
||||||
m_pp.thirst_level
|
|
||||||
);
|
|
||||||
|
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -550,6 +550,7 @@ struct StatBonuses {
|
|||||||
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
||||||
int aura_slots;
|
int aura_slots;
|
||||||
int trap_slots;
|
int trap_slots;
|
||||||
|
bool hunger; // Song of Sustenance -- min caps to 3500
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@ -3656,16 +3656,6 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
|||||||
break;
|
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_Invisibility:
|
||||||
case SE_InvisVsAnimals:
|
case SE_InvisVsAnimals:
|
||||||
case SE_InvisVsUndead: {
|
case SE_InvisVsUndead: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user