implemented air supply and lung capacity

This commit is contained in:
solar
2025-08-29 07:02:57 +01:00
parent a4e47d9180
commit 8ef369ee57
7 changed files with 68 additions and 5 deletions
+2 -1
View File
@@ -700,7 +700,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
newbon->CHA += base_value; newbon->CHA += base_value;
break; break;
case SE_WaterBreathing: case SE_WaterBreathing:
// handled by client newbon->WaterBreathing = base_value;
break; break;
case SE_CurrentMana: case SE_CurrentMana:
newbon->ManaRegen += base_value; newbon->ManaRegen += base_value;
@@ -742,6 +742,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
case SE_TwoHandBash: case SE_TwoHandBash:
break; break;
case SE_SetBreathLevel: case SE_SetBreathLevel:
newbon->BreathLevel += base_value;
break; break;
case SE_RaiseStatCap: case SE_RaiseStatCap:
switch (limit_value) { switch (limit_value) {
+22 -2
View File
@@ -189,7 +189,8 @@ Client::Client() : Mob(
tmSitting(0), tmSitting(0),
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)), parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
lazy_load_bank_check_timer(1000), lazy_load_bank_check_timer(1000),
bandolier_throttle_timer(0) bandolier_throttle_timer(0),
underwater_timer(1000)
{ {
eqs = nullptr; eqs = nullptr;
for (auto client_filter = FilterNone; client_filter < _FilterCount; client_filter = eqFilterType(client_filter + 1)) { 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), tmSitting(0),
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)), parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
lazy_load_bank_check_timer(1000), 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)) { for (auto client_filter = FilterNone; client_filter < _FilterCount; client_filter = eqFilterType(client_filter + 1)) {
SetFilter(client_filter, FilterShow); SetFilter(client_filter, FilterShow);
@@ -13282,3 +13284,21 @@ bool Client::UncompleteTask(int task_id)
return task_state->UncompleteTask(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;
}
+3
View File
@@ -2037,6 +2037,7 @@ private:
int64 CalcHPRegen(bool bCombat = false); int64 CalcHPRegen(bool bCombat = false);
int64 CalcManaRegen(bool bCombat = false); int64 CalcManaRegen(bool bCombat = false);
int64 CalcBaseManaRegen(); int64 CalcBaseManaRegen();
int32 CalculateLungCapacity();
void DoHPRegen(); void DoHPRegen();
void DoManaRegen(); void DoManaRegen();
void DoStaminaHungerUpdate(); 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 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 lazy_load_bank_check_timer;
Timer bandolier_throttle_timer; Timer bandolier_throttle_timer;
Timer underwater_timer;
bool m_lazy_load_bank = false; bool m_lazy_load_bank = false;
int m_lazy_load_sent_bank_slots = 0; int m_lazy_load_sent_bank_slots = 0;
@@ -2433,6 +2435,7 @@ public:
bool IsFilteredAFKPacket(const EQApplicationPacket *p); bool IsFilteredAFKPacket(const EQApplicationPacket *p);
void CheckAutoIdleAFK(PlayerPositionUpdateClient_Struct *p); void CheckAutoIdleAFK(PlayerPositionUpdateClient_Struct *p);
void SyncWorldPositionsToClient(bool ignore_idle = false); void SyncWorldPositionsToClient(bool ignore_idle = false);
bool IsUnderWater();
}; };
#endif #endif
+27
View File
@@ -1774,3 +1774,30 @@ int Client::GetRawACNoShield(int &shield_ac) const
} }
return ac; 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;
}
-2
View File
@@ -1707,8 +1707,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
m_pp.abilitySlotRefresh = 0; 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*/ /* Check for PVP Zone status*/
if (zone->IsPVPZone()) if (zone->IsPVPZone())
m_pp.pvp = 1; m_pp.pvp = 1;
+12
View File
@@ -223,6 +223,18 @@ bool Client::Process() {
if (IsStunned() && stunned_timer.Check()) if (IsStunned() && stunned_timer.Check())
Mob::UnStun(); 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(); cheat_manager.ClientProcess();
if (bardsong_timer.Check() && bardsong != 0) { if (bardsong_timer.Check() && bardsong != 0) {
+2
View File
@@ -575,6 +575,8 @@ struct StatBonuses {
int aura_slots; int aura_slots;
int trap_slots; int trap_slots;
bool hunger; // Song of Sustenance -- min caps to 3500 bool hunger; // Song of Sustenance -- min caps to 3500
int32 BreathLevel;
bool WaterBreathing;
int64 heroic_max_hp; int64 heroic_max_hp;
int64 heroic_max_mana; int64 heroic_max_mana;
int64 heroic_max_end; int64 heroic_max_end;