mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-05 20:22:28 +00:00
implemented air supply and lung capacity
This commit is contained in:
parent
a4e47d9180
commit
8ef369ee57
@ -700,7 +700,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
newbon->CHA += base_value;
|
||||
break;
|
||||
case SE_WaterBreathing:
|
||||
// handled by client
|
||||
newbon->WaterBreathing = base_value;
|
||||
break;
|
||||
case SE_CurrentMana:
|
||||
newbon->ManaRegen += base_value;
|
||||
@ -742,6 +742,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
case SE_TwoHandBash:
|
||||
break;
|
||||
case SE_SetBreathLevel:
|
||||
newbon->BreathLevel += base_value;
|
||||
break;
|
||||
case SE_RaiseStatCap:
|
||||
switch (limit_value) {
|
||||
|
||||
@ -189,7 +189,8 @@ Client::Client() : Mob(
|
||||
tmSitting(0),
|
||||
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
|
||||
lazy_load_bank_check_timer(1000),
|
||||
bandolier_throttle_timer(0)
|
||||
bandolier_throttle_timer(0),
|
||||
underwater_timer(1000)
|
||||
{
|
||||
eqs = nullptr;
|
||||
for (auto client_filter = FilterNone; client_filter < _FilterCount; client_filter = eqFilterType(client_filter + 1)) {
|
||||
@ -497,7 +498,8 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
|
||||
tmSitting(0),
|
||||
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
|
||||
lazy_load_bank_check_timer(1000),
|
||||
bandolier_throttle_timer(0)
|
||||
bandolier_throttle_timer(0),
|
||||
underwater_timer(1000)
|
||||
{
|
||||
for (auto client_filter = FilterNone; client_filter < _FilterCount; client_filter = eqFilterType(client_filter + 1)) {
|
||||
SetFilter(client_filter, FilterShow);
|
||||
@ -13282,3 +13284,21 @@ bool Client::UncompleteTask(int task_id)
|
||||
|
||||
return task_state->UncompleteTask(task_id);
|
||||
}
|
||||
|
||||
bool Client::IsUnderWater()
|
||||
{
|
||||
if (!zone->watermap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (zone->GetZoneID() == Zones::KEDGE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto underwater = glm::vec3(GetX(), GetY(), GetZ() + GetZOffset());
|
||||
if (zone->IsWaterZone(underwater.z) || zone->watermap->InLiquid(underwater)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2037,6 +2037,7 @@ private:
|
||||
int64 CalcHPRegen(bool bCombat = false);
|
||||
int64 CalcManaRegen(bool bCombat = false);
|
||||
int64 CalcBaseManaRegen();
|
||||
int32 CalculateLungCapacity();
|
||||
void DoHPRegen();
|
||||
void DoManaRegen();
|
||||
void DoStaminaHungerUpdate();
|
||||
@ -2215,6 +2216,7 @@ private:
|
||||
Timer parcel_timer; //Used to limit the number of parcels to one every 30 seconds (default). Changable via rule.
|
||||
Timer lazy_load_bank_check_timer;
|
||||
Timer bandolier_throttle_timer;
|
||||
Timer underwater_timer;
|
||||
|
||||
bool m_lazy_load_bank = false;
|
||||
int m_lazy_load_sent_bank_slots = 0;
|
||||
@ -2433,6 +2435,7 @@ public:
|
||||
bool IsFilteredAFKPacket(const EQApplicationPacket *p);
|
||||
void CheckAutoIdleAFK(PlayerPositionUpdateClient_Struct *p);
|
||||
void SyncWorldPositionsToClient(bool ignore_idle = false);
|
||||
bool IsUnderWater();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1774,3 +1774,30 @@ int Client::GetRawACNoShield(int &shield_ac) const
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
int32 Client::CalculateLungCapacity()
|
||||
{
|
||||
// Iksar and Frogloks do not benefit from Innate Lung Capacity and do not have STA penalty
|
||||
if (GetBaseRace() == IKSAR) return 127;
|
||||
if (GetBaseRace() == FROGLOK) return 256;
|
||||
|
||||
// Innate Lung Capacity AA gives 10%/25%/50% more
|
||||
int base_lung_capacity = aabonuses.BreathLevel > 0 ? aabonuses.BreathLevel : 100;
|
||||
int lung_capacity = base_lung_capacity;
|
||||
|
||||
// having less than 130 STA applies a reduction to air supply, but having more than 130 does not provide a bonus
|
||||
int STA_penalty = GetSTA() - 30;
|
||||
if (STA_penalty < 100) {
|
||||
lung_capacity = base_lung_capacity * STA_penalty / 100;
|
||||
|
||||
if (lung_capacity < 10) {
|
||||
lung_capacity = 10;
|
||||
}
|
||||
|
||||
if (lung_capacity > base_lung_capacity) {
|
||||
lung_capacity = base_lung_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
return lung_capacity;
|
||||
}
|
||||
|
||||
@ -1707,8 +1707,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
m_pp.abilitySlotRefresh = 0;
|
||||
}
|
||||
|
||||
/* Reset to max so they dont drown on zone in if its underwater */
|
||||
m_pp.air_remaining = 60;
|
||||
/* Check for PVP Zone status*/
|
||||
if (zone->IsPVPZone())
|
||||
m_pp.pvp = 1;
|
||||
|
||||
@ -223,6 +223,18 @@ bool Client::Process() {
|
||||
if (IsStunned() && stunned_timer.Check())
|
||||
Mob::UnStun();
|
||||
|
||||
if (underwater_timer.Check()) {
|
||||
if ((IsUnderWater() || GetZoneID() == Zones::THEGREY) &&
|
||||
!spellbonuses.WaterBreathing && !aabonuses.WaterBreathing && !itembonuses.WaterBreathing) {
|
||||
if (m_pp.air_remaining > 0) {
|
||||
--m_pp.air_remaining;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_pp.air_remaining = CalculateLungCapacity();
|
||||
}
|
||||
}
|
||||
|
||||
cheat_manager.ClientProcess();
|
||||
|
||||
if (bardsong_timer.Check() && bardsong != 0) {
|
||||
|
||||
@ -575,6 +575,8 @@ struct StatBonuses {
|
||||
int aura_slots;
|
||||
int trap_slots;
|
||||
bool hunger; // Song of Sustenance -- min caps to 3500
|
||||
int32 BreathLevel;
|
||||
bool WaterBreathing;
|
||||
int64 heroic_max_hp;
|
||||
int64 heroic_max_mana;
|
||||
int64 heroic_max_end;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user