// Wire type is used in the case of decrafting to give back the correct base Ingredient
enum eWireMaterial
{
WIRE = 0,
BARBED_WIRE = 1,
ROPE = 2
}
class TripwireTrap : TrapBase
{
// Current state of the tripwire
static const int FOLDED = 3;
static const int DEPLOYED = 2;
static const int TRIGGERED = 1;
int m_State = FOLDED;
private int m_WireMaterial;
protected bool m_ResultOfAdvancedPlacing;
protected vector m_TriggerPosition;
protected vector m_TriggerOrientation;
void TripwireTrap()
{
m_DamagePlayers = 0; //How much damage player gets when caught
m_InitWaitTime = 0.0; //After this time after deployment, the trap is activated
m_DefectRate = 15;
m_NeedActivation = false;
m_AnimationPhaseGrounded = "inventory";
m_AnimationPhaseSet = "placing";
m_AnimationPhaseTriggered = "triggered";
m_InfoActivationTime = string.Format("#STR_TripwireTrap0%1#STR_TripwireTrap1", m_InitWaitTime.ToString()); // nefunguje dynamicke vyrazy mimo funkcii
RegisterNetSyncVariableInt("m_State");
}
override void OnStoreSave(ParamsWriteContext ctx)
{
super.OnStoreSave(ctx);
ctx.Write( m_State );
}
//----------------------------------------------------------------
override bool OnStoreLoad(ParamsReadContext ctx, int version)
{
if ( !super.OnStoreLoad(ctx, version) )
return false;
int state = FOLDED;
if ( !ctx.Read( state ) )
state = FOLDED;
SetState( state );
RefreshState();
return true;
}
override void CreateTrigger()
{
m_TrapTrigger = TripWireTrigger.Cast(g_Game.CreateObjectEx("TripWireTrigger", GetPosition(), SPAWN_FLAGS));
vector mins = "-0.75 0.3 -0.01";
vector maxs = "0.75 0.32 0.01";
m_TrapTrigger.SetOrientation(GetOrientation());
m_TrapTrigger.SetExtents(mins, maxs);
m_TrapTrigger.SetParentObject(this);
g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Call(DeferredEnableTrigger);
}
override void OnSteppedOn(EntityAI victim)
{
if (!victim)
{
return;
}
if (!victim.GetAllowDamage())
{
return;
}
// We must deal some damage, here 5 shock as melee damage in order to trigger hit animation
if (g_Game.IsServer())
{
victim.ProcessDirectDamage(DamageType.CLOSE_COMBAT, this, "", "TripWireHit", "0 0 0", 1);
SetState(TRIGGERED);
SetInactive(false);
}
// We play the trap trigger sound
#ifndef SERVER
EffectSound sound = SEffectManager.PlaySound("TripwireTrap_Trigger_SoundSet", GetPosition());
sound.SetAutodestroy(true);
#endif
}
override void OnItemLocationChanged(EntityAI old_owner, EntityAI new_owner)
{
super.OnItemLocationChanged(old_owner, new_owner);
PlayerBase player = PlayerBase.Cast(new_owner);
if (player)
{
StartDeactivate(player);
return;
}
}
override void EEItemLocationChanged(notnull InventoryLocation oldLoc, notnull InventoryLocation newLoc)
{
super.EEItemLocationChanged(oldLoc, newLoc);
if (m_ResultOfAdvancedPlacing)
{
if (oldLoc.GetType() == InventoryLocationType.GROUND && newLoc.GetType() == InventoryLocationType.GROUND)
{
SetActive();
m_TrapTrigger.SetPosition(m_TriggerPosition);
m_TrapTrigger.SetOrientation(m_TriggerOrientation);
}
m_ResultOfAdvancedPlacing = false;
}
if (oldLoc.GetType() == InventoryLocationType.GROUND && newLoc.GetType() == InventoryLocationType.CARGO)
{
SetInactive();
DeleteTrigger();
SetState(FOLDED);
RefreshState();
}
}
override void EEHealthLevelChanged(int oldLevel, int newLevel, string zone)
{
super.EEHealthLevelChanged(oldLevel, newLevel, zone);
if (g_Game.IsServer())
{
if (newLevel == GameConstants.STATE_RUINED)
{
SetState(TRIGGERED);
RefreshState();
}
}
}
override void SetInactive(bool stop_timer = true)
{
super.SetInactive(stop_timer);
// de-attach attachments after "activating them"
GameInventory inventory = GetInventory();
for (int att = 0; att < inventory.AttachmentCount(); ++att)
{
ItemBase attachment = ItemBase.Cast(inventory.GetAttachmentFromIndex(att));
if (attachment)
{
if (attachment.IsLockedInSlot())
{
attachment.UnlockFromParent();
}
attachment.OnActivatedByItem(this);
inventory.DropEntity(InventoryMode.SERVER, this, attachment);
}
}
}
void SetState(int state_ID)
{
m_State = state_ID;
}
int GetState()
{
return m_State;
}
void SetWireType( int wireType )
{
m_WireMaterial = wireType;
}
int GetWireType()
{
return m_WireMaterial;
}
override void RefreshState()
{
super.RefreshState();
if (GetState() == FOLDED)
{
FoldTripWire();
}
}
override void SetupTrapPlayer( PlayerBase player, bool set_position = true )
{
super.SetupTrapPlayer( player, set_position );
SetState(DEPLOYED);
}
override void StartDeactivate(PlayerBase player)
{
super.StartDeactivate(player);
DeleteTrigger();
SetState(FOLDED);
}
// We do not want players to attach charges before trap is deployed
override bool CanReceiveAttachment( EntityAI attachment, int slotId )
{
if ( GetState() != DEPLOYED )
return false;
return super.CanReceiveAttachment( attachment, slotId );
}
// As players cannot attch charges, we do not display the attachment slot before it is necessary
override bool CanDisplayAttachmentSlot( int slot_id )
{
if ( GetState() != DEPLOYED )
return false;
return super.CanDisplayAttachmentSlot( slot_id );
}
override void EEItemAttached(EntityAI item, string slot_name)
{
super.EEItemAttached(item, slot_name);
SetTakeable(false);
}
override void EEItemDetached(EntityAI item, string slot_name)
{
super.EEItemDetached(item, slot_name);
SetTakeable(false);
}
override void EEKilled(Object killer)
{
if (m_TrapTrigger)
{
StartDeactivate(null);
}
super.EEKilled(killer);
}
// We reset the animation phases to see the tripwire as folded
void FoldTripWire()
{
if ( m_AnimationPhaseGrounded != "" )
{
SetAnimationPhase( m_AnimationPhaseSet, 1 );
if ( m_AnimationPhaseTriggered != m_AnimationPhaseGrounded )
{
SetAnimationPhase( m_AnimationPhaseTriggered, 1 );
}
SetAnimationPhase( m_AnimationPhaseGrounded, 0 );
}
}
override void OnInventoryEnter( Man player )
{
SetState( FOLDED );
}
#ifdef PLATFORM_WINDOWS
// How one sees the tripwire when in vicinity
override int GetViewIndex()
{
if ( MemoryPointExists( "invView2" ) )
{
InventoryLocation il = new InventoryLocation;
GetInventory().GetCurrentInventoryLocation( il );
InventoryLocationType type = il.GetType();
switch ( type )
{
case InventoryLocationType.CARGO:
{
return 0;
}
case InventoryLocationType.ATTACHMENT:
{
return 1;
}
case InventoryLocationType.HANDS:
{
return 0;
}
case InventoryLocationType.GROUND:
{
// Different view index depending on deployment state
if ( GetState() == DEPLOYED )
return 1;
else if ( GetState() == TRIGGERED )
return 2;
// When folded
return 0;
}
case InventoryLocationType.PROXYCARGO:
{
return 0;
}
default:
{
if ( GetState() == DEPLOYED )
return 1;
else if ( GetState() == TRIGGERED )
return 2;
// When folded
return 0;
}
}
}
return 0;
}
#endif
//================================================================
// ADVANCED PLACEMENT
//================================================================
// On placement complete, set state, play sound, create trigger and synch to client
override void OnPlacementComplete(Man player, vector position = "0 0 0", vector orientation = "0 0 0")
{
if (g_Game.IsServer())
{
SetState(DEPLOYED);
m_TriggerPosition = position;
m_TriggerOrientation = orientation;
m_ResultOfAdvancedPlacing = true;
}
super.OnPlacementComplete(player, position, orientation);
}
override void OnPlacementCancelled(Man player)
{
super.OnPlacementCancelled(player);
SetState(FOLDED);
m_ResultOfAdvancedPlacing = false;
}
override bool IsDeployable()
{
return true;
}
// Tripwire cannot be taken if deployed with attachment
override bool IsTakeable()
{
return GetState() != DEPLOYED || (GetInventory().AttachmentCount() == 0 && GetState() == DEPLOYED);
}
override string GetDeploySoundset()
{
return "tripwire_deploy_SoundSet";
}
override string GetLoopDeploySoundset()
{
return "tripwiretrap_deploy_SoundSet";
}
override void SetActions()
{
super.SetActions();
AddAction(ActionTogglePlaceObject);
AddAction(ActionDeployObject);
}
// ====================================
// =========== DEPRECATED ===========
// ====================================
void UpdateProxySelections()
{
if ( GetInventory().AttachmentCount() > 0)
{
ItemBase attachment = ItemBase.Cast( GetInventory().GetAttachmentFromIndex(0) );
if ( attachment )
{
// Hide all proxies
for (int i = 1; i <= 3; i++)
{
HideSelection("s" + i + "_charge");
}
// Now show the one we need to see
string proxy_to_show = string.Format("s%1_charge", GetState() );
//Print(proxy_to_show);
ShowSelection( proxy_to_show );
}
}
}
#ifdef DEVELOPER
//================================================================
// DEBUG
//================================================================
//Debug menu Spawn Ground Special
override void OnDebugSpawn()
{
SetState(DEPLOYED);
StartActivate(null);
}
override void GetDebugActions(out TSelectableActionInfoArrayEx outputList)
{
outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.ACTIVATE_ENTITY, "Activate", FadeColors.LIGHT_GREY));
outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.DEACTIVATE_ENTITY, "Deactivate", FadeColors.LIGHT_GREY));
outputList.Insert(new TSelectableActionInfoWithColor(SAT_DEBUG_ACTION, EActions.SEPARATOR, "___________________________", FadeColors.RED));
super.GetDebugActions(outputList);
}
override bool OnAction(int action_id, Man player, ParamsReadContext ctx)
{
if (super.OnAction(action_id, player, ctx))
return true;
if (g_Game.IsServer() || !g_Game.IsMultiplayer())
{
if (action_id == EActions.ACTIVATE_ENTITY)
{
StartActivate(null);
}
else if (action_id == EActions.DEACTIVATE_ENTITY)
{
SetInactive();
}
}
return false;
}
#endif
}
class TripwireTrapDeployed : TripwireTrap
{
}