123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- class BleedingSourcesManagerServer extends BleedingSourcesManagerBase
- {
- const float TICK_INTERVAL_SEC = 3;
- float m_Tick;
- bool m_DisableBloodLoss = false;
- ref array<int> m_DeleteList = new array<int>;
-
- const int STORAGE_VERSION = 103;
-
- protected BleedingSourceZone GetBleedingSourceZone(int bit)
- {
- return m_BleedingSourceZone.Get(GetSelectionNameFromBit(bit));
- }
-
- int GetStorageVersion()
- {
- return STORAGE_VERSION;
- }
-
- void RequestDeletion(int bit)
- {
- m_DeleteList.Insert(bit);
- }
-
- override protected void AddBleedingSource(int bit)
- {
- #ifdef DEVELOPER
- if (m_Player && !m_Player.GetAllowDamage())//full invincibility prevents bleeding source creation
- return;
- #endif
-
- m_Player.SetBleedingBits(m_Player.GetBleedingBits() | bit );
- super.AddBleedingSource(bit);
- m_Player.OnBleedingSourceAdded();
- }
-
- override protected bool RemoveBleedingSource(int bit)
- {
- if(!super.RemoveBleedingSource(bit))
- {
- Error("Failed to remove bleeding source:" + bit);
- }
- else
- {
- m_Player.OnBleedingSourceRemovedEx(m_Item);
- }
-
- int inverse_bit_mask = ~bit;
- m_Player.SetBleedingBits(m_Player.GetBleedingBits() & inverse_bit_mask );
-
-
- //infection moved here to allow proper working in singleplayer
- float chanceToInfect;
-
- if (m_Item)
- {
- chanceToInfect = m_Item.GetInfectionChance(0, CachedObjectsParams.PARAM1_BOOL);
- }
- else
- {
- chanceToInfect = PlayerConstants.BLEEDING_SOURCE_CLOSE_INFECTION_CHANCE;
- }
- float diceRoll = Math.RandomFloat01();
- if (diceRoll < chanceToInfect)
- {
- m_Player.InsertAgent(eAgents.WOUND_AGENT);
- }
-
- m_Item = null;//reset, so that next call, if induced by self-healing, will have no item
-
- return true;
- }
-
- void RemoveAnyBleedingSource()
- {
- int bleeding_sources_bits = m_Player.GetBleedingBits();
- int rightmost_bit = bleeding_sources_bits & (-bleeding_sources_bits);
-
- RemoveBleedingSource(rightmost_bit);
- }
-
- void RemoveMostSignificantBleedingSource()
- {
- int bit = GetMostSignificantBleedingSource();
- if( bit != 0)
- RemoveBleedingSource(bit);
- }
-
- void RemoveMostSignificantBleedingSourceEx(ItemBase item)
- {
- SetItem(item);
- RemoveMostSignificantBleedingSource();
- }
-
- int GetMostSignificantBleedingSource()
- {
- int bleeding_sources_bits = m_Player.GetBleedingBits();
-
- float highest_flow;
- int highest_flow_bit;
- int bit_offset;
-
- for(int i = 0; i < BIT_INT_SIZE; i++)
- {
- int bit = 1 << bit_offset;
-
- if( (bit & bleeding_sources_bits) != 0 )
- {
- BleedingSourceZone meta = GetBleedingSourceMeta(bit);
- if(meta)
- {
- if( meta.GetFlowModifier() > highest_flow )
- {
- highest_flow = meta.GetFlowModifier();
- highest_flow_bit = bit;
- //Print(meta.GetSelectionName());
- }
- }
- }
- bit_offset++;
- }
- return highest_flow_bit;
- }
-
- void OnTick(float delta_time)
- {
- m_Tick += delta_time;
- if( m_Tick > TICK_INTERVAL_SEC )
- {
- while( m_DeleteList.Count() > 0 )
- {
- RemoveBleedingSource(m_DeleteList.Get(0));
- m_DeleteList.Remove(0);
- }
-
- float blood_scale = Math.InverseLerp(PlayerConstants.BLOOD_THRESHOLD_FATAL, PlayerConstants.BLEEDING_LOW_PRESSURE_BLOOD, m_Player.GetHealth( "GlobalHealth", "Blood" ));
- blood_scale = Math.Clamp( blood_scale, PlayerConstants.BLEEDING_LOW_PRESSURE_MIN_MOD, 1 );
- for(int i = 0; i < m_BleedingSources.Count(); i++)
- {
- m_BleedingSources.GetElement(i).OnUpdateServer( m_Tick, blood_scale, m_DisableBloodLoss );
- }
- m_Tick = 0;
- }
- }
-
- void ActivateAllBS()
- {
- for(int i = 0; i < m_BleedingSourceZone.Count(); i++)
- {
- int bit = m_BleedingSourceZone.GetElement(i).GetBit();
- if( CanAddBleedingSource(bit) )
- {
- AddBleedingSource(bit);
- }
- }
- }
-
- //damage must be to "Blood" healthType
- void ProcessHit(float damage, EntityAI source, int component, string zone, string ammo, vector modelPos)
- {
- float dmg_max = m_Player.GetMaxHealth(zone, "Blood");
- float bleed_threshold = GetGame().ConfigGetFloat("CfgAmmo " + ammo + " DamageApplied bleedThreshold");
- string damageTypeString = GetGame().ConfigGetTextOut("CfgAmmo " + ammo + " DamageApplied type");
- bleed_threshold = Math.Clamp(bleed_threshold,0,1);
- float bleedingChance;
- bool createBleedingSource = false;
-
- // 'true' only when the damageTypeString is handled there
- if (BleedChanceData.CalculateBleedChance(damageTypeString, damage, bleed_threshold,bleedingChance))
- {
- float roll = Math.RandomFloat01();
- createBleedingSource = bleedingChance != 0 && bleedingChance >= roll;
-
- #ifdef ENABLE_LOGGING
- if (LogManager.IsBleedingChancesLogEnable())
- {
- Debug.BleedingChancesLog(roll.ToString(), "BleedingSourcesManagerServer" , "n/a", "bleeding random roll:");
- }
- #endif
- }
- else if (source && source.IsZombie())
- {
- int chance = Math.RandomInt(0,100);
- if (chance <= damage)
- {
- createBleedingSource = true;
- }
- }
- else if (damage > (dmg_max * (1 - bleed_threshold)) )
- {
- createBleedingSource = true;
- }
-
- if (createBleedingSource)
- {
- #ifdef ENABLE_LOGGING
- if (LogManager.IsBleedingChancesLogEnable())
- {
- Debug.BleedingChancesLog("true", "BleedingSourcesManagerServer" , "n/a", "Attempting to create bleeding source");
- }
- #endif
- AttemptAddBleedingSource(component);
- }
- }
-
- void DebugActivateBleedingSource(int source)
- {
- RemoveAllSources();
-
- if(source >= m_BleedingSourceZone.Count() || !m_BleedingSourceZone.GetElement(source)) return;
-
- int bit = m_BleedingSourceZone.GetElement(source).GetBit();
-
- if( bit && CanAddBleedingSource(bit) )
- {
- AddBleedingSource(bit);
- }
- }
-
- void SetBloodLoss(bool status)
- {
- m_DisableBloodLoss = status;
- }
-
- void OnStoreSave( ParamsWriteContext ctx )
- {
- //int count = m_BleedingSources.Count();
- int active_bits = m_Player.GetBleedingBits();
- ctx.Write(active_bits);
-
- int bit_offset = 0;
- for(int i = 0; i < BIT_INT_SIZE; i++)
- {
- int bit = 1 << bit_offset;
- if( (bit & active_bits) != 0 )
- {
- int active_time = GetBleedingSourceActiveTime(bit);
- eBleedingSourceType type = GetBleedingSourceType(bit);
-
- ctx.Write(active_time);
- ctx.Write(type);
- }
- bit_offset++;
- }
- }
- bool OnStoreLoad( ParamsReadContext ctx, int version )
- {
- int active_bits;
- if(!ctx.Read(active_bits))
- {
- return false;
- }
-
- int bit_offset = 0;
- for(int i = 0; i < BIT_INT_SIZE; i++)
- {
- int bit = 1 << bit_offset;
- if( (bit & active_bits) != 0 && CanAddBleedingSource(bit))
- {
- AddBleedingSource(bit);
- int active_time = 0;
- if(!ctx.Read(active_time))
- {
- return false;
- }
- else
- {
- SetBleedingSourceActiveTime(bit,active_time);
- }
- if( version >= 121 )//type was added in this version
- {
- eBleedingSourceType type = eBleedingSourceType.NORMAL;
- if (!ctx.Read(type))
- {
- return false;
- }
- else
- {
- SetBleedingSourceType(bit,type);
- }
- }
- }
- bit_offset++;
- }
- return true;
- }
-
-
- void ~BleedingSourcesManagerServer()
- {
- if (m_Player && !m_Player.IsAlive())
- RemoveAllSources();
- }
- }
|