AreaExposure.c
class AreaExposureMdfr: ModifierBase
{
const int EVENT_1_INTERVAL_MIN = 3;
const int EVENT_1_INTERVAL_MAX = 5;
const float AGENTS_PER_SEC = 5;
protected float m_NextEvent1;
protected float m_Time1;
const int EVENT_2_INTERVAL_MIN = 13;
const int EVENT_2_INTERVAL_MAX = 18;
const float AGENT_DOSE_PER_BS_SEC = 0.33;//how many agents will be injected in one sec per a single bleeding source
protected float m_NextEvent2;
protected float m_Time2;
override void Init()
{
m_TrackActivatedTime = false;
m_AnalyticsStatsEnabled = true;
m_ID = eModifiers.MDF_AREAEXPOSURE;
m_TickIntervalInactive = DEFAULT_TICK_TIME_INACTIVE_LONG;
m_TickIntervalActive = DEFAULT_TICK_TIME_ACTIVE_SHORT;
m_SyncID = eModifierSyncIDs.MODIFIER_SYNC_ZONE_EXPOSURE;
DisableActivateCheck();
DisableDeactivateCheck();
}
override bool ActivateCondition(PlayerBase player)
{
return false;
}
override void OnActivate(PlayerBase player)
{
JsonDataContaminatedAreas data = EffectAreaLoader.GetData();
if (data)
{
MiscGameplayFunctions.TeleportCheck(player, data.SafePositions);
player.SetPersistentFlag(PersistentFlag.AREA_PRESENCE, false);
}
//make the player cough immediately
float transmitted = TransmitAgents(player, 1);
if(transmitted)
player.GetSymptomManager().QueueUpPrimarySymptom(SymptomIDs.SYMPTOM_COUGH);
m_NextEvent1 = Math.RandomFloatInclusive( EVENT_1_INTERVAL_MIN, EVENT_1_INTERVAL_MAX );
}
override void OnDeactivate(PlayerBase player)
{
}
override bool DeactivateCondition(PlayerBase player)
{
return false;
}
override void OnTick(PlayerBase player, float deltaT)
{
#ifdef DEVELOPER
if(!player.GetCanBeDestroyed())
return;
#endif
float transmitted = TransmitAgents(player, AGENTS_PER_SEC * deltaT);
m_Time2 += deltaT;
if (transmitted)
{
m_Time1 += deltaT;
if (m_Time1 >= m_NextEvent1 )
{
player.GetSymptomManager().QueueUpPrimarySymptom(SymptomIDs.SYMPTOM_COUGH);
if(Math.RandomFloat01() < 0.25)//creates a cough cooldown once in a while
{
m_NextEvent1 = Math.RandomFloatInclusive( EVENT_1_INTERVAL_MIN * 2, EVENT_1_INTERVAL_MAX * 2 );
}
else
{
m_NextEvent1 = Math.RandomFloatInclusive( EVENT_1_INTERVAL_MIN, EVENT_1_INTERVAL_MAX );
}
m_Time1 = 0;
}
}
if ( m_Time2 >= m_NextEvent2 )
{
BleedingSourceCreateCheck(player);
m_Time2 = 0;
m_NextEvent2 = Math.RandomFloatInclusive( EVENT_2_INTERVAL_MIN, EVENT_2_INTERVAL_MAX );
}
ApplyAgentsToBleedingSources(player, deltaT);
}
void ApplyAgentsToBleedingSources(PlayerBase player, float deltaT)
{
int count = player.GetBleedingSourceCount();
float agent_dose = count * AGENT_DOSE_PER_BS_SEC * deltaT;
player.InsertAgent(eAgents.CHEMICAL_POISON, agent_dose);
}
void BleedingSourceCreateCheck(PlayerBase player)
{
int free_bs_locations = 0;//bitmask where each bit set to 1 represents available bleeding source location
set<int> list = player.GetBleedingManagerServer().GetBleedingSourcesLocations();
foreach(int location: list)
{
float prot_level = PluginTransmissionAgents.GetProtectionLevelEx(DEF_CHEMICAL, location, player, true);
float dice_throw = Math.RandomFloat01();
if(dice_throw > prot_level)
{
free_bs_locations = player.GetBleedingManagerServer().GetFreeBleedingSourceBitsByInvLocation(location) | free_bs_locations;
}
}
int num_of_free_bs = Math.GetNumberOfSetBits(free_bs_locations);//gets us the number of bits set to 1, where each represents a free bleeding source location
if ( num_of_free_bs > 0 )
{
int random_bs_index = Math.RandomIntInclusive(0, num_of_free_bs - 1 );// - 1 on the max to convert count to index
int random_bs_bit = Math.Pow(2, Math.GetNthBitSet(free_bs_locations,random_bs_index));
player.GetBleedingManagerServer().AttemptAddBleedingSourceDirectly(random_bs_bit, eBleedingSourceType.CONTAMINATED);
}
}
float TransmitAgents(PlayerBase player, float count)
{
PluginTransmissionAgents plugin = PluginTransmissionAgents.Cast(GetPlugin(PluginTransmissionAgents));
return plugin.TransmitAgentsEx(null, player, AGT_AIRBOURNE_CHEMICAL, count, eAgents.CHEMICAL_POISON);
}
};