Skip to content

Instantly share code, notes, and snippets.

@SalahAdDin
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SalahAdDin/7cb06e30c2e228508967 to your computer and use it in GitHub Desktop.
Save SalahAdDin/7cb06e30c2e228508967 to your computer and use it in GitHub Desktop.
Mina de Proximidad para CryEngine
#include "StdAfx.h"
#include "Nodes\G2FlowBaseNode.h"
class CFlowMineListener : public CFlowBaseNode < eNCT_Instanced >, public IEntityEventListener
{
public:
CFlowMineListener(SActivationInfo *pActInfo):
pTargetEnt(nullptr)
{
}
~CFlowMineListener(){
if (pTargetEnt)
gEnv->pEntitySystem->RemoveEntityEventListener(pTargetEnt->GetId(), ENTITY_EVENT_MINE_PLACED, this);
}
virtual IFlowNodePtr Clone(SActivationInfo *pActInfo){
return new CFlowMineListener(pActInfo);
}
virtual void GetConfiguration(SFlowNodeConfig& Config){
static const SOutputPortConfig Outputs[] = {
OutputPortConfig_Void("MinePlaced", _HELP("Triggered when a Mine is placed. ")),
OutputPortConfig<EntityId>("Placer", _HELP("EntityId of the Entity that placed the Mine. ")),
OutputPortConfig<EntityId>("Mine", _HELP("EntityId of the Mine that was placed. "))
};
Config.pOutputPorts = Outputs;
Config.SetCategory(EFLN_APPROVED);
Config.sDescription = _HELP("Listens for Mines to be placed.");
Config.nFlags |= EFLN_TARGET_ENTITY;
}
enum EOP
{
EOP_MINEPLACED = 0,
EOP_PLACER,
EOP_MINE
};
virtual void Serialize(SActivationInfo *, TSerialize ser){
}
virtual void ProcessEvent(EFlowEvent event, SActivationInfo *pActInfo){
switch (event)
{
case IFlowNode::eFE_Update:
break;
case IFlowNode::eFE_Activate:
break;
case IFlowNode::eFE_FinalActivate:
break;
case IFlowNode::eFE_PrecacheResources:
break;
case IFlowNode::eFE_Initialize:
{
ActInfo = *pActInfo;
}
break;
case IFlowNode::eFE_FinalInitialize:
break;
case IFlowNode::eFE_SetEntityId:
{
if (pTargetEnt)
gEnv->pEntitySystem->RemoveEntityEventListener(pTargetEnt->GetId(), ENTITY_EVENT_MINE_PLACED, this);
if (pActInfo->pEntity)
gEnv->pEntitySystem->AddEntityEventListener(pActInfo->pEntity->GetId(), ENTITY_EVENT_MINE_PLACED, this);
pTargetEnt = pActInfo->pEntity;
}
break;
case IFlowNode::eFE_Suspend:
break;
case IFlowNode::eFE_Resume:
break;
case IFlowNode::eFE_ConnectInputPort:
break;
case IFlowNode::eFE_DisconnectInputPort:
break;
case IFlowNode::eFE_ConnectOutputPort:
break;
case IFlowNode::eFE_DisconnectOutputPort:
break;
case IFlowNode::eFE_DontDoAnythingWithThisPlease:
break;
default:
break;
}
}
virtual void GetMemoryUsage(ICrySizer * s) const {
s->Add(this);
}
virtual void OnEntityEvent(IEntity *pEntity, SEntityEvent &event){
EEntityEvent Event = event.event;
if (event.event == ENTITY_EVENT_MINE_PLACED){
if (pTargetEnt){
ActivateOutput(&ActInfo, EOP_PLACER, pTargetEnt->GetId());
/*ActivateOutput(&ActInfo, EOP_MINE, event.nParam[0]);*/
ActivateOutput(&ActInfo, EOP_MINEPLACED, NULL);
}
}
}
private:
SActivationInfo ActInfo;
IEntity *pTargetEnt;
};
REGISTER_FLOW_NODE("Packt:MineLister", CFlowMineListener);
/*************************************************************************
Crytek Source File.
Copyright (C), Crytek Studios, 2001-2010.
-------------------------------------------------------------------------
History:
October 2010 : Jens Schöbel added move overlay
*************************************************************************/
#include "StdAfx.h"
#include "PlayerInput.h"
#include "Player.h"
#include "PlayerStateEvents.h"
#include "Game.h"
#include "GameCVars.h"
#include "GameActions.h"
#include "GameInputActionHandlers.h"
#include "Weapon.h"
#include "WeaponSystem.h"
#include "IVehicleSystem.h"
#include "VehicleClient.h"
#include "UI/HUD/HUDSilhouettes.h"
#include "GameRules.h"
#include "ScreenEffects.h"
#include "PlayerMovementController.h"
#include "GunTurret.h"
#include "GameRulesModules/IGameRulesActorActionModule.h"
#include "GameRulesModules/IGameRulesSpectatorModule.h"
#include "Utility/CryWatch.h"
#include "UI/HUD//HUDEventWrapper.h"
#include <IWorldQuery.h>
#include <IInteractor.h>
#include "RecordingSystem.h"
#include "GodMode.h"
#include "GameCodeCoverage/GameCodeCoverageTracker.h"
#include "IAIActor.h"
#include "AI/GameAISystem.h"
#include "StatsRecordingMgr.h"
#include "PlayerPlugin_Interaction.h"
#include "IUIDraw.h"
#include "EntityUtility/EntityScriptCalls.h"
#include "PlayerEntityInteraction.h"
#include "VTOLVehicleManager/VTOLVehicleManager.h"
#include "GameRulesModules/IGameRulesObjectivesModule.h"
#include "UI/UICVars.h"
#include "UI/UIManager.h"
#include "UI/UIInput.h"
#include "Project/ProximityMine.h"
//#define KG2LB(Kilograms) (double)Kilograms * 2.2046
//#define LB2KG(Pounds) (double)Pounds / 2.2046
CPlayerInput::CPlayerInput( CPlayer * pPlayer ) :
m_pPlayer(pPlayer),
m_actions(0),
m_actionFlags(CPlayer::eAF_NONE),
m_deltaRotation(0,0,0),
m_lastMouseRawInput(0,0,0),
m_deltaMovement(0,0,0),
m_xi_deltaMovement(0,0,0),
m_xi_deltaRotation(0,0,0),
m_xi_deltaRotationRaw(0.0f, 0.0f, 0.0f),
m_HMD_deltaRotation(0.0f, 0.0f, 0.0f),
m_lookAtSmoothRate(0.f, 0.f, 0.f),
m_flyCamDeltaMovement(0,0,0),
m_flyCamDeltaRotation(0,0,0),
m_flyCamTurbo(false),
m_filteredDeltaMovement(0,0,0),
m_jumpPressTime(0.0f),
m_suitArmorPressTime(0.0f),
m_suitStealthPressTime(0.0f),
m_moveButtonState(0),
m_lastSerializeFrameID(0),
m_bDisabledXIRot(false),
m_bUseXIInput(false),
m_lastSensitivityFactor(1.0f),
m_lastRegisteredInputTime(0.0f),
m_lookingAtButtonActive(false),
m_isAimingWithMouse(false),
m_isAimingWithHMD(false),
m_crouchButtonDown(false),
m_sprintButtonDown(false),
m_lookAtTimeStamp(0.0f),
m_fLastWeaponToggleTimeStamp(0.f),
m_fLastNoGrenadeTimeStamp(0.f),
m_isNearTheLookAtTarget(false),
m_autoPickupMode(false),
m_standingOn(0),
m_openingVisor(false),
m_playerInVehicleAtFrameStart(false)
{
m_pPlayer->GetGameObject()->CaptureActions(this);
#if FREE_CAM_SPLINE_ENABLED
m_freeCamPlaying = false;
m_freeCamCurrentIndex = 0;
m_freeCamPlayTimer = 0.f;
m_freeCamTotalPlayTime = 0.f;
#endif
m_nextSlideTime = gEnv->pTimer->GetFrameStartTime();
memset (m_inputCancelHandler, 0, sizeof(m_inputCancelHandler));
if (m_actionHandler.GetNumHandlers() == 0)
{
#define ADD_HANDLER(action, func) m_actionHandler.AddHandler(actions.action, &CPlayerInput::func)
const CGameActions& actions = g_pGame->Actions();
ADD_HANDLER(moveforward, OnActionMoveForward);
ADD_HANDLER(moveback, OnActionMoveBack);
ADD_HANDLER(moveleft, OnActionMoveLeft);
ADD_HANDLER(moveright, OnActionMoveRight);
ADD_HANDLER(rotateyaw, OnActionRotateYaw);
ADD_HANDLER(hmd_rotatepitch, OnActionHMDRotatePitch);
ADD_HANDLER(hmd_rotateyaw, OnActionHMDRotateYaw);
ADD_HANDLER(hmd_rotateroll, OnActionHMDRotateRoll);
ADD_HANDLER(rotatepitch, OnActionRotatePitch);
ADD_HANDLER(jump, OnActionJump);
ADD_HANDLER(crouch, OnActionCrouch);
ADD_HANDLER(sprint, OnActionSprint);
ADD_HANDLER(sprint_xi, OnActionSprintXI);
ADD_HANDLER(use, OnActionUse);
ADD_HANDLER(attack1_xi, OnActionAttackRightTrigger);
ADD_HANDLER(special, OnActionSpecial);
ADD_HANDLER(weapon_change_firemode, OnActionChangeFireMode);
ADD_HANDLER(thirdperson, OnActionThirdPerson);
#ifdef INCLUDE_DEBUG_ACTIONS
ADD_HANDLER(flymode, OnActionFlyMode);
#endif
ADD_HANDLER(godmode, OnActionGodMode);
ADD_HANDLER(toggleaidebugdraw, OnActionAIDebugDraw);
ADD_HANDLER(togglepdrawhelpers, OnActionPDrawHelpers);
ADD_HANDLER(toggledmode, OnActionDMode);
ADD_HANDLER(record_bookmark, OnActionRecordBookmark);
#ifdef INCLUDE_DEBUG_ACTIONS
ADD_HANDLER(mannequin_debugai, OnActionMannequinDebugAI);
ADD_HANDLER(mannequin_debugplayer, OnActionMannequinDebugPlayer);
ADD_HANDLER(ai_debugCenterViewAgent, OnActionAIDebugCenterViewAgent);
#endif
ADD_HANDLER(v_rotateyaw, OnActionVRotateYaw); // needed so player can shake unfreeze while in a vehicle
ADD_HANDLER(v_rotatepitch, OnActionVRotatePitch);
ADD_HANDLER(xi_v_rotateyaw, OnActionXIRotateYaw);
ADD_HANDLER(xi_rotateyaw, OnActionXIRotateYaw);
ADD_HANDLER(xi_rotatepitch, OnActionXIRotatePitch);
ADD_HANDLER(xi_v_rotatepitch, OnActionXIRotatePitch);
ADD_HANDLER(xi_movex, OnActionXIMoveX);
ADD_HANDLER(xi_movey, OnActionXIMoveY);
ADD_HANDLER(xi_disconnect, OnActionXIDisconnect);
ADD_HANDLER(invert_mouse, OnActionInvertMouse);
ADD_HANDLER(flycam_movex, OnActionFlyCamMoveX);
ADD_HANDLER(flycam_movey, OnActionFlyCamMoveY);
ADD_HANDLER(flycam_moveup, OnActionFlyCamMoveUp);
ADD_HANDLER(flycam_movedown, OnActionFlyCamMoveDown);
ADD_HANDLER(flycam_speedup, OnActionFlyCamSpeedUp);
ADD_HANDLER(flycam_speeddown, OnActionFlyCamSpeedDown);
ADD_HANDLER(flycam_turbo, OnActionFlyCamTurbo);
ADD_HANDLER(flycam_rotateyaw, OnActionFlyCamRotateYaw);
ADD_HANDLER(flycam_rotatepitch, OnActionFlyCamRotatePitch);
ADD_HANDLER(flycam_setpoint, OnActionFlyCamSetPoint);
ADD_HANDLER(flycam_play, OnActionFlyCamPlay);
ADD_HANDLER(flycam_clear, OnActionFlyCamClear);
ADD_HANDLER(lookAt, OnActionLookAt);
ADD_HANDLER(itemPrePickup, OnActionPrePickUpItem);
ADD_HANDLER(move_overlay_enable, OnActionMoveOverlayTurnOn);
ADD_HANDLER(move_overlay_disable, OnActionMoveOverlayTurnOff);
ADD_HANDLER(move_overlay_weight, OnActionMoveOverlayWeight);
ADD_HANDLER(move_overlay_x, OnActionMoveOverlayX);
ADD_HANDLER(move_overlay_y, OnActionMoveOverlayY);
ADD_HANDLER(respawn, OnActionRespawn);
ADD_HANDLER(nextitem, OnActionSelectNextItem);
ADD_HANDLER(previtem, OnActionSelectNextItem);
ADD_HANDLER(handgrenade, OnActionSelectNextItem);
ADD_HANDLER(toggle_explosive, OnActionSelectNextItem);
ADD_HANDLER(toggle_special, OnActionSelectNextItem);
ADD_HANDLER(toggle_weapon, OnActionSelectNextItem);
ADD_HANDLER(grenade, OnActionQuickGrenadeThrow);
ADD_HANDLER(xi_grenade, OnActionQuickGrenadeThrow);
ADD_HANDLER(debug, OnActionSelectNextItem);
ADD_HANDLER(mouse_wheel, OnActionMouseWheelClick);
#undef ADD_HANDLER
}
CCCPOINT(PlayerState_SetInputCallbacks);
}
CPlayerInput::~CPlayerInput()
{
m_pPlayer->GetGameObject()->ReleaseActions(this);
}
void CPlayerInput::Reset()
{
m_actions = 0;
m_lastActions = m_actions;
m_actionFlags = CPlayer::eAF_NONE;
ClearDeltaMovement();
m_xi_deltaMovement.zero();
m_filteredDeltaMovement.zero();
m_jumpPressTime = 0.f;
m_deltaRotation.Set(0,0,0);
m_lastMouseRawInput.Set(0,0,0);
m_xi_deltaRotation.Set(0,0,0);
m_xi_deltaRotationRaw.Set(0.0f, 0.0f, 0.0f);
m_lookAtSmoothRate.Set(0.f, 0.f, 0.f);
m_flyCamDeltaMovement.Set(0,0,0);
m_flyCamDeltaRotation.Set(0,0,0);
m_flyCamTurbo=false;
m_bDisabledXIRot = false;
m_lastSerializeFrameID = 0;
m_lastSensitivityFactor = 1.0f;
m_suitArmorPressTime = 0.0f;
m_suitStealthPressTime = 0.0f;
m_lastRegisteredInputTime = gEnv->pTimer->GetAsyncCurTime();
m_lookingAtButtonActive = false;
m_fLastWeaponToggleTimeStamp = 0.f;
m_moveOverlay.Reset();
m_standingOn = 0;
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT_AUGMENTED);
}
void CPlayerInput::DisableXI(bool disabled)
{
m_bDisabledXIRot = disabled;
}
//////////////////////////////////////////////////////////////////////////
void CPlayerInput::ApplyMovement(Vec3 delta)
{
m_deltaMovement.x = clamp_tpl(m_deltaMovement.x+delta.x,-1.0f,1.0f);
m_deltaMovement.y = clamp_tpl(m_deltaMovement.y+delta.y,-1.0f,1.0f);
m_deltaMovement.z = 0;
}
//////////////////////////////////////////////////////////////////////////
void CPlayerInput::ClearDeltaMovement()
{
m_deltaMovement.zero();
m_actions &= ~ACTION_MOVE;
m_moveButtonState = 0;
}
//////////////////////////////////////////////////////////////////////////
void CPlayerInput::OnAction( const ActionId& actionId, int activationMode, float value )
{
// Pass action to actor telemetry.
m_pPlayer->m_telemetry.OnPlayerAction(actionId, activationMode, value);
FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);
#if defined(USER_timf)
CryLogAlways ("$7PLAYER INPUT:$o <FRAME %05d> $6%s $%c[MODE=0x%x] $4value=%.3f$o", gEnv->pRenderer->GetFrameID(false), actionId.c_str(), (char) ((activationMode > 7) ? '8' : (activationMode + '1')), activationMode, value);
#endif
if (actionId == "attack1"){
if (activationMode == EActionActivationMode::eAAM_OnPress ){
SEntitySpawnParams SP;
SP.nFlags = EEntityFlags::ENTITY_FLAG_CALC_PHYSICS | EEntityFlags::ENTITY_FLAG_CASTSHADOW;
SP.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("ProximityMine");
SP.qRotation = IDENTITY;
SP.sName = "ProximityMine";
SP.vPosition = m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,1.5);
SP.vScale = Vec3(1,1,1);
IEntity *pProximityMine = gEnv->pEntitySystem->SpawnEntity(SP);
if (pProximityMine){
IGameObject *pGameObject = gEnv->pGame->GetIGameFramework()->GetGameObject(pProximityMine->GetId());
if (pGameObject){
CProximityMine *pProximityMineExt = (CProximityMine*)pGameObject->AcquireExtension("ProximityMine");
}
IPhysicalEntity *pPhysEnt = pProximityMine->GetPhysics();
if (pPhysEnt){
pe_action_impulse Impulse;
Impulse.iApplyTime = 0;
Vec3 Dir = m_pPlayer->GetEntity()->GetForwardDir().normalized();
Dir.SetLength(50);
Impulse.impulse = Dir;
pPhysEnt->Action(&Impulse);
}
}
}
}
if (!m_pPlayer->GetLinkedVehicle())
{
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT );
}
m_lastActions = m_actions;
m_lastRegisteredInputTime = gEnv->pTimer->GetAsyncCurTime();
//this tell if OnAction have to be forwarded to scripts, now its true by default, only high framerate actions are ignored
bool filterOut = true;
const CGameActions& actions = g_pGame->Actions();
IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle();
// disable movement
if ( !CanMove() )
{
ClearDeltaMovement();
}
// try to dispatch action to OnActionHandlers
bool handled = false;
{
FRAME_PROFILER("New Action Processing", GetISystem(), PROFILE_GAME);
handled = m_actionHandler.Dispatch(this, m_pPlayer->GetEntityId(), actionId, activationMode, value, filterOut);
}
//------------------------------------
{
FRAME_PROFILER("Regular Action Processing", GetISystem(), PROFILE_GAME);
bool inKillCam = g_pGame->GetRecordingSystem() && (g_pGame->GetRecordingSystem()->IsPlayingBack() || g_pGame->GetRecordingSystem()->IsPlaybackQueued());
if (!handled)
{
filterOut = true;
if (!m_pPlayer->GetSpectatorMode() && !inKillCam)
{
if (actions.debug_ag_step == actionId)
{
gEnv->pConsole->ExecuteString("ag_step");
}
}
}
if (!m_pPlayer->GetSpectatorMode() && !inKillCam )
{
if (pVehicle)
{
float vehicleValue = value;
if (actionId == actions.xi_v_movex)
{
vehicleValue = MapControllerValue(value, g_pGameCVars->vehicle_steering_curve_scale, g_pGameCVars->vehicle_steering_curve, false);
}
else if (actionId == actions.xi_v_movey)
{
vehicleValue = MapControllerValue(value, g_pGameCVars->vehicle_steering_curve_scale, g_pGameCVars->vehicle_steering_curve, false);
}
else if (actionId == actions.xi_v_accelerate)
{
vehicleValue = MapControllerValue(value, g_pGameCVars->vehicle_acceleration_curve_scale, g_pGameCVars->vehicle_acceleration_curve, false);
}
else if (actionId == actions.xi_v_deccelerate)
{
vehicleValue = MapControllerValue(value, g_pGameCVars->vehicle_deceleration_curve_scale, g_pGameCVars->vehicle_deceleration_curve, false);
}
if (m_pPlayer->m_pVehicleClient)
{
m_pPlayer->m_pVehicleClient->OnAction(pVehicle, m_pPlayer->GetEntityId(), actionId, activationMode, vehicleValue);
}
//FIXME:not really good
m_actions = 0;
m_actionFlags = CPlayer::eAF_NONE;
// m_deltaRotation.Set(0,0,0);
ClearDeltaMovement();
}
else if (IsPlayerOkToAction())
{
m_pPlayer->CActor::OnAction(actionId, activationMode, value);
if (actionId == actions.use && activationMode != eAAM_OnRelease)
{
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if (interactionInfo.interactionType == eInteraction_Grab || interactionInfo.interactionType == eInteraction_GrabEnemy)
{
if (activationMode == eAAM_OnHold)
{
SHUDEventWrapper::OnInteractionUseHoldActivated(true);
}
m_pPlayer->RequestEnterPickAndThrow( interactionInfo.interactiveEntityId );
}
else if(interactionInfo.interactionType == eInteraction_Ladder)
{
if (IEntity* pEntity = gEnv->pEntitySystem->GetEntity(interactionInfo.interactiveEntityId))
{
SStateEventLadder ladderEvent(pEntity);
m_pPlayer->StateMachineHandleEventMovement(ladderEvent);
}
}
// Record 'Use' telemetry stats.
// I'm not sure this is the best place to perform the check, but the actual process of using items appears to be handled within the scripting system.
if((m_actions & ACTION_USE) && (interactionInfo.interactionType == eInteraction_Use))
{
IEntity *pInteractionEntity = gEnv->pEntitySystem->GetEntity(interactionInfo.interactiveEntityId);
CStatsRecordingMgr::TryTrackEvent(m_pPlayer, eGSE_Use, pInteractionEntity ? pInteractionEntity->GetName() : "unknown entity");
}
}
}
}
}
UIEvents::Get<CUIInput>()->OnActionInput(actionId, activationMode, value);
if (IsItemPickUpScriptAction(actionId))
{
CPlayerEntityInteraction& playerEntityInteractor = m_pPlayer->GetPlayerEntityInteration();
playerEntityInteractor.ItemPickUpMechanic(m_pPlayer, actionId, activationMode);
}
CGameRules* pGameRules = g_pGame->GetGameRules();
if (pGameRules != NULL)
{
pGameRules->OnActorAction( m_pPlayer, actionId, activationMode, value );
}
}
const bool CPlayerInput::AllowToggleWeapon(const int activationMode, const float currentTime)
{
if(gEnv->bMultiplayer)
{
if(m_pPlayer->IsStillWaitingOnServerUseResponse())
{
return false;
}
if (!m_pPlayer->AllowSwitchingItems() || activationMode != eAAM_OnPress)
{
return false;
}
}
else
{
if (!CanLookAt())
{
if (activationMode != eAAM_OnPress)
{
return false;
}
}
else if (CanLookAt() && activationMode != eAAM_OnRelease)
{
return false;
}
else if (CanLookAt() && activationMode == eAAM_OnRelease && currentTime > m_lookAtTimeStamp+g_pGameCVars->pl_useItemHoldTime)
{
return false;
}
}
return true;
}
bool CPlayerInput::IsPlayerOkToAction() const
{
return m_pPlayer->IsPlayerOkToAction();
}
//this function basically returns a smoothed movement vector, for better movement responsivness in small spaces
const Vec3 &CPlayerInput::FilterMovement(const Vec3 &desired)
{
float frameTimeCap(min(gEnv->pTimer->GetFrameTime(),0.033f));
float inputAccel(g_pGameCVars->pl_inputAccel);
Vec3 oldFilteredMovement = m_filteredDeltaMovement;
if (desired.len2()<0.01f)
{
m_filteredDeltaMovement.zero();
}
else if (inputAccel<=0.0f)
{
m_filteredDeltaMovement = desired;
}
else
{
Vec3 delta(desired - m_filteredDeltaMovement);
float len(delta.len());
if (len<=1.0f)
delta = delta * (1.0f - len*0.55f);
m_filteredDeltaMovement += delta * min(frameTimeCap * inputAccel,1.0f);
}
if (oldFilteredMovement.GetDistance(m_filteredDeltaMovement) > 0.001f && !m_pPlayer->GetLinkedVehicle())
{
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT );
}
return m_filteredDeltaMovement;
}
bool CPlayerInput::CanMove() const
{
bool canMove = !m_pPlayer->GetSpectatorMode();
canMove &= m_pPlayer->IsPlayerOkToAction();
const SActorStats * pActorStats = m_pPlayer->GetActorStats();
if(pActorStats)
{
canMove &= (pActorStats->mountedWeaponID == 0);
}
return canMove;
}
bool CPlayerInput::CanCrouch() const
{
if (!CanMove())
return false;
if (m_pPlayer->GetBlockMovementInputs())
return false;
CWeapon* pWeapon = m_pPlayer->GetWeapon(m_pPlayer->GetCurrentItemId());
if (!pWeapon)
return true;
bool rippedOff = pWeapon->IsRippedOff();
bool heavyWeapon = pWeapon->IsHeavyWeapon();
bool canCrouch = true;
if (heavyWeapon && (!rippedOff || m_sprintButtonDown))
canCrouch = false;
return canCrouch;
}
void CPlayerInput::NormalizeInput(float& fX, float& fY, float fCoeff, float fCurve)
{
float fMag = MapControllerValue(min(sqrt_tpl(fX*fX + fY*fY), 1.0f), fCoeff, fCurve, false);
if (fMag > 0.0f)
{
float fAbsX = fabs_tpl(fX);
float fAbsY = fabs_tpl(fY);
float fFactor = fMag / max(fAbsX, fAbsY);
fX *= fFactor;
fY *= fFactor;
}
}
void CPlayerInput::DrawDebugInfo()
{
#if !defined(_RELEASE)
const float fRadius = 60.0f;
const float fX = 120.0f;
const float fY = 600.0f;
const float fTimeOut = 0.5f;
const float fSize = 12.f;
// process the input as in PreProcess, but without scaling
Ang3 processedDeltaRot(UpdateXIInputs(m_xi_deltaRotationRaw, false));
IUIDraw* pUIDraw = gEnv->pGame->GetIGameFramework()->GetIUIDraw();
pUIDraw->PreRender();
// Draw enclosing circle
ColorF whiteColor(0.7f, 1.0f, 1.0f, 1.0f);
// pUIDraw->DrawCircleHollow(fX, fY, fRadius, 1.0f, whiteColor.pack_argb8888());
// Print explanatory text
IFFont* pFont = gEnv->pCryFont->GetFont("default");
string sMsg;
sMsg.Format("Raw input: (%f, %f)", m_xi_deltaRotationRaw.z, m_xi_deltaRotationRaw.x);
pUIDraw->DrawTextSimple(pFont, fX - fRadius, fY + fRadius + fSize, fSize, fSize, sMsg.c_str(), Col_Green, UIDRAWHORIZONTAL_LEFT, UIDRAWVERTICAL_TOP);
sMsg.Format("Processed input: (%f, %f)", processedDeltaRot.z, processedDeltaRot.x);
pUIDraw->DrawTextSimple(pFont, fX - fRadius, fY + fRadius + (fSize * 2.f), fSize, fSize, sMsg.c_str(), Col_Orange, UIDRAWHORIZONTAL_LEFT, UIDRAWVERTICAL_TOP);
pUIDraw->PostRender();
// to improve following the movement
IPersistantDebug* pPersistantDebug = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug();
pPersistantDebug->Begin("CPlayerInput::DrawDebugInfo", false);
float fTraceRawXStart = fX + (m_debugDrawStats.lastRaw.z * fRadius);
float fTraceRawYStart = fY + (-m_debugDrawStats.lastRaw.x * fRadius);
float fTraceProcessedXStart = fX + (-m_debugDrawStats.lastProcessed.z * fRadius);
float fTraceProcessedYStart = fY + (-m_debugDrawStats.lastProcessed.x * fRadius);
float fRawXEnd = fX + (m_xi_deltaRotationRaw.z * fRadius);
float fRawYEnd = fY + (-m_xi_deltaRotationRaw.x * fRadius);
float fProcessedXEnd = fX + (-processedDeltaRot.z * fRadius);
float fProcessedYEnd = fY + (-processedDeltaRot.x * fRadius);
if ((fProcessedXEnd != fX) && (fProcessedYEnd != fY))
pPersistantDebug->Add2DLine(fTraceProcessedXStart, fTraceProcessedYStart, fProcessedXEnd, fProcessedYEnd, Col_Orange, fTimeOut);
if ((fRawXEnd != fX) && (fRawYEnd != fY))
pPersistantDebug->Add2DLine(fTraceRawXStart, fTraceRawYStart, fRawXEnd, fRawYEnd, Col_Green, fTimeOut);
// Display our aiming displacement
const CCamera& camera = gEnv->pRenderer->GetCamera();
float fDepth = camera.GetNearPlane() + 0.15f;
Vec3 vNewAimPos = camera.GetPosition() + (camera.GetViewdir() * fDepth);
pPersistantDebug->AddLine(m_debugDrawStats.vOldAimPos, vNewAimPos, Col_White, fTimeOut);
// Draw input lines
pPersistantDebug->Begin("CPlayerInput::DrawDebugInfo::InputLines", true);
pPersistantDebug->Add2DLine(fX, fY, fProcessedXEnd, fProcessedYEnd, Col_Orange, 0.1f);
pPersistantDebug->Add2DLine(fX, fY, fRawXEnd, fRawYEnd, Col_Green, 0.1f);
// store values for next call
m_debugDrawStats.lastRaw = m_xi_deltaRotationRaw;
m_debugDrawStats.lastProcessed = processedDeltaRot;
m_debugDrawStats.vOldAimPos = vNewAimPos;
#endif //!defined(_RELEASE)
}
Ang3 CPlayerInput::UpdateXIInputs(const Ang3& inputAngles, bool bScaling/* = true*/)
{
const SCVars* const __restrict pGameCVars = g_pGameCVars;
if (pGameCVars->aim_altNormalization.enable == 0)
{
Ang3 xiDeltaRot(inputAngles.x, 0.0f, inputAngles.z);
// Calculate the parameters for the input mapping
const float fCurve = g_pGameCVars->controller_power_curve;
// NormalizeInput maps the magnitude internally
NormalizeInput(xiDeltaRot.z, xiDeltaRot.x, 1.0f, fCurve);
xiDeltaRot.z = -xiDeltaRot.z;
return Ang3(xiDeltaRot.x, 0.0f, xiDeltaRot.z);
}
else
{
Ang3 xiDeltaRot(inputAngles.x, 0.0f, inputAngles.z);
// Calculate the parameters for the input mapping
const float fCoeff = g_pGameCVars->aim_altNormalization.hud_ctrl_Coeff_Unified;
const float fCurve = g_pGameCVars->aim_altNormalization.hud_ctrl_Curve_Unified;
// NormalizeInput maps the magnitude internally
NormalizeInput(xiDeltaRot.z, xiDeltaRot.x, bScaling ? fCoeff : 1.0f, fCurve);
xiDeltaRot.z = -xiDeltaRot.z;
return Ang3(xiDeltaRot.x, 0.0f, xiDeltaRot.z);
}
}
void CPlayerInput::PreUpdate()
{
CMovementRequest request;
float generalSensitivity = 1.0f; //sensitivity adjustment regardless of control type
float mouseSensitivity; //sensitivity adjustment specific to mouse control
float dt = gEnv->pTimer->GetFrameTime();
UpdateAutoLookAtTargetId(dt);
mouseSensitivity = 0.00333f * max(0.01f, g_pGameCVars->cl_sensitivity);
mouseSensitivity *= gf_PI / 180.0f;//doesnt make much sense, but after all helps to keep reasonable values for the sensitivity cvars
//Move this to player rotation instead?
generalSensitivity *= m_pPlayer->GetWeaponRotationFactor();
//Interpolate(m_lastSensitivityFactor, generalSensitivity, 4.0f, dt, 1.0f);
//generalSensitivity = m_lastSensitivityFactor;
Ang3 deltaRotation = m_deltaRotation * mouseSensitivity * generalSensitivity;
deltaRotation += m_HMD_deltaRotation; // We don't control player's head, so it should not have sensitivity factors.
m_HMD_deltaRotation.Set(0,0,0); // We don't need the delta anymore.
IVehicle *pVehicle = m_pPlayer->GetLinkedVehicle();
m_playerInVehicleAtFrameStart = (pVehicle != NULL);
// apply rotation from xinput controller
if(!m_bDisabledXIRot)
{
Ang3 rawRotationInput;
rawRotationInput.x = clamp_tpl(m_xi_deltaRotationRaw.x, -1.0f, 1.0f);
rawRotationInput.y = 0.0f;
rawRotationInput.z = clamp_tpl(m_xi_deltaRotationRaw.z, -1.0f, 1.0f);
m_xi_deltaRotation = UpdateXIInputs(rawRotationInput);
Ang3 xiDeltaRot = m_xi_deltaRotation;
//Apply turning acceleration to the input values. This is here because the acceleration
// should be application-specific, e.g. different for the player and vehicles
m_pPlayer->m_pMovementController->ApplyControllerAcceleration(xiDeltaRot.x, xiDeltaRot.z, gEnv->pTimer->GetFrameTime());
// Applying aspect modifiers
if (g_pGameCVars->hud_aspectCorrection > 0)
{
int vx, vy, vw, vh;
gEnv->pRenderer->GetViewport(&vx, &vy, &vw, &vh);
float med=((float)vw+vh)/2.0f;
float crW=((float)vw)/med;
float crH=((float)vh)/med;
xiDeltaRot.x*=g_pGameCVars->hud_aspectCorrection == 2 ? crW : crH;
xiDeltaRot.z*=g_pGameCVars->hud_aspectCorrection == 2 ? crH : crW;
}
if(g_pGameCVars->cl_invertController)
xiDeltaRot.x*=-1;
// Controller framerate compensation needs frame time!
// The constant is to counter for small frame time values.
// adjust some too small values, should be handled differently later on
if(g_pGameCVars->pl_aim_acceleration_enabled == 0)
{
deltaRotation += (xiDeltaRot * dt * 50.0f * generalSensitivity * mouseSensitivity);
}
else
{
const float sensitivityValue = (gEnv->bMultiplayer ? g_pGameCVars->cl_sensitivityControllerMP : g_pGameCVars->cl_sensitivityController);
float controllerSensitivity = clamp_tpl(sensitivityValue * 0.5f, 0.0f, 1.0f);
float fractionIncrease = 1.0f + ((controllerSensitivity - 0.5f) * 1.5f ); //result is between 0.25f to 1.75f
xiDeltaRot.z *= g_pGameCVars->controller_multiplier_z * fractionIncrease;
xiDeltaRot.x *= g_pGameCVars->controller_multiplier_x * fractionIncrease;
//Output debug information
if(g_pGameCVars->ctrlr_OUTPUTDEBUGINFO > 0)
{
const float dbg_my_white[4] = {1,1,1,1};
gEnv->pRenderer->Draw2dLabel( 20, 400, 1.3f, dbg_my_white, false, "PRE-DT MULTIPLY:\n xRot: %.9f\n zRot: %.9f\n", xiDeltaRot.x, xiDeltaRot.z);
}
deltaRotation += (xiDeltaRot * dt * generalSensitivity);
}
if (pVehicle)
{
if (m_pPlayer->m_pVehicleClient)
{
m_pPlayer->m_pVehicleClient->PreUpdate(pVehicle, m_pPlayer->GetEntityId(), dt);
}
//FIXME:not really good
m_actions = 0;
m_actionFlags = CPlayer::eAF_NONE;
ClearDeltaMovement();
m_deltaRotation.Set(0,0,0);
}
}
if (m_pPlayer->GetBlockMovementInputs())
{
ClearDeltaMovement();
m_actions &= ~(ACTION_JUMP);
}
else if(m_bUseXIInput)
{
ClearDeltaMovement(); //we are ignoring the delta movement values, so we need to clear the button inputs as well.
m_deltaMovement.x = m_xi_deltaMovement.x;
m_deltaMovement.y = m_xi_deltaMovement.y;
m_deltaMovement.z = 0;
if (m_xi_deltaMovement.len2()>0.0f)
m_actions |= ACTION_MOVE;
else
m_actions &= ~ACTION_MOVE;
}
bool animControlled(m_pPlayer->m_stats.animationControlledID!=0);
// If there was a recent serialization, ignore the delta rotation, since it's accumulated over several frames.
if ((m_lastSerializeFrameID + 2) > gEnv->pRenderer->GetFrameID())
deltaRotation.Set(0,0,0);
// Aim & look forward along the 'BaseQuat' direction
const Vec3 playerEyePosition = m_pPlayer->GetEntity()->GetWorldTM().TransformPoint(m_pPlayer->GetEyeOffset());
const Vec3 playerTargetPosition = playerEyePosition + 5 * m_pPlayer->GetBaseQuat().GetColumn1();
request.SetAimTarget( playerTargetPosition );
request.SetLookTarget( playerTargetPosition );
request.AddDeltaRotation( deltaRotation );
if (!animControlled)
{
request.AddDeltaMovement( FilterMovement( m_moveOverlay.GetMixedOverlay(m_deltaMovement) ) );
}
// handle actions
if (m_actions & ACTION_JUMP)
{
request.SetJump();
}
request.SetStance(FigureOutStance());
float pseudoSpeed = 0.0f;
if ((m_moveOverlay.GetMixedOverlay(m_deltaMovement)).len2() > 0.0f)
{
pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_pPlayer->IsSprinting(), m_moveOverlay.GetMixedOverlay(m_deltaMovement).len());
}
request.SetPseudoSpeed(pseudoSpeed);
Vec3 overlayDeltaMovement( (m_moveOverlay.GetMixedOverlay(m_deltaMovement)) );
if (overlayDeltaMovement.GetLengthSquared() > 0.01f)
{
float moveAngle = (float)RAD2DEG(fabs_tpl(atan2_tpl(-overlayDeltaMovement.x, fabsf(overlayDeltaMovement.y)<0.01f?0.01f:overlayDeltaMovement.y)));
request.SetAllowStrafing(moveAngle > 20.0f);
}
else
{
request.SetAllowStrafing(true);
}
// send the movement request to the appropriate spot!
m_pPlayer->m_pMovementController->RequestMovement( request );
m_pPlayer->m_actions = m_actions;
m_pPlayer->m_actionFlags = m_actionFlags;
if (g_pGameCVars->g_detachCamera && g_pGameCVars->g_moveDetachedCamera)
{
HandleMovingDetachedCamera(m_flyCamDeltaRotation, m_flyCamDeltaMovement);
}
// reset things for next frame that need to be
m_lastMouseRawInput = m_deltaRotation;
m_deltaRotation.Set(0.0f, 0.0f, 0.0f);
if (m_pPlayer->GetFlyMode() == 0)
{
m_actions &= ~ACTION_JUMP;
m_actionFlags &= ~(CPlayer::eAF_JUMP_QUICK);
}
}
// TODO - tidy up
// TODO - add up down movement on analogue shoulder buttons
// TODO - perhaps move to somewhere else more suitable?
void CPlayerInput::HandleMovingDetachedCamera(const Ang3 &deltaRotation, const Vec3 &deltaMovement)
{
//CryWatch("deltaRot=%f,%f,%f; deltaMove=%f,%f,%f", deltaRotation.x, deltaRotation.y, deltaRotation.z, deltaMovement.x, deltaMovement.y, deltaMovement.z);
IView* pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView();
assert(pView);
if (!pView)
{
return;
}
#if FREE_CAM_SPLINE_ENABLED
if (g_pGameCVars->g_detachedCameraDebug)
{
ColorB col(255,255,255);
ColorB col2(255,255,130);
SFreeCamPointData *camData = NULL;
SFreeCamPointData *lastCamData = NULL;
float totalDistance = 0.f;
Vec3 diff;
for (int num=0; num < MAX_FREE_CAM_DATA_POINTS; ++num)
{
camData = &m_freeCamData[num];
if (camData->valid)
{
gEnv->pRenderer->GetIRenderAuxGeom()->DrawPoint(camData->position, col, 3);
gEnv->pRenderer->GetIRenderAuxGeom()->DrawPoint(camData->lookAtPosition, col2, 3);
gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(camData->position, col, camData->lookAtPosition, col);
if (lastCamData)
{
gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(camData->position, col, lastCamData->position, col, 3.f);
gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(camData->lookAtPosition, col2, lastCamData->lookAtPosition, col2, 3.f);
}
}
else
{
break;
}
lastCamData = camData;
}
}
if (m_freeCamPlaying)
{
if (m_freeCamSpline.num_keys() > 0)
{
const SViewParams* pViewParams = pView->GetCurrentParams();
SViewParams params = (*pViewParams);
float frameTime=gEnv->pTimer->GetFrameTime();
m_freeCamPlayTimer += frameTime;
Vec3 point, lookAtPoint;
float time = CLAMP((m_freeCamPlayTimer / m_freeCamTotalPlayTime), 0.f, 1.f);
m_freeCamSpline.interpolate( time, point);
m_freeCamLookAtSpline.interpolate( time, lookAtPoint);
Vec3 diff = lookAtPoint - point;
diff.Normalize();
Quat lookAtQuat = Quat::CreateRotationVDir( diff );
params.rotation = lookAtQuat;
params.position = point;
pView->SetCurrentParams(params);
if (m_freeCamPlayTimer > m_freeCamTotalPlayTime)
{
if (g_pGameCVars->g_flyCamLoop)
{
m_freeCamPlayTimer = 0;
}
else
{
m_freeCamPlaying = false;
m_freeCamPlayTimer = m_freeCamTotalPlayTime;
}
}
}
else
{
m_freeCamPlaying = false;
}
}
else
#endif
{
float moveSpeed = g_pGameCVars->g_detachedCameraMoveSpeed;
if (m_flyCamTurbo)
{
moveSpeed *= g_pGameCVars->g_detachedCameraTurboBoost;
}
const SViewParams* pViewParams = pView->GetCurrentParams();
Quat curRot = pViewParams->rotation;
Quat newRot;
Vec3 upDir = curRot.GetColumn2();
Vec3 rightDir = curRot.GetColumn0();
//Quat::CreateRotationXYZ()
newRot = curRot;
float frameTime=gEnv->pTimer->GetFrameTime();
Ang3 useRot;
useRot.x = MapControllerValue(deltaRotation.x, g_pGameCVars->g_detachedCameraRotateSpeed, 2.5f, false);
useRot.y = MapControllerValue(deltaRotation.y, g_pGameCVars->g_detachedCameraRotateSpeed, 2.5f, false);
useRot.z = MapControllerValue(deltaRotation.z, g_pGameCVars->g_detachedCameraRotateSpeed, 2.5f, true);
// space of transformation done left to right
// rotz in world space (or no space)
// newRot is applied to worldspaced rotz
// rotx in current view space already worldspaced rotz (as held in newRot)
newRot = Quat::CreateRotationZ(frameTime*useRot.z) * newRot * (Quat::CreateRotationX(frameTime*useRot.x) ) ;
newRot.Normalize();
Vec3 movement; // don't call FilterMovement() its actually doing state things as well
movement.x = MapControllerValue(deltaMovement.x, moveSpeed, 2.5f, false);
movement.y = MapControllerValue(deltaMovement.y, moveSpeed, 2.5f, false);
movement.z = MapControllerValue(deltaMovement.z, moveSpeed, 2.5f, false);
rightDir = newRot.GetColumn0();
upDir = newRot.GetColumn2();
Vec3 lookDir = newRot.GetColumn1();
lookDir *= movement.y * frameTime;
rightDir *= movement.x * frameTime;
upDir *= movement.z * frameTime;
movement = lookDir + rightDir + upDir;
SViewParams params = (*pViewParams);
params.position += movement;
params.rotation = newRot;
pView->SetCurrentParams(params);
}
}
EStance CPlayerInput::FigureOutStance()
{
if (m_actions & (ACTION_CROUCH | ACTION_FORCE_CROUCH))
return STANCE_CROUCH;
else if (m_actions & ACTION_RELAXED)
return STANCE_RELAXED;
else if (m_actions & ACTION_STEALTH)
return STANCE_STEALTH;
else if (m_pPlayer->GetStance() == STANCE_NULL)
return STANCE_STAND;
return STANCE_STAND;
}
void CPlayerInput::Update()
{
if( (m_actions & ACTION_FORCE_CROUCH) && m_pPlayer->GetStance() == STANCE_CROUCH)
{
//Remove the force crouch action as soon as physics is enabled for the player - the player will then un-crouch as soon as physically possible (unless the user is holding down the crouch button)
pe_player_dynamics player_dynamics;
IPhysicalEntity* pPhysicalEntity = m_pPlayer->GetEntity()->GetPhysics();
if(pPhysicalEntity && pPhysicalEntity->GetParams(&player_dynamics) && player_dynamics.bActive)
{
m_actions &= ~ACTION_FORCE_CROUCH;
}
}
if(m_pPlayer->IsSprinting())
{
if (m_actions & ACTION_CROUCH)
{
m_actions &= ~ACTION_SPRINT;
}
}
UpdateWeaponToggle();
if (m_jumpPressTime > 0.0f)
{
const float pressDelta = (gEnv->pTimer->GetAsyncCurTime() - m_jumpPressTime);
if (pressDelta > g_pGameCVars->pl_jump_quickPressThresh)
{
//CryLog("[tlh] calling PerformJump(false) from PlayerInput::Update()");
m_jumpPressTime = 0.f;
PerformJump(false);
}
}
if(m_autoPickupMode)
{
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if(interactionInfo.interactionType == eInteraction_PickupItem || interactionInfo.interactionType == eInteraction_ExchangeItem)
{
const CGameActions& actions = g_pGame->Actions();
OnActionPrePickUpItem(interactionInfo.interactiveEntityId, CCryName("itemPickup"), eAAM_OnHold, 0.f);
CPlayerEntityInteraction& playerEntityInteractor = m_pPlayer->GetPlayerEntityInteration();
playerEntityInteractor.ItemPickUpMechanic(m_pPlayer, actions.itemPickup, eAAM_OnHold);
m_autoPickupMode = false;
}
}
}
// [tlh] TODO? copy-pasted from HUDTagNames.cpp (where it's implicitly static - ie. not in any header files) ... shouldn't this be in the engine alongside the ProjectToScreen funcs?
static bool CoordsOnScreen(const Vec3& vScreenSpace)
{
bool bResult = true;
if(vScreenSpace.z < 0.0f || vScreenSpace.z > 1.0f)
{
bResult = false;
}
if(vScreenSpace.y < 0.0f || vScreenSpace.y > 100.0f)
{
bResult = false;
}
if(vScreenSpace.x < 0.0f || vScreenSpace.x > 100.0f)
{
bResult = false;
}
return bResult;
}
void CPlayerInput::PostUpdate()
{
/////////////////////////////////////////////////////////////////////////////////
// Have we changed what entity we are standing on?
EntityId standingOn = 0;
IPhysicalEntity* pEnt = m_pPlayer->GetEntity()->GetPhysics();
pe_status_living psl;
CGameRules* pGameRules = g_pGame->GetGameRules();
if (pGameRules && pEnt && pEnt->GetStatus(&psl) && psl.pGroundCollider)
{
IEntity* pGroundEntity = gEnv->pEntitySystem->GetEntityFromPhysics(psl.pGroundCollider);
if (pGroundEntity)
{
int id = pGroundEntity->GetId();
if (pGameRules->GetVTOLVehicleManager() && pGameRules->GetVTOLVehicleManager()->IsVTOL(id))
standingOn = id;
}
}
if (standingOn!=m_standingOn)
{
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT );
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT_AUGMENTED);
m_standingOn = standingOn;
}
/////////////////////////////////////////////////////////////////////////////////
if (m_actions!=m_lastActions && !m_pPlayer->GetLinkedVehicle())
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT );
#ifndef _RELEASE
// Debug Drawing
if (g_pGameCVars->pl_debug_aiming_input && !m_bDisabledXIRot)
DrawDebugInfo();
#endif
}
void CPlayerInput::GetState( SSerializedPlayerInput& input )
{
SMovementState movementState;
m_pPlayer->GetMovementController()->GetMovementState( movementState );
input.stance = FigureOutStance();
input.inAir = m_pPlayer->IsInAir();
if (g_pGameCVars->pl_serialisePhysVel)
{
//--- Serialise the physics vel instead, velocity over the NET_SERIALISE_PLAYER_MAX_SPEED will be clamped by the network so no guards here
input.standingOn = m_standingOn;
input.deltaMovement.zero();
IPhysicalEntity* pEnt = m_pPlayer->GetEntity()->GetPhysics();
pe_status_living psl;
if (pEnt && pEnt->GetStatus(&psl))
{
// Remove the ground velocity
input.deltaMovement = (psl.vel - psl.velGround) / g_pGameCVars->pl_netSerialiseMaxSpeed;
//input.deltaMovement.z = 0.0f;
}
}
else
{
Quat worldRot = m_pPlayer->GetBaseQuat();
input.deltaMovement = worldRot.GetNormalized() * m_filteredDeltaMovement;
// ensure deltaMovement has the right length
input.deltaMovement = input.deltaMovement.GetNormalizedSafe(ZERO) * m_filteredDeltaMovement.GetLength();
}
input.sprint = m_pPlayer->IsSprinting();
input.lookDirection = movementState.eyeDirection;
input.bodyDirection = movementState.entityDirection;
input.aiming = true;
input.usinglookik = true;
input.allowStrafing = true;
float pseudoSpeed=0.0f;
if (input.deltaMovement.len2() > 0.0f)
pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(input.sprint);
input.pseudoSpeed=pseudoSpeed;
}
void CPlayerInput::SetState( const SSerializedPlayerInput& input )
{
GameWarning("CPlayerInput::SetState called: should never happen");
}
void CPlayerInput::SerializeSaveGame( TSerialize ser )
{
if(ser.GetSerializationTarget() != eST_Network)
{
// Store the frame we serialize, to avoid accumulated input during serialization.
m_lastSerializeFrameID = gEnv->pRenderer->GetFrameID();
if(ser.IsReading())
{
Reset();
}
}
}
bool CPlayerInput::OnActionMoveForward(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
bool bClearDeltaMovement = false;
if (CanMove() || (activationMode == eAAM_OnRelease))
{
if(activationMode == eAAM_OnRelease)
{
if(!(m_moveButtonState&eMBM_Left) && !(m_moveButtonState&eMBM_Back) && !(m_moveButtonState&eMBM_Right))
{
bClearDeltaMovement = true;
m_actions &= ~ACTION_MOVE;
}
}
else
{
m_actions |= ACTION_MOVE;
}
if(CheckMoveButtonStateChanged(eMBM_Forward, activationMode))
{
ApplyMovement(Vec3(0,value*2.0f - 1.0f,0));
AdjustMoveButtonState(eMBM_Forward, activationMode);
}
}
m_bUseXIInput = false;
if (bClearDeltaMovement)
{
ClearDeltaMovement();
}
return false;
}
bool CPlayerInput::OnActionMoveBack(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
bool bClearDeltaMovement = false;
if (CanMove() || (activationMode == eAAM_OnRelease))
{
if(activationMode == eAAM_OnRelease)
{
if(!(m_moveButtonState&eMBM_Left) && !(m_moveButtonState&eMBM_Forward) && !(m_moveButtonState&eMBM_Right))
{
bClearDeltaMovement = true;
m_actions &= ~ACTION_MOVE;
}
}
else
{
m_actions |= ACTION_MOVE;
}
if(CheckMoveButtonStateChanged(eMBM_Back, activationMode))
{
ApplyMovement(Vec3(0,-(value*2.0f - 1.0f),0));
AdjustMoveButtonState(eMBM_Back, activationMode);
}
}
m_bUseXIInput = false;
if (bClearDeltaMovement)
{
ClearDeltaMovement();
}
return false;
}
bool CPlayerInput::OnActionMoveLeft(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
bool bClearDeltaMovement = false;
if (CanMove() || (activationMode == eAAM_OnRelease))
{
if(activationMode == eAAM_OnRelease)
{
if(!(m_moveButtonState&eMBM_Forward) && !(m_moveButtonState&eMBM_Back) && !(m_moveButtonState&eMBM_Right))
{
bClearDeltaMovement = true;
m_actions &= ~ACTION_MOVE;
}
}
else
{
m_actions |= ACTION_MOVE;
}
if(CheckMoveButtonStateChanged(eMBM_Left, activationMode))
{
ApplyMovement(Vec3(-(value*2.0f - 1.0f),0,0));
AdjustMoveButtonState(eMBM_Left, activationMode);
}
}
m_bUseXIInput = false;
if (bClearDeltaMovement)
{
ClearDeltaMovement();
}
return false;
}
bool CPlayerInput::OnActionMoveRight(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
bool bClearDeltaMovement = false;
if (CanMove() || (activationMode == eAAM_OnRelease))
{
if(activationMode == eAAM_OnRelease)
{
if(!(m_moveButtonState&eMBM_Left) && !(m_moveButtonState&eMBM_Back) && !(m_moveButtonState&eMBM_Forward))
{
bClearDeltaMovement = true;
m_actions &= ~ACTION_MOVE;
}
}
else
{
m_actions |= ACTION_MOVE;
}
if(CheckMoveButtonStateChanged(eMBM_Right, activationMode))
{
ApplyMovement(Vec3(value*2.0f - 1.0f,0,0));
AdjustMoveButtonState(eMBM_Right, activationMode);
}
}
m_bUseXIInput = false;
if (bClearDeltaMovement)
{
ClearDeltaMovement();
}
return false;
}
bool CPlayerInput::OnActionRotateYaw(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_deltaRotation.z -= value;
m_isAimingWithMouse = true;
return false;
}
bool CPlayerInput::OnActionRotatePitch(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(g_pGameCVars->cl_invertMouse)
{
value *= -1.0f;
}
// As the HMD control method is currently differential, there is very high
// potential to have the view going out of sync with rotation if we allow
// both, especially due to the limitation on +-90 degrees.
// Therefore, when using Head Mounted Devices, we may want to disable mouse Pitch.
//if (!m_isAimingWithHMD)
{
m_deltaRotation.x -= value;
}
m_isAimingWithMouse = true;
return false;
}
bool CPlayerInput::OnActionHMDRotateYaw(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_HMD_deltaRotation.x -= value;
m_isAimingWithHMD=true;
return false;
}
bool CPlayerInput::OnActionHMDRotatePitch(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_HMD_deltaRotation.z -= value;
m_isAimingWithHMD=true;
return false;
}
bool CPlayerInput::OnActionHMDRotateRoll(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
// Roll doesn't seem to be applied by the player control.
// The information is passed, though.
m_HMD_deltaRotation.y -= value;
m_isAimingWithHMD=true;
return false;
}
bool CPlayerInput::OnActionVRotateYaw(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_deltaRotation.z -= value;
return false;
}
bool CPlayerInput::OnActionVRotatePitch(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_deltaRotation.x -= value;
if(g_pGameCVars->cl_invertMouse)
m_deltaRotation.x*=-1.0f;
return false;
}
bool CPlayerInput::OnActionJump(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
bool canJump = (!m_pPlayer->GetLinkedVehicle()) && ((m_pPlayer->IsSwimming() || (m_pPlayer->TrySetStance(STANCE_STAND) && (m_pPlayer->m_stats.onGround > 0.01f))));
bool performJump = false;
bool performQuickJump = false;
m_pPlayer->m_jumpButtonIsPressed = (activationMode == eAAM_OnPress);
if (!CallTopCancelHandler(kCancelPressFlag_jump) && CanMove() && canJump)
{
if (value > 0.0f)
{
if(m_actions & ACTION_CROUCH)
{
CCCPOINT(PlayerMovement_PressJumpWhileCrouchedToStandUp);
m_actions &= ~ACTION_CROUCH;
if (!m_pPlayer->IsSliding())
{
return false;
}
else
{
m_pPlayer->StateMachineHandleEventMovement( PLAYER_EVENT_FORCEEXITSLIDE );
}
}
CRY_ASSERT(m_jumpPressTime <= 0.f);
m_jumpPressTime = gEnv->pTimer->GetAsyncCurTime();
return true;
}
else
{
if (m_jumpPressTime > 0.f)
{
float pressDelta = (gEnv->pTimer->GetAsyncCurTime() - m_jumpPressTime);
//CryLog("[tlh] @ CPlayerInput::OnActionJump(), pressDelta = %f", pressDelta);
m_jumpPressTime = 0.f;
performQuickJump = true;
}
}
}
else
{
CCCPOINT_IF(value > 0.0f, PlayerMovement_PressJumpInputIgnored);
m_jumpPressTime = 0.f;
}
if (performJump || performQuickJump)
{
PerformJump(performQuickJump);
}
else
{
// Moved this outside the (CanMove() && ...) condition, since if it's false the JUMP flag might not be cleared,
// and the player continues jumping as if the jump key was held.
if ((m_pPlayer->GetFlyMode() == 0) || (activationMode == eAAM_OnRelease))
{
m_actions &= ~ACTION_JUMP;
m_actionFlags &= ~CPlayer::eAF_JUMP_QUICK;
}
}
CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT);
return false;
}
bool CPlayerInput::PerformJump(bool quickPress)
{
//CryLog("[tlh] @ CPlayerInput::PerformJump(quickPress=%d)", quickPress);
bool canJump = ((m_pPlayer->IsSwimming()) ||
(m_pPlayer->TrySetStance(STANCE_STAND)) &&
(m_pPlayer->m_stats.onGround > 0.01f));
if (!CanMove() || !canJump || (m_pPlayer->GetSpectatorMode() != CActor::eASM_None))
{
CryLog(" > either can't move or can't jump or is spectating, aborting.");
return false;
}
if(m_actions & ACTION_CROUCH)
{
CryLog(" > is crouching, un-crouching rather than jumping.");
CCCPOINT(PlayerMovement_PressJumpWhileCrouchedToStandUp);
m_actions &= ~ACTION_CROUCH;
return false;
}
m_actions |= ACTION_JUMP;
if (quickPress)
m_actionFlags |= CPlayer::eAF_JUMP_QUICK;
else
m_actionFlags &= ~CPlayer::eAF_JUMP_QUICK;
// Record 'Jump' telemetry stats.
CStatsRecordingMgr::TryTrackEvent(m_pPlayer, eGSE_Jump);
return true;
}
bool CPlayerInput::CallTopCancelHandler(TCancelButtonBitfield cancelButtonPressed)
{
for (int i = 0; i < kCHS_num; ++ i)
{
if (m_inputCancelHandler[i] && m_inputCancelHandler[i]->HandleCancelInput(*m_pPlayer, cancelButtonPressed))
{
return true;
}
}
return false;
}
bool CPlayerInput::CallAllCancelHandlers()
{
bool reply = false;
for (int i = 0; i < kCHS_num; ++ i)
{
if (m_inputCancelHandler[i] && m_inputCancelHandler[i]->HandleCancelInput(*m_pPlayer, kCancelPressFlag_forceAll))
{
reply = true;
}
}
return reply;
}
void CPlayerInput::RemoveInputCancelHandler (IPlayerInputCancelHandler * handler)
{
assert (handler);
for (int i = 0; i < kCHS_num; ++ i)
{
if (m_inputCancelHandler[i] == handler)
{
m_inputCancelHandler[i] = NULL;
return;
}
}
#ifndef _RELEASE
GameWarning ("%s trying to remove input cancel handler %p \"%s\" but it's not installed", m_pPlayer->GetEntity()->GetEntityTextDescription(), handler, handler->DbgGetCancelHandlerName().c_str());
#endif
}
void CPlayerInput::AddInputCancelHandler (IPlayerInputCancelHandler * handler, ECancelHandlerSlot slot)
{
assert (handler);
assert (slot >= 0 && slot < kCHS_num);
#ifndef _RELEASE
CRY_ASSERT_TRACE (m_inputCancelHandler[slot] == NULL, ("%s already has an input cancel handler \"%s\" installed in slot %d - can't add \"%s\" too", m_pPlayer->GetEntity()->GetEntityTextDescription(), m_inputCancelHandler[slot]->DbgGetCancelHandlerName().c_str(), slot, handler->DbgGetCancelHandlerName().c_str()));
#endif
m_inputCancelHandler[slot] = handler;
}
bool CPlayerInput::OnActionCrouch(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (CallTopCancelHandler(kCancelPressFlag_crouchOrProne))
{
return false;
}
uint32 oldCrouchAction = (m_actions & ACTION_CROUCH);
m_crouchButtonDown = (activationMode == eAAM_OnPress);
if (CanCrouch())
{
if (g_pGameCVars->cl_crouchToggle)
{
if (value > 0.0f)
{
if (!(m_actions & ACTION_CROUCH))
m_actions |= ACTION_CROUCH;
else
m_actions &= ~ACTION_CROUCH;
}
}
else
{
if (value > 0.0f)
{
m_actions |= ACTION_CROUCH;
}
else
{
m_actions &= ~ACTION_CROUCH;
}
}
}
// Record 'Crouch' telemetry stats.
if(oldCrouchAction != (m_actions & ACTION_CROUCH))
{
CStatsRecordingMgr::TryTrackEvent(m_pPlayer, eGSE_Crouch, (m_actions & ACTION_CROUCH) != 0);
}
SetSliding((m_actions&ACTION_CROUCH) ? true : false );
#if ENABLE_GAME_CODE_COVERAGE || ENABLE_SHARED_CODE_COVERAGE
if (oldCrouchAction == (m_actions & ACTION_CROUCH))
{
CCCPOINT(PlayerMovement_IgnoreCrouchInput);
}
else if (m_actions & ACTION_CROUCH)
{
CCCPOINT(PlayerMovement_ToggleCrouchActionOn);
}
else
{
CCCPOINT(PlayerMovement_ToggleCrouchActionOff);
}
#endif
return false;
}
//------------------------------------------------------------
void CPlayerInput::SetSliding(bool set)
{
if(set)
{
const SPlayerSlideControl& slideCvars = gEnv->bMultiplayer ? g_pGameCVars->pl_sliding_control_mp : g_pGameCVars->pl_sliding_control;
const SPlayerStats& stats = *m_pPlayer->GetActorStats();
bool canSlide =
(m_pPlayer->IsSprinting()) &&
!m_pPlayer->IsSwimming() &&
(stats.pickAndThrowEntity == 0) &&
((stats.onGround > 0.0f)) &&
(stats.speedFlat >= slideCvars.min_speed_threshold) &&
!m_pPlayer->IsMovementRestricted() &&
!m_pPlayer->HasHeavyWeaponEquipped() &&
(!gEnv->bMultiplayer || gEnv->pTimer->GetFrameStartTime().GetDifferenceInSeconds(m_nextSlideTime) >= 0.0f);
if( canSlide )
{
m_pPlayer->StateMachineHandleEventMovement( PLAYER_EVENT_SLIDE );
m_nextSlideTime = gEnv->pTimer->GetFrameStartTime() + CTimeValue(1.2f);
}
}
else if (m_pPlayer->IsSliding())
{
m_pPlayer->StateMachineHandleEventMovement( PLAYER_EVENT_LAZY_EXITSLIDE );
}
}
bool CPlayerInput::OnActionSprint(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_sprintButtonDown = (activationMode != eAAM_OnRelease);
SInputEventData inputEventData( SInputEventData::EInputEvent_Sprint, entityId, actionId, activationMode, value );
m_pPlayer->StateMachineHandleEventMovement( SStateEventPlayerInput( &inputEventData ) );
return false;
}
bool CPlayerInput::OnActionSprintXI(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
return OnActionSprint( entityId, actionId, activationMode, value );
}
void CPlayerInput::ForceStopSprinting()
{
SInputEventData inputEventData( SInputEventData::EInputEvent_Sprint, m_pPlayer->GetEntityId(), CCryName("sprint"), eAAM_OnRelease, 0.0f );
m_pPlayer->StateMachineHandleEventMovement( SStateEventPlayerInput( &inputEventData ) );
}
bool CPlayerInput::OnActionAttackRightTrigger(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!m_pPlayer->IsDead())
{
if (activationMode & (eAAM_OnPress|eAAM_OnHold))
{
m_actions |= ACTION_FIRE;
}
else
{
m_actions &= ~ACTION_FIRE;
}
return false;
}
else
{
return true;
}
}
bool CPlayerInput::OnActionUse(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
bool filterOut = true;
IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle();
//FIXME:on vehicles use cannot be used
if (pVehicle)
{
filterOut = false;
}
if (activationMode==eAAM_OnPress)
{
m_actions |= ACTION_USE;
}
else
{
m_actions &= ~ACTION_USE;
}
return filterOut;
}
bool CPlayerInput::OnActionThirdPerson(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if (!m_pPlayer->GetSpectatorMode() && m_pPlayer->m_pGameFramework->CanCheat())
{
if (!m_pPlayer->GetLinkedVehicle())
m_pPlayer->ToggleThirdPerson();
}
return false;
}
#ifdef INCLUDE_DEBUG_ACTIONS
bool CPlayerInput::OnActionFlyMode(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if (!m_pPlayer->GetSpectatorMode() && m_pPlayer->m_pGameFramework->CanCheat())
{
uint8 flyMode=m_pPlayer->GetFlyMode()+1;
m_pPlayer->StateMachineHandleEventMovement( SStateEventFly( flyMode ) );
}
return false;
}
#endif
bool CPlayerInput::OnActionGodMode(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if (!m_pPlayer->GetSpectatorMode() && m_pPlayer->m_pGameFramework->CanCheat())
{
CGodMode& godMode = CGodMode::GetInstance();
godMode.MoveToNextState();
godMode.RespawnIfDead(m_pPlayer);
}
return false;
}
bool CPlayerInput::OnActionAIDebugDraw(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if(ICVar* pCVar = gEnv->pConsole->GetCVar("ai_DebugDraw"))
{
pCVar->Set(pCVar->GetIVal()==0 ? 1 : 0);
return true;
}
return false;
}
bool CPlayerInput::OnActionPDrawHelpers(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if(ICVar* pCVar = gEnv->pConsole->GetCVar("p_draw_helpers"))
{
pCVar->Set(pCVar->GetIVal()==0 ? 1 : 0);
return true;
}
return false;
}
bool CPlayerInput::OnActionDMode(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if(ICVar* pCVar = gEnv->pConsole->GetCVar("hud_DMode"))
{
pCVar->Set(pCVar->GetIVal()==0 ? 1 : 0);
return true;
}
return false;
}
bool CPlayerInput::OnActionRecordBookmark(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
#ifdef INCLUDE_GAME_AI_RECORDER
if(CGameAISystem* pAiSys = g_pGame->GetGameAISystem())
{
pAiSys->GetGameAIRecorder().RequestAIRecordBookmark();
}
#endif //INCLUDE_GAME_AI_RECORDER
return false;
}
#ifdef INCLUDE_DEBUG_ACTIONS
bool CPlayerInput::OnActionMannequinDebugAI(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
gEnv->pConsole->ExecuteString("mn_debugai");
return true;
}
bool CPlayerInput::OnActionMannequinDebugPlayer(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (!gEnv->pSystem->IsDevMode())
return false;
if(ICVar* pCVar = gEnv->pConsole->GetCVar("mn_debug"))
{
EntityId actorEntityId = gEnv->pGame->GetIGameFramework()->GetClientActorId();
IEntity* pEntity = gEnv->pEntitySystem->GetEntity(actorEntityId);
if(pEntity)
{
pCVar->Set(strcmp(pCVar->GetString(),pEntity->GetName())==0 ? "" : pEntity->GetName());
return true;
}
}
return false;
}
bool CPlayerInput::OnActionAIDebugCenterViewAgent(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
gEnv->pConsole->ExecuteString("ai_DebugAgent centerview");
return true;
}
#endif
bool CPlayerInput::OnActionXIRotateYaw(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_xi_deltaRotationRaw.z = value;
//NOTE: Controller mapping no longer carried out here. Speak to Richard Semmens
m_isAimingWithMouse = false;
// For now assuming the same fix is needed for HMDs.
m_isAimingWithHMD = false;
return false;
}
bool CPlayerInput::OnActionXIRotatePitch(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_xi_deltaRotationRaw.x = value;
//NOTE: Controller mapping no longer carried out here. Speak to Richard Semmens
// For now assuming the same fix is needed for HMDs.
m_isAimingWithHMD = false;
m_isAimingWithMouse = false;
return false;
}
bool CPlayerInput::OnActionXIMoveX(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (CanMove())
{
m_xi_deltaMovement.x = value;
if(fabsf(value)>0.001f && !m_bUseXIInput)
{
m_bUseXIInput = true;
}
else if(fabsf(value)<=0.001f && m_bUseXIInput && fabsf(m_xi_deltaMovement.y)<=0.001f)
{
m_bUseXIInput = false;
if (!GetMoveButtonsState())
m_actions &= ~ACTION_MOVE;
ClearDeltaMovement();
}
}
return false;
}
bool CPlayerInput::OnActionXIMoveY(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (CanMove())
{
m_xi_deltaMovement.y = value;
if(fabsf(value)>0.001f && !m_bUseXIInput)
{
m_bUseXIInput = true;
}
else if(fabsf(value)<=0.001f && m_bUseXIInput && fabsf(m_xi_deltaMovement.x)<=0.001f)
{
m_bUseXIInput = false;
if (!GetMoveButtonsState())
m_actions &= ~ACTION_MOVE;
ClearDeltaMovement();
}
}
return false;
}
void CPlayerInput::ClearXIMovement()
{
m_xi_deltaRotationRaw.Set(0.0f, 0.0f, 0.0f);
m_xi_deltaRotation.Set(0.f,0.f,0.f);
m_xi_deltaMovement.zero();
}
bool CPlayerInput::OnActionXIDisconnect(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_xi_deltaRotation.Set(0,0,0);
m_xi_deltaMovement.zero();
m_bUseXIInput = false;
ClearDeltaMovement();
return false;
}
bool CPlayerInput::OnActionInvertMouse(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
g_pGameCVars->cl_invertMouse = !g_pGameCVars->cl_invertMouse;
return false;
}
bool CPlayerInput::OnActionFlyCamMoveX(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_flyCamDeltaMovement.x = value;
if(fabs(m_flyCamDeltaMovement.x) < 0.003f)
m_flyCamDeltaMovement.x = 0.f;//some dead point
return false;
}
bool CPlayerInput::OnActionFlyCamMoveY(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_flyCamDeltaMovement.y = value;
if(fabs(m_flyCamDeltaMovement.y) < 0.003f)
m_flyCamDeltaMovement.y = 0.f;//some dead point
return false;
}
bool CPlayerInput::OnActionFlyCamMoveUp(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_flyCamDeltaMovement.z = value;
if(fabs(m_flyCamDeltaMovement.z) < 0.003f)
m_flyCamDeltaMovement.z = 0.f;//some dead point
return false;
}
bool CPlayerInput::OnActionFlyCamMoveDown(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_flyCamDeltaMovement.z = -value;
if(fabs(m_flyCamDeltaMovement.z) < 0.003f)
m_flyCamDeltaMovement.z = 0.f;//some dead point
return false;
}
bool CPlayerInput::OnActionFlyCamSpeedUp(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(activationMode == eAAM_OnPress)
{
g_pGameCVars->g_detachedCameraMoveSpeed = CLAMP(g_pGameCVars->g_detachedCameraMoveSpeed + 0.5f, 0.5f, 30.f);
}
return false;
}
bool CPlayerInput::OnActionFlyCamSpeedDown(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(activationMode == eAAM_OnPress)
{
g_pGameCVars->g_detachedCameraMoveSpeed = CLAMP(g_pGameCVars->g_detachedCameraMoveSpeed - 0.5f, 0.5f, 30.f);
}
return false;
}
bool CPlayerInput::OnActionFlyCamTurbo(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(activationMode == eAAM_OnPress)
{
m_flyCamTurbo=true;
}
else if (activationMode == eAAM_OnRelease)
{
m_flyCamTurbo=false;
}
return false;
}
bool CPlayerInput::OnActionFlyCamRotateYaw(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_flyCamDeltaRotation.z = value;
if(fabs(m_flyCamDeltaRotation.z) < 0.003f)
m_flyCamDeltaRotation.z = 0.f;//some dead point
return false;
}
bool CPlayerInput::OnActionFlyCamRotatePitch(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_flyCamDeltaRotation.x = value;
if(fabs(m_flyCamDeltaRotation.x) < 0.003f)
m_flyCamDeltaRotation.x = 0.f;//some dead point
return false;
}
bool CPlayerInput::OnActionFlyCamSetPoint(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
#if FREE_CAM_SPLINE_ENABLED
if(activationMode == eAAM_OnPress)
{
AddFlyCamPoint();
}
#endif
return false;
}
void CPlayerInput::AddFlyCamPoint()
{
IView* pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetActiveView();
assert(pView);
const SViewParams* pViewParams = pView->GetCurrentParams();
Vec3 curPos = pViewParams->position;
Vec3 lookAtPos = pViewParams->position;
Matrix34 mtx(pViewParams->rotation);
Vec3 forward(0.f,3.f,0.f);
forward = mtx * forward;
lookAtPos += forward;
AddFlyCamPoint(curPos, lookAtPos);
}
void CPlayerInput::AddFlyCamPoint(Vec3 pos, Vec3 lookAtPos)
{
#if FREE_CAM_SPLINE_ENABLED
if (m_freeCamCurrentIndex < MAX_FREE_CAM_DATA_POINTS)
{
SFreeCamPointData &camData = m_freeCamData[m_freeCamCurrentIndex];
camData.valid = true;
camData.position = pos;
camData.lookAtPosition = lookAtPos;
CryLog("FREECAM Added new FreeCamPointData - index:%d pos:%f %f %f lookAt:%f %f %f", m_freeCamCurrentIndex, pos.x, pos.y, pos.z, lookAtPos.x, lookAtPos.y, lookAtPos.z);
++m_freeCamCurrentIndex;
}
else
{
CryLog("FREECAM Have reached the maximum (%d) num of FreeCamPointData, no more can be added!", MAX_FREE_CAM_DATA_POINTS);
}
#endif
}
void CPlayerInput::FlyCamPlay()
{
#if FREE_CAM_SPLINE_ENABLED
m_freeCamPlaying = !m_freeCamPlaying;
if (m_freeCamPlaying)
{
m_freeCamPlayTimer = 0.f;
int num=0;
SFreeCamPointData *camData = NULL;
SFreeCamPointData *lastCamData = NULL;
float totalDistance = 0.f;
Vec3 diff;
for (num=0; num < MAX_FREE_CAM_DATA_POINTS; ++num)
{
camData = &m_freeCamData[num];
if (camData->valid)
{
if (lastCamData)
{
diff = camData->position - lastCamData->position;
camData->distanceFromLast = diff.len();
totalDistance += camData->distanceFromLast;
}
}
else
{
break;
}
lastCamData = camData;
}
m_freeCamSpline.resize(num);
m_freeCamLookAtSpline.resize(num);
float curDistance = 0.f;
for (int i=0; i<num; ++i)
{
camData = &m_freeCamData[i];
curDistance += camData->distanceFromLast;
float time = curDistance / totalDistance;
m_freeCamSpline.key(i).flags = 0;
m_freeCamSpline.time(i) = time;
m_freeCamSpline.value(i) = camData->position;
m_freeCamLookAtSpline.key(i).flags = 0;
m_freeCamLookAtSpline.time(i) = time;
m_freeCamLookAtSpline.value(i) = camData->lookAtPosition;
}
m_freeCamTotalPlayTime = totalDistance / g_pGameCVars->g_detachedCameraMoveSpeed;
if (num > 0)
CryLog("FREECAM Starting to play free cam spline numpoints:%d distance:%f totaltime:%f", num, totalDistance, m_freeCamTotalPlayTime);
else
CryLog("FREECAM Cannot start playing free cam spline - no points set");
}
else
{
CryLog("FREECAM Stop playing free cam spline");
}
#endif
}
bool CPlayerInput::OnActionFlyCamPlay(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(activationMode == eAAM_OnPress)
{
FlyCamPlay();
}
return false;
}
bool CPlayerInput::OnActionFlyCamClear(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
#if FREE_CAM_SPLINE_ENABLED
if(activationMode == eAAM_OnPress)
{
for (int i=0; i<MAX_FREE_CAM_DATA_POINTS; ++i)
{
SFreeCamPointData &camData = m_freeCamData[i];
camData.valid = false;
}
m_freeCamCurrentIndex = 0;
m_freeCamPlayTimer = 0.f;
m_freeCamTotalPlayTime = 0.f;
m_freeCamSpline.empty();
m_freeCamLookAtSpline.empty();
CryLog("FREECAM Cleared data");
}
#endif
return false;
}
bool CPlayerInput::OnActionSpecial(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (CallTopCancelHandler())
{
return false;
}
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if (activationMode == eAAM_OnPress)
{
if (interactionInfo.interactionType == eInteraction_Stealthkill)
{
m_pPlayer->AttemptStealthKill(interactionInfo.interactiveEntityId);
}
else if (interactionInfo.interactionType == eInteraction_LargeObject)
{
if(!m_pPlayer->GetLargeObjectInteraction().IsBusy())
{
m_pPlayer->EnterLargeObjectInteraction(interactionInfo.interactiveEntityId); //always use power kick in MP
}
}
}
return false;
}
bool CPlayerInput::OnActionChangeFireMode(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(activationMode == eAAM_OnPress && !m_pPlayer->IsCinematicFlagActive(SPlayerStats::eCinematicFlag_LowerWeapon) && !m_pPlayer->IsCinematicFlagActive(SPlayerStats::eCinematicFlag_LowerWeaponMP))
{
SHUDEvent event(eHUDEvent_ShowDpadMenu);
event.AddData(eDPAD_Left);
CHUDEventDispatcher::CallEvent(event);
}
return false;
}
bool CPlayerInput::OnActionToggleVision(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
m_openingVisor = false;
return false;
}
bool CPlayerInput::OnActionMindBattle(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
SInputEventData inputEventData( SInputEventData::EInputEvent_ButtonMashingSequence, entityId, actionId, activationMode, value );
m_pPlayer->StateMachineHandleEventMovement( SStateEventPlayerInput( &inputEventData ) );
return false;
}
bool CPlayerInput::OnActionLookAt( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
float currentTime = gEnv->pTimer->GetCurrTime();
if (activationMode == eAAM_OnPress)
m_lookAtTimeStamp = currentTime;
else if (activationMode == eAAM_OnHold)
m_lookingAtButtonActive = currentTime > m_lookAtTimeStamp + g_pGameCVars->pl_useItemHoldTime;
else if (activationMode == eAAM_OnRelease)
m_lookingAtButtonActive = false;
return false;
}
bool CPlayerInput::OnActionPrePickUpItem( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if ((interactionInfo.interactionType == eInteraction_ExchangeItem) ||
(interactionInfo.interactionType == eInteraction_PickupItem))
{
//Most probably we will end pick up this item soon, start to preload dba's ahead
CItem* pTargetItem = static_cast<CItem*>(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(interactionInfo.interactiveEntityId));
if (pTargetItem)
{
pTargetItem->Prepare1pAnimationDbas();
pTargetItem->Prepare1pChrs();
}
}
else if( IInventory* pInventory = m_pPlayer->GetInventory() )
{
if ( CWeapon *pWeapon = m_pPlayer->GetWeapon(pInventory->GetCurrentItem()) )
{
const char* category = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItemCategory(pWeapon->GetEntity()->GetClass()->GetName());
int categoryType = GetItemCategoryType(category);
bool currentItemIsGrenade = (categoryType & DoubleTapGrenadeCategories()) != 0;
if(!currentItemIsGrenade)
{
pWeapon->CancelCharge();
}
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CPlayerInput::OnActionMoveOverlayTurnOn( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
m_moveOverlay.isEnabled = true;
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CPlayerInput::OnActionMoveOverlayTurnOff( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
m_moveOverlay.isEnabled = false;
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CPlayerInput::OnActionMoveOverlayWeight( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
m_moveOverlay.weight = clamp_tpl(value, 0.0f, 1.0f);
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CPlayerInput::OnActionMoveOverlayX( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
m_moveOverlay.moveX = clamp_tpl(value, -1.0f, 1.0f);
return false;
}
//////////////////////////////////////////////////////////////////////////
bool CPlayerInput::OnActionMoveOverlayY( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
m_moveOverlay.moveY = clamp_tpl(-value, -1.0f, 1.0f);
return true;
}
bool CPlayerInput::OnActionRespawn(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if (m_pPlayer->IsDead())
{
g_pGame->OnDeathReloadComplete();
}
return false;
}
bool CPlayerInput::OnActionMouseWheelClick(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
if(activationMode == eAAM_OnPress)
{
CHUDEventDispatcher::CallEvent(SHUDEvent(eHUDEvent_ShowMouseWheel));
}
else if (activationMode == eAAM_OnRelease)
{
CHUDEventDispatcher::CallEvent(SHUDEvent(eHUDEvent_HideMouseWheel));
}
return false;
}
void CPlayerInput::AdjustMoveButtonState(EMoveButtonMask buttonMask, int activationMode )
{
if (activationMode == eAAM_OnPress || activationMode == eAAM_OnHold)
{
m_moveButtonState |= buttonMask;
}
else if (activationMode == eAAM_OnRelease)
{
m_moveButtonState &= ~buttonMask;
}
}
bool CPlayerInput::CheckMoveButtonStateChanged(EMoveButtonMask buttonMask, int activationMode)
{
bool current = (m_moveButtonState & buttonMask) != 0;
if(activationMode == eAAM_OnRelease)
{
return current;
}
else if(activationMode == eAAM_OnPress || activationMode == eAAM_OnHold)
{
return !current;
}
return true;
}
float CPlayerInput::MapControllerValue(float value, float scale, float curve, bool inverse)
{
// Any attempts to create an advanced analog stick value mapping function could be put here
// After several experiments a simple pow(x, n) function seemed to work best.
float res=scale * powf(fabs(value), curve);
return (value >= 0.0f ? (inverse ? -1.0f : 1.0f) : (inverse ? 1.0f : -1.0f))*res;
}
void CPlayerInput::ClearAllExceptAction( uint32 actionFlags )
{
uint32 actionsToKeep = m_actions & actionFlags;
Reset();
m_actions |= actionsToKeep;
}
bool CPlayerInput::OnActionSelectNextItem(EntityId entityId, const ActionId& actionId, int activationMode, float value)
{
const CGameActions& actions = g_pGame->Actions();
bool suitVisorOn = false;
bool allowSwitch = true;
const float currentTime = gEnv->pTimer->GetCurrTime();
bool inKillCam = g_pGame->GetRecordingSystem() && (g_pGame->GetRecordingSystem()->IsPlayingBack() || g_pGame->GetRecordingSystem()->IsPlaybackQueued());
IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle();
if (m_pPlayer->GetSpectatorMode() || inKillCam)
return false;
if (pVehicle)
return false;
if (!IsPlayerOkToAction())
return false;
if (actions.toggle_weapon==actionId)
{
allowSwitch = AllowToggleWeapon(activationMode, currentTime);
}
else if (actions.handgrenade==actionId) // Keyboard only action
{
const bool bHasGrenades = (!gEnv->bMultiplayer || g_pGameCVars->g_enableMPDoubleTapGrenadeSwitch) && DoubleTapGrenadeAvailable();
if (!bHasGrenades)
{
const float displayTime = gEnv->bMultiplayer ? g_pGame->GetUI()->GetCVars()->hud_warningDisplayTimeMP : g_pGame->GetUI()->GetCVars()->hud_warningDisplayTimeSP;
SHUDEventWrapper::DisplayInfo( eInfo_Warning, displayTime, "@ui_no_grenades");
}
}
if(allowSwitch && !CallTopCancelHandler(kCancelPressFlag_switchItem))
{
bool currentItemIsGrenade = false;
if(IInventory* pInventory = m_pPlayer->GetInventory())
{
EntityId itemId = pInventory->GetCurrentItem();
CWeapon *pWeapon = 0;
if (itemId)
{
pWeapon = m_pPlayer->GetWeapon(itemId);
if (pWeapon)
{
IEntityClass* pEntityClass = pWeapon->GetEntity()->GetClass();
assert(pEntityClass != NULL);
if (pEntityClass != NULL)
{
suitVisorOn = (pEntityClass == CItem::sBinocularsClass);
// Support the primary secondary fast weapon switching (Doesn't wait for animations to finish)
const char* category = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItemCategory(pEntityClass->GetName());
int categoryType = GetItemCategoryType(category);
if (categoryType & eICT_Primary || categoryType & eICT_Secondary) // For primary or secondary can ignore the can deselect
allowSwitch = !pWeapon->IsMounted();
else
allowSwitch = pWeapon->CanDeselect() && !pWeapon->IsMounted();
currentItemIsGrenade = (categoryType & DoubleTapGrenadeCategories()) != 0;
if(allowSwitch && actionId == actions.toggle_weapon)
{
CFireMode* pFiremode = static_cast<CFireMode*>(pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()));
if(pFiremode && pFiremode->IsEnabledByAccessory())
{
pWeapon->StartChangeFireMode();
allowSwitch = false;
}
}
}
}
}
}
if (allowSwitch)
{
if (actions.nextitem==actionId)
SelectNextItem(1, true, eICT_Grenade|eICT_Explosive|eICT_Primary|eICT_Secondary|eICT_Special, suitVisorOn);
else if (actions.previtem==actionId)
SelectNextItem(-1, true, eICT_Grenade|eICT_Explosive|eICT_Primary|eICT_Secondary|eICT_Special, suitVisorOn);
else if (actions.handgrenade == actionId)
{
int category = gEnv->bMultiplayer ? eICT_Grenade|eICT_Explosive : eICT_Grenade;
SelectNextItem(1, true, category, suitVisorOn);
}
else if (actions.toggle_explosive == actionId)
{
int primaryCategory = eICT_Primary | eICT_Secondary;
int secondaryCategory = gEnv->bMultiplayer ? eICT_Grenade|eICT_Explosive : eICT_Explosive;
SHUDEvent event(eHUDEvent_IsDoubleTapExplosiveSelect);
event.AddData(SHUDEventData(false));
CHUDEventDispatcher::CallEvent(event);
ToggleItem(primaryCategory, secondaryCategory, suitVisorOn);
}
else if (actions.toggle_special == actionId)
{
int primaryCategory = eICT_Primary | eICT_Secondary;
int secondaryCategory = eICT_Special;
ToggleItem(primaryCategory, secondaryCategory, suitVisorOn);
}
else if (actions.toggle_weapon ==actionId)
{
float fCurrentTimeStamp = gEnv->pTimer->GetFrameStartTime().GetSeconds();
bool bHasGrenades = DoubleTapGrenadeAvailable();
float fTapTime = 0.2f;
fTapTime = g_pGame->GetUI()->GetCVars()->hud_double_taptime;
if (currentItemIsGrenade || !bHasGrenades)
{
bool doubleTapTime = fCurrentTimeStamp - m_fLastWeaponToggleTimeStamp < fTapTime;
if(m_fLastWeaponToggleTimeStamp && !doubleTapTime)
{
SelectNextItem(1, true, eICT_Primary | eICT_Secondary, suitVisorOn);
m_fLastWeaponToggleTimeStamp = 0.f;
}
else
{
m_fLastWeaponToggleTimeStamp = fCurrentTimeStamp;
}
if (fCurrentTimeStamp - m_fLastNoGrenadeTimeStamp < fTapTime && !bHasGrenades && (!gEnv->bMultiplayer || g_pGameCVars->g_enableMPDoubleTapGrenadeSwitch) )
{
const float displayTime = gEnv->bMultiplayer ? g_pGame->GetUI()->GetCVars()->hud_warningDisplayTimeMP : g_pGame->GetUI()->GetCVars()->hud_warningDisplayTimeSP;
SHUDEventWrapper::DisplayInfo( eInfo_Warning, displayTime, "@ui_no_grenades");
m_fLastWeaponToggleTimeStamp = 0.f;
}
}
else if (fCurrentTimeStamp - m_fLastWeaponToggleTimeStamp < fTapTime)
{
SHUDEvent event(eHUDEvent_IsDoubleTapExplosiveSelect);
event.AddData(SHUDEventData(true));
CHUDEventDispatcher::CallEvent(event);
SelectNextItem(1, true, DoubleTapGrenadeCategories(), suitVisorOn);
SActorStats* pActorStats = m_pPlayer->GetActorStats();
if(pActorStats)
{
if (CWeapon* pCurrentItem = static_cast<CWeapon*>(m_pPlayer->GetItem(pActorStats->exchangeItemStats.switchingToItemID)))
{
pCurrentItem->CancelCharge();
}
}
m_fLastWeaponToggleTimeStamp = 0.f;
}
else
{
CItem *pCurItem = (CItem*)m_pPlayer->GetCurrentItem();
const int numOptions = m_pPlayer->GetInventory()->GetSlotCount(IInventory::eInventorySlot_Weapon);
if (pCurItem && m_pPlayer->CanSwitchItems() && (numOptions > 1) && pCurItem->CanDeselect())
{
pCurItem->StartDeselection(false);
}
m_fLastWeaponToggleTimeStamp = fCurrentTimeStamp;
}
if (!bHasGrenades)
{
m_fLastNoGrenadeTimeStamp = fCurrentTimeStamp;
}
}
else if (actions.debug==actionId)
{
if (g_pGame)
{
if (!m_pPlayer->GetInventory()->GetItemByClass(CItem::sDebugGunClass)&& CItem::sDebugGunClass != 0)
g_pGame->GetWeaponSystem()->DebugGun(0);
if (!m_pPlayer->GetInventory()->GetItemByClass(CItem::sRefWeaponClass) && CItem::sRefWeaponClass != 0)
g_pGame->GetWeaponSystem()->RefGun(0);
}
int currentItemCategory = GetItemCategoryType(actionId.c_str());
SelectNextItem(1, true, currentItemCategory, suitVisorOn);
}
}
}
return false;
}
bool CPlayerInput::OnActionQuickGrenadeThrow( EntityId entityId, const ActionId& actionId, int activationMode, float value )
{
if (!UseQuickGrenadeThrow())
{
return false;
}
bool suitVisorOn = false;
bool allowSwitch = true;
const float currentTime = gEnv->pTimer->GetCurrTime();
bool inKillCam = g_pGame->GetRecordingSystem() && (g_pGame->GetRecordingSystem()->IsPlayingBack() || g_pGame->GetRecordingSystem()->IsPlaybackQueued());
IVehicle* pVehicle = m_pPlayer->GetLinkedVehicle();
if (m_pPlayer->GetSpectatorMode() || inKillCam || pVehicle || !IsPlayerOkToAction())
{
return false;
}
CItem *pCurrentItem = static_cast<CItem*>(m_pPlayer->GetCurrentItem());
bool bInvalidWeapon = pCurrentItem && (pCurrentItem->IsRippingOrRippedOff() || pCurrentItem->IsMounted() || pCurrentItem->IsHeavyWeapon());
if (bInvalidWeapon)
{
return false;
}
if(m_pPlayer->IsInPickAndThrowMode())
{
return false;
}
if(CGameRules* pGameRules = g_pGame->GetGameRules())
{
if(IGameRulesObjectivesModule* pObjectivesModule = pGameRules->GetObjectivesModule())
{
if(pObjectivesModule->CheckIsPlayerEntityUsingObjective(m_pPlayer->GetEntityId()))
{
return false;
}
}
}
if(m_pPlayer->IsInPickAndThrowMode())
{
return false;
}
const CGameActions& actions = g_pGame->Actions();
if (actions.grenade == actionId ||(gEnv->bMultiplayer && actions.xi_grenade == actionId))
{
IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
const int grenadeCategories = eICT_Grenade;
if (activationMode == eAAM_OnPress)
{
const bool bCanActivate = !m_pPlayer->IsSliding() &&
!m_pPlayer->IsExitingSlide() &&
!m_pPlayer->IsSwimming() &&
!m_pPlayer->IsOnLedge();
if(bCanActivate)
{
IInventory *pInventory = m_pPlayer->GetInventory();
if (pInventory)
{
int numItems = pInventory->GetCount();
for (int i = 0; i < numItems; i ++)
{
EntityId itemId = pInventory->GetItem(i);
IItem* pItem = pItemSystem->GetItem(itemId);
if (pItem && !pItem->IsSelected() && pItem->CanSelect())
{
const char* category = pItemSystem->GetItemCategory(pItem->GetEntity()->GetClass()->GetName());
int categoryType = GetItemCategoryType(category);
if (categoryType & grenadeCategories)
{
ForceStopSprinting();
m_pPlayer->SelectItem(pItem->GetEntityId(), true, false);
CWeapon *pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon());
if (pWeapon)
{
pWeapon->StartQuickGrenadeThrow();
}
break;
}
//We don't have a grenade... but we have some explosives... so make these the active item
else if(categoryType & eICT_Explosive)
{
m_pPlayer->SelectItem(pItem->GetEntityId(), true, false);
break;
}
}
}
}
}
}
else if (activationMode == eAAM_OnRelease)
{
IItem *pItem = m_pPlayer->GetCurrentItem();
if (pItem)
{
const char* category = pItemSystem->GetItemCategory(pItem->GetEntity()->GetClass()->GetName());
int categoryType = GetItemCategoryType(category);
if (categoryType & grenadeCategories)
{
CWeapon *pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon());
if (pWeapon)
{
pWeapon->StopQuickGrenadeThrow();
}
}
}
}
}
return false;
}
bool CPlayerInput::DoubleTapGrenadeAvailable()
{
if(gEnv->bMultiplayer && g_pGameCVars->g_enableMPDoubleTapGrenadeSwitch == 0)
{
return false;
}
if(IInventory* pInventory = m_pPlayer->GetInventory())
{
IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
int grenadeCategories = DoubleTapGrenadeCategories();
int numItems = pInventory->GetCount();
for(int i = 0; i < numItems; i++)
{
EntityId itemId = pInventory->GetItem(i);
IItem* pItem = pItemSystem->GetItem(itemId);
if(pItem && pItem->CanSelect())
{
const char* category = pItemSystem->GetItemCategory(pItem->GetEntity()->GetClass()->GetName());
int categoryType = GetItemCategoryType(category);
if(categoryType & grenadeCategories)
{
return true;
}
}
}
}
return false;
}
void CPlayerInput::UpdateWeaponToggle()
{
if(m_fLastWeaponToggleTimeStamp)
{
float fCurrentTimeStamp = gEnv->pTimer->GetFrameStartTime().GetSeconds();
float fTapTime = 0.2f;
fTapTime = g_pGame->GetUI()->GetCVars()->hud_double_taptime;
if (fCurrentTimeStamp - m_fLastWeaponToggleTimeStamp > fTapTime)
{
bool suitVisorOn = false;
bool allowSwitch = true;
if(IInventory* pInventory = m_pPlayer->GetInventory())
{
CItem* pCurrentItem = static_cast<CItem*>(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pInventory->GetCurrentItem()));
if(pCurrentItem)
{
allowSwitch = pCurrentItem->CanDeselect();
suitVisorOn = (pCurrentItem->GetEntity()->GetClass() == CItem::sBinocularsClass);
}
}
if (allowSwitch)
{
SelectNextItem(1, true, eICT_Primary | eICT_Secondary, suitVisorOn);
}
m_fLastWeaponToggleTimeStamp = 0.f;
}
}
}
void CPlayerInput::ToggleVisor()
{
bool toggleVisor = !m_pPlayer->IsDead();
IInventory* pInventory = m_pPlayer->GetInventory();
if (pInventory)
{
EntityId itemId = pInventory->GetCurrentItem();
if (itemId)
{
CWeapon* pWeapon = m_pPlayer->GetWeapon(itemId);
toggleVisor = pWeapon ? !pWeapon->IsReloading() : toggleVisor;
}
}
}
void CPlayerInput::SelectNextItem( int direction, bool keepHistory, int category, bool disableVisorFirst )
{
m_pPlayer->SelectNextItem(direction, keepHistory, category);
}
void CPlayerInput::ToggleItem(int primaryCategory, int secondaryCategory, bool disableVisorFirst)
{
IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
IItem* pCurrentItem = m_pPlayer->GetCurrentItem();
if (pCurrentItem)
{
const char* name = pCurrentItem->GetEntity()->GetClass()->GetName();
const char* nextWeaponCatStr = pItemSystem->GetItemCategory(name);
int currentCategory = GetItemCategoryType(nextWeaponCatStr);
int nextCategory = secondaryCategory;
if (currentCategory == secondaryCategory)
nextCategory = primaryCategory;
SelectNextItem(1, true, nextCategory, disableVisorFirst);
}
}
bool CPlayerInput::CanLookAt()
{
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
bool canLookAt = interactionInfo.lookAtInfo.lookAtTargetId != 0;
return canLookAt;
}
void CPlayerInput::UpdateAutoLookAtTargetId( float frameTime )
{
const SInteractionInfo& interactionInfo = m_pPlayer->GetCurrentInteractionInfo();
if ( !(m_lookingAtButtonActive || interactionInfo.lookAtInfo.forceLookAt) )
{
m_isNearTheLookAtTarget = false;
m_lookAtSmoothRate.Set(0.f, 0.f, 0.f);
return;
}
if (interactionInfo.lookAtInfo.lookAtTargetId == 0)
{
m_lookAtSmoothRate.Set(0.f, 0.f, 0.f);
return;
}
IEntity* pLookAtEntity = gEnv->pEntitySystem->GetEntity(interactionInfo.lookAtInfo.lookAtTargetId);
if (!pLookAtEntity)
{
m_lookAtSmoothRate.Set(0.f, 0.f, 0.f);
return;
}
AABB entityBbox;
pLookAtEntity->GetWorldBounds(entityBbox);
const Vec3 lookAtEntityPosition = (entityBbox.IsEmpty() == false) ? entityBbox.GetCenter(): pLookAtEntity->GetWorldPos();
const Vec3 playerEyePosition = m_pPlayer->GetEntity()->GetWorldTM().TransformPoint(m_pPlayer->GetEyeOffset());
const Quat desiredLookAtOrientation = Quat::CreateRotationVDir((lookAtEntityPosition - playerEyePosition).GetNormalizedSafe());
const Ang3 desiredLookAtAngles(desiredLookAtOrientation);
const Ang3 currentViewAngles(m_pPlayer->GetViewQuat());
Ang3 diffAngles = desiredLookAtAngles - currentViewAngles;
diffAngles.x = DEG2RAD(Snap_s180(RAD2DEG(diffAngles.x)));
diffAngles.z = DEG2RAD(Snap_s180(RAD2DEG(diffAngles.z)));
diffAngles.y = 0;
Ang3 smoothedDiffAngles = diffAngles;
Ang3 targetDiff(0.f, 0.f, 0.f);
SmoothCD( smoothedDiffAngles, m_lookAtSmoothRate, frameTime, targetDiff, interactionInfo.lookAtInfo.interpolationTime );
Ang3 difference = diffAngles - smoothedDiffAngles;
difference.y = 0;
CMovementRequest request;
request.AddDeltaRotation( difference );
m_pPlayer->m_pMovementController->RequestMovement( request );
const float dist = fabs(diffAngles.x) + fabs(diffAngles.y) + fabs(diffAngles.z);
m_isNearTheLookAtTarget = (dist < g_pGameCVars->pl_aim_near_lookat_target_distance);
}
bool CPlayerInput::IsItemPickUpScriptAction(const ActionId& actionId) const
{
const CGameActions& actions = g_pGame->Actions();
const ActionId* itemPickUpEvents[] =
{
&actions.heavyweaponremove,
&actions.use,
&actions.itemPickup,
&actions.preUse,
};
const int numEvents = sizeof(itemPickUpEvents) / sizeof(itemPickUpEvents[0]);
for (int i = 0; i < numEvents; ++i)
if (actionId == *itemPickUpEvents[i])
return true;
return false;
}
bool CPlayerInput::UseQuickGrenadeThrow()
{
if (g_pGameCVars->g_useQuickGrenadeThrow == 1)
{
return true;
}
else if (gEnv->bMultiplayer && (g_pGameCVars->g_useQuickGrenadeThrow == 2))
{
return true;
}
return false;
}
void CPlayerInput::AddCrouchAction()
{
if(g_pGameCVars->cl_crouchToggle)
{
m_actions |= ACTION_CROUCH;
}
else
{
m_actions |= ACTION_FORCE_CROUCH;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CAIInput::CAIInput( CPlayer * pPlayer ) :
m_pPlayer(pPlayer),
m_pStats(&pPlayer->m_stats)
{
}
CAIInput::~CAIInput()
{
}
void CAIInput::GetState( SSerializedPlayerInput& input )
{
SMovementState movementState;
m_pPlayer->GetMovementController()->GetMovementState( movementState );
Quat worldRot = m_pPlayer->GetBaseQuat();
input.stance = movementState.stance;
input.bodystate = 0;
IAIActor* pAIActor = CastToIAIActorSafe(m_pPlayer->GetEntity()->GetAI());
if (pAIActor)
{
input.bodystate=pAIActor->GetState().bodystate;
input.allowStrafing = pAIActor->GetState().allowStrafing;
}
input.deltaMovement = movementState.movementDirection.GetNormalizedSafe()*movementState.desiredSpeed;
input.lookDirection = movementState.eyeDirection;
input.bodyDirection = movementState.entityDirection;
input.sprint = false;
IAnimationGraphState *pState=0;
if (m_pPlayer->GetAnimatedCharacter())
pState=m_pPlayer->GetAnimatedCharacter()->GetAnimationGraphState();
if (pState)
{
input.pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(input.sprint);
}
}
void CAIInput::SetState( const SSerializedPlayerInput& input )
{
GameWarning("CAIInput::SetState called: should never happen");
}
/*
==================================================================================================================
SSerializedPlayerInput
==================================================================================================================
*/
#define PLAYER_INPUT_STANDING_ON_OFFSET Vec3(20.f)
static void SerialiseRelativePosition(TSerialize ser, Vec3& position, EntityId standingOn)
{
// Convert position to local space and offset it since policy
// doesn't allow negative numbers
IEntity* pGroundEntity = gEnv->pEntitySystem->GetEntity(standingOn);
if (ser.IsReading())
{
ser.Value( "position", position, 'wrld' );
if (pGroundEntity)
position -= PLAYER_INPUT_STANDING_ON_OFFSET;
}
else
{
Vec3 serPosition = position;
if (pGroundEntity!=NULL)
serPosition = (pGroundEntity->GetWorldTM().GetInverted() * position) + PLAYER_INPUT_STANDING_ON_OFFSET;
ser.Value( "position", serPosition, 'wrld' );
}
}
void SSerializedPlayerInput::Serialize( TSerialize ser, EEntityAspects aspect )
{
if (aspect & CPlayer::ASPECT_INPUT_CLIENT)
{
ser.Value( "stance", stance, 'stnc' );
ser.Value( "deltaMovement", deltaMovement, 'dMov' );
SerializeDirHelper(ser, lookDirection, 'pYaw', 'pElv');
ser.Value( "sprint", sprint, 'bool' );
ser.Value( "inAir", inAir, 'bool' );
ser.Value( "physcounter", physCounter, 'ui2');
}
else if (aspect & CPlayer::ASPECT_INPUT_CLIENT_AUGMENTED)
{
bool bIsEntity = standingOn!=0;
ser.Value( "bIsEntity", bIsEntity, 'bool');
ser.Value( "standingOn", standingOn, 'eid');
// Did we get a valid entity? This is a failsafe for late joiners to get CryNetwork to send the data again!
if (ser.IsReading() && standingOn==0 && bIsEntity)
ser.FlagPartialRead();
}
// Always serialise the position
SerialiseRelativePosition(ser, position, standingOn);
}
#include "StdAfx.h"
#include "ProximityMine.h"
#include "IActorSystem.h"
//Mass Operations
#define KG2LB(Kilograms) (float)Kilograms * 2.2046
#define LB2KG(Pounds) (float)Pounds / 2.2046
CProximityMine::CProximityMine() :
m_pSelfTable(nullptr),
m_Script_bActive(true),
m_Script_bRigidBodyActive(true),
m_Script_fMass(20.0f),
m_Script_bIgnorePlayer(true),
m_Script_fDetonationRadius(1.0f),
m_Script_fExplosionStrength(200.0f),
m_Script_object_Model("GameSDK/Objects/weapons/ammo/avmine/avmine.cgf")
{
}
CProximityMine::~CProximityMine()
{
}
void CProximityMine::GetMemoryUsage(ICrySizer *pSizer) const
{
pSizer->Add(this);
}
bool CProximityMine::Init(IGameObject * pGameObject)
{
SetGameObject(pGameObject);
/*IEntity *pEnt = GetEntity();
if (pEnt){
pEnt->LoadGeometry(0, "GameSDK/Objects/weapons/ammo/avmine/avmine.cgf",(const char*)NULL, IEntity::EEntityLoadFlags::EF_AUTO_PHYSICALIZE);
}*/
return true;
}
void CProximityMine::PostInit(IGameObject * pGameObject)
{
IEntity *pEnt = GetEntity();
if (pEnt)
{
UpdateEntityTables();
UpdateEntityProperties();
if (m_Script_bActive)
pGameObject->EnableUpdateSlot(this, 0);
else
pGameObject->DisableUpdateSlot(this, 0);
pEnt->LoadGeometry(0, m_Script_object_Model, (const char*)NULL, IEntity::EEntityLoadFlags::EF_AUTO_PHYSICALIZE);
SEntityPhysicalizeParams PhysParams;
PhysParams.density = 0;
//LB2KG Is Defined In "StdAfx.h" As #define LB2KG(Pounds) (double)Pounds / 2.2046 (Not works for me)
PhysParams.mass = LB2KG(m_Script_fMass);
PhysParams.nSlot = 0;
if (m_Script_bRigidBodyActive)
PhysParams.type = PE_RIGID;
else
PhysParams.type = PE_STATIC;
pEnt->Physicalize(PhysParams);
}
}
void CProximityMine::InitClient(int channelId){}
void CProximityMine::PostInitClient(int channelId){}
bool CProximityMine::ReloadExtension(IGameObject * pGameObject, const SEntitySpawnParams &params)
{
ResetGameObject();
return true;
}
void CProximityMine::PostReloadExtension(IGameObject * pGameObject, const SEntitySpawnParams &params){}
bool CProximityMine::GetEntityPoolSignature(TSerialize signature)
{
return true;
}
void CProximityMine::Release()
{
delete this;
}
void CProximityMine::FullSerialize(TSerialize ser){
ser.Value("bActive", m_Script_bActive);
ser.Value("bRigidBodyActive", m_Script_bRigidBodyActive);
ser.Value("fMass", m_Script_fMass);
ser.Value("bIgnorePlayer", m_Script_bIgnorePlayer);
ser.Value("fDetonationRadius", m_Script_fDetonationRadius);
ser.Value("fExplosionStrength", m_Script_fExplosionStrength);
ser.Value("object_Model", m_Script_object_Model);
}
bool CProximityMine::NetSerialize(TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags)
{
return true;
}
void CProximityMine::PostSerialize(){}
void CProximityMine::SerializeSpawnInfo(TSerialize ser){}
ISerializableInfoPtr CProximityMine::GetSpawnInfo()
{
return nullptr;
}
void CProximityMine::Update(SEntityUpdateContext& ctx, int updateSlot)
{
IEntity *pEnt = GetEntity();
if (pEnt){
SEntityProximityQuery Query;
Query.box = AABB(pEnt->GetWorldPos(), m_Script_fDetonationRadius);
Query.nEntityFlags = 0;
Query.pEntityClass = nullptr;
gEnv->pEntitySystem->QueryProximity(Query);
IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor();
bool bExploded = false;
for (int i = 0; i < Query.nCount; i++){
IEntity *pQueryEnt = Query.pEntities[i];
IPhysicalEntity *pQueryPhysEnt = pQueryEnt->GetPhysics();
if (pQueryPhysEnt && (pQueryEnt != pEnt) && (pQueryEnt->GetClass() != gEnv->pEntitySystem->GetClassRegistry()->FindClass("ProximityMine"))){
//if (pQueryPhysEnt && (pQueryEnt != pEnt) && (pQueryEnt->GetClass() != gEnv->pEntitySystem->GetClassRegistry()->FindClass("ProximityMine")) && (pQueryEnt != gEnv->pGame->GetIGameFramework()->GetClientActor()->GetEntity())){
if (m_Script_bIgnorePlayer){
if (pQueryEnt != pPlayerActor->GetEntity()){
pe_action_impulse Impulse;
Impulse.iApplyTime = 0;
Vec3 Dir = (pQueryEnt->GetWorldPos() - pEnt->GetWorldPos()).normalized();
Dir.SetLength(m_Script_fExplosionStrength);
Impulse.impulse = Dir;
pQueryPhysEnt->Action(&Impulse);
bExploded = true;
}
}
else{
pe_action_impulse Impulse;
Impulse.iApplyTime = 0;
Vec3 Dir = (pQueryEnt->GetWorldPos() - pEnt->GetWorldPos()).normalized();
Dir.SetLength(m_Script_fExplosionStrength);
Impulse.impulse = Dir;
pQueryPhysEnt->Action(&Impulse);
bExploded = true;
}
}
IActor *pQueryActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pQueryEnt->GetId());
if (pQueryActor){
if (m_Script_bIgnorePlayer){
if (pQueryActor != pPlayerActor){
pQueryActor->SetHealth(-1);
bExploded = true;
}
}
else{
pQueryActor->SetHealth(-1);
bExploded = true;
}
}
}
if (bExploded)
GetGameObject()->DisableUpdateSlot(this, 0);
}
}
void CProximityMine::HandleEvent(const SGameObjectEvent& event){}
void CProximityMine::ProcessEvent(SEntityEvent& event){
EEntityEvent Event = event.event;
switch (Event)
{
case ENTITY_EVENT_XFORM:
break;
case ENTITY_EVENT_TIMER:
break;
case ENTITY_EVENT_INIT:
break;
case ENTITY_EVENT_DONE:
break;
case ENTITY_EVENT_VISIBLITY:
break;
case ENTITY_EVENT_RESET:
{
// Entering Game Mode
if (event.nParam[0] == 1)
{
}
// Leaving Game Mode
else
{
}
}
break;
case ENTITY_EVENT_ATTACH:
break;
case ENTITY_EVENT_ATTACH_THIS:
break;
case ENTITY_EVENT_DETACH:
break;
case ENTITY_EVENT_DETACH_THIS:
break;
case ENTITY_EVENT_LINK:
break;
case ENTITY_EVENT_DELINK:
break;
case ENTITY_EVENT_HIDE:
break;
case ENTITY_EVENT_UNHIDE:
break;
case ENTITY_EVENT_ENABLE_PHYSICS:
break;
case ENTITY_EVENT_PHYSICS_CHANGE_STATE:
break;
case ENTITY_EVENT_SCRIPT_EVENT:
break;
case ENTITY_EVENT_ENTERAREA:
break;
case ENTITY_EVENT_LEAVEAREA:
break;
case ENTITY_EVENT_ENTERNEARAREA:
break;
case ENTITY_EVENT_LEAVENEARAREA:
break;
case ENTITY_EVENT_MOVEINSIDEAREA:
break;
case ENTITY_EVENT_MOVENEARAREA:
break;
case ENTITY_EVENT_CROSS_AREA:
break;
case ENTITY_EVENT_PHYS_POSTSTEP:
break;
case ENTITY_EVENT_PHYS_BREAK:
break;
case ENTITY_EVENT_AI_DONE:
break;
case ENTITY_EVENT_SOUND_DONE:
break;
case ENTITY_EVENT_NOT_SEEN_TIMEOUT:
break;
case ENTITY_EVENT_COLLISION:
break;
case ENTITY_EVENT_RENDER:
break;
case ENTITY_EVENT_PREPHYSICSUPDATE:
break;
case ENTITY_EVENT_LEVEL_LOADED:
break;
case ENTITY_EVENT_START_LEVEL:
break;
case ENTITY_EVENT_START_GAME:
break;
case ENTITY_EVENT_ENTER_SCRIPT_STATE:
break;
case ENTITY_EVENT_LEAVE_SCRIPT_STATE:
break;
case ENTITY_EVENT_PRE_SERIALIZE:
break;
case ENTITY_EVENT_POST_SERIALIZE:
break;
case ENTITY_EVENT_INVISIBLE:
break;
case ENTITY_EVENT_VISIBLE:
break;
case ENTITY_EVENT_MATERIAL:
break;
case ENTITY_EVENT_MATERIAL_LAYER:
break;
case ENTITY_EVENT_ONHIT:
break;
case ENTITY_EVENT_PICKUP:
break;
case ENTITY_EVENT_ANIM_EVENT:
break;
case ENTITY_EVENT_SCRIPT_REQUEST_COLLIDERMODE:
break;
case ENTITY_EVENT_ACTIVE_FLOW_NODE_OUTPUT:
break;
case ENTITY_EVENT_RELOAD_SCRIPT:
break;
case ENTITY_EVENT_MINE_PLACED:
break;
case ENTITY_EVENT_LAST:
break;
default:
break;
}
}
void CProximityMine::SetChannelId(uint16 id){}
void CProximityMine::SetAuthority(bool auth){}
const void *CProximityMine::GetRMIBase() const
{
return CGameObjectExtensionHelper::GetRMIBase();
}
void CProximityMine::PostUpdate(float frameTime){}
void CProximityMine::PostRemoteSpawn(){}
bool CProximityMine::UpdateEntityProperties()
{
if (!UpdateEntityTables())
return false;
bool bSuccess = true;
IEntity *pEnt = GetEntity();
if (!pEnt)
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The Entity's Script Properties Because The Entity Doesn't Exist Or Is NULL.");
return bSuccess;
}
if (!m_pSelfTable)
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The Entity Table For Entity \"" + string(pEnt->GetName()) + "\" Because The Entity Table Doesn't Exist Or Is NULL.");
return bSuccess;
}
if (!m_PropertiesTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"Properties\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"Properties\" Table Doesn't Exist Or Is NULL.");
return bSuccess;
}
if (!m_PhysicsTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"Physics\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"Physics\" Table Doesn't Exist Or Is NULL.");
return bSuccess;
}
if (!m_DetonationTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"Detonation\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"Detonation\" Table Doesn't Exist Or Is NULL.");
return bSuccess;
}
if (!m_VisualTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"Visual\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"Visual\" Table Doesn't Exist Or Is NULL.");
return bSuccess;
}
bSuccess = m_PropertiesTable->GetValue("bActive", m_Script_bActive);
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"bActive\" Value From The \"Properties\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"bActive\" Value Doesn't Exist Or Another Error Occured.");
bSuccess = m_PhysicsTable->GetValue("bRigidBodyActive", m_Script_bRigidBodyActive);
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"bRigidBodyActive\" Value From The \"Physics\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"bRigidBodyActive\" Value Doesn't Exist Or Another Error Occured.");
bSuccess = m_PhysicsTable->GetValue("fMass", m_Script_fMass);
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"fMass\" Value From The \"Physics\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"fMass\" Value Doesn't Exist Or Another Error Occured.");
bSuccess = m_DetonationTable->GetValue("bIgnorePlayer", m_Script_bIgnorePlayer);
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"bIgnorePlayer\" Value From The \"Detonation\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"bIgnorePlayer\" Value Doesn't Exist Or Another Error Occured.");
bSuccess = m_DetonationTable->GetValue("fDetonationRadius", m_Script_fDetonationRadius);
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"fDetonationRadius\" Value From The \"Detonation\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"fDetonationRadius\" Value Doesn't Exist Or Another Error Occured.");
bSuccess = m_DetonationTable->GetValue("fExplosionStrength", m_Script_fExplosionStrength);
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"fExplosionStrength\" Value From The \"Detonation\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"fExplosionStrength\" Value Doesn't Exist Or Another Error Occured.");
ScriptAnyValue object_ModelValue;
bSuccess = m_VisualTable->GetValueAny("object_Model", object_ModelValue);
m_Script_object_Model = object_ModelValue.str;
if (!bSuccess)
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityProperties(): Failed To Update The \"object_Model\" Value From The \"Visual\" Table For Entity \"" + string(pEnt->GetName()) + "\" Because The \"object_Model\" Value Doesn't Exist Or Another Error Occured.");
return bSuccess;
}
bool CProximityMine::UpdateEntityTables()
{
bool bSuccess = true;
IEntity *pEnt = GetEntity();
if (!pEnt)
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityTables(): Failed To Update The Entity's Script Tables Because The Entity Doesn't Exist Or Is NULL.");
return bSuccess;
}
m_pSelfTable = pEnt->GetScriptTable();
if (!m_pSelfTable)
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityTables(): Failed To Load The Entity Table For Entity \"" + string(pEnt->GetName()) + "\".");
return bSuccess;
}
m_pSelfTable->GetValue("Properties", m_PropertiesTable);
if (!m_PropertiesTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityTables(): Failed To Load The \"Properties\" Table For Entity \"" + string(pEnt->GetName()) + "\".");
return bSuccess;
}
m_PropertiesTable->GetValue("Physics", m_PhysicsTable);
if (!m_PhysicsTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityTables(): Failed To Load The \"Physics\" Table For Entity \"" + string(pEnt->GetName()) + "\".");
return bSuccess;
}
m_PropertiesTable->GetValue("Detonation", m_DetonationTable);
if (!m_DetonationTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityTables(): Failed To Load The \"Detonation\" Table For Entity \"" + string(pEnt->GetName()) + "\".");
return bSuccess;
}
m_PropertiesTable->GetValue("Visual", m_VisualTable);
if (!m_VisualTable.GetPtr())
{
bSuccess = false;
gEnv->pLog->LogToConsole("CProximityMine::UpdateEntityTables(): Failed To Load The \"Visual\" Table For Entity \"" + string(pEnt->GetName()) + "\".");
return bSuccess;
}
return bSuccess;
}
#ifndef __PROXIMITYMINE_H__
#define __PROXIMITYMINE_H__
#pragma once
#include <IGameObject.h>
class CProximityMine : public CGameObjectExtensionHelper <CProximityMine, IGameObjectExtension>
{
public:
CProximityMine();
virtual ~CProximityMine();
virtual void GetMemoryUsage(ICrySizer *pSizer) const;
virtual bool Init(IGameObject * pGameObject);
virtual void PostInit(IGameObject * pGameObject);
virtual void InitClient(int channelId);
virtual void PostInitClient(int channelId);
virtual bool ReloadExtension(IGameObject * pGameObject, const SEntitySpawnParams &params);
virtual void PostReloadExtension(IGameObject * pGameObject, const SEntitySpawnParams &params);
virtual bool GetEntityPoolSignature(TSerialize signature);
virtual void Release();
virtual void FullSerialize(TSerialize ser);
virtual bool NetSerialize(TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags);
virtual void PostSerialize();
virtual void SerializeSpawnInfo(TSerialize ser);
virtual ISerializableInfoPtr GetSpawnInfo();
virtual void Update(SEntityUpdateContext& ctx, int updateSlot);
virtual void HandleEvent(const SGameObjectEvent& event);
virtual void ProcessEvent(SEntityEvent& event);
virtual void SetChannelId(uint16 id);
virtual void SetAuthority(bool auth);
virtual const void * GetRMIBase() const;
virtual void PostUpdate(float frameTime);
virtual void PostRemoteSpawn();
/// <summary>
/// Updates The C++ Version Of The Entity's Properties By Reading In The Current Values Of The Entity's Lua Script
/// </summary>
/// <returns>True If Updating Was Successful, False Otherwise</returns>
bool UpdateEntityProperties();
/// <summary>
/// Updates The C++ Version Of The Entity's Lua Script Tables
/// </summary>
/// <returns>True If Updating Was Successful, False Otherwise</returns>
bool UpdateEntityTables();
private:
/// Script Tables
IScriptTable *m_pSelfTable;
SmartScriptTable m_PropertiesTable;
SmartScriptTable m_PhysicsTable;
SmartScriptTable m_DetonationTable;
SmartScriptTable m_VisualTable;
///Entity Properties
bool m_Script_bActive;
bool m_Script_bRigidBodyActive;
float m_Script_fMass;
bool m_Script_bIgnorePlayer;
float m_Script_fDetonationRadius;
float m_Script_fExplosionStrength;
string m_Script_object_Model;
};
#endif
ProximityMine =
{
Properties =
{
Visual =
{
object_Model = "GameSDK/Objects/weapons/ammo/avmine/avmine.cgf",
bRigidBodyActive = 1,
fMass = 20.0f,
},
Detonation =
{
bActive = 1,
bIgnorePlayer = 1,
fDetonationRadius = 1.5f,
fExplosionStrength = 200.0f,
},
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment