actionbase.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  1. enum ActionConditionMask
  2. {
  3. ACM_NO_EXEPTION = 0,
  4. ACM_IN_VEHICLE = 1,
  5. ACM_ON_LADDER = 2,
  6. ACM_SWIMMING = 4,
  7. ACM_RESTRAIN = 8,
  8. ACM_RAISED = 16,
  9. ACM_ON_BACK = 32,
  10. ACM_THROWING = 64,
  11. ACM_LEANING = 128,
  12. ACM_BROKEN_LEGS = 256,
  13. ACM_IN_FREELOOK = 512,
  14. }
  15. class ActionReciveData
  16. {
  17. ItemBase m_MainItem;
  18. ref ActionTarget m_Target;
  19. }
  20. class ActionOverrideData : Managed
  21. {
  22. int m_CommandUID = -1;
  23. int m_CommandUIDProne = -1;
  24. int m_StanceMask = -1;
  25. }
  26. class ActionData
  27. {
  28. void ActionData()
  29. {
  30. m_State = UA_NONE;
  31. }
  32. ref ActionBase m_Action;
  33. ItemBase m_MainItem;
  34. ActionBaseCB m_Callback;
  35. ref CABase m_ActionComponent;
  36. int m_State;
  37. ref ActionTarget m_Target;
  38. PlayerBase m_Player;
  39. int m_PossibleStanceMask;
  40. ref array<ref InventoryLocation> m_ReservedInventoryLocations; //used also for juncture
  41. int m_RefreshReservationTimer;
  42. int m_RefreshJunctureTimer;
  43. int m_DelayedAnimationEventID;
  44. bool m_WasExecuted;
  45. bool m_WasActionStarted;
  46. bool m_ReciveEndInput;
  47. }
  48. class ActionBase : ActionBase_Basic
  49. {
  50. //STATIC DATA
  51. protected int m_RefreshReservationTimerValue = 140;
  52. // Configurable action parameters
  53. protected string m_Sound; //sound played at the beggining of action
  54. protected string m_Text;
  55. protected bool m_LockTargetOnUse; //this parameter sets wheter player can perform actions on target while other player is already performing action on it. defaulted as true
  56. protected bool m_FullBody; //tells whether action is full body or additive
  57. protected int m_StanceMask;
  58. protected ref TStringArray m_Sounds; //User action sound is picked from this array randomly
  59. ref CCIBase m_ConditionItem; //Condition Component
  60. ref CCTBase m_ConditionTarget; //Condition Component
  61. protected ActionInput m_Input;
  62. protected int m_ActionID;
  63. protected int m_VariantID;
  64. int m_ConditionMask;
  65. protected ref ActionVariantManager m_VariantManager;
  66. //RUNTIME DATA
  67. protected ref Param1<string> m_MessageParam; //used for passing messages from server to client
  68. //protected ref Param2<int,int> m_MessagesParam;
  69. //SOFT SKILLS
  70. protected float m_SpecialtyWeight;
  71. //-----------------------------------------------------
  72. // Action events and methods
  73. //-----------------------------------------------------
  74. void ActionBase()
  75. {
  76. // definable
  77. m_StanceMask = DayZPlayerConstants.STANCEMASK_ERECT | DayZPlayerConstants.STANCEMASK_CROUCH | DayZPlayerConstants.STANCEMASK_PRONE;
  78. m_FullBody = false;
  79. m_Sound = "";
  80. m_Text = "default action text";
  81. m_LockTargetOnUse = HasTarget();
  82. // dont override
  83. m_MessageParam = new Param1<string>("");
  84. //m_MessagesParam = new Param2<int,int>(0,0);
  85. m_Sounds = new TStringArray;
  86. m_Input = null;
  87. m_ActionID = 0;
  88. InitConditionMask();
  89. }
  90. bool IsLockTargetOnUse()
  91. {
  92. return m_LockTargetOnUse;
  93. }
  94. void InitConditionMask()
  95. {
  96. m_ConditionMask = ActionConditionMask.ACM_NO_EXEPTION;
  97. if (CanBeUsedInVehicle())
  98. {
  99. m_ConditionMask |= ActionConditionMask.ACM_IN_VEHICLE;
  100. }
  101. if (CanBeUsedOnLadder())
  102. {
  103. m_ConditionMask |= ActionConditionMask.ACM_ON_LADDER;
  104. }
  105. if (CanBeUsedSwimming())
  106. {
  107. m_ConditionMask |= ActionConditionMask.ACM_SWIMMING;
  108. }
  109. if (CanBeUsedInRestrain())
  110. {
  111. m_ConditionMask |= ActionConditionMask.ACM_RESTRAIN;
  112. }
  113. if (CanBeUsedRaised())
  114. {
  115. m_ConditionMask |= ActionConditionMask.ACM_RAISED;
  116. }
  117. if (CanBeUsedOnBack())
  118. {
  119. m_ConditionMask |= ActionConditionMask.ACM_ON_BACK;
  120. }
  121. if (CanBeUsedThrowing())
  122. {
  123. m_ConditionMask |= ActionConditionMask.ACM_THROWING;
  124. }
  125. if (CanBeUsedLeaning())
  126. {
  127. m_ConditionMask |= ActionConditionMask.ACM_LEANING;
  128. }
  129. if (CanBeUsedWithBrokenLegs())
  130. {
  131. m_ConditionMask |= ActionConditionMask.ACM_BROKEN_LEGS;
  132. }
  133. if (CanBeUsedInFreelook())
  134. m_ConditionMask |= ActionConditionMask.ACM_IN_FREELOOK;
  135. }
  136. bool SetupAction(PlayerBase player, ActionTarget target, ItemBase item, out ActionData action_data, Param extra_data = NULL )
  137. {
  138. action_data = CreateActionData();
  139. action_data.m_Action = this;
  140. action_data.m_Player = player;
  141. action_data.m_Target = target;
  142. action_data.m_MainItem = item;
  143. action_data.m_PossibleStanceMask = GetStanceMask(player);
  144. action_data.m_ReservedInventoryLocations = new array<ref InventoryLocation>;
  145. action_data.m_RefreshReservationTimer = m_RefreshReservationTimerValue;
  146. action_data.m_WasExecuted = false;
  147. action_data.m_WasActionStarted = false;
  148. action_data.m_ReciveEndInput = false;
  149. ActionReciveData action_recive_data = player.GetActionManager().GetReciveData();
  150. if ( action_recive_data )
  151. {
  152. HandleReciveData(action_recive_data,action_data);
  153. if ( UseMainItem() && MainItemAlwaysInHands() )
  154. {
  155. if ( player.GetItemInHands() != action_data.m_MainItem )
  156. {
  157. return false;
  158. }
  159. }
  160. }
  161. if ( !Post_SetupAction( action_data ) )
  162. return false;
  163. if ( (!GetGame().IsDedicatedServer()) && !IsInstant() )
  164. {
  165. if (!InventoryReservation(action_data))
  166. {
  167. ClearInventoryReservationEx(action_data);
  168. return false;
  169. }
  170. if ( LogManager.IsActionLogEnable() )
  171. {
  172. for ( int i = 0; i < action_data.m_ReservedInventoryLocations.Count(); i++)
  173. {
  174. Debug.ActionLog( InventoryLocation.DumpToStringNullSafe( action_data.m_ReservedInventoryLocations[i] ), action_data.m_Action.ToString() , "n/a", "LockInventoryList", action_data.m_Player.ToString() );
  175. }
  176. }
  177. }
  178. return true;
  179. }
  180. bool Post_SetupAction( ActionData action_data )
  181. {
  182. return true;
  183. }
  184. void ActionCleanup( ActionData action_data )
  185. {}
  186. typename GetInputType()
  187. {
  188. return DefaultActionInput;
  189. }
  190. void SetInput( ActionInput ai)
  191. {
  192. m_Input = ai;
  193. }
  194. ActionData CreateActionData()
  195. {
  196. return new ActionData;
  197. }
  198. void CreateConditionComponents() //Instantiates components, called once from ActionManager on actions construction
  199. {
  200. m_ConditionItem = new CCIDummy;
  201. m_ConditionTarget = new CCTDummy;
  202. }
  203. Object GetDisplayInteractObject(PlayerBase player, ActionTarget target)
  204. {
  205. return null;
  206. }
  207. //! Action is performed on target, not with item itself, when set to true.
  208. //! * target will be synced to server
  209. //! * UI: floating widget will be displayed at target pos
  210. bool HasTarget()
  211. {
  212. return true;
  213. }
  214. //! For UI: hiding of progress bar
  215. bool HasProgress()
  216. {
  217. return true;
  218. }
  219. //Action isn't synchronize to server
  220. bool IsLocal()
  221. {
  222. return false;
  223. }
  224. //Action not using animation/callback action are executed instantly (OnStart)
  225. bool IsInstant()
  226. {
  227. return false;
  228. }
  229. //! not using plane object - it's using multiple proxies
  230. bool IsUsingProxies()
  231. {
  232. return false;
  233. }
  234. bool RemoveForceTargetAfterUse()
  235. {
  236. return true;
  237. }
  238. int GetActionCategory()
  239. {
  240. return AC_UNCATEGORIZED;
  241. }
  242. bool IsEat()
  243. {
  244. return false;
  245. }
  246. bool IsDrink()
  247. {
  248. return false;
  249. }
  250. bool IsShaveSelf()
  251. {
  252. return false;
  253. }
  254. string GetText() //text game displays in HUD hint
  255. {
  256. return m_Text;
  257. }
  258. bool CanBePerformedFromQuickbar()
  259. {
  260. return false;
  261. }
  262. bool CanBePerformedFromInventory()
  263. {
  264. return false;
  265. }
  266. //! Condition used in PlayerBase::CanChangeStance to check if stance can be changed while action is performed/executed
  267. bool CanBePerformedWhileChangingStance()
  268. {
  269. return true;
  270. }
  271. bool CanBeSetFromInventory()
  272. {
  273. return !CanBePerformedFromInventory();
  274. }
  275. bool CanBeUsedInRestrain()
  276. {
  277. return false;
  278. }
  279. bool CanBeUsedInVehicle()
  280. {
  281. return false;
  282. }
  283. bool CanTargetBeInVehicle()
  284. {
  285. return false;
  286. }
  287. bool CanBeUsedOnBack()
  288. {
  289. return false;
  290. }
  291. bool CanBeUsedSwimming()
  292. {
  293. return false;
  294. }
  295. bool CanBeUsedOnLadder()
  296. {
  297. return false;
  298. }
  299. bool CanBeUsedRaised()
  300. {
  301. return false;
  302. }
  303. bool CanBeUsedThrowing()
  304. {
  305. return false;
  306. }
  307. bool CanBeUsedLeaning()
  308. {
  309. return true;
  310. }
  311. bool CanBeUsedWithBrokenLegs()
  312. {
  313. return true;
  314. }
  315. bool CanBeUsedInFreelook()
  316. {
  317. return true;
  318. }
  319. //! Is an action directly related to deployment/advanced placing
  320. bool IsDeploymentAction()
  321. {
  322. return false;
  323. }
  324. bool UseMainItem()
  325. {
  326. return true;
  327. }
  328. bool MainItemAlwaysInHands()
  329. {
  330. return true;
  331. }
  332. /**
  333. Action will display the content of ActionBase::GetTargetName next to action action name (ActionTargetsCursor::GetActionDesc).
  334. \returns true if allowed; otherwise false
  335. */
  336. bool DisplayTargetInActionText()
  337. {
  338. return false;
  339. }
  340. protected bool ActionConditionContinue(ActionData action_data) //condition for action
  341. {
  342. return ActionCondition(action_data.m_Player,action_data.m_Target,action_data.m_MainItem);
  343. }
  344. protected bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item) //condition for action
  345. {
  346. return true;
  347. }
  348. /**
  349. Used to set the name of action target displayed in UI in case ActionBase::DisplayTargetInActionText is true.
  350. \param player reference to player running action
  351. \param target actual target reference
  352. \returns name of the target
  353. */
  354. string GetTargetName(PlayerBase player, ActionTarget target)
  355. {
  356. return string.Empty;
  357. }
  358. void ApplyModifiers(ActionData action_data);
  359. int GetRefreshReservationTimerValue()
  360. {
  361. return m_RefreshReservationTimerValue;
  362. }
  363. void WriteToContext(ParamsWriteContext ctx, ActionData action_data)
  364. {
  365. int componentIndex = -1;
  366. int proxyBoneIdx = -1;
  367. vector cursorHitPos = vector.Zero;
  368. array<string> selectionNames = new array<string>();
  369. Object targetObject = null;
  370. Object targetParent = null;
  371. string surfaceName;
  372. if (UseMainItem())
  373. {
  374. ctx.Write(action_data.m_MainItem);
  375. }
  376. if (HasTarget() && !IsUsingProxies())
  377. {
  378. // callback data
  379. targetObject = action_data.m_Target.GetObject();
  380. ctx.Write(targetObject);
  381. targetParent = action_data.m_Target.GetParent();
  382. ctx.Write(targetParent);
  383. componentIndex = action_data.m_Target.GetComponentIndex();
  384. ctx.Write(componentIndex);
  385. cursorHitPos = action_data.m_Target.GetCursorHitPos();
  386. ctx.Write(cursorHitPos);
  387. surfaceName = action_data.m_Target.GetSurfaceName();
  388. ctx.Write(surfaceName);
  389. }
  390. else if (HasTarget() && IsUsingProxies())
  391. {
  392. //! get proxy bone idx from parent and selection we are looking at
  393. //! ID is used for synchronisation to server where it's translated back to object
  394. Entity entParent = Entity.Cast(action_data.m_Target.GetParent());
  395. if (entParent)
  396. {
  397. action_data.m_Target.GetObject().GetActionComponentNameList(action_data.m_Target.GetComponentIndex(), selectionNames);
  398. for (int s = 0; s < selectionNames.Count(); s++)
  399. {
  400. proxyBoneIdx = entParent.GetBoneIndex(selectionNames[s]);
  401. if( proxyBoneIdx > -1 )
  402. {
  403. break;
  404. }
  405. }
  406. }
  407. ctx.Write(proxyBoneIdx);
  408. targetParent = action_data.m_Target.GetParent();
  409. ctx.Write(targetParent);
  410. componentIndex = action_data.m_Target.GetComponentIndex();
  411. ctx.Write(componentIndex);
  412. cursorHitPos = action_data.m_Target.GetCursorHitPos();
  413. ctx.Write(cursorHitPos);
  414. surfaceName = action_data.m_Target.GetSurfaceName();
  415. ctx.Write(surfaceName);
  416. }
  417. }
  418. bool ReadFromContext(ParamsReadContext ctx, out ActionReciveData action_recive_data )
  419. {
  420. if (!action_recive_data)
  421. action_recive_data = new ActionReciveData;
  422. Object actionTargetObject = null;
  423. Object actionTargetParent = null;
  424. int componentIndex = -1;
  425. int proxyBoneIdx = -1;
  426. vector cursorHitPos = vector.Zero;
  427. ItemBase mainItem = null;
  428. ActionTarget target;
  429. string surfaceName;
  430. if (UseMainItem())
  431. {
  432. if (!ctx.Read(mainItem))
  433. return false;
  434. }
  435. if (HasTarget() && !IsUsingProxies())
  436. {
  437. if (!ctx.Read(actionTargetObject))
  438. return false;
  439. if (!ctx.Read(actionTargetParent))
  440. return false;
  441. if (!ctx.Read(componentIndex))
  442. return false;
  443. if (!ctx.Read(cursorHitPos))
  444. return false;
  445. if (!ctx.Read(surfaceName))
  446. return false;
  447. target = new ActionTarget(actionTargetObject, actionTargetParent, componentIndex, cursorHitPos, 0, surfaceName);
  448. action_recive_data.m_Target = target;
  449. }
  450. else if (HasTarget() && IsUsingProxies())
  451. {
  452. if (!ctx.Read(proxyBoneIdx))
  453. return false;
  454. if (!ctx.Read(actionTargetParent))
  455. return false;
  456. if (!ctx.Read(componentIndex))
  457. return false;
  458. if (!ctx.Read(cursorHitPos))
  459. return false;
  460. if (!ctx.Read(surfaceName))
  461. return false;
  462. //! create target object from proxyBoneIdx synced from client
  463. if (proxyBoneIdx > -1)
  464. {
  465. Entity entParent = Entity.Cast(actionTargetParent);
  466. if (entParent)
  467. {
  468. actionTargetObject = entParent.GetBoneObject(proxyBoneIdx);
  469. }
  470. }
  471. else
  472. {
  473. return false;
  474. }
  475. target = new ActionTarget(actionTargetObject, actionTargetParent, componentIndex, cursorHitPos, 0, surfaceName);
  476. action_recive_data.m_Target = target;
  477. }
  478. action_recive_data.m_MainItem = mainItem;
  479. return true;
  480. }
  481. SurfaceInfo GetTargetSurfaceInfo(vector cursorHitPos)
  482. {
  483. SurfaceInfo surfaceInfo;
  484. SurfaceDetectionParameters surfaceParams = new SurfaceDetectionParameters();
  485. surfaceParams.type = SurfaceDetectionType.Roadway;
  486. surfaceParams.position = cursorHitPos;
  487. surfaceParams.includeWater = true;
  488. surfaceParams.syncMode = UseObjectsMode.NoWait;
  489. surfaceParams.rsd = RoadSurfaceDetection.ABOVE;
  490. SurfaceDetectionResult surfaceResult = new SurfaceDetectionResult();
  491. if (g_Game.GetSurface(surfaceParams, surfaceResult) && surfaceResult.surface)
  492. {
  493. surfaceInfo = surfaceResult.surface;
  494. }
  495. return surfaceInfo;
  496. }
  497. void HandleReciveData(ActionReciveData action_recive_data, ActionData action_data)
  498. {
  499. action_data.m_MainItem = action_recive_data.m_MainItem;
  500. if(HasTarget())
  501. {
  502. if (action_recive_data.m_Target)
  503. {
  504. action_data.m_Target = action_recive_data.m_Target;
  505. }
  506. else
  507. {
  508. Error("Action target not created.");
  509. action_data.m_Target = new ActionTarget(NULL, NULL, -1, vector.Zero, 0);
  510. }
  511. }
  512. }
  513. //----------------------------------------------------------------------------------------------
  514. // Core methods don't override unless you know what you are doing
  515. //----------------------------------------------------------------------------------------------
  516. // COMMANDS -----------------------------------------------------------------------
  517. protected int GetStanceMaskEx(PlayerBase player, ActionTarget target, ItemBase item)
  518. {
  519. return GetStanceMask(player);
  520. }
  521. protected int GetStanceMask(PlayerBase player)
  522. {
  523. if ( HasProneException() )
  524. {
  525. if ( player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_RAISEDERECT | DayZPlayerConstants.STANCEMASK_RAISEDCROUCH | DayZPlayerConstants.STANCEMASK_RAISEDPRONE))
  526. return -1;
  527. else if ( player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_CROUCH | DayZPlayerConstants.STANCEMASK_ERECT))
  528. return DayZPlayerConstants.STANCEMASK_CROUCH | DayZPlayerConstants.STANCEMASK_ERECT;
  529. else
  530. return DayZPlayerConstants.STANCEMASK_PRONE;
  531. }
  532. return m_StanceMask;
  533. }
  534. protected int GetClosestPossibleStance(PlayerBase player, ActionTarget target, ItemBase item)
  535. {
  536. int stanceMask = GetStanceMaskEx(player, target, item);
  537. if (player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_ERECT))
  538. {
  539. if (stanceMask & DayZPlayerConstants.STANCEMASK_ERECT)
  540. return DayZPlayerConstants.STANCEMASK_ERECT;
  541. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDERECT)
  542. return DayZPlayerConstants.STANCEMASK_RAISEDERECT;
  543. else if (stanceMask & DayZPlayerConstants.STANCEMASK_CROUCH)
  544. return DayZPlayerConstants.STANCEMASK_CROUCH;
  545. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDCROUCH)
  546. return DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  547. else if (stanceMask & DayZPlayerConstants.STANCEMASK_PRONE)
  548. return DayZPlayerConstants.STANCEMASK_PRONE;
  549. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDPRONE)
  550. return DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  551. }
  552. if (player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_RAISEDERECT))
  553. {
  554. if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDERECT)
  555. return DayZPlayerConstants.STANCEMASK_RAISEDERECT;
  556. else if (stanceMask & DayZPlayerConstants.STANCEMASK_ERECT)
  557. return DayZPlayerConstants.STANCEMASK_ERECT;
  558. else if (stanceMask & DayZPlayerConstants.STANCEMASK_CROUCH)
  559. return DayZPlayerConstants.STANCEMASK_CROUCH;
  560. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDCROUCH)
  561. return DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  562. else if (stanceMask & DayZPlayerConstants.STANCEMASK_PRONE)
  563. return DayZPlayerConstants.STANCEMASK_PRONE;
  564. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDPRONE)
  565. return DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  566. }
  567. if (player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_CROUCH))
  568. {
  569. if (stanceMask & DayZPlayerConstants.STANCEMASK_CROUCH)
  570. return DayZPlayerConstants.STANCEMASK_CROUCH;
  571. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDCROUCH)
  572. return DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  573. else if (stanceMask & DayZPlayerConstants.STANCEMASK_ERECT)
  574. return DayZPlayerConstants.STANCEMASK_ERECT;
  575. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDERECT)
  576. return DayZPlayerConstants.STANCEMASK_RAISEDERECT;
  577. else if (stanceMask & DayZPlayerConstants.STANCEMASK_PRONE)
  578. return DayZPlayerConstants.STANCEMASK_PRONE;
  579. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDPRONE)
  580. return DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  581. }
  582. if (player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_RAISEDCROUCH))
  583. {
  584. if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDCROUCH)
  585. return DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  586. else if (stanceMask & DayZPlayerConstants.STANCEMASK_CROUCH)
  587. return DayZPlayerConstants.STANCEMASK_CROUCH;
  588. else if (stanceMask & DayZPlayerConstants.STANCEMASK_ERECT)
  589. return DayZPlayerConstants.STANCEMASK_ERECT;
  590. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDERECT)
  591. return DayZPlayerConstants.STANCEMASK_RAISEDERECT;
  592. else if (stanceMask & DayZPlayerConstants.STANCEMASK_PRONE)
  593. return DayZPlayerConstants.STANCEMASK_PRONE;
  594. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDPRONE)
  595. return DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  596. }
  597. if (player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_PRONE))
  598. {
  599. if (stanceMask & DayZPlayerConstants.STANCEMASK_PRONE)
  600. return DayZPlayerConstants.STANCEMASK_PRONE;
  601. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDPRONE)
  602. return DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  603. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDCROUCH)
  604. return DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  605. else if (stanceMask & DayZPlayerConstants.STANCEMASK_CROUCH)
  606. return DayZPlayerConstants.STANCEMASK_CROUCH;
  607. else if (stanceMask & DayZPlayerConstants.STANCEMASK_ERECT)
  608. return DayZPlayerConstants.STANCEMASK_ERECT;
  609. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDERECT)
  610. return DayZPlayerConstants.STANCEMASK_RAISEDERECT;
  611. }
  612. if (player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_RAISEDPRONE))
  613. {
  614. if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDPRONE)
  615. return DayZPlayerConstants.STANCEMASK_RAISEDPRONE;
  616. else if (stanceMask & DayZPlayerConstants.STANCEMASK_PRONE)
  617. return DayZPlayerConstants.STANCEMASK_PRONE;
  618. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDCROUCH)
  619. return DayZPlayerConstants.STANCEMASK_RAISEDCROUCH;
  620. else if (stanceMask & DayZPlayerConstants.STANCEMASK_CROUCH)
  621. return DayZPlayerConstants.STANCEMASK_CROUCH;
  622. else if (stanceMask & DayZPlayerConstants.STANCEMASK_ERECT)
  623. return DayZPlayerConstants.STANCEMASK_ERECT;
  624. else if (stanceMask & DayZPlayerConstants.STANCEMASK_RAISEDERECT)
  625. return DayZPlayerConstants.STANCEMASK_RAISEDERECT;
  626. }
  627. return -1;
  628. }
  629. protected bool IsFullBodyEx(PlayerBase player, ActionTarget target, ItemBase item)
  630. {
  631. return IsFullBody(player);
  632. }
  633. bool IsFullBody(PlayerBase player)
  634. {
  635. if ( HasProneException() )
  636. {
  637. return !( player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_CROUCH | DayZPlayerConstants.STANCEMASK_ERECT) );
  638. }
  639. return m_FullBody;
  640. }
  641. // if it is set to true if action have special fullbody animation for prone and additive for crouch and erect
  642. protected bool HasProneException()
  643. {
  644. return false;
  645. }
  646. // ACTION LOGIC -------------------------------------------------------------------
  647. // called from actionmanager.c
  648. void Start( ActionData action_data ) //Setup on start of action
  649. {
  650. action_data.m_State = UA_START;
  651. if ( LogManager.IsActionLogEnable() )
  652. {
  653. Debug.ActionLog("Time stamp: " + action_data.m_Player.GetSimulationTimeStamp(), this.ToString() , "n/a", "OnStart", action_data.m_Player.ToString() );
  654. }
  655. OnStart(action_data);
  656. if ( GetGame().IsServer() )
  657. {
  658. OnStartServer(action_data);
  659. string soundCat = GetSoundCategory(action_data);
  660. if (soundCat)
  661. action_data.m_Player.SetSoundCategoryHash(soundCat.Hash());
  662. }
  663. else
  664. {
  665. OnStartClient(action_data);
  666. }
  667. InformPlayers(action_data.m_Player,action_data.m_Target,UA_START);
  668. }
  669. void End( ActionData action_data )
  670. {
  671. if ( action_data.m_Player )
  672. {
  673. OnEnd(action_data);
  674. if ( GetGame().IsServer() )
  675. {
  676. OnEndServer(action_data);
  677. }
  678. else
  679. {
  680. OnEndClient(action_data);
  681. }
  682. action_data.m_Player.GetActionManager().OnActionEnd();
  683. }
  684. }
  685. void Interrupt(ActionData action_data)
  686. {
  687. End(action_data);
  688. }
  689. void OnEndInput(ActionData action_data)
  690. {}
  691. void EndInput(ActionData action_data)
  692. {
  693. action_data.m_ReciveEndInput = true;
  694. OnEndInput(action_data);
  695. }
  696. void OnEndRequest(ActionData action_data)
  697. {}
  698. void EndRequest(ActionData action_data)
  699. {
  700. OnEndRequest(action_data);
  701. }
  702. bool CanReceiveAction(ActionTarget target)
  703. {
  704. bool result = true;
  705. PlayerBase target_player = PlayerBase.Cast(target.GetObject());
  706. if (target_player)
  707. {
  708. result = !target_player.IsJumpInProgress();
  709. result = result && !(target_player.GetCommand_Ladder() || (target_player.GetCommand_Vehicle() && !CanTargetBeInVehicle()) || target_player.GetCommand_Swim());
  710. }
  711. return result;
  712. }
  713. static int ComputeConditionMask( PlayerBase player, ActionTarget target, ItemBase item )
  714. {
  715. int mask = 0;
  716. if ( player.GetCommand_Vehicle() )
  717. {
  718. mask |= ActionConditionMask.ACM_IN_VEHICLE;
  719. }
  720. if ( player.GetCommand_Ladder() )
  721. {
  722. mask |= ActionConditionMask.ACM_ON_LADDER;
  723. }
  724. if ( player.IsRestrained() )
  725. {
  726. mask |= ActionConditionMask.ACM_RESTRAIN;
  727. }
  728. if ( player.GetCommand_Swim() )
  729. {
  730. mask |= ActionConditionMask.ACM_SWIMMING;
  731. }
  732. if ( player.IsRaised() )
  733. {
  734. mask |= ActionConditionMask.ACM_RAISED;
  735. }
  736. if ( player.GetCommand_Move() && player.GetCommand_Move().IsOnBack() )
  737. {
  738. mask |= ActionConditionMask.ACM_ON_BACK;
  739. }
  740. if ( player.GetThrowing().IsThrowingModeEnabled())
  741. {
  742. mask |= ActionConditionMask.ACM_THROWING;
  743. }
  744. if (player.IsLeaning())
  745. {
  746. mask |= ActionConditionMask.ACM_LEANING;
  747. }
  748. if (player.GetBrokenLegs() == eBrokenLegs.BROKEN_LEGS)
  749. {
  750. mask |= ActionConditionMask.ACM_BROKEN_LEGS;
  751. }
  752. if (player.GetInputController() && player.GetInputController().CameraIsFreeLook())
  753. mask |= ActionConditionMask.ACM_IN_FREELOOK;
  754. return mask;
  755. }
  756. bool Can( PlayerBase player, ActionTarget target, ItemBase item, int condition_mask )
  757. {
  758. if (( (condition_mask & m_ConditionMask) != condition_mask ) || ( !IsFullBodyEx(player, target, item) && !player.IsPlayerInStance(GetStanceMaskEx(player, target, item)) ) || player.IsRolling())
  759. return false;
  760. if (HasTarget())
  761. {
  762. if (!FirearmActionBase.Cast(this))
  763. {
  764. EntityAI entity = EntityAI.Cast(target.GetObject());
  765. if (entity && !target.GetObject().IsMan())
  766. {
  767. Man man = entity.GetHierarchyRootPlayer();
  768. if (man && man != player)
  769. return false;
  770. }
  771. }
  772. if (m_ConditionTarget && !m_ConditionTarget.Can(player, target))
  773. return false;
  774. }
  775. if (m_ConditionItem && !m_ConditionItem.Can(player, item))
  776. return false;
  777. if (!ActionCondition(player, target, item))
  778. return false;
  779. if (IsFullBodyEx(player, target, item))
  780. {
  781. int nextStance = GetClosestPossibleStance(player, target, item);
  782. int stanceIdx = DayZPlayerUtils.ConvertStanceMaskToStanceIdx(nextStance);
  783. if (stanceIdx != -1 && !DayZPlayerUtils.PlayerCanChangeStance(player, stanceIdx ))
  784. return false;
  785. }
  786. return true;
  787. }
  788. bool Can(PlayerBase player, ActionTarget target, ItemBase item)
  789. {
  790. int condition_mask = ComputeConditionMask(player, target, item);
  791. return Can( player, target, item, condition_mask);
  792. }
  793. protected bool CanContinue( ActionData action_data )
  794. {
  795. if (!action_data.m_Player.IsPlayerInStance(action_data.m_PossibleStanceMask) || !m_ConditionItem || !m_ConditionItem.CanContinue(action_data.m_Player,action_data.m_MainItem) || !m_ConditionTarget || !m_ConditionTarget.CanContinue(action_data.m_Player,action_data.m_Target))
  796. return false;
  797. return ActionConditionContinue(action_data);
  798. }
  799. bool HasVariants()
  800. {
  801. return m_VariantManager != null;
  802. }
  803. int GetVariantsCount()
  804. {
  805. if (m_VariantManager)
  806. return m_VariantManager.GetActionsCount();
  807. return 0;
  808. }
  809. int GetVariants(out array<ref ActionBase> variants)
  810. {
  811. if (m_VariantManager)
  812. return m_VariantManager.GetActions(variants);
  813. return 0;
  814. }
  815. void SetVariantID(int ID)
  816. {
  817. m_VariantID = ID;
  818. }
  819. int GetVariantID()
  820. {
  821. return m_VariantID;
  822. }
  823. void UpdateVariants(Object item, Object target, int componet_index)
  824. {
  825. if ( m_VariantManager )
  826. {
  827. m_VariantManager.UpdateVariants(item, target, componet_index);
  828. }
  829. }
  830. ActionVariantManager GetVariantManager()
  831. {
  832. if ( !m_VariantManager )
  833. m_VariantManager = new ActionVariantManager(this.Type());
  834. return m_VariantManager;
  835. }
  836. // Called when item changes location during performed action
  837. void OnItemLocationChanged(ItemBase item)
  838. {}
  839. // call only on client side for lock inventory before action
  840. // return if has successfuly reserved inventory
  841. bool InventoryReservation(ActionData action_data)
  842. {
  843. if ((IsLocal() || !UseAcknowledgment()) && IsInstant())
  844. return true;
  845. //action_data.m_ReservedInventoryLocations = new array<ref InventoryLocation>;
  846. bool success = true;
  847. InventoryLocation targetInventoryLocation = NULL;
  848. InventoryLocation handInventoryLocation = NULL;
  849. // lock target if it has target
  850. if (HasTarget())
  851. {
  852. ItemBase targetItem;
  853. if ( ItemBase.CastTo(targetItem,action_data.m_Target.GetObject()) )
  854. {
  855. targetInventoryLocation = new InventoryLocation;
  856. targetItem.GetInventory().GetCurrentInventoryLocation(targetInventoryLocation);
  857. if ( action_data.m_Player.GetInventory().HasInventoryReservation( targetItem, targetInventoryLocation) )
  858. {
  859. success = false;
  860. }
  861. else
  862. {
  863. action_data.m_Player.GetInventory().AddInventoryReservationEx( targetItem, targetInventoryLocation, GameInventory.c_InventoryReservationTimeoutMS);
  864. }
  865. }
  866. }
  867. handInventoryLocation = new InventoryLocation;
  868. handInventoryLocation.SetHands(action_data.m_Player,action_data.m_Player.GetItemInHands());
  869. if (action_data.m_Player.GetInventory().HasInventoryReservation( action_data.m_Player.GetItemInHands(), handInventoryLocation))
  870. {
  871. if (HasTarget())
  872. {
  873. action_data.m_Player.GetInventory().ClearInventoryReservation(targetItem, targetInventoryLocation);
  874. }
  875. success = false;
  876. }
  877. else
  878. {
  879. action_data.m_Player.GetInventory().AddInventoryReservationEx( action_data.m_Player.GetItemInHands(), handInventoryLocation, GameInventory.c_InventoryReservationTimeoutMS);
  880. }
  881. if (success)
  882. {
  883. if (targetInventoryLocation)
  884. action_data.m_ReservedInventoryLocations.Insert(targetInventoryLocation);
  885. if (handInventoryLocation)
  886. action_data.m_ReservedInventoryLocations.Insert(handInventoryLocation);
  887. }
  888. return success;
  889. }
  890. void ClearInventoryReservationEx(ActionData action_data)
  891. {
  892. if (action_data.m_Player.GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  893. {
  894. if (action_data.m_ReservedInventoryLocations)
  895. {
  896. InventoryLocation il;
  897. for ( int i = 0; i < action_data.m_ReservedInventoryLocations.Count(); i++)
  898. {
  899. il = action_data.m_ReservedInventoryLocations.Get(i);
  900. action_data.m_Player.GetInventory().ClearInventoryReservationEx( il.GetItem() , il );
  901. }
  902. action_data.m_ReservedInventoryLocations.Clear();
  903. }
  904. }
  905. }
  906. void RefreshReservations(ActionData action_data)
  907. {
  908. if (action_data.m_ReservedInventoryLocations)
  909. {
  910. InventoryLocation il;
  911. for (int i = 0; i < action_data.m_ReservedInventoryLocations.Count(); i++)
  912. {
  913. il = action_data.m_ReservedInventoryLocations.Get(i);
  914. EntityAI entity = il.GetItem();
  915. action_data.m_Player.GetInventory().ExtendInventoryReservationEx(il.GetItem() , il, 10000);
  916. }
  917. }
  918. }
  919. bool AddActionJuncture(ActionData action_data)
  920. {
  921. bool accepted = true;
  922. if (action_data.m_Player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  923. {
  924. if (HasTarget() && IsLockTargetOnUse() && action_data.m_Target)
  925. {
  926. EntityAI targetEntity;
  927. if (EntityAI.CastTo(targetEntity, action_data.m_Target.GetObject()))
  928. {
  929. InventoryLocation targetIl = new InventoryLocation();
  930. targetEntity.GetInventory().GetCurrentInventoryLocation(targetIl);
  931. //Lock target
  932. if (!GetGame().AddInventoryJunctureEx(action_data.m_Player, targetEntity, targetIl, true, 10000))
  933. {
  934. accepted = false;
  935. }
  936. else
  937. {
  938. action_data.m_ReservedInventoryLocations.Insert(targetIl);
  939. }
  940. }
  941. }
  942. }
  943. return accepted;
  944. }
  945. void ClearActionJuncture(ActionData action_data)
  946. {
  947. if (action_data.m_Player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_SERVER)
  948. {
  949. if (action_data.m_ReservedInventoryLocations)
  950. {
  951. InventoryLocation il;
  952. for ( int i = 0; i < action_data.m_ReservedInventoryLocations.Count(); i++)
  953. {
  954. il = action_data.m_ReservedInventoryLocations.Get(i);
  955. EntityAI entity = il.GetItem();
  956. if (entity)
  957. {
  958. GetGame().ClearJunctureEx(action_data.m_Player, entity);
  959. }
  960. }
  961. action_data.m_ReservedInventoryLocations.Clear();
  962. }
  963. }
  964. }
  965. void RefreshActionJuncture(ActionData action_data)
  966. {
  967. if (action_data.m_ReservedInventoryLocations)
  968. {
  969. InventoryLocation il;
  970. for (int i = 0; i < action_data.m_ReservedInventoryLocations.Count(); i++)
  971. {
  972. il = action_data.m_ReservedInventoryLocations.Get(i);
  973. EntityAI entity = il.GetItem();
  974. if (entity)
  975. {
  976. GetGame().ExtendActionJuncture(action_data.m_Player, entity, 10000);
  977. }
  978. }
  979. }
  980. }
  981. // action need first have permission from server before can start
  982. bool UseAcknowledgment()
  983. {
  984. return true;
  985. }
  986. //! DEPRECATED delivers message ids to clients based on given context
  987. protected void InformPlayers( PlayerBase player, ActionTarget target, int state );
  988. void SendMessageToClient( Object reciever, string message ) //sends given string to client, don't use if not nescessary
  989. {
  990. PlayerBase man;
  991. if (GetGame().IsServer() && Class.CastTo(man, reciever) && m_MessageParam && reciever.IsAlive() && message != "")
  992. {
  993. m_MessageParam.param1 = message;
  994. GetGame().RPCSingleParam(man, ERPCs.RPC_USER_ACTION_MESSAGE, m_MessageParam, true, man.GetIdentity());
  995. }
  996. }
  997. // ActionCondition Rules
  998. // ------------------------------------------------------
  999. protected bool IsDamageDestroyed(ActionTarget target)
  1000. {
  1001. return target.GetObject() && target.GetObject().IsDamageDestroyed();
  1002. }
  1003. protected bool IsBuilding(ActionTarget target)
  1004. {
  1005. return target.GetObject() && target.GetObject().IsBuilding();
  1006. }
  1007. protected bool IsTransport(ActionTarget target)
  1008. {
  1009. return target.GetObject() && target.GetObject().IsTransport();
  1010. }
  1011. protected bool IsInReach(PlayerBase player, ActionTarget target, float maxDistance = 1.0)
  1012. {
  1013. Object obj = target.GetObject();
  1014. if (!obj)
  1015. return false;
  1016. float distanceRoot, distanceHead;
  1017. vector modelPos, worldPos, playerHeadPos;
  1018. // we're using sq distance in comparison
  1019. maxDistance = maxDistance * maxDistance;
  1020. // get position of Head bone
  1021. MiscGameplayFunctions.GetHeadBonePos(player, playerHeadPos);
  1022. array<string> componentNames = new array<string>();
  1023. obj.GetActionComponentNameList(target.GetComponentIndex(), componentNames);
  1024. foreach (string componentName : componentNames)
  1025. {
  1026. if (componentName.Contains("doorstwin"))
  1027. continue;
  1028. modelPos = obj.GetSelectionPositionMS(componentName);
  1029. worldPos = obj.ModelToWorld(modelPos);
  1030. break;
  1031. }
  1032. distanceRoot = vector.DistanceSq(worldPos, player.GetPosition());
  1033. distanceHead = vector.DistanceSq(worldPos, playerHeadPos);
  1034. return distanceRoot <= maxDistance || distanceHead <= maxDistance;
  1035. }
  1036. // ------------------------------------------------------
  1037. // SOUNDS ------------------------------------------------------
  1038. SoundOnVehicle PlayActionSound( PlayerBase player )
  1039. {
  1040. if ( GetGame().IsServer() && player )
  1041. {
  1042. if ( m_Sound != "" )
  1043. {
  1044. return GetGame().CreateSoundOnObject(player, m_Sound, 6, false);
  1045. }
  1046. else if ( m_Sounds && m_Sounds.Count() > 0 )
  1047. {
  1048. int rand_num = Math.RandomInt(0, m_Sounds.Count());
  1049. return GetGame().CreateSoundOnObject(player, m_Sounds.Get(rand_num), 6, false);
  1050. }
  1051. }
  1052. return NULL;
  1053. }
  1054. void OnActionInfoUpdate( PlayerBase player, ActionTarget target, ItemBase item )
  1055. {
  1056. }
  1057. //sound category matches with a soundtable category in config, selects correct soundset
  1058. string GetSoundCategory(ActionData action_data)
  1059. {
  1060. return "";
  1061. }
  1062. // EVENTS ------------------------------------------------
  1063. void OnUpdate(ActionData action_data)
  1064. {}
  1065. void OnUpdateClient(ActionData action_data)
  1066. {
  1067. if ( !GetGame().IsDedicatedServer() )
  1068. {
  1069. if (action_data.m_RefreshReservationTimer > 0)
  1070. {
  1071. action_data.m_RefreshReservationTimer--;
  1072. }
  1073. else
  1074. {
  1075. action_data.m_RefreshReservationTimer = m_RefreshReservationTimerValue;
  1076. RefreshReservations(action_data);
  1077. }
  1078. }
  1079. }
  1080. void OnUpdateServer(ActionData action_data)
  1081. {
  1082. if (action_data.m_RefreshJunctureTimer > 0)
  1083. {
  1084. action_data.m_RefreshJunctureTimer--;
  1085. }
  1086. else
  1087. {
  1088. action_data.m_RefreshJunctureTimer = m_RefreshReservationTimerValue;
  1089. RefreshActionJuncture(action_data);
  1090. }
  1091. }
  1092. void OnStart(ActionData action_data)
  1093. {
  1094. if (action_data.m_Player != NULL && action_data.m_Player.IsPlacingLocal() && !IsDeploymentAction())
  1095. action_data.m_Player.PlacingCancelLocal();
  1096. }
  1097. void OnStartClient(ActionData action_data)
  1098. {}
  1099. void OnStartServer(ActionData action_data)
  1100. {
  1101. }
  1102. void OnEnd(ActionData action_data)
  1103. {
  1104. }
  1105. void OnEndClient(ActionData action_data)
  1106. {}
  1107. void OnEndServer(ActionData action_data)
  1108. {
  1109. }
  1110. // SOFT SKILLS ------------------------------------------------
  1111. float GetSpecialtyWeight()
  1112. {
  1113. if(m_SpecialtyWeight == 0)
  1114. {
  1115. #ifdef DEVELOPER
  1116. //Print("UserAction does not use SoftSkills");
  1117. #endif
  1118. }
  1119. return m_SpecialtyWeight;
  1120. }
  1121. int GetState( ActionData action_data )
  1122. {
  1123. return action_data.m_State;
  1124. }
  1125. float GetProgress( ActionData action_data )
  1126. {
  1127. return -1;
  1128. }
  1129. float GetProgressWidgetMultiplier( ActionData action_data ) // override when action length is not supposed to be the same length as progress widget
  1130. {
  1131. return 1;
  1132. }
  1133. ActionInput GetInput()
  1134. {
  1135. return m_Input;
  1136. }
  1137. void SetID(int actionId)
  1138. {
  1139. m_ActionID = actionId;
  1140. }
  1141. int GetID()
  1142. {
  1143. return m_ActionID;
  1144. }
  1145. string GetAdminLogMessage(ActionData action_data)
  1146. {
  1147. return "";
  1148. }
  1149. };