ClaymoreMine.c
class ClaymoreMine : ExplosivesBase
{
protected const string ANIM_PHASE_PACKED = "Bag";
protected const string ANIM_PHASE_DEPLOYED = "Mine";
protected const string SELECTION_NAME_LED = "LED";
protected ref RemotelyActivatedItemBehaviour m_RAIB;
protected ERemoteDetonatorLEDState m_LastLEDState;
void ClaymoreMine()
{
m_RAIB = new RemotelyActivatedItemBehaviour(this);
SetAmmoTypes({"ClaymoreMine_Ammo","ClaymoreMine_Secondary_Ammo"});
SetParticleExplosion(ParticleList.CLAYMORE_EXPLOSION);
SetParticleOrientation("90 0 0");
RegisterNetSyncVariableInt("m_RAIB.m_PairDeviceNetIdLow");
RegisterNetSyncVariableInt("m_RAIB.m_PairDeviceNetIdHigh");
UpdateLED(ERemoteDetonatorLEDState.OFF, true);
}
override void EOnInit(IEntity other, int extra)
{
UpdateVisuals();
}
override void EEKilled(Object killer)
{
super.EEKilled(killer);
#ifdef DIAG_DEVELOPER
#ifndef SERVER
RemoveDebugVisuals();
#endif
#endif
}
override void EEDelete(EntityAI parent)
{
super.EEDelete(parent);
#ifdef DIAG_DEVELOPER
#ifndef SERVER
RemoveDebugVisuals();
#endif
#endif
}
override protected void InitiateExplosion()
{
if (GetDefused())
{
return;
}
super.InitiateExplosion();
}
override void AfterStoreLoad()
{
super.AfterStoreLoad();
UpdateVisuals();
if (GetArmed())
{
UpdateLED(ERemoteDetonatorLEDState.LIT, true);
}
}
override void OnVariablesSynchronized()
{
super.OnVariablesSynchronized();
if (m_RAIB)
{
m_RAIB.OnVariableSynchronized();
}
UpdateVisuals();
}
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
{
super.EEItemLocationChanged(oldLoc, newLoc);
if (m_RAIB)
{
m_RAIB.Pair();
}
}
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 CanBeDisarmed()
{
return GetArmed();
}
override void OnActivatedByItem(notnull ItemBase item)
{
if (g_Game.IsServer())
{
if (m_RAIB.IsPaired() && GetArmed())
{
if (GetPairDevice() == item)
{
SetHealth("", "", 0.0);
}
}
}
}
override void OnArmed()
{
super.OnArmed();
UpdateVisuals();
UpdateLED(ERemoteDetonatorLEDState.LIT, true);
#ifdef DIAG_DEVELOPER
#ifndef SERVER
// have to call this function a little later, after claymore transform has been finalized
g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(DrawDamageZone, 500);
#endif
#endif
}
override void OnDisarmed(bool pWithTool)
{
super.OnDisarmed(pWithTool);
#ifdef DIAG_DEVELOPER
RemoveDebugVisuals();
#endif
SetDefused(pWithTool);
UnpairRemote();
if (pWithTool)
{
SetHealth("", "", 0.0);
}
UpdateVisuals();
UpdateLED(ERemoteDetonatorLEDState.OFF, true);
}
override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
{
super.OnPlacementComplete(player, position, orientation);
if (g_Game.IsServer())
{
RemoteDetonatorTrigger rdt = RemoteDetonatorTrigger.SpawnInPlayerHands(player);
if (rdt)
{
PairWithDevice(rdt);
Arm();
}
}
}
protected void UpdateVisuals()
{
if (GetArmed() || GetDefused())
{
ShowSelection(ANIM_PHASE_DEPLOYED);
HideSelection(ANIM_PHASE_PACKED);
if (GetOnViewIndexChanged())
{
GetOnViewIndexChanged().Invoke();
}
}
else
{
HideSelection(ANIM_PHASE_DEPLOYED);
ShowSelection(ANIM_PHASE_PACKED);
if (GetOnViewIndexChanged())
{
GetOnViewIndexChanged().Invoke();
}
}
}
protected void UpdateLED(ERemoteDetonatorLEDState pState, bool pForced = false)
{
if (pState != m_LastLEDState || pForced)
{
int selectionIdx = GetHiddenSelectionIndex(SELECTION_NAME_LED);
switch (pState)
{
case ERemoteDetonatorLEDState.LIT:
SetObjectTexture(selectionIdx, RemoteDetonator.COLOR_LED_LIT);
break;
default:
SetObjectTexture(selectionIdx, RemoteDetonator.COLOR_LED_OFF);
break;
}
m_LastLEDState = pState;
}
}
override bool IsTakeable()
{
return !GetArmed() && super.IsTakeable();
}
override bool IsDeployable()
{
return true;
}
override void SetActions()
{
super.SetActions();
AddAction(ActionTogglePlaceObject);
AddAction(ActionDeployObject);
AddAction(ActionArmExplosive);
}
override int GetViewIndex()
{
if (MemoryPointExists("invView2"))
{
if (GetArmed())
{
return 1;
}
}
return 0;
}
override string GetDeploySoundset()
{
return "placeClaymore_SoundSet";
}
override string GetLoopDeploySoundset()
{
return "claymore_deploy_Soundset";
}
override string GetArmSoundset()
{
return "claymore_disarm_SoundSet";
}
override string GetDisarmSoundset()
{
return "claymore_disarm_SoundSet";
}
override string GetDisarmSoundsetUnpaired()
{
return "claymore_disarm_long_SoundSet";
}
override void OnDebugSpawn()
{
RemoteDetonatorTrigger rdt = RemoteDetonatorTrigger.Cast(SpawnEntityOnGroundPos("RemoteDetonatorTrigger", GetPosition() + GetDirection() * 0.5));
PairWithDevice(rdt);
Arm();
}
#ifdef DIAG_DEVELOPER
//================================================================
// DEBUG
//================================================================
protected Shape m_DamageZone;
override protected string GetDebugText()
{
string debug_output;
debug_output += string.Format("low net id: %1\n", m_RAIB.GetPairDeviceNetIdLow());
debug_output += string.Format("high net id: %1\n", m_RAIB.GetPairDeviceNetIdHigh());
debug_output += string.Format("pair device: %1\n", m_RAIB.GetPairDevice());
return debug_output;
}
protected void DrawDamageZone()
{
if (!DiagMenu.GetBool(DiagMenuIDs.WEAPON_CLAYMORE_DEBUG))
{
return;
}
string cfgPath = "CfgAmmo " + m_AmmoTypes[0];
float hitRange = g_Game.ConfigGetFloat(cfgPath + " indirectHitRange");
float hitRangeMultiplier = g_Game.ConfigGetFloat(cfgPath + " indirectHitRangeMultiplier");
float verticalAngle = g_Game.ConfigGetFloat(cfgPath + " indirectHitAngle1");
float horizontalAngle = g_Game.ConfigGetFloat(cfgPath + " indirectHitAngle2");
float range = hitRange * hitRangeMultiplier;
vector selfMatrix[4];
RemoveDebugVisuals();
GetTransform(selfMatrix);
m_DamageZone = Debug.DrawFrustum(horizontalAngle, verticalAngle, range);
m_DamageZone.SetMatrix(selfMatrix);
}
void RemoveDebugVisuals()
{
if ( m_DamageZone )
{
m_DamageZone.Destroy();
m_DamageZone = null;
}
}
#endif
}
class ClaymoreMinePlacing : ClaymoreMine {}