DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
Bot.c
См. документацию.
1#ifdef ROBOCLIENT
4class BotTrigger
5{
6 bool CheckTrigger () { return false; }
7};
8
9class MyBotTrigger : BotTrigger
10{
11 PlayerBase m_Owner;
12 void MyBotTrigger (PlayerBase p) { m_Owner = p; }
13 override bool CheckTrigger () { return null != m_Owner.GetInventory().FindAttachment(InventorySlots.GetSlotIdFromString("Headgear")); }
14};
15
16
19class Bot
20{
21 PlayerBase m_Owner = null;
22 protected ref BotFSM m_ActiveFSM = null;
23 protected DayZPlayerInstanceType m_InstanceType = DayZPlayerInstanceType.INSTANCETYPE_CLIENT;
24 private ref BotStateBase m_Attack;
25 private ref BotStateBase m_TurnValidForward;
26 private ref BotStateBase m_MoveForward;
27 protected ref BotStateBase m_IdleState = null;
28
29 private ref map<ref BotFSM, BotStateMachineData> m_StateMachines;
30 private ref map<string, BotStateBase> m_States;
31 private ref map<string, BotEventBase> m_Events;
32 private ref map<string, BotActionBase> m_Actions;
33 private ref map<string, BotGuardBase> m_Guards;
34
35 private const vector m_InfectedHalfRange = "2 0 2";
36 EntityAI m_Target = null;
37
38 bool m_Active = true;
39
40 // events
41 ref BotEventBase ___Bgn__ = new BotEventStart;
42 ref BotEventBase __Stop__ = new BotEventStop;
43 ref BotEventBase ___OK___ = new BotEventEndOK;
44 ref BotEventBase __Fail__ = new BotEventEndFail;
45 ref BotEventBase __Tout__ = new BotEventEndTimeout;
46 ref BotEventBase __IChg__ = new BotEventOnItemInHandsChanged;
47 ref BotEventBase __Obst__ = new BotEventObstacle;
48 ref BotEventBase __VaFw__ = new BotEventValidForward;
49 ref BotEventBase __Atkd__ = new BotEventAttacked;
50
51
52 void Bot (PlayerBase ow)
53 {
54 m_Owner = ow;
55
56 // basic states
57 m_IdleState = new BotStateIdle(this, NULL);
58 m_TurnValidForward = new BotTurnToValidForward(this, NULL);
59 m_Attack = new BotAttack(this, NULL);
60 m_MoveForward = new BotMoveForward(this, NULL);
61
62 m_States = new map<string, BotStateBase>;
63 m_States.Insert(m_IdleState.ClassName(), m_IdleState);
64 m_States.Insert(m_MoveForward.ClassName(), m_MoveForward);
65 m_States.Insert(m_TurnValidForward.ClassName(), m_TurnValidForward);
66 m_States.Insert(m_Attack.ClassName(), m_Attack);
67 m_States.Insert("None", NULL);
68
69 m_Events = new map<string, BotEventBase>;
70 m_Events.Insert(__Obst__.ClassName(), __Obst__);
71 m_Events.Insert(__VaFw__.ClassName(), __VaFw__);
72 m_Events.Insert(__Atkd__.ClassName(), __Atkd__);
73 m_Events.Insert("None", NULL);
74
75 m_Actions = new map<string, BotActionBase>;
76 m_Actions.Insert("None", NULL);
77
78 m_Guards = new map<string, BotGuardBase>;
79 m_Guards.Insert("None", NULL);
80
81 m_StateMachines = new map<ref BotFSM, BotStateMachineData>;
82 RoboclientUtils.ReadStateMachines();
83 GetStateMachines();
84
85 InitFSM();
86 RegisterStateMachineDiag();
87 }
88
89 void ~Bot()
90 {
91 delete m_States;
92 delete m_Events;
93 delete m_Actions;
94 delete m_Guards;
95 delete m_StateMachines;
96 }
97
98 void RegisterStateMachineDiag()
99 {
100 string stateMachineNames;
101 int activeStateMachineIndex = 0;
102 for(int i = 0; i < m_StateMachines.Count(); i++)
103 {
104 stateMachineNames += m_StateMachines.GetElement(i).GetName();
105 if (i != m_StateMachines.Count() - 1)
106 stateMachineNames += ",";
107 if (m_ActiveFSM == m_StateMachines.GetKey(i))
108 activeStateMachineIndex = i;
109 }
110
111#ifdef DIAG_DEVELOPER
112 DiagMenu.RegisterItem(DiagMenuIDs.ROBOCLIENTS_STATE_MACHINES, "", "State Machine", DiagMenuIDs.ROBOCLIENTS_MENU, stateMachineNames);
113 DiagMenu.SetValue(DiagMenuIDs.ROBOCLIENTS_STATE_MACHINES, activeStateMachineIndex);
114 DiagMenu.BindCallback(DiagMenuIDs.ROBOCLIENTS_STATE_MACHINES, PluginDiagMenuClient.CBRoboclientChangeStateMachine);
115#endif
116 }
117
118 void SetInstanceType (DayZPlayerInstanceType t) { m_InstanceType = t; }
119
120 void GetStateMachines()
121 {
122 array<BotStateMachineData> stateMachinesData = new array<BotStateMachineData>;
123 RoboclientUtils.GetStateMachines(stateMachinesData);
124 for (int i = 0; i < stateMachinesData.Count(); i++)
125 {
126 string name = stateMachinesData[i].GetName();
127 TStringArray from = new TStringArray;
128 stateMachinesData[i].GetFromStates(from);
129 TStringArray to = new TStringArray;
130 stateMachinesData[i].GetToStates(to);
131 TStringArray evnt = new TStringArray;
132 stateMachinesData[i].GetEvents(evnt);
133 TStringArray action = new TStringArray;
134 stateMachinesData[i].GetActions(action);
135 TStringArray guard = new TStringArray;
136 TStringArray guardDecorator = new TStringArray;
137 stateMachinesData[i].GetGuards(guard, guardDecorator);
138 //checking the number of from states, transition events, to states and actions are equal since there is one for each transition
139 //there are 2 guards for each transition, so they must be twice as many as from states (or events, to states, action)
140 if (from.Count() != to.Count() || from.Count() != evnt.Count() || from.Count() != action.Count() || from.Count() != guardDecorator.Count() || 2 * from.Count() != guard.Count())
141 continue;
142
143 BotFSM fsm = new BotFSM();
144 for(int j = 0; j < from.Count(); j++)
145 {
146 BotGuardBase resultGuard = NULL;
147 if (m_Guards[guard[2 * j]])
148 {
149 switch (guardDecorator[j])
150 {
151 case "Not":
152 resultGuard = BotGuardNot(m_Guards[guard[2 * j]]);
153 break;
154 case "And":
155 if (m_Guards[guard[2 * j + 1]])
156 resultGuard = BotGuardAnd(m_Guards[guard[2 * j]], m_Guards[guard[2 * j + 1]]);
157 break;
158 case "Or":
159 if (m_Guards[guard[2 * j + 1]])
160 resultGuard = BotGuardOr(m_Guards[guard[2 * j]], m_Guards[guard[2 * j + 1]]);
161 break;
162 default:
163 if (guardDecorator[j] != "None")
164 break;
165 }
166
167 if (!resultGuard)
168 resultGuard = m_Guards[guard[2 * j]];
169 }
170 fsm.AddTransition(new BotTransition(m_States[from[j]], m_Events[evnt[j]], m_States[to[j]], m_Actions[action[j]], resultGuard));
171 }
172 fsm.SetInitialState(m_States[stateMachinesData[i].GetInitialState()]);
173 m_StateMachines.Insert(fsm, stateMachinesData[i]);
174 if (stateMachinesData[i].GetActive())
175 m_ActiveFSM = fsm;
176 }
177 }
178
179 void Start ()
180 {
181 if (!m_ActiveFSM || m_ActiveFSM.IsRunning())
182 return;
183
184 m_Target = null;
185 m_ActiveFSM.Start();
186 }
187
188 void Stop ()
189 {
190 if (!m_ActiveFSM)
191 return;
192
193 m_ActiveFSM.Terminate();
194#ifdef INPUT_OVERRIDE
195 g_Game.GetPlayer().GetInputInterface().SyncedRemoveAllOverrides();
196#endif
197 }
198
199 void Restart()
200 {
201 Stop();
202 Start();
203 }
204
205 void StartAction(int action)
206 {
207 switch (action)
208 {
209 case EActions.PLAYER_BOT_STOP_CURRENT:
210 ProcessEvent(new BotEventStop(m_Owner, null));
211 return;
212 }
213
214 ProcessEvent(new BotEventStartDebug(m_Owner, null, action));
215 }
216
217 void OnUpdate (float dt)
218 {
219 if (!m_ActiveFSM)
220 return;
221
222 if (m_ActiveFSM.IsRunning())
223 m_ActiveFSM.GetCurrentState().OnUpdate(dt);
224 }
225
226 bool GetShouldRespawn()
227 {
228 BotStateMachineData data = NULL;
229 if (m_StateMachines.Find(m_ActiveFSM, data))
230 return data.GetRoboRespawn();
231 return RoboclientUtils.GetDefaultRoboRespawn();
232 }
233
234 int GetRespawnTime()
235 {
236 BotStateMachineData data = NULL;
237 if (m_StateMachines.Find(m_ActiveFSM, data))
238 return data.GetRoboRespawnTime();
239 return RoboclientUtils.GetDefaultRoboRespawnTime();
240 }
241
242 void GetRespawnData(out bool shouldRespawn, out int respawnTime)
243 {
244 BotStateMachineData data = NULL;
245 if (m_StateMachines.Find(m_ActiveFSM, data))
246 {
247 shouldRespawn = data.GetRoboRespawn();
248 respawnTime = data.GetRoboRespawnTime();
249 return;
250 }
251 shouldRespawn = RoboclientUtils.GetDefaultRoboRespawn();
252 respawnTime = RoboclientUtils.GetDefaultRoboRespawnTime();
253 }
254
255 void ChangeStateMachine (int index)
256 {
257 if (index >= m_StateMachines.Count())
258 return;
259
260 Stop();
261 m_ActiveFSM = m_StateMachines.GetKey(index);
262 if (DiagMenu.GetBool(DiagMenuIDs.ROBOCLIENTS_ACTIVE))
263 Start();
264 }
265
266 void ChangeStateMachine (string stateMachineName)
267 {
268 BotFSM newStateMachine;
269 for (int i = 0; i < m_StateMachines.Count(); i++)
270 {
271 if (m_StateMachines.GetElement(i).GetName() == stateMachineName)
272 {
273 ChangeStateMachine(i);
274 return;
275 }
276 }
277 }
278
279 private bool IsEntityEnemy(EntityAI entity)
280 {
281 if (DayZInfected.Cast(entity))
282 return true;
283
284 PlayerBase p = PlayerBase.Cast(entity);
285 if (p)
286 {
287 return !p.IsUnconscious();
288 }
289
290 if (DayZAnimal.Cast(entity))
291 return true;
292
293 return false;
294 }
295
296 void CheckForEnemies(bool Force = false)
297 {
298 if (!m_ActiveFSM)
299 return;
300
301 vector min = m_Owner.GetPosition() - m_InfectedHalfRange;
302 vector max = m_Owner.GetPosition() + m_InfectedHalfRange + "0 2 0";
303 array<EntityAI> entities = {};
304 DayZPlayerUtils.SceneGetEntitiesInBox(min, max, entities);
305
306 if (m_Target && m_Target.IsAlive() && entities.Find(m_Target) != -1)
307 {
308 if (Force || m_ActiveFSM.GetCurrentState() != m_Attack)
309 ProcessEvent(__Atkd__);
310
311 return;
312 }
313
314 for (int i = 0; i < entities.Count(); i++)
315 {
316 if (entities[i] != m_Owner && entities[i].IsAlive() && IsEntityEnemy(entities[i]))
317 {
318 if (Force || m_ActiveFSM.GetCurrentState() != m_Attack)
319 {
320 m_Target = entities[i];
321 ProcessEvent(__Atkd__);
322 }
323 return;
324 }
325 }
326
327 m_Target = null;
328 ProcessEvent(__VaFw__);
329 }
330
331 void AddTransition(BotStateBase state, int id)
332 {
333 BotEventStartDebug evt = new BotEventStartDebug(null, null, id);
334
335 m_ActiveFSM.AddTransition(new BotTransition(m_IdleState, evt, state, null, new BotGuardDebugEventMatches(evt)));
336
337 m_ActiveFSM.AddTransition(new BotTransition(state, ___OK___, m_IdleState));
338 m_ActiveFSM.AddTransition(new BotTransition(state, __Fail__, m_IdleState));
339 m_ActiveFSM.AddTransition(new BotTransition(state, __Tout__, m_IdleState));
340
341 m_ActiveFSM.AddTransition(new BotTransition(state, __Stop__, m_IdleState));
342 }
343
344 void InitFSM ()
345 {
346 if (GetGame().m_IsRoboclient)
347 {
348 //Script version of the default state machine that's defined in the config file:
349 //m_ActiveFSM = new BotFSM();
350 //m_ActiveFSM.AddTransition(new BotTransition(m_MoveForward, __Obst__, m_TurnValidForward));
351 //m_ActiveFSM.AddTransition(new BotTransition(m_MoveForward, __Atkd__, m_Attack));
352 //m_ActiveFSM.AddTransition(new BotTransition(m_TurnValidForward, __VaFw__, m_MoveForward));
353 //m_ActiveFSM.AddTransition(new BotTransition(m_TurnValidForward, __Atkd__, m_Attack));
354 //m_ActiveFSM.AddTransition(new BotTransition(m_Attack, __VaFw__, m_MoveForward));
355 //m_ActiveFSM.SetInitialState(m_MoveForward);
356 //BotStateMachineData data = new BotStateMachineData();
357 //data.SetName("Default");
358 //data.SetRoboRespawn(true);
359 //data.SetRoboRespawnTime(5);
360 //m_StateMachines.Insert(m_ActiveFSM, data);
361 }
362 else
363 {
364 m_ActiveFSM = new BotFSM();
365 AddTransition(new BotStanceRandomizer(this, NULL), EActions.PLAYER_BOT_RANDOMIZE_STANCE);
366 AddTransition(new BotMovementRandomizer(this, NULL), EActions.PLAYER_BOT_RANDOMIZE_MOVEMENT);
367 AddTransition(new BotTestSpamUserActions(this, NULL), EActions.PLAYER_BOT_SPAM_USER_ACTIONS);
368 AddTransition(new BotTestAttachAndDropCycle(this, NULL), EActions.PLAYER_BOT_TEST_ATTACH_AND_DROP_CYCLE);
369 AddTransition(new BotTestItemMoveBackAndForth(this, NULL), EActions.PLAYER_BOT_TEST_ITEM_MOVE_BACK_AND_FORTH);
370 AddTransition(new Bot_TestSpawnOpen(this, NULL), EActions.PLAYER_BOT_TEST_SPAWN_OPEN);
371 AddTransition(new Bot_TestSpawnOpenDestroy(this, NULL), EActions.PLAYER_BOT_TEST_SPAWN_OPEN_DESTROY);
372 AddTransition(new Bot_TestSpawnOpenEat(this, NULL), EActions.PLAYER_BOT_TEST_SPAWN_OPEN_EAT);
373 AddTransition(new BotTestSwapG2H(this, NULL), EActions.PLAYER_BOT_TEST_SWAP_G2H);
374 //AddTransition(new BotTestSwapC2H(this, NULL), EActions.PLAYER_BOT_TEST_SWAP_C2H);
375 AddTransition(new BotTestSwapInternal(this, NULL), EActions.PLAYER_BOT_TEST_SWAP_INTERNAL);
376
378
379 m_ActiveFSM.SetInitialState(m_IdleState);
380 }
381 }
382
383 bool ProcessEvent (BotEventBase e)
384 {
385 if (m_ActiveFSM.ProcessEvent(e) == ProcessEventResult.FSM_OK)
386 {
387 botDebugSpam("[botfsm] Processed event e=" + e.ToString());
388 return true;
389 }
390 else
391 {
392 botDebugSpam("[botfsm] FSM refused to process event (no transition): src=" + m_ActiveFSM.GetCurrentState().ToString() + " event=" + e.ToString());
393 return false;
394 }
395 }
396};
397
398void botDebugPrint (string s)
399{
400#ifdef BOT_DEBUG
401 PrintToRPT("" + s); // comment/uncomment to hide/see debug logs
402#else
403 //Print("" + s); // comment/uncomment to hide/see debug logs
404#endif
405}
406
407void botDebugSpam (string s)
408{
409#ifdef BOT_DEBUG_SPAM
410 PrintToRPT("" + s); // comment/uncomment to hide/see debug logs
411#else
412 //Print("" + s); // comment/uncomment to hide/see debug logs
413#endif
414}
415#endif
class LogManager EntityAI
ref ActionTarget m_Target
Определения ActionBase.c:18
PlayerSpawnPresetDiscreteItemSetSlotData name
one set for cargo
map
Определения ControlsXboxNew.c:4
DayZGame g_Game
Определения DayZGame.c:4074
void DayZPlayerUtils()
cannot be instantiated
Определения DayZPlayerUtils.c:465
EActions
Определения EActions.c:2
DiagMenuIDs
Определения EDiagMenuIDs.c:2
void Start()
Plays all elements this effects consists of.
Определения Effect.c:157
ProcessEventResult
Определения FSMBase.c:41
enum ProcessDirectDamageFlags m_Owner
void ProcessEvent(EPresenceNotifierNoiseEventType pEventType)
processing of external one-time events (land, fire, etc.)
Определения PluginPresenceNotifier.c:207
DayZPlayerInstanceType
defined in C++
Определения dayzplayer.c:1084
DayZGame GetGame()
Определения gameplay.c:636
proto void PrintToRPT(void var)
Prints content of variable to RPT file (performance warning - each write means fflush!...
class array< Class T > TStringArray
proto void Restart()
void Stop()
Stops all elements this effect consists of.
Определения Effect.c:183
proto native void OnUpdate()
Определения 3_Game/DayZ/tools/tools.c:349
proto native bool StartAction(WeaponActions pAction, int pActionType)
start reload,mechanism,chambering,unjam ...