class Land_WarheadStorage_Main : House
{
protected bool m_HasPowerPrev;
protected bool m_IsLowEnergy;
protected WarheadStorageLight m_StorageDoorLights[4];
protected EffectSound m_SoundDoorLoop[4];
protected ref array<EffectSound> m_PoweredSoundEffects = new array<EffectSound>();
protected ref map<int, ref Timer> m_AutoCloseTimers;
protected const float DOOR_AUTOCLOSE_TIME = 12;//how long before the outer door auto-close after being opened
protected const int SOURCES_COUNT = 4; // storage lights, side vents, lamps
protected const string WARHEAD_BUNKER_TRIGGER = "UndergroundBunkerTrigger";
protected const string ALARM_POS_MEMPOINT = "underground";
protected const string VENT_MAIN_POS_MEMPOINT = "Ventilation_main";
protected const string VENT_POS_MEMPOINT = "Ventilation";
protected const string ALARM_DOOR_OPEN_SOUND = "UndergroundDoor_Alarm_Start_SoundSet";
protected const string ALARM_DOOR_OPEN_LOOP_SOUND = "UndergroundDoor_Alarm_Loop_SoundSet";
protected const string ALARM_DOOR_CLOSE_SOUND = "UndergroundDoor_Alarm_End_SoundSet";
protected const string VENTILATION_SOUND = "Bunker_Ventilation_SoundSet";
protected const string LAMPS_SOUND = "Bunker_Lamp_Hum_SoundSet";
protected const string ELECTRICITY_ON_SOUND = "Bunker_bunker_electricity_on_SoundSet";
protected const string ELECTRICITY_OFF_SOUND = "Bunker_bunker_electricity_off_SoundSet";
protected const string LAMP_SELECTION = "GlassLamp";
protected const string MAIN_DOOR_SELECTION1 = "maindoor1_outer";
protected const string MAIN_DOOR_SELECTION2 = "maindoor2_outer";
protected const string COLOR_LAMP_OFF = "DZ\\structures_sakhal\\military\\storage\\data\\Warhead_Storage_Lamp_Glass_int.rvmat";
protected const string COLOR_LAMP_ON = "DZ\\structures_sakhal\\military\\storage\\data\\Warhead_Storage_Lamp_Glass_e_int.rvmat";
// sync
protected bool m_HasPower;
protected bool m_LeverStatesBits;
void Land_WarheadStorage_Main()
{
RegisterNetSyncVariableBool("m_HasPower");
RegisterNetSyncVariableInt("m_LeverStatesBits");
RegisterNetSyncVariableInt("m_IsLowEnergy");
Land_WarheadStorage_PowerStation.RegisterBunker(this);
}
void ~Land_WarheadStorage_Main()
{
Land_WarheadStorage_PowerStation.UnregisterBunker(this);
for (int i; i < 4; i++)
{
if (m_StorageDoorLights[i])
m_StorageDoorLights[i].Destroy();
}
}
override void DeferredInit()
{
g_Game.RegisterNetworkStaticObject(this);
if (g_Game.IsServer())
{
UpdateDoorStateServer(); // init closed state - code randomization? of opened state messes with doors in general
for (int i = 0; i < 12; i++)
{
if (IsBunkerDoor(i))
AutoCloseDoor(i);
}
JsonUndergroundTriggers.SpawnParentedTriggers(this);
}
}
void SetPowerServer(bool hasPower)
{
m_HasPower = hasPower;
SetSynchDirty();
}
void SetLeverStatesServer(int leverBits)
{
m_LeverStatesBits = leverBits;
SetSynchDirty();
UpdateDoorStateServer();
}
void SetLowEnergyStateServer(bool state)
{
m_IsLowEnergy = state;
SetSynchDirty();
}
bool IsLowEnergy()
{
return m_IsLowEnergy;
}
protected void OnPowerOnClient()
{
EffectSound soundEff;
PlaySoundSetAtMemoryPoint(soundEff, VENTILATION_SOUND, VENT_MAIN_POS_MEMPOINT, true, 0.5, 0.5);
m_PoweredSoundEffects.Insert(soundEff);
soundEff.SetAutodestroy(true);
PlaySoundSetAtMemoryPoint(soundEff, ELECTRICITY_ON_SOUND, VENT_MAIN_POS_MEMPOINT, false);
soundEff.SetAutodestroy(true);
for (int i; i < SOURCES_COUNT; i++)
{
PlaySoundSetAtMemoryPoint(soundEff, VENTILATION_SOUND, VENT_POS_MEMPOINT + (i+1).ToString(), true, 0.5, 0.5);
m_PoweredSoundEffects.Insert(soundEff);
soundEff.SetAutodestroy(true);
PlaySoundSetAtMemoryPoint(soundEff, LAMPS_SOUND, "lamp" + (i+1).ToString() + "_pos", true, 0.1, 0.1);
m_PoweredSoundEffects.Insert(soundEff);
soundEff.SetAutodestroy(true);
}
}
protected void OnPowerOffClient()
{
foreach (EffectSound soundEff : m_PoweredSoundEffects)
{
if (soundEff)
soundEff.Stop();
}
PlaySoundSetAtMemoryPoint(soundEff, ELECTRICITY_OFF_SOUND, VENT_MAIN_POS_MEMPOINT, false);
soundEff.SetAutodestroy(true);
m_PoweredSoundEffects.Clear();
}
override void OnDoorOpenStart(DoorStartParams params)
{
#ifndef SERVER
if (IsBunkerDoor(params.param1))
{
EffectSound sound;
PlaySoundSetAtMemoryPoint(sound, ALARM_DOOR_OPEN_SOUND, ALARM_POS_MEMPOINT, false, 0, 0);
sound.SetAutodestroy(true);
int effectID = GetBunkerEffectIndexByDoor(params.param1);
PlaySoundSetAtMemoryPoint(sound, ALARM_DOOR_OPEN_LOOP_SOUND, ALARM_POS_MEMPOINT, true, 0, 0);
m_SoundDoorLoop[effectID] = sound;
m_SoundDoorLoop[effectID].SetAutodestroy(true);
}
#endif
if (!IsBunkerDoor(params.param1))
return;
if (!m_AutoCloseTimers)
m_AutoCloseTimers = new map<int, ref Timer>();
Timer doorTimer = new Timer();
doorTimer.Run(DOOR_AUTOCLOSE_TIME, this, "AutoCloseDoor", new Param1<int>(params.param1));
m_AutoCloseTimers.Set(params.param1, doorTimer);
}
override void OnDoorOpenFinish(DoorFinishParams params)
{
#ifndef SERVER
if (IsBunkerDoor(params.param1))
{
int effectID = GetBunkerEffectIndexByDoor(params.param1);
if (m_SoundDoorLoop[effectID] && m_SoundDoorLoop[effectID].IsPlaying())
{
EffectSound sound = m_SoundDoorLoop[effectID];
StopSoundSet(sound);
}
}
#endif
}
override void OnSpawnByObjectSpawner(ITEM_SpawnerObject item)
{
super.OnSpawnByObjectSpawner(item);
if (item.customString == string.Empty)
return;
JsonUndergroundTriggers jsonData = UndergroundAreaLoader.GetData();
if (jsonData && jsonData.Triggers)
{
foreach (int index, auto triggerData : jsonData.Triggers)
{
if (triggerData.CustomSpawn)
{
//JSON: "customString": "undergroundTriggerTag=TAG_NAME"
TStringArray customStringData = new TStringArray();
item.customString.Split(";", customStringData);
foreach (string entry : customStringData)
{
TStringArray optionValuePair = new TStringArray();
entry.Split("=", optionValuePair);
if (optionValuePair[0] == "undergroundTriggerTag")
{
if (optionValuePair[1] == triggerData.Tag)
{
JsonUndergroundTriggers.SpawnTriggerCarrier(this, index, triggerData);
}
}
}
}
}
}
}
protected void RemoveDoorTimer(int doorIndex)
{
if (!IsBunkerDoor(doorIndex))
return;
if (m_AutoCloseTimers)
{
m_AutoCloseTimers.Remove(doorIndex);
}
}
override void OnDoorCloseStart(DoorStartParams params)
{
#ifndef SERVER
if (IsBunkerDoor(params.param1))
{
EffectSound sound;
int effectID = GetBunkerEffectIndexByDoor(params.param1);
if (m_SoundDoorLoop[effectID] && m_SoundDoorLoop[effectID].IsPlaying()) // in case events fire in wrong order
{
sound = m_SoundDoorLoop[effectID];
StopSoundSet(sound);
}
PlaySoundSetAtMemoryPoint(sound, ALARM_DOOR_OPEN_LOOP_SOUND, ALARM_POS_MEMPOINT, true, 0, 0);
m_SoundDoorLoop[effectID] = sound;
m_SoundDoorLoop[effectID].SetAutodestroy(true);
}
#endif
RemoveDoorTimer(params.param1);
}
override void OnDoorCloseFinish(DoorFinishParams params)
{
#ifndef SERVER
if (IsBunkerDoor(params.param1))
{
EffectSound sound;
PlaySoundSetAtMemoryPoint(sound, ALARM_DOOR_CLOSE_SOUND, ALARM_POS_MEMPOINT, false, 0, 0);
sound.SetAutodestroy(true);
int effectID = GetBunkerEffectIndexByDoor(params.param1);
if (m_SoundDoorLoop[effectID] && m_SoundDoorLoop[effectID].IsPlaying())
{
sound = m_SoundDoorLoop[effectID];
StopSoundSet(sound);
}
}
#endif
}
void AutoCloseDoor(int doorIndex)
{
CloseDoor(doorIndex);
RemoveDoorTimer(doorIndex);
}
void UpdateDoorStateServer()
{
for (int index = 1; index <= 4; index++)
{
int bit = 1 << (index - 1);
int doorIndex = GetDoorIndexByLeverIndex(index);
if ( ((bit & m_LeverStatesBits) != 0) && m_HasPower )
{
if (!IsDoorOpen(doorIndex))
OpenDoor(doorIndex);
}
else
{
if (IsDoorOpen(doorIndex))
CloseDoor(doorIndex);
}
}
}
void UpdateDoorStateClient()
{
for (int index = 1; index <= 4; index++)
{
int bit = 1 << (index - 1);
int doorIndex = GetDoorIndexByLeverIndex(index);
int lightId = GetStorageLightIndexByDoor(doorIndex);
if ( ((bit & m_LeverStatesBits) != 0) && m_HasPower )
{
if (!m_StorageDoorLights[lightId])
{
m_StorageDoorLights[lightId] = WarheadStorageLight.Cast(ScriptedLightBase.CreateLightAtObjMemoryPoint(WarheadStorageLight, this, "lamp" + (lightId + 1).ToString() + "_pos"));
m_StorageDoorLights[lightId].SetSelectionID(GetHiddenSelectionIndex(LAMP_SELECTION + (lightId + 1).ToString()));
m_StorageDoorLights[lightId].UpdateLightSourceMaterial(WarheadStorageLight.LIGHT_MAT_ON);
}
}
else
{
if (m_StorageDoorLights[lightId])
{
m_StorageDoorLights[lightId].UpdateLightSourceMaterial(WarheadStorageLight.LIGHT_MAT_OFF);
m_StorageDoorLights[lightId].Destroy();
}
}
}
}
protected int GetStorageLightIndexByDoor(int doorIndex)
{
return doorIndex - 8;
}
protected int GetDoorIndexByLeverIndex(int LeverIndex)
{
switch (LeverIndex)
{
case 1:
return 8;
case 2:
return 9;
case 3:
return 10;
case 4:
return 11;
}
return -1;
}
override bool CanDoorBeOpened(int doorIndex, bool checkIfLocked = false)
{
if (!super.CanDoorBeOpened(doorIndex, checkIfLocked))
return false;
switch (doorIndex)
{
case 4:
return IsDoorClosed(4) && IsDoorClosed(5);
case 5:
return IsDoorClosed(4) && IsDoorClosed(5);
case 6:
return IsDoorClosed(6) && IsDoorClosed(7);
case 7:
return IsDoorClosed(6) && IsDoorClosed(7);
case 8:
case 9:
case 10:
case 11:
return false;
}
return true;
}
override bool CanDoorBeLocked(int doorIndex)
{
if (IsStorageDoor(doorIndex) || IsBunkerDoor(doorIndex))
return false;
return super.CanDoorBeLocked(doorIndex);
}
protected int GetBunkerEffectIndexByDoor(int doorIndex)
{
return doorIndex - 4;
}
protected bool IsBunkerDoor(int doorIndex)
{
return (doorIndex >= 4 && doorIndex <= 7);
}
protected bool IsStorageDoor(int doorIndex)
{
return (doorIndex >= 8 && doorIndex <= 11);
}
override bool CanDoorBeClosed(int doorIndex)
{
if (IsStorageDoor(doorIndex))
return false;
if (IsBunkerDoor(doorIndex))
return IsDoorOpen(doorIndex) && !IsDoorOpening(doorIndex);
return super.CanDoorBeClosed(doorIndex);
}
override string GetDebugText()
{
string debug_output;
if( g_Game.IsServer())
{
debug_output = "IsDoorOpen(4) " + IsDoorOpen(4)+ "\n";
debug_output += "IsDoorOpen(5) " + IsDoorOpen(5)+ "\n";
debug_output += "IsDoorOpen(6) " + IsDoorOpen(6)+ "\n";
debug_output += "IsDoorOpen(7) " + IsDoorOpen(7)+ "\n";
}
else
{
debug_output = "this is client";
}
return debug_output;
}
override void OnVariablesSynchronized()
{
super.OnVariablesSynchronized();
if (m_HasPower && !m_HasPowerPrev)
OnPowerOnClient();
else if(!m_HasPower && m_HasPowerPrev)
OnPowerOffClient();
m_HasPowerPrev = m_HasPower;
UpdateDoorStateClient();
}
}