16 [
Attribute(defvalue:
"1", uiwidget: UIWidgets.CheckBox,
desc:
"Approximate time (in seconds) for the needle to reach a new direction",
params:
"0.1 10 0.1",
category:
"Compass")]
17 float m_fDirectionChangeTime;
19 [
Attribute(defvalue:
"25", uiwidget: UIWidgets.Slider,
desc:
"Percentage overshoot of the needle when settling",
params:
"0 95 0.1",
category:
"Compass")]
20 float m_fDirectionOvershootPercentage;
22 [
Attribute(defvalue:
"2", UIWidgets.CheckBox,
desc:
"Frequency (in hertz) of the vertical shaking of the needle",
params:
"0.1 5 0.1",
category:
"Compass")]
23 float m_fShakeFrequency;
25 [
Attribute(defvalue:
"15", uiwidget: UIWidgets.Slider,
desc:
"Percentage overshoot the vertical needle shaking",
params:
"0 95 0.1",
category:
"Compass")]
26 float m_fShakeOvershootPercentage;
28 [
Attribute(defvalue:
"3", UIWidgets.CheckBox,
desc:
"Maximum angle (in degrees) of the shaking",
params:
"0 15 0.1",
category:
"Compass")]
29 float m_fShakeMaximumAngle;
31 [
Attribute(
"0 0.3 0", UIWidgets.Coords,
desc:
"camera position when displayed in map UI mode",
category:
"Compass")]
32 vector m_vMapCameraPos;
34 [
Attribute(
"{72691366C26BD901}Prefabs/Items/Equipment/Compass/Compass_SY183_Map.et",
desc:
"Compass prefab used for display within 2D map",
category:
"Compass")]
35 ResourceName m_sMapResource;
38 bool m_bSignalInit =
false;
39 int m_iSignalNeedle = -1;
40 int m_iSignalShake = -1;
41 int m_iSignalInHand = -1;
42 int m_iSignalInMap = -1;
43 int m_iSignalClose = -1;
47 void InitSignals(IEntity owner)
49 SignalsManagerComponent signalMgr = SignalsManagerComponent.Cast( owner.FindComponent( SignalsManagerComponent ) );
54 m_iSignalNeedle = signalMgr.FindSignal(
"Needle");
55 m_iSignalShake = signalMgr.FindSignal(
"Shake");
56 m_iSignalInHand = signalMgr.FindSignal(
"InHand");
57 m_iSignalInMap = signalMgr.FindSignal(
"InMap");
58 m_iSignalClose = signalMgr.FindSignal(
"Close");
60 if (m_iSignalNeedle != -1 && m_iSignalShake != -1 && m_iSignalInHand != -1)
67 void SCR_CompassComponentClass(BaseContainer prefab)
75 static const float E = 2.71828182845904;
78 protected float m_fNeedleAccelerationConstant = 0;
79 protected float m_fNeedleDragConstant = 0;
82 protected float m_fNeedleAngle = 0;
83 protected float m_fNeedleVelocity = 0;
86 protected float m_fShakeAccelerationConstant = 0;
87 protected float m_fShakeDragConstant = 0;
90 protected float m_fShakeAngle = 0;
91 protected float m_fShakeVelocity = 0;
94 protected vector m_vPreviousFrameAngles;
97 protected bool m_bIsInMapMode;
99 protected SignalsManagerComponent m_SignalManager;
100 protected ref SCR_CompassComponentClass m_PrefabData;
105 ResourceName GetMapPrefabResource()
113 protected void UpdateNeedleDirection(
float timeSlice)
115 vector angles =
GetOwner().GetYawPitchRoll();
116 float northDirection = -angles[0];
118 float magneticTorque = Math.Sin((northDirection - m_fNeedleAngle) * Math.DEG2RAD);
120 float acceleration = magneticTorque * m_fNeedleAccelerationConstant;
121 float drag = m_fNeedleVelocity * m_fNeedleDragConstant;
123 float cappedTimeSlice = Math.Min(timeSlice, 1);
125 m_fNeedleVelocity += (acceleration - drag) * cappedTimeSlice;
126 m_fNeedleAngle += m_fNeedleVelocity * cappedTimeSlice;
128 m_fNeedleAngle =
SCR_Math.fmod(m_fNeedleAngle, 360);
129 if (m_fNeedleAngle > 180) m_fNeedleAngle -= 360;
137 protected void UpdateNeedleShake(
float timeSlice)
139 vector angles =
GetOwner().GetYawPitchRoll();
140 vector deltaAngles = (m_vPreviousFrameAngles - angles);
142 m_vPreviousFrameAngles = angles;
144 float acceleration = -m_fShakeAngle * m_fShakeAccelerationConstant;
145 float drag = m_fShakeVelocity * m_fShakeDragConstant;
147 float cappedTimeSlice = Math.Min(timeSlice, 1);
149 m_fShakeVelocity += (acceleration - drag) * cappedTimeSlice;
153 m_fShakeAngle += m_fShakeVelocity * cappedTimeSlice + deltaAngles[0] + deltaAngles[1];
158 m_fShakeVelocity = 0;
164 m_fShakeVelocity = 0;
173 void Init2DMapCompass()
177 m_fNeedleVelocity = 5;
180 vector angles =
GetOwner().GetYawPitchRoll();
181 m_fNeedleAngle = -angles[0] + Math.RandomInt(-10, 10);
187 void DragMapCompass()
191 m_fNeedleVelocity = 5;
198 m_iMode = EGadgetMode.IN_HAND;
200 m_bIsInMapMode =
true;
202 UpdateCompassState();
207 vector GetMapCamPosition()
214 protected void UpdateCompassState()
216 if (System.IsConsoleApp())
220 ActivateGadgetUpdate();
222 DeactivateGadgetUpdate();
237 else if (m_iMode != EGadgetMode.IN_SLOT)
257 protected float GetDampingRatio(
float overshootPercentage)
259 float logOvershoot = Math.Log2(Math.Max(0.001, overshootPercentage / 100.0)) / Math.Log2(E);
260 float zeta = -logOvershoot / Math.Sqrt(Math.PI * Math.PI + logOvershoot * logOvershoot);
267 protected void CalculateConstants()
270 float zeta = GetDampingRatio(
m_PrefabData.m_fDirectionOvershootPercentage);
271 float naturalFrequency = Math.PI / Math.Max(0.1,
m_PrefabData.m_fDirectionChangeTime);
273 m_fNeedleAccelerationConstant = naturalFrequency * naturalFrequency * Math.RAD2DEG;
274 m_fNeedleDragConstant = 2 * naturalFrequency * zeta;
277 zeta = GetDampingRatio(
m_PrefabData.m_fShakeOvershootPercentage);
280 m_fShakeAccelerationConstant = naturalFrequency * naturalFrequency * Math.RAD2DEG;
281 m_fShakeDragConstant = 2 * naturalFrequency * zeta;
286 override void ModeSwitch(EGadgetMode mode, IEntity charOwner)
288 super.ModeSwitch(mode, charOwner);
290 if (mode == EGadgetMode.IN_HAND)
293 UpdateCompassState();
298 override void ModeClear(EGadgetMode mode)
300 super.ModeClear(mode);
302 if (mode == EGadgetMode.IN_HAND)
304 m_bActivated =
false;
305 UpdateCompassState();
310 override void ActivateGadgetUpdate()
312 super.ActivateGadgetUpdate();
316 itemComponent.ActivateOwner(
true);
320 override void DeactivateGadgetUpdate()
322 super.DeactivateGadgetUpdate();
326 itemComponent.ActivateOwner(
false);
330 override EGadgetType GetType()
332 return EGadgetType.COMPASS;
336 override bool CanBeRaised()
342 override bool IsUsingADSControls()
348 override bool RplSave(ScriptBitWriter writer)
350 if (!super.RplSave(writer))
353 writer.WriteBool(m_bActivated);
359 override bool RplLoad(ScriptBitReader reader)
361 if (!super.RplLoad(reader))
364 reader.ReadBool(m_bActivated);
366 UpdateCompassState();
372 override void Update(
float timeSlice)
374 UpdateNeedleDirection(timeSlice);
375 UpdateNeedleShake(timeSlice);
379 override void OnPostInit(IEntity owner)
381 super.OnPostInit(owner);
383 m_PrefabData = SCR_CompassComponentClass.Cast( GetComponentData(owner) );
384 m_SignalManager = SignalsManagerComponent.Cast( owner.FindComponent( SignalsManagerComponent ) );
386 CalculateConstants();
387 UpdateCompassState();