1 (* |
|
2 * Hedgewars, a worms-like game |
|
3 * Copyright (c) 2005 Andrey Korotaev <unC0Rr@gmail.com> |
|
4 * |
|
5 * Distributed under the terms of the BSD-modified licence: |
|
6 * |
|
7 * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
8 * of this software and associated documentation files (the "Software"), to deal |
|
9 * with the Software without restriction, including without limitation the |
|
10 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|
11 * sell copies of the Software, and to permit persons to whom the Software is |
|
12 * furnished to do so, subject to the following conditions: |
|
13 * |
|
14 * 1. Redistributions of source code must retain the above copyright notice, |
|
15 * this list of conditions and the following disclaimer. |
|
16 * 2. Redistributions in binary form must reproduce the above copyright notice, |
|
17 * this list of conditions and the following disclaimer in the documentation |
|
18 * and/or other materials provided with the distribution. |
|
19 * 3. The name of the author may not be used to endorse or promote products |
|
20 * derived from this software without specific prior written permission. |
|
21 * |
|
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
|
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
|
25 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
|
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
|
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
|
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
32 *) |
|
33 |
|
34 unit uAIActions; |
1 unit uAIActions; |
35 interface |
2 interface |
36 {$INCLUDE options.inc} |
3 uses uGears; |
37 const aia_none = 0; |
4 const MAXACTIONS = 256; |
|
5 aia_none = 0; |
38 aia_Left = 1; |
6 aia_Left = 1; |
39 aia_Right = 2; |
7 aia_Right = 2; |
40 aia_Timer = 3; |
8 aia_Timer = 3; |
41 aia_Slot = 4; |
9 aia_Slot = 4; |
42 aia_attack = 5; |
10 aia_attack = 5; |
51 |
19 |
52 aim_push = $80000000; |
20 aim_push = $80000000; |
53 aim_release = $80000001; |
21 aim_release = $80000001; |
54 ai_specmask = $80000000; |
22 ai_specmask = $80000000; |
55 |
23 |
56 type PAction = ^TAction; |
24 type TAction = record |
57 TAction = record |
|
58 Action, Param: Longword; |
25 Action, Param: Longword; |
59 Time: Longword; |
26 Time: Longword; |
60 Next: PAction; |
|
61 end; |
27 end; |
|
28 TActions = record |
|
29 Count, Pos: Longword; |
|
30 actions: array[0..Pred(MAXACTIONS)] of TAction; |
|
31 Score: integer; |
|
32 end; |
62 |
33 |
63 function AddAction(Action, Param, TimeDelta: Longword): PAction; |
34 procedure AddAction(var Actions: TActions; Action, Param, TimeDelta: Longword); |
64 procedure FreeActionsList; |
35 procedure ProcessAction(var Actions: TActions; Me: PGear); |
65 function IsActionListEmpty: boolean; |
|
66 procedure ProcessAction; |
|
67 |
36 |
68 implementation |
37 implementation |
69 uses uMisc, uConsts, uConsole, uTeams; |
38 uses uMisc, uTeams, uConsts, uConsole; |
70 |
39 |
71 const ActionIdToStr: array[0..7] of string[16] = ( |
40 const ActionIdToStr: array[0..7] of string[16] = ( |
72 {aia_none} '', |
41 {aia_none} '', |
73 {aia_Left} 'left', |
42 {aia_Left} 'left', |
74 {aia_Right} 'right', |
43 {aia_Right} 'right', |
75 {aia_Timer} 'timer', |
44 {aia_Timer} 'timer', |
76 {aia_slot} 'slot', |
45 {aia_slot} 'slot', |
77 {aia_attack} 'attack', |
46 {aia_attack} 'attack', |
78 {aia_Up} 'up', |
47 {aia_Up} 'up', |
79 {aia_Down} 'down' |
48 {aia_Down} 'down' |
80 ); |
49 ); |
81 |
50 |
82 |
51 procedure AddAction(var Actions: TActions; Action, Param, TimeDelta: Longword); |
83 var ActionList, |
|
84 FinAction: PAction; |
|
85 |
|
86 function AddAction(Action, Param, TimeDelta: Longword): PAction; |
|
87 begin |
52 begin |
88 New(Result); |
53 with Actions do |
89 TryDo(Result <> nil, 'AddAction: Result = nil', true); |
54 begin |
90 FillChar(Result^, sizeof(TAction), 0); |
55 actions[Count].Action:= Action; |
91 Result.Action:= Action; |
56 actions[Count].Param:= Param; |
92 Result.Param:= Param; |
57 if Count > 0 then actions[Count].Time:= actions[Pred(Count)].Time + TimeDelta |
93 if ActionList = nil then |
58 else actions[Count].Time:= GameTicks + TimeDelta; |
94 begin |
59 inc(Count); |
95 Result.Time:= GameTicks + TimeDelta; |
60 TryDo(Count < MAXACTIONS, 'AI: actions overflow', true); |
96 ActionList:= Result; |
61 end |
97 FinAction := Result |
|
98 end else |
|
99 begin |
|
100 Result.Time:= TimeDelta; |
|
101 FinAction.Next:= Result; |
|
102 FinAction:= Result |
|
103 end |
|
104 end; |
|
105 |
|
106 procedure DeleteCurrAction; |
|
107 var t: PAction; |
|
108 begin |
|
109 t:= ActionList; |
|
110 ActionList:= ActionList.Next; |
|
111 if ActionList = nil then FinAction:= nil |
|
112 else inc(ActionList.Time, t.Time); |
|
113 Dispose(t) |
|
114 end; |
|
115 |
|
116 function IsActionListEmpty: boolean; |
|
117 begin |
|
118 Result:= ActionList = nil |
|
119 end; |
|
120 |
|
121 procedure FreeActionsList; |
|
122 begin |
|
123 while ActionList <> nil do DeleteCurrAction; |
|
124 end; |
62 end; |
125 |
63 |
126 procedure SetWeapon(weap: Longword); |
64 procedure SetWeapon(weap: Longword); |
127 var t: integer; |
|
128 begin |
65 begin |
129 t:= 0; |
|
130 with CurrentTeam^ do |
66 with CurrentTeam^ do |
131 with Hedgehogs[CurrHedgehog] do |
67 with Hedgehogs[CurrHedgehog] do |
132 while Ammo[CurSlot, CurAmmo].AmmoType <> TAmmotype(weap) do |
68 while Ammo[CurSlot, CurAmmo].AmmoType <> TAmmotype(weap) do |
133 begin |
|
134 ParseCommand('/slot ' + chr(49 + Ammoz[TAmmoType(weap)].Slot)); |
69 ParseCommand('/slot ' + chr(49 + Ammoz[TAmmoType(weap)].Slot)); |
135 inc(t); |
|
136 if t > 10 then OutError('AI: incorrect try to change weapon!', true) |
|
137 end |
|
138 end; |
70 end; |
139 |
71 |
140 procedure ProcessAction; |
72 procedure ProcessAction(var Actions: TActions; Me: PGear); |
141 var s: shortstring; |
73 var s: shortstring; |
142 begin |
74 begin |
143 if ActionList = nil then exit; |
75 if Actions.Pos >= Actions.Count then exit; |
144 with ActionList^ do |
76 with Actions.actions[Actions.Pos] do |
145 begin |
77 begin |
146 if Time > GameTicks then exit; |
78 if Time > GameTicks then exit; |
147 if (Action and ai_specmask) <> 0 then |
79 if (Action and ai_specmask) <> 0 then |
148 case Action of |
80 case Action of |
149 aia_Weapon: SetWeapon(Param); |
81 aia_Weapon: SetWeapon(Param); |
150 aia_WaitX: with CurrentTeam^ do |
82 aia_WaitX: if round(Me.X) = Param then Time:= GameTicks |
151 with Hedgehogs[CurrHedgehog] do |
83 else exit; |
152 if round(Gear.X) = Param then Time:= GameTicks |
84 aia_WaitY: if round(Me.Y) = Param then Time:= GameTicks |
153 else exit; |
85 else exit; |
154 aia_WaitY: with CurrentTeam^ do |
86 aia_LookLeft: if Me.dX >= 0 then |
155 with Hedgehogs[CurrHedgehog] do |
87 begin |
156 if round(Gear.Y) = Param then Time:= GameTicks |
88 ParseCommand('+left'); |
157 else exit; |
89 exit |
158 aia_LookLeft: with CurrentTeam^ do |
90 end else ParseCommand('-left'); |
159 with Hedgehogs[CurrHedgehog] do |
91 aia_LookRight: if Me.dX < 0 then |
160 if Gear.dX >= 0 then |
92 begin |
161 begin |
93 ParseCommand('+right'); |
162 ParseCommand('+left'); |
94 exit |
163 exit |
95 end else ParseCommand('-right'); |
164 end else ParseCommand('-left'); |
|
165 aia_LookRight: with CurrentTeam^ do |
|
166 with Hedgehogs[CurrHedgehog] do |
|
167 if Gear.dX < 0 then |
|
168 begin |
|
169 ParseCommand('+right'); |
|
170 exit |
|
171 end else ParseCommand('-right'); |
|
172 end else |
96 end else |
173 begin |
97 begin |
174 s:= ActionIdToStr[Action]; |
98 s:= ActionIdToStr[Action]; |
175 if (Param and ai_specmask) <> 0 then |
99 if (Param and ai_specmask) <> 0 then |
176 case Param of |
100 case Param of |