Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
actionfishingnew.c
Go to the documentation of this file.
1class FishingActionReceiveData : ActionReciveData
2{
3 bool m_IsSurfaceSea;
4}
5
6class FishingActionData : ActionData
7{
9 int m_FishingResult = -1; //use for hashed name?
10 bool m_IsSignalActive = false;
11
13
15
17 {
20
21 m_IsSignalActive = false; //redundant?
23 {
25 }
26 else
27 {
28 component.SetNewSignalData(-1,-1);
29 }
30 }
31
32 //signal methods
40
41 void AnimateRod(float phase, bool instant = false)
42 {
44 rod.AnimateFishingRodEx(phase,instant);
45 }
46
47 //------------------------------------------------------------------
48 //DEPRECATED
49 //------------------------------------------------------------------
50 const float FISHING_SUCCESS = 0.2;
51 const float FISHING_BAIT_LOSS = 0.02;
52 const float FISHING_HOOK_LOSS = 0.015;
53 const float FISHING_DAMAGE = 1.5;
54 const float FISHING_GARBAGE_CHANCE = 0.2;
58 void InitBait(ItemBase item)
59 {
60 m_Bait = item;
61 m_IsBaitAnEmptyHook = !m_Bait.ConfigIsExisting("hookType");
62 }
64 {
66 }
67}
68
70{
71 FishingActionData m_ActionDataFishing;
72
73 override void CreateActionComponent()
74 {
75 EnableStateChangeCallback();
76 float cycleTime = UAFishingConstants.CYCLE_LENGTH_BASE; //redundant?
77 if (Class.CastTo(m_ActionDataFishing,m_ActionData))
78 {
79 cycleTime = m_ActionDataFishing.m_ContextData.GetActionCycleTime();
80 }
81 m_ActionData.m_ActionComponent = new CAContinuousRepeatFishing(cycleTime);
82 }
83
84 override void InitActionComponent()
85 {
86 super.InitActionComponent();
87
88 RegisterAnimationEvent("ParticleSplash", UAFishingConstants.EVENT_SPLASH_SIGNAL);
89 RegisterAnimationEvent("EventFishPlacement", UAFishingConstants.EVENT_ANIMATE_ROD_CLOSE);
90 }
91
92 override void EndActionComponent()
93 {
94 bool animateRod = false;
95 if (m_ActionDataFishing.m_State == UA_CANCEL)
96 m_Canceled = true;
97
98 if (m_ActionDataFishing.m_State == UA_FINISHED)
99 {
100 if (m_ActionDataFishing.m_FishingResult == 1)
101 {
102 SetCommand(DayZPlayerConstants.CMD_ACTIONINT_END);
103 }
104 else
105 {
106 SetCommand(DayZPlayerConstants.CMD_ACTIONINT_FINISH);
107 animateRod = true;
108 }
109 }
110 else
111 {
112 SetCommand(DayZPlayerConstants.CMD_ACTIONINT_INTERRUPT);
113 animateRod = true;
114 }
115
116 animateRod |= m_Canceled;
117 if (animateRod)
118 {
119 m_ActionDataFishing.AnimateRod(false,m_Canceled);
120 }
121
122 DestroySplashEffectSynced();
123 }
124
125 override void OnStateChange(int pOldState, int pCurrentState)
126 {
127 super.OnStateChange(pOldState,pCurrentState);
128
129 if (pOldState == STATE_NONE && pCurrentState == STATE_LOOP_IN)
130 {
131 m_ActionDataFishing.AnimateRod(true);
132 }
133 }
134
135 void ToggleFishBiting()
136 {
137 if (GetState() == STATE_LOOP_LOOP || GetState() == STATE_LOOP_LOOP2)
138 SetCommand(DayZPlayerConstants.CMD_ACTIONINT_ACTIONLOOP);
139 }
140
142 void DestroySplashEffectSynced()
143 {
144 if (GetGame().IsServer() && m_ActionDataFishing.m_SplashUniqueID >= 0)
145 {
146 SEffectManager.DestroyEffecterParticleServer(m_ActionDataFishing.m_SplashUniqueID);
147 m_ActionDataFishing.m_SplashUniqueID = -1;
148 }
149 }
150
151 //DEPRECATED
152 ref array<string> m_JunkTypes = {};
153 void HandleFishingResultSuccess();
154 void HandleFishingResultFailure();
155};
156
158{
159 private const string ALLOWED_WATER_SURFACES = string.Format("%1|%2", UAWaterType.SEA, UAWaterType.FRESH);
160
161 void ActionFishingNew()
162 {
164 m_SpecialtyWeight = UASoftSkillsWeight.PRECISE_MEDIUM;
165 m_CommandUID = DayZPlayerConstants.CMD_ACTIONFB_FISHING;
166 m_FullBody = true;
167 m_StanceMask = DayZPlayerConstants.STANCEMASK_CROUCH;
168 m_Text = "#start_fishing";
169 }
170
171 override void CreateConditionComponents()
172 {
175 }
176
177 override bool HasTarget()
178 {
179 return true;
180 }
181
182 override bool HasAlternativeInterrupt()
183 {
184 return true;
185 }
186
187 override bool CanBeUsedInFreelook()
188 {
189 return false;
190 }
191
192 override bool ActionCondition(PlayerBase player, ActionTarget target, ItemBase item )
193 {
194 ItemBase hook;
195 hook = ItemBase.Cast(item.FindAttachmentBySlotName("Hook"));
196
197 return hook && !hook.IsRuined() && !hook.IsPendingDeletion();
198 }
199
200 override ActionData CreateActionData()
201 {
202 FishingActionData actionData = new FishingActionData();
203 return actionData;
204 }
205
206 override bool SetupAction(PlayerBase player, ActionTarget target, ItemBase item, out ActionData action_data, Param extra_data = null)
207 {
208 if (super.SetupAction(player, target, item, action_data, extra_data))
209 {
210 FishingActionData data;
211 if (Class.CastTo(data,action_data))
212 {
214 return true;
215 }
216 }
217 return false;
218 }
219
220 protected void ComposeLocalContextData(FishingActionData data)
221 {
222 #ifndef SERVER
223 data.m_IsSurfaceSea = CheckForSea(data); //already synced from client by this point
224 #endif
225 Param2<EntityAI,bool> par = new Param2<EntityAI,bool>(data.m_MainItem,data.m_IsSurfaceSea);
226 data.m_ContextData = new CatchingContextFishingRodAction(par);
227
228 data.m_ContextData.GenerateResult(); //call only once
229
230 #ifdef DEVELOPER
231 data.m_ContextData.SetResultChanceOverride(data.m_Player.IsQuickFishing(),1.0); //active override sets chance to 100% for the action duration
232 #endif
233 }
234
235 override void WriteToContext(ParamsWriteContext ctx, ActionData action_data)
236 {
237 super.WriteToContext(ctx, action_data);
238 FishingActionData data
239 if (Class.CastTo(data,action_data))
240 {
241 ctx.Write(data.m_IsSurfaceSea);
242 }
243 }
244
245 override bool ReadFromContext(ParamsReadContext ctx, out ActionReciveData action_recive_data )
246 {
247 if (!action_recive_data)
248 {
249 action_recive_data = new FishingActionReceiveData;
250 }
251
252 super.ReadFromContext(ctx, action_recive_data);
253
254 FishingActionReceiveData receiveDataFishing;
255 if (Class.CastTo(receiveDataFishing,action_recive_data))
256 {
257 if (!ctx.Read(receiveDataFishing.m_IsSurfaceSea))
258 return false;
259
260 return true;
261 }
262
263 return false;
264 }
265
266 override void HandleReciveData(ActionReciveData action_recive_data, ActionData action_data)
267 {
268 super.HandleReciveData(action_recive_data, action_data);
269
270 FishingActionReceiveData receiveDataFishing = FishingActionReceiveData.Cast(action_recive_data);
271 FishingActionData fishingData = FishingActionData.Cast(action_data);
272
273 fishingData.m_IsSurfaceSea = receiveDataFishing.m_IsSurfaceSea;
274 }
275
276 override protected void CreateAndSetupActionCallback(ActionData action_data)
277 {
278 super.CreateAndSetupActionCallback(action_data);
279
280 FishingActionData data;
281 if (Class.CastTo(data,action_data))
282 {
283 data.RollNextResultChance(); //performed here so that component exists
284 }
285 }
286
287 override void OnAnimationEvent( ActionData action_data )
288 {
289 super.OnAnimationEvent(action_data);
290 FishingActionData actionDataFishing = FishingActionData.Cast(action_data);
291
292 switch (action_data.m_DelayedAnimationEventID)
293 {
294 case UAFishingConstants.EVENT_SPLASH_SIGNAL:
295 PlaySplashEffectSynced(actionDataFishing);
296 break;
297
298 case UAFishingConstants.EVENT_ANIMATE_ROD_CLOSE:
299 actionDataFishing.AnimateRod(false,false);
300 break;
301 }
302 }
303
304 override void OnUpdate(ActionData action_data)
305 {
306 super.OnUpdate(action_data);
307
308 vector dir = vector.Direction(action_data.m_Player.GetPosition(), action_data.m_Target.GetCursorHitPos());
309 dir[1] = 0;
310 dir.Normalize();
311 action_data.m_Player.AlignDirectionWS(dir);
312 }
313
314 void PlaySplashEffectSynced(FishingActionData actionDataFishing)
315 {
316 if (GetGame().IsServer())
317 {
318 int particleId = actionDataFishing.m_ContextData.GetResultParticleId();
319 if (actionDataFishing.m_SplashUniqueID < 0)
320 {
321 actionDataFishing.m_SplashUniqueID = SEffectManager.CreateParticleServer(actionDataFishing.m_Target.GetCursorHitPos(), new ParticleEffecterParameters("ParticleEffecter", EffecterBase.NOT_DEFINED_LIFESPAN, particleId));
322 }
323 else
324 {
325 SEffectManager.ReinitParticleServer(actionDataFishing.m_SplashUniqueID, new ParticleEffecterParameters("ParticleEffecter", EffecterBase.NOT_DEFINED_LIFESPAN, particleId)); //reinit here, since particleId might differ
326 SEffectManager.ReactivateParticleServer(actionDataFishing.m_SplashUniqueID);
327 }
328 }
329 }
330
331 protected bool CheckForSea(ActionData action_data)
332 {
333 bool ret = false;
334 vector cursorPosition = action_data.m_Target.GetCursorHitPos();
335
336 if (GetGame().SurfaceIsSea(cursorPosition[0], cursorPosition[2]))
337 {
338 ret = true;
339 }
340
341 return ret;
342 }
343
344 //------------------------------------------------------
345
346 override void OnFinishProgress(ActionData action_data)
347 {
348 super.OnFinishProgress(action_data);
349
350 FishingActionData data;
351 if (Class.CastTo(data,action_data))
352 {
353 data.RollNextResultChance();
354 }
355 }
356
357 override void OnEndInput(ActionData action_data)
358 {
359 ActionContinuousBaseCB callback;
360 if (Class.CastTo(callback, action_data.m_Callback))
361 {
362 switch (callback.GetState())
363 {
364 case HumanCommandActionCallback.STATE_LOOP_ACTION:
365 case HumanCommandActionCallback.STATE_LOOP_LOOP:
366 case HumanCommandActionCallback.STATE_LOOP_LOOP2:
367 FishingActionData data;
368 if (Class.CastTo(data,action_data))
369 {
370 data.m_FishingResult = EvaluateFishingResult(action_data);
371 if (data.m_FishingResult != -1)
372 data.m_State = UA_FINISHED;
373 }
374 break;
375
376 default:
377 super.OnEndInput(action_data);
378 callback.EndActionComponent(); //think about putting this everywhere, interrupts HumanCommandActionCallback.STATE_LOOP_IN neatly
379 break;
380 }
381 }
382 }
383
384 override void OnEnd(ActionData action_data)
385 {
386 super.OnEnd(action_data);
387
388 FishingActionData fad;
389 if (Class.CastTo(fad,action_data))
390 fad.AnimateRod(false,true); //just in case
391 }
392
394 int EvaluateFishingResult(ActionData action_data)
395 {
396 FishingActionData fad;
397 if (Class.CastTo(fad,action_data))
398 {
399 //legacy stuff
400 ActionFishingNewCB legacyCB = ActionFishingNewCB.Cast(fad.m_Callback);
401 if (fad.m_IsSignalActive)//catch
402 {
403 fad.m_ContextData.OnBeforeSpawnSignalHit();
404
405 if (!GetGame().IsMultiplayer() || GetGame().IsDedicatedServer())
406 TrySpawnCatch(fad);
407
408 fad.m_ContextData.OnAfterSpawnSignalHit();
409 if (legacyCB)
410 legacyCB.HandleFishingResultSuccess();
411
412 EntityAI hookCheck = action_data.m_MainItem.FindAttachmentBySlotName("Hook");
413 return hookCheck != null && !hookCheck.IsPendingDeletion(); //success animation only if hook loss didn't prevent catch (local)
414 }
415 else//fail
416 {
417 fad.m_ContextData.OnSignalMiss();
418 if (legacyCB)
419 legacyCB.HandleFishingResultFailure();
420
421 return false;
422 }
423 }
424
425 return -1;
426 }
427
428 //------------------------------------------------------
429 void OnSignalStart(FishingActionData action_data)
430 {
431 action_data.m_IsSignalActive = true;
432 ActionFishingNewCB fishingCB;
433 if (Class.CastTo(fishingCB,action_data.m_Callback))
434 fishingCB.ToggleFishBiting();
435 }
436
437 void OnSignalEnd(FishingActionData action_data)
438 {
439 action_data.m_IsSignalActive = false;
440 ActionFishingNewCB fishingCB;
441 if (Class.CastTo(fishingCB,action_data.m_Callback))
442 fishingCB.ToggleFishBiting();
443
444 action_data.m_ContextData.OnSignalPass();
445 }
446
447 protected EntityAI TrySpawnCatch(FishingActionData action_data)
448 {
449 vector spawnPos = vector.Direction(action_data.m_Player.GetPosition(),action_data.m_Target.GetCursorHitPos()); //direction first
450 spawnPos = MiscGameplayFunctions.GetRandomizedPositionVerified(action_data.m_Player.GetPosition(),action_data.m_Player.GetPosition() + spawnPos * 0.1,0.15,action_data.m_Player);
451
452 int idx;
453 return action_data.m_ContextData.SpawnAndSetupCatch(idx,spawnPos);
454 }
455}
ref CABase m_ActionComponent
Definition actionbase.c:38
ItemBase m_Bait
const float FISHING_GARBAGE_CHANCE
FishingActionReceiveData m_IsSurfaceSea
float m_RodQualityModifier
const float FISHING_HOOK_LOSS
bool m_IsSignalActive
int m_FishingResult
void RollNextResultChance()
void AnimateRod(float phase, bool instant=false)
int m_SplashUniqueID
const float FISHING_BAIT_LOSS
const float FISHING_SUCCESS
const float FISHING_DAMAGE
void RandomizeSignalValues()
bool IsBaitEmptyHook()
bool m_IsBaitAnEmptyHook
void InitBait(ItemBase item)
ref CatchingContextFishingRodAction m_ContextData
#define LIQUID_FRESHWATER
#define LIQUID_SALTWATER
class BaitData m_MainItem
Definition actionbase.c:36
void CCTWaterSurfaceEx(float maximal_target_distance, int allowedLiquidSource)
void SetCommand(int command_uid)
ActionData m_ActionData
float m_SpecialtyWeight
Definition actionbase.c:77
int m_StanceMask
Definition actionbase.c:62
string m_Text
Definition actionbase.c:58
ref CCIBase m_ConditionItem
Definition actionbase.c:64
bool m_FullBody
Definition actionbase.c:61
ref CCTBase m_ConditionTarget
Definition actionbase.c:65
int EvaluateFishingResult(ActionData action_data)
Player input reaction evaluation.
override bool ReadFromContext(ParamsReadContext ctx, out ActionReciveData action_recive_data)
override void OnEndInput(ActionData action_data)
EntityAI TrySpawnCatch(FishingActionData action_data)
void OnSignalEnd(FishingActionData action_data)
void CreateAndSetupActionCallback(ActionData action_data)
override void OnUpdate(ActionData action_data)
override void OnAnimationEvent(ActionData action_data)
override void OnFinishProgress(ActionData action_data)
void ComposeLocalContextData(FishingActionData data)
override void WriteToContext(ParamsWriteContext ctx, ActionData action_data)
override void OnEnd(ActionData action_data)
override void HandleReciveData(ActionReciveData action_recive_data, ActionData action_data)
void PlaySplashEffectSynced(FishingActionData actionDataFishing)
void OnSignalStart(FishingActionData action_data)
bool CheckForSea(ActionData action_data)
Super root of all classes in Enforce script.
Definition enscript.c:11
Base Param Class with no parameters. Used as general purpose parameter overloaded with Param1 to Para...
Definition param.c:12
Manager class for managing Effect (EffectParticle, EffectSound)
static void DestroyEffecterParticleServer(int effecterID)
static int CreateParticleServer(vector pos, EffecterParameters parameters)
returns unique effecter ID
static void ReinitParticleServer(int effecterID, EffecterParameters parameters)
allows re-initializing existing effecter with new parameters (extept m_EffecterType,...
static void ReactivateParticleServer(int effecterID)
Serialization general interface. Serializer API works with:
Definition serializer.c:56
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
class DayZCreatureAnimInterface RegisterAnimationEvent(string event_name, string function_name)
DayZPlayerConstants
defined in C++
Definition dayzplayer.c:602
proto native CGame GetGame()
const int UA_FINISHED
Definition constants.c:466
const int UA_CANCEL
Definition constants.c:467
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.