class Plastic_Explosive : ExplosivesBase
{
protected const string SLOT_TRIGGER = "TriggerRemoteDetonator_Receiver";
protected const string ANIM_PHASE_TRIGGER_REMOTE = "TriggerRemote";
protected bool m_UsedAsCharge;
protected ref RemotelyActivatedItemBehaviour m_RAIB;
void Plastic_Explosive()
{
m_RAIB = new RemotelyActivatedItemBehaviour(this);
SetAmmoType("Plastic_Explosive_Ammo");
SetParticleExplosion(ParticleList.PLASTIC_EXPLOSION);
RegisterNetSyncVariableInt("m_RAIB.m_PairDeviceNetIdLow");
RegisterNetSyncVariableInt("m_RAIB.m_PairDeviceNetIdHigh");
}
override void EOnInit(IEntity other, int extra)
{
if (!g_Game.IsMultiplayer())
LockTriggerSlots();
}
//! special behaviour - do not call super from ExplosivesBase
override void EEKilled(Object killer)
{
//analytics (behaviour from EntityAI)
g_Game.GetAnalyticsServer().OnEntityKilled(killer, this);
}
override bool HasLockedTriggerSlots()
{
return GetInventory().GetSlotLock(InventorySlots.GetSlotIdFromString(SLOT_TRIGGER));
}
override void LockTriggerSlots()
{
GetInventory().SetSlotLock(InventorySlots.GetSlotIdFromString(SLOT_TRIGGER), true);
}
override void UnlockTriggerSlots()
{
GetInventory().SetSlotLock(InventorySlots.GetSlotIdFromString(SLOT_TRIGGER), false);
}
override bool OnStoreLoad(ParamsReadContext ctx, int version)
{
if (!super.OnStoreLoad(ctx, version))
return false;
if (version <= 134) // up to 1.21
{
int slotId = InventorySlots.GetSlotIdFromString(SLOT_TRIGGER);
bool locked = GetInventory().GetSlotLock(slotId);
while (locked)
{
GetInventory().SetSlotLock(slotId, false);
locked = GetInventory().GetSlotLock(slotId);
}
}
return true;
}
override void OnStoreSave(ParamsWriteContext ctx)
{
super.OnStoreSave(ctx);
LockTriggerSlots();
}
override void OnVariablesSynchronized()
{
super.OnVariablesSynchronized();
if (m_RAIB)
{
m_RAIB.OnVariableSynchronized();
}
int slotId = InventorySlots.GetSlotIdFromString(SLOT_TRIGGER);
UpdateVisuals(GetInventory().FindAttachment(slotId));
}
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
{
super.EEItemLocationChanged(oldLoc, newLoc);
if (m_RAIB)
{
m_RAIB.Pair();
}
}
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
{
InventoryLocation il = new InventoryLocation();
GetInventory().GetCurrentInventoryLocation(il);
if (il.GetType() != InventoryLocationType.GROUND)
{
return false;
}
ClockBase timer = ClockBase.Cast(attachment);
if (timer && !timer.IsAlarmOn())
{
return false;
}
return !GetArmed();
}
override bool CanDisplayAttachmentSlot(int slot_id)
{
string slotName = InventorySlots.GetSlotName(slot_id);
switch (slotName)
{
case SLOT_TRIGGER:
return FindAttachmentBySlotName(slotName) != null;
break;
}
return true;
}
override bool IsTakeable()
{
return !GetArmed() && super.IsTakeable();
}
override bool IsDeployable()
{
return !GetArmed();
}
override void SetActions()
{
super.SetActions();
AddAction(ActionTogglePlaceObject);
AddAction(ActionDeployObject);
}
override void OnWasAttached(EntityAI parent, int slot_id)
{
super.OnWasAttached(parent, slot_id);
m_UsedAsCharge = false;
if (parent && parent.IsInherited(ExplosivesBase))
{
m_UsedAsCharge = true;
}
}
override void OnWasDetached(EntityAI parent, int slot_id)
{
super.OnWasDetached(parent, slot_id);
if (parent && !parent.IsInherited(ExplosivesBase))
{
m_UsedAsCharge = false;
}
}
override bool EEOnDamageCalculated(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
{
//! ignores explosion damage from other Plastic_Explosive that are used as charge(like 2 PE fired via IED)
if (damageType == DamageType.EXPLOSION)
{
return !m_UsedAsCharge;
}
return true;
}
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
{
super.EEHealthLevelChanged(oldLevel, newLevel, zone);
if (g_Game.IsServer())
{
if (newLevel == GameConstants.STATE_RUINED)
{
for (int attachmentIdx = 0; attachmentIdx < GetInventory().AttachmentCount(); attachmentIdx++)
{
ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(attachmentIdx));
if (attachment)
{
attachment.UnlockFromParent();
attachment.SetHealth("", "", 0.0);
}
}
SetArmed(false);
SetTakeable(true);
}
}
}
override RemotelyActivatedItemBehaviour GetRemotelyActivatedItemBehaviour()
{
return m_RAIB;
}
override void PairRemote(notnull EntityAI trigger)
{
m_RAIB.Pair(trigger);
}
override EntityAI GetPairDevice()
{
return m_RAIB.GetPairDevice();
}
override bool CanBeArmed()
{
if (!super.CanBeArmed())
{
return false;
}
return HasLockedTriggerSlots() && !GetArmed();
}
override bool CanBeDisarmed()
{
return GetArmed();
}
override void OnActivatedByItem(notnull ItemBase item)
{
if (g_Game.IsServer())
{
if (GetHealthLevel("") == GameConstants.STATE_RUINED)
{
return;
}
if (item == this)
{
SetHealth("", "", 0.0);
InitiateExplosion();
return;
}
if (m_RAIB.IsPaired() && GetArmed())
{
if (GetPairDevice() == item)
{
SetHealth("", "", 0.0);
InitiateExplosion();
}
}
}
}
override void OnDisarmed(bool pWithTool)
{
super.OnDisarmed(pWithTool);
UnpairRemote();
UpdateVisuals(null);
for (int att = 0; att < GetInventory().AttachmentCount(); att++)
{
ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(att));
if (attachment)
{
attachment.UnlockFromParent();
if (attachment.IsInherited(RemoteDetonator))
{
if (pWithTool)
{
GetInventory().DropEntity(InventoryMode.SERVER, this, attachment);
attachment.SetHealth("", "", 0.0);
}
else
{
attachment.Delete();
}
}
}
}
LockTriggerSlots();
SetTakeable(true);
}
override void EEItemAttached(EntityAI item, string slot_name)
{
super.EEItemAttached(item, slot_name);
if (slot_name == SLOT_TRIGGER)
OnTriggerAttached(item);
}
override void EEItemDetached(EntityAI item, string slot_name)
{
super.EEItemDetached(item, slot_name);
if (slot_name == SLOT_TRIGGER)
OnTriggerDetached(item);
}
override void UpdateLED(int pState)
{
RemoteDetonatorReceiver receiver = RemoteDetonatorReceiver.Cast(FindAttachmentBySlotName(SLOT_TRIGGER));
if (receiver)
{
receiver.UpdateLED(pState, true);
}
}
protected void OnTriggerAttached(EntityAI entity)
{
Arm();
UpdateVisuals(entity);
UpdateLED(ERemoteDetonatorLEDState.LIT);
for (int att = 0; att < GetInventory().AttachmentCount(); att++)
{
ItemBase attachment = ItemBase.Cast(GetInventory().GetAttachmentFromIndex(att));
if (attachment)
{
attachment.LockToParent();
}
}
}
protected void OnTriggerDetached(EntityAI entity)
{
UpdateVisuals(null);
UpdateLED(ERemoteDetonatorLEDState.OFF);
}
protected void UpdateVisuals(EntityAI entity)
{
if (entity)
{
SetAnimationPhase(ANIM_PHASE_TRIGGER_REMOTE, 0.0);
}
else
{
SetAnimationPhase(ANIM_PHASE_TRIGGER_REMOTE, 1.0);
}
}
override string GetDeploySoundset()
{
return "placePlasticExplosive_SoundSet";
}
override string GetLoopDeploySoundset()
{
return "plasticexplosive_deploy_SoundSet";
}
override string GetArmSoundset()
{
return "ImprovisedExplosive_disarm_SoundSet";
}
override string GetDisarmSoundset()
{
return "ImprovisedExplosive_disarm_SoundSet";
}
}
class Plastic_Explosive_Placing : Plastic_Explosive {}