Skip to content

Commit

Permalink
Add artefact degradation
Browse files Browse the repository at this point in the history
  • Loading branch information
Shtrecker committed Aug 11, 2024
1 parent 8e2622b commit bf1c330
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 45 deletions.
1 change: 1 addition & 0 deletions gamedata/configs/engine_external.ltx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ EnableAutoreload = false
EnableMonstersInventory = true
EnableWeaponInertion = false ;Shoker Mod Style
EnableWeaponCollision = false ;Shoker Mod Style
EnableArtefactDegradation = false

[render]
LoadScreenTips = true
Expand Down
3 changes: 2 additions & 1 deletion src/xrEngine/EngineExternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ enum class EEngineExternalGame
EnableAutoreload,
EnableMonstersInventory,
EnableWeaponInertion,
EnableWeaponCollision
EnableWeaponCollision,
EnableArtefactDegradation
};

enum class EEngineExternalRender {
Expand Down
224 changes: 192 additions & 32 deletions src/xrGame/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ void CActor::Hit(SHit* pHDS)
{
HDS.power = hit_power;
HDS.add_wound = true;
HitArtefactsCondition (HDS);
inherited::Hit (&HDS);
}
}else
Expand Down Expand Up @@ -1258,6 +1259,7 @@ void CActor::UpdateCL ()
}

UpdateDefferedMessages();
UpdateConditionArtefacts();

if (g_Alive())
CStepManager::update(this==Level().CurrentViewEntity());
Expand Down Expand Up @@ -1285,6 +1287,142 @@ void CActor::UpdateCL ()
pPickup->SetPickupMode(false);
}

void CActor::UpdateConditionArtefacts()
{
if (!EngineExternal()[EEngineExternalGame::EnableArtefactDegradation])
return;

static u32 _tmr = 0;

if (_tmr && Device.dwTimeGlobal < _tmr)
return;

_tmr = Device.dwTimeGlobal + 2000;

auto it = inventory().m_belt.begin();
auto ite = inventory().m_belt.end();
for (; it != ite; ++it)
{
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if (artefact)
{
float cond_loss = 0;
float val = 0;

if (conditions().GetHealth() < 1.0f)
{
val = artefact->m_fHealthRestoreSpeed;
if (val > 0)
cond_loss += val * 0.2f;
}

if (conditions().GetRadiation() > 0)
{
val = artefact->m_fRadiationRestoreSpeed;
if (val < 0)
cond_loss += std::abs(val) * 0.2f;
}

if (conditions().GetSatiety() < 1.0f)
{
val = artefact->m_fSatietyRestoreSpeed;
if (val > 0)
cond_loss += val * 0.2f;
}

if (conditions().GetPower() < 1.0f)
{
val = artefact->m_fPowerRestoreSpeed;
if (val > 0)
cond_loss += val * 0.2f;
}

if (conditions().BleedingSpeed() > 0)
{
val = artefact->m_fBleedingRestoreSpeed;
if (val > 0)
cond_loss += val * 0.2f;
}

val = artefact->AdditionalInventoryWeight();
if (val > 0)
{
float diff = inventory().TotalWeight() - conditions().MaxWalkWeight() - (GetOutfit() ? GetOutfit()->m_additional_weight2 : 0);
if (diff > 0)
cond_loss += ((diff * 0.0001) / val);
}

if (cond_loss > 0)
{
val = artefact->GetCondition() - (cond_loss * 1);
val -= artefact->GetCondition();
artefact->ChangeCondition(val);
}
}
}
}

std::map<shared_str, float> imm_mul =
{
{"light_burn_immunity", 1.2f},
{"burn_immunity", 1.2f},
{"strike_immunity", 1.2f},
{"shock_immunity", 1.2f},
{"wound_immunity", 1.2f},
{"radiation_immunity", 1.2f},
{"telepatic_immunity", 1.2f},
{"chemical_burn_immunity", 1.2f},
{"explosion_immunity", 1.2f},
{"fire_wound_immunity", 1.2f}
};

std::map<ALife::EHitType, shared_str> hit_to_section =
{
{ALife::EHitType::eHitTypeLightBurn , "light_burn_immunity"},
{ALife::EHitType::eHitTypeBurn, "burn_immunity"},
{ALife::EHitType::eHitTypeStrike, "strike_immunity"},
{ALife::EHitType::eHitTypeShock, "shock_immunity"},
{ALife::EHitType::eHitTypeWound, "wound_immunity"},
{ALife::EHitType::eHitTypeRadiation, "radiation_immunity"},
{ALife::EHitType::eHitTypeTelepatic, "telepatic_immunity"},
{ALife::EHitType::eHitTypeChemicalBurn, "chemical_burn_immunity"},
{ALife::EHitType::eHitTypeExplosion, "explosion_immunity"},
{ALife::EHitType::eHitTypeFireWound, "fire_wound_immunity"}
};

void CActor::HitArtefactsCondition(SHit& hit)
{
if (!EngineExternal()[EEngineExternalGame::EnableArtefactDegradation])
return;

if (hit.power <= 0)
return;

auto it = inventory().m_belt.begin();
auto ite = inventory().m_belt.end();
for (; it != ite; ++it)
{
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if (artefact)
{
shared_str hit_absorbation_sect = READ_IF_EXISTS(pSettings, r_string, artefact->m_section_id.c_str(), "hit_absorbation_sect", "");

if (hit_absorbation_sect.size() > 0)
{
shared_str imm_sect = hit_to_section[hit.hit_type];
float cond_loss = pSettings->line_exist(hit_absorbation_sect, imm_sect.c_str()) ? pSettings->r_float(hit_absorbation_sect, imm_sect.c_str()) : 0;
if (cond_loss > 0)
{
cond_loss = (hit.power * imm_mul[imm_sect] * cond_loss);

float val = artefact->GetCondition() - (cond_loss * 1);
val -= artefact->GetCondition();
artefact->ChangeCondition(val);
}
}
}
}
}

void CActor::set_state_box(u32 mstate)
{
Expand Down Expand Up @@ -1848,26 +1986,28 @@ void CActor::UpdateArtefactsOnBeltAndOutfit()
update_time = 0.0f;
}

for(TIItemContainer::iterator it = inventory().m_belt.begin();
inventory().m_belt.end() != it; ++it)
for (TIItemContainer::iterator it = inventory().m_belt.begin(); inventory().m_belt.end() != it; ++it)
{
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if(artefact)
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if (artefact)
{
conditions().ChangeBleeding (artefact->m_fBleedingRestoreSpeed * f_update_time);
conditions().ChangeHealth (artefact->m_fHealthRestoreSpeed * f_update_time);
conditions().ChangePower (artefact->m_fPowerRestoreSpeed * f_update_time);
conditions().ChangeSatiety (artefact->m_fSatietyRestoreSpeed * f_update_time);
if(artefact->m_fRadiationRestoreSpeed>0.0f)
float art_cond = artefact->GetCondition();
conditions().ChangeBleeding((artefact->m_fBleedingRestoreSpeed * art_cond) * f_update_time);
conditions().ChangeHealth((artefact->m_fHealthRestoreSpeed * art_cond) * f_update_time);
conditions().ChangePower((artefact->m_fPowerRestoreSpeed * art_cond) * f_update_time);
conditions().ChangeSatiety((artefact->m_fSatietyRestoreSpeed * art_cond) * f_update_time);

if ((artefact->m_fRadiationRestoreSpeed * art_cond) > 0.0f)
{
float val = artefact->m_fRadiationRestoreSpeed - conditions().GetBoostRadiationImmunity();
float val = (artefact->m_fRadiationRestoreSpeed * art_cond) - conditions().GetBoostRadiationImmunity();
clamp(val, 0.0f, val);
conditions().ChangeRadiation(val * f_update_time);
}
else
conditions().ChangeRadiation(artefact->m_fRadiationRestoreSpeed * f_update_time);
conditions().ChangeRadiation((artefact->m_fRadiationRestoreSpeed * art_cond) * f_update_time);
}
}

CCustomOutfit* outfit = GetOutfit();
if ( outfit )
{
Expand All @@ -1891,36 +2031,56 @@ void CActor::UpdateArtefactsOnBeltAndOutfit()
}
}

float CActor::HitArtefactsOnBelt(float hit_power, ALife::EHitType hit_type)
float CActor::HitArtefactsOnBelt(float hit_power, ALife::EHitType hit_type)
{
TIItemContainer::iterator it = inventory().m_belt.begin();
TIItemContainer::iterator ite = inventory().m_belt.end() ;
for( ; it != ite; ++it )
float sum = 0.0f;

auto it = inventory().m_belt.begin();
auto ite = inventory().m_belt.end();

for (; it != ite; ++it)
{
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if ( artefact )
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if (artefact)
{
hit_power -= artefact->m_ArtefactHitImmunities.AffectHit( 1.0f, hit_type );
sum += (artefact->m_ArtefactHitImmunities.AffectHit(1.0f, hit_type) * artefact->GetCondition());
}
}
clamp(hit_power, 0.0f, flt_max);

return hit_power;
if (sum == 0.0f)
return hit_power;

clamp(sum, -0.99f, 0.99f);

if (sum > 0.0f)
{
sum = 1.5f * pow(0.9f, (4.0f / sum));
hit_power = hit_power * (1.0f - sum);
return hit_power;
}
else
{
sum = 1.5f * pow(0.9f, (4.0f / (-1.0f * sum)));
hit_power = hit_power * (1.0f + sum);
return hit_power;
}
}

float CActor::GetProtection_ArtefactsOnBelt( ALife::EHitType hit_type )
float CActor::GetProtection_ArtefactsOnBelt(ALife::EHitType hit_type)
{
float sum = 0.0f;
TIItemContainer::iterator it = inventory().m_belt.begin();
TIItemContainer::iterator ite = inventory().m_belt.end() ;
for( ; it != ite; ++it )
auto it = inventory().m_belt.begin();
auto ite = inventory().m_belt.end();

for (; it != ite; ++it)
{
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if ( artefact )
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if (artefact)
{
sum += artefact->m_ArtefactHitImmunities.AffectHit( 1.0f, hit_type );
sum += (artefact->m_ArtefactHitImmunities.AffectHit(1.0f, hit_type) * artefact->GetCondition());
}
}

return sum;
}

Expand Down Expand Up @@ -2081,7 +2241,7 @@ float CActor::GetRestoreSpeed( ALife::EConditionRestoreType const& type )
CArtefact* artefact = smart_cast<CArtefact*>( *itb );
if ( artefact )
{
res += artefact->m_fHealthRestoreSpeed;
res += (artefact->m_fHealthRestoreSpeed * artefact->GetCondition());
}
}
CCustomOutfit* outfit = GetOutfit();
Expand All @@ -2100,7 +2260,7 @@ float CActor::GetRestoreSpeed( ALife::EConditionRestoreType const& type )
CArtefact* artefact = smart_cast<CArtefact*>( *itb );
if ( artefact )
{
res += artefact->m_fRadiationRestoreSpeed;
res += (artefact->m_fRadiationRestoreSpeed * artefact->GetCondition());
}
}
CCustomOutfit* outfit = GetOutfit();
Expand All @@ -2121,7 +2281,7 @@ float CActor::GetRestoreSpeed( ALife::EConditionRestoreType const& type )
CArtefact* artefact = smart_cast<CArtefact*>( *itb );
if ( artefact )
{
res += artefact->m_fSatietyRestoreSpeed;
res += (artefact->m_fSatietyRestoreSpeed * artefact->GetCondition());
}
}
CCustomOutfit* outfit = GetOutfit();
Expand All @@ -2142,7 +2302,7 @@ float CActor::GetRestoreSpeed( ALife::EConditionRestoreType const& type )
CArtefact* artefact = smart_cast<CArtefact*>( *itb );
if ( artefact )
{
res += artefact->m_fPowerRestoreSpeed;
res += (artefact->m_fPowerRestoreSpeed * artefact->GetCondition());
}
}
CCustomOutfit* outfit = GetOutfit();
Expand All @@ -2167,7 +2327,7 @@ float CActor::GetRestoreSpeed( ALife::EConditionRestoreType const& type )
CArtefact* artefact = smart_cast<CArtefact*>( *itb );
if ( artefact )
{
res += artefact->m_fBleedingRestoreSpeed;
res += (artefact->m_fBleedingRestoreSpeed * artefact->GetCondition());
}
}
CCustomOutfit* outfit = GetOutfit();
Expand Down
2 changes: 2 additions & 0 deletions src/xrGame/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ struct SDefNewsMsg{

//свойства артефактов
virtual void UpdateArtefactsOnBeltAndOutfit();
void UpdateConditionArtefacts();
void HitArtefactsCondition(SHit& hit);
float HitArtefactsOnBelt (float hit_power, ALife::EHitType hit_type);
float GetProtection_ArtefactsOnBelt(ALife::EHitType hit_type);

Expand Down
2 changes: 1 addition & 1 deletion src/xrGame/Actor_Movement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ float CActor::get_additional_weight() const
{
CArtefact* artefact = smart_cast<CArtefact*>(*it);
if(artefact)
res += artefact->AdditionalInventoryWeight();
res += artefact->AdditionalInventoryWeight() * artefact->GetCondition();
}

return res;
Expand Down
10 changes: 5 additions & 5 deletions src/xrGame/ui/UIItemInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ void CUIItemInfo::InitItem(CUICellItem* pCellItem, CInventoryItem* pCompareItem,
TryAddConditionInfo (*pInvItem, pCompareItem);
TryAddWpnInfo (*pInvItem, pCompareItem);
TryAddKnifeInfo (*pInvItem, pCompareItem);
TryAddArtefactInfo (pInvItem->object().cNameSect());
TryAddArtefactInfo (*pInvItem);
TryAddOutfitInfo (*pInvItem, pCompareItem);
TryAddUpgradeInfo (*pInvItem);
TryAddBoosterInfo (*pInvItem);
Expand Down Expand Up @@ -394,11 +394,11 @@ void CUIItemInfo::TryAddKnifeInfo( CInventoryItem& pInvItem, CInventoryItem* pCo
}
}

void CUIItemInfo::TryAddArtefactInfo (const shared_str& af_section)
void CUIItemInfo::TryAddArtefactInfo (CInventoryItem& pInvItem)
{
if ( UIArtefactParams->Check( af_section ) )
if (UIArtefactParams->Check(pInvItem.object().cNameSect()))
{
UIArtefactParams->SetInfo( af_section );
UIArtefactParams->SetInfo(pInvItem);
UIDesc->AddWindow( UIArtefactParams, false );
}
}
Expand All @@ -422,7 +422,7 @@ void CUIItemInfo::TryAddOutfitInfo( CInventoryItem& pInvItem, CInventoryItem* pC

if (UIOutfitParams && outfit)
{
UIOutfitParams->SetInfo(pInvItem.object().cNameSect());
UIOutfitParams->SetInfo(pInvItem);
UIDesc->AddWindow(UIOutfitParams, false);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/xrGame/ui/UIItemInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CUIItemInfo: public CUIWindow
void TryAddConditionInfo (CInventoryItem& pInvItem, CInventoryItem* pCompareItem);
void TryAddWpnInfo (CInventoryItem& pInvItem, CInventoryItem* pCompareItem);
void TryAddKnifeInfo (CInventoryItem& pInvItem, CInventoryItem* pCompareItem);
void TryAddArtefactInfo (const shared_str& af_section);
void TryAddArtefactInfo (CInventoryItem& pInvItem);
void TryAddOutfitInfo (CInventoryItem& pInvItem, CInventoryItem* pCompareItem);
void TryAddUpgradeInfo (CInventoryItem& pInvItem);
void TryAddBoosterInfo (CInventoryItem& pInvItem);
Expand Down
Loading

0 comments on commit bf1c330

Please sign in to comment.