2 #using scripts\shared\array_shared;
4 #insert scripts\shared\shared.gsh;
5 #insert scripts\shared\statemachine.gsh;
7 #namespace statemachine;
9 function create(
name, owner, change_notify =
"change_state" )
11 state_machine = SpawnStruct();
12 state_machine.name =
name;
13 state_machine.states = [];
14 state_machine.previous_state = undefined;
15 state_machine.current_state = undefined;
16 state_machine.next_state = undefined;
17 state_machine.change_note = change_notify;
19 if ( isdefined( owner ) )
21 state_machine.owner = owner;
25 state_machine.owner = level;
28 if ( !isdefined( state_machine.owner.state_machines ) )
30 state_machine.owner.state_machines = [];
33 state_machine.owner.state_machines[ state_machine.name ] = state_machine;
40 if ( isdefined(
self.states ) && IsArray(
self.states ) )
42 foreach( state
in self.states )
44 state.connections_notify = undefined;
45 state.connections_utility = undefined;
49 self.states = undefined;
50 self.previous_state = undefined;
51 self.current_state = undefined;
52 self.next_state = undefined;
53 self.owner = undefined;
55 self notify(
"_cancel_connections" );
62 if ( !IsDefined(
self.states[
name ] ) )
64 self.states[
name ] = SpawnStruct();
68 self.states[
name ].enter_func = enter_func;
69 self.states[
name ].exit_func = exit_func;
70 self.states[
name ].update_func = update_func;
71 self.states[
name ].reenter_func = reenter_func;
72 self.states[
name ].connections_notify = [];
73 self.states[
name ].connections_utility = [];
74 self.states[
name ].owner =
self;
77 return self.states[
name ];
82 return self.states[
name ];
95 connection = SpawnStruct();
96 connection.to_state = to_state;
98 connection.on_notify = on_notify;
99 connection.checkfunc = checkfunc;
101 from_state.connections_notify[ on_notify ] = connection;
103 return from_state.connections_notify[ from_state.connections_notify.size - 1 ];
117 connection = SpawnStruct();
118 connection.to_state = to_state;
120 connection.checkfunc = checkfunc;
121 connection.score = defaultScore;
122 if ( !isdefined( connection.score ) )
127 ARRAY_ADD( from_state.connections_utility, connection );
129 return from_state.connections_utility[ from_state.connections_utility.size - 1 ];
136 state =
self.states[
name ];
138 if ( !isdefined(
self.owner ) )
144 if ( !isdefined( state ) )
146 AssertMsg(
"Could not find state named " +
name +
" in statemachine: " +
self.
name );
150 reenter = (
self.current_state === state );
153 if ( isdefined( state.reenter_func ) && reenter )
155 shouldReenter =
self.owner [[ state.reenter_func ]]( state.state_params );
158 if ( reenter && shouldReenter !==
true )
164 if ( isdefined(
self.current_state ) )
166 self.next_state = state;
169 if ( isdefined(
self.current_state.exit_func ) )
171 self.owner [[
self.current_state.exit_func ]](
self.current_state.state_params );
176 self.previous_state =
self.current_state;
178 self.current_state.state_params = undefined;
181 if ( !isdefined( state_params ) )
183 state_params = SpawnStruct();
185 state.state_params = state_params;
188 self.owner notify(
self.change_note );
191 self.current_state = state;
196 if ( isdefined(
self.current_state.enter_func ) )
198 self.owner [[
self.current_state.enter_func ]](
self.current_state.state_params );
202 if ( isdefined(
self.current_state.update_func ) )
204 self.owner thread [[
self.current_state.update_func ]](
self.current_state.state_params );
212 self notify(
"_cancel_connections" );
215 foreach( connection
in state.connections_notify )
224 self endon( state_machine.change_note );
225 state_machine endon(
"_cancel_connections" );
229 self waittill( notify_name, param0, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15 );
230 params = SpawnStruct();
231 params.notify_param = [];
249 connectionValid =
true;
250 if ( isdefined( connection.checkfunc ) )
252 connectionValid =
self [[connection.checkfunc]](
self.current_state, connection.to_state.name, connection, params );
255 if ( connectionValid )
257 state_machine thread
set_state( connection.to_state.name, params );
268 assert( isdefined(
self.current_state ) );
270 connectionArray = [];
273 best_connection = undefined;
276 foreach ( connection
in self.current_state.connections_utility )
280 score = connection.score;
281 if ( isdefined( connection.checkfunc ) )
283 score =
self.owner [[ connection.checkfunc ]](
self.current_state.name, connection.to_state.name, connection );
291 if ( score > best_score )
293 best_connection = connection;
299 if ( isdefined( eval_func ) && connectionArray.size > 0 )
301 best_connection =
self.owner [[eval_func]]( connectionArray, scoreArray,
self.current_state );
304 if ( isdefined( best_connection ) )
306 self thread
set_state( best_connection.to_state.name, params );
312 dvarVal = GetDvarInt(
"statemachine_debug" );