92 ); |
93 ); |
93 |
94 |
94 procedure DumpAction(Action: TAction; Me: PGear); |
95 procedure DumpAction(Action: TAction; Me: PGear); |
95 begin |
96 begin |
96 if (Action.Action and ai_specmask) = 0 then |
97 if (Action.Action and ai_specmask) = 0 then |
97 WriteLnToConsole('AI action: '+ActionIdToStr[Action.Action]) |
98 WriteLnToConsole('AI action: '+ActionIdToStr[Action.Action]) |
98 else begin |
99 else |
99 WriteLnToConsole('AI action: '+SpecActionIdToStr[Action.Action]); |
100 begin |
100 if (Action.Action = aia_WaitXL) or (Action.Action = aia_WaitXR) then |
101 WriteLnToConsole('AI action: '+SpecActionIdToStr[Action.Action]); |
101 WriteLnToConsole('AI action Wait X = '+IntToStr(Action.Param)+', current X = '+IntToStr(hwRound(Me^.X))) |
102 if (Action.Action = aia_WaitXL) or (Action.Action = aia_WaitXR) then |
102 else if (Action.Action = aia_AwareExpl) then WriteLnToConsole('Aware X = ' + IntToStr(Action.X) + ', Y = ' + IntToStr(Action.Y)); |
103 WriteLnToConsole('AI action Wait X = '+IntToStr(Action.Param)+', current X = '+IntToStr(hwRound(Me^.X))) |
103 end |
104 |
|
105 else if (Action.Action = aia_AwareExpl) then |
|
106 WriteLnToConsole('Aware X = ' + IntToStr(Action.X) + ', Y = ' + IntToStr(Action.Y)); |
|
107 end |
104 end; |
108 end; |
105 {$ENDIF} |
109 {$ENDIF} |
106 |
110 |
107 procedure AddAction(var Actions: TActions; Action: Longword; Param: LongInt; TimeDelta: Longword; X, Y: LongInt); |
111 procedure AddAction(var Actions: TActions; Action: Longword; Param: LongInt; TimeDelta: Longword; X, Y: LongInt); |
108 begin |
112 begin |
109 with Actions do |
113 with Actions do |
110 begin |
114 begin |
111 actions[Count].Action:= Action; |
115 actions[Count].Action:= Action; |
112 actions[Count].Param:= Param; |
116 actions[Count].Param:= Param; |
113 actions[Count].X:= X; |
117 actions[Count].X:= X; |
114 actions[Count].Y:= Y; |
118 actions[Count].Y:= Y; |
115 if Count > 0 then actions[Count].Time:= TimeDelta |
119 if Count > 0 then |
116 else actions[Count].Time:= GameTicks + TimeDelta; |
120 actions[Count].Time:= TimeDelta |
117 inc(Count); |
121 else |
118 TryDo(Count < MAXACTIONS, 'AI: actions overflow', true); |
122 actions[Count].Time:= GameTicks + TimeDelta; |
119 end |
123 inc(Count); |
|
124 TryDo(Count < MAXACTIONS, 'AI: actions overflow', true); |
|
125 end |
120 end; |
126 end; |
121 |
127 |
122 procedure CheckHang(Me: PGear); |
128 procedure CheckHang(Me: PGear); |
123 const PrevX: LongInt = 0; |
129 const PrevX: LongInt = 0; |
124 timedelta: Longword = 0; |
130 timedelta: Longword = 0; |
125 begin |
131 begin |
126 if hwRound(Me^.X) <> PrevX then |
132 if hwRound(Me^.X) <> PrevX then |
127 begin |
133 begin |
128 PrevX:= hwRound(Me^.X); |
134 PrevX:= hwRound(Me^.X); |
129 timedelta:= 0 |
135 timedelta:= 0 |
130 end else |
136 end else |
131 begin |
137 begin |
132 inc(timedelta); |
138 inc(timedelta); |
133 if timedelta > 1700 then |
139 if timedelta > 1700 then |
134 begin |
140 begin |
135 timedelta:= 0; |
141 timedelta:= 0; |
136 FreeActionsList |
142 FreeActionsList |
137 end |
143 end |
138 end |
144 end |
139 end; |
145 end; |
140 |
146 |
141 procedure ProcessAction(var Actions: TActions; Me: PGear); |
147 procedure ProcessAction(var Actions: TActions; Me: PGear); |
142 var s: shortstring; |
148 var s: shortstring; |
143 begin |
149 begin |
144 repeat |
150 repeat |
145 if Actions.Pos >= Actions.Count then exit; |
151 if Actions.Pos >= Actions.Count then exit; |
146 with Actions.actions[Actions.Pos] do |
152 with Actions.actions[Actions.Pos] do |
147 begin |
153 begin |
148 if Time > GameTicks then exit; |
154 if Time > GameTicks then |
149 {$IFDEF TRACEAIACTIONS} |
155 exit; |
150 DumpAction(Actions.actions[Actions.Pos], Me); |
156 {$IFDEF TRACEAIACTIONS} |
151 {$ENDIF} |
157 DumpAction(Actions.actions[Actions.Pos], Me); |
152 if (Action and ai_specmask) <> 0 then |
158 {$ENDIF} |
|
159 if (Action and ai_specmask) <> 0 then |
153 case Action of |
160 case Action of |
154 aia_Weapon: SetWeapon(TAmmoType(Param)); |
161 aia_Weapon: |
155 aia_WaitXL: if hwRound(Me^.X) = Param then |
162 SetWeapon(TAmmoType(Param)); |
156 begin |
163 |
157 Action:= aia_LookLeft; |
164 aia_WaitXL: |
158 Time:= GameTicks; |
165 if hwRound(Me^.X) = Param then |
159 exit |
166 begin |
160 end |
167 Action:= aia_LookLeft; |
161 else if hwRound(Me^.X) < Param then |
168 Time:= GameTicks; |
162 begin |
169 exit |
163 //OutError('AI: WaitXL assert (' + IntToStr(hwRound(Me^.X)) + ' < ' + IntToStr(Param) + ')', false); |
170 end |
164 FreeActionsList; |
171 else if hwRound(Me^.X) < Param then |
165 exit |
172 begin |
166 end |
173 //OutError('AI: WaitXL assert (' + IntToStr(hwRound(Me^.X)) + ' < ' + IntToStr(Param) + ')', false); |
167 else begin CheckHang(Me); exit end; |
174 FreeActionsList; |
168 aia_WaitXR: if hwRound(Me^.X) = Param then |
175 exit |
169 begin |
176 end |
170 Action:= aia_LookRight; |
177 else |
171 Time:= GameTicks; |
178 begin CheckHang(Me); |
172 exit |
179 exit |
173 end |
180 end; |
174 else if hwRound(Me^.X) > Param then |
181 |
175 begin |
182 aia_WaitXR: |
176 //OutError('AI: WaitXR assert (' + IntToStr(hwRound(Me^.X)) + ' > ' + IntToStr(Param) + ')', false); |
183 if hwRound(Me^.X) = Param then |
177 FreeActionsList; |
184 begin |
178 exit |
185 Action:= aia_LookRight; |
179 end |
186 Time:= GameTicks; |
180 else begin CheckHang(Me); exit end; |
187 exit |
181 aia_LookLeft: if not Me^.dX.isNegative then |
188 end |
182 begin |
189 else if hwRound(Me^.X) > Param then |
183 ParseCommand('+left', true); |
190 begin |
184 exit |
191 //OutError('AI: WaitXR assert (' + IntToStr(hwRound(Me^.X)) + ' > ' + IntToStr(Param) + ')', false); |
185 end else ParseCommand('-left', true); |
192 FreeActionsList; |
186 aia_LookRight: if Me^.dX.isNegative then |
193 exit |
187 begin |
194 end |
188 ParseCommand('+right', true); |
195 else |
189 exit |
196 begin CheckHang(Me); |
190 end else ParseCommand('-right', true); |
197 exit |
191 aia_AwareExpl: AwareOfExplosion(X, Y, Param); |
198 end; |
192 aia_HJump: ParseCommand('hjump', true); |
199 aia_LookLeft: |
193 aia_LJump: ParseCommand('ljump', true); |
200 if not Me^.dX.isNegative then |
194 aia_Skip: ParseCommand('skip', true); |
201 begin |
195 aia_Put: doPut(X, Y, true); |
202 ParseCommand('+left', true); |
196 end else |
203 exit |
197 begin |
204 end |
198 s:= ActionIdToStr[Action]; |
205 else |
199 if (Param and ai_specmask) <> 0 then |
206 ParseCommand('-left', true); |
200 case Param of |
207 aia_LookRight: |
201 aim_push: s:= '+' + s; |
208 if Me^.dX.isNegative then |
202 aim_release: s:= '-' + s; |
209 begin |
203 end |
210 ParseCommand('+right', true); |
204 else if Param <> 0 then s:= s + ' ' + IntToStr(Param); |
211 exit |
|
212 end |
|
213 else ParseCommand('-right', true); |
|
214 aia_AwareExpl: |
|
215 AwareOfExplosion(X, Y, Param); |
|
216 |
|
217 aia_HJump: |
|
218 ParseCommand('hjump', true); |
|
219 |
|
220 aia_LJump: |
|
221 ParseCommand('ljump', true); |
|
222 |
|
223 aia_Skip: |
|
224 ParseCommand('skip', true); |
|
225 |
|
226 aia_Put: |
|
227 doPut(X, Y, true); |
|
228 end |
|
229 else |
|
230 begin |
|
231 s:= ActionIdToStr[Action]; |
|
232 if (Param and ai_specmask) <> 0 then |
|
233 case Param of |
|
234 aim_push: |
|
235 s:= '+' + s; |
|
236 |
|
237 aim_release: |
|
238 s:= '-' + s; |
|
239 end |
|
240 else if Param <> 0 then |
|
241 s:= s + ' ' + IntToStr(Param); |
205 ParseCommand(s, true) |
242 ParseCommand(s, true) |
206 end |
243 end |
207 end; |
244 end; |
208 inc(Actions.Pos); |
245 inc(Actions.Pos); |
209 if Actions.Pos <= Actions.Count then |
246 if Actions.Pos <= Actions.Count then |
210 inc(Actions.actions[Actions.Pos].Time, GameTicks); |
247 inc(Actions.actions[Actions.Pos].Time, GameTicks); |
211 until false |
248 until false |
212 end; |
249 end; |
213 |
250 |
214 end. |
251 end. |