10 procedure Create(typ
, x
, y
: integer);
11 function FindAndHit(value
, x
, y
, w
, h
, addvx
, addvy
: integer) : integer;
13 (* Части главного цикла *)
16 procedure Draw(camx
, camy
: integer);
18 (* Управление сохранениями *)
23 (* Управление текстурами *)
24 procedure LoadTextures(path
: string);
25 procedure FreeTextures
;
29 uses phy
, player
, canvas
, jsr75i
, func
, drop
;
39 mtype
, mx
, my
, mvx
, mvy
, mpos
, mhp
, ma
, mb
, mc
: array [0..lastMob
] of integer;
40 mjump
: array [0..lastMob
] of boolean;
41 tw
, th
, thp
, tjump
: array [none
..lastType
] of integer;
43 zombyBody
: array [0..1] of image
;
44 zombyLegs
: array [0..1, 0..2] of image
;
45 zombyAnim
: array [0..lastZombyFrame
] of integer;
47 procedure UseObject(i
: integer);
49 Phy
.SetObject(mx
[i
], my
[i
], tw
[mtype
[i
]], th
[mtype
[i
]], mvx
[i
], mvy
[i
], mjump
[i
]);
52 procedure UpdateObject(i
: integer);
58 mjump
[i
] := Phy
.GetJump
;
61 procedure InitTab(typ
, w
, h
, hp
, jump
: integer);
63 assert((typ
>= 0) and (typ
<= lastType
));
70 function GetW(i
: integer) : integer;
72 result
:= tw
[mtype
[i
]];
75 function GetH(i
: integer) : integer;
77 result
:= th
[mtype
[i
]];
80 function GetMaxHp(i
: integer) : integer;
82 result
:= thp
[mtype
[i
]];
85 function GetJumpHeight(i
: integer) : integer;
87 result
:= tjump
[mtype
[i
]];
90 function IsSolidStep(i
, vec
: integer) : boolean;
94 if vec
< 0 then x
:= (mx
[i
] - 8) / 16;
95 else if vec
> 0 then x
:= (mx
[i
] + GetW(i
) + 4) / 16;
96 else x
:= (mx
[i
] + GetW(i
) / 2) / 16;
97 y
:= (my
[i
] + GetH(i
) - 8) / 16;
98 result
:= Phy
.IsSolid(x
, y
);
101 procedure Swim(i
, vec
: integer);
103 if Phy
.AreaWithBlock(50, mx
[i
], my
[i
], GetW(i
), GetH(i
) / 2) or
104 Phy
.AreaWithBlock(51, mx
[i
], my
[i
], GetW(i
), GetH(i
) / 2)
106 if (vec
<> 0) and IsSolidStep(i
, vec
) then mvy
[i
] := -10 else mvy
[i
] := -2;
110 procedure Step(i
, vec
: integer);
115 mvx
[i
] := mvx
[i
] + vec
;
120 mvx
[i
] := mvx
[i
] + vec
;
125 procedure Jump(i
, vec
: integer);
128 Phy
.Jump(GetJumpHeight(i
));
132 function CollisionWithPlayer(i
: integer) : boolean;
134 result
:= Phy
.IntersectRects(
135 mx
[i
], my
[i
], GetW(i
), GetH(i
),
136 Player
.GetX
, Player
.GetY
, Player
.GetW
, Player
.GetH
140 procedure Die(i
: integer);
144 x
:= mx
[i
] + GetW(i
) / 2;
145 y
:= my
[i
] + GetH(i
) / 2;
146 if mtype
[i
] = zomby
then begin
147 Drop
.Create(rottenMeat
, x
, y
, Random(3));
152 procedure Hit(i
, damage
: integer);
154 mhp
[i
] := mhp
[i
] - damage
;
155 if mhp
[i
] <= 0 then Die(i
);
158 (** ZombyThink -- мозги зомби **)
159 (** ma = Кадр анимации **)
160 (** mb = Таймер действий **)
161 (** mc = Состояние **)
163 procedure ZombyThink(i
: integer);
176 // Debug('state: ' + mc[i] + ' / anim ' + ma[i] + ' / ticks ' + mb[i]);
179 if mb
[i
] < 0 then mb
[i
] := 0;
180 if CollisionWithPlayer(i
) then Player
.BiteIt(bite
, mvx
[i
]);
182 (* Вижу игрока - сразу агрюсь и бегу за ним некоторое время *)
183 if (mpos
[i
] = 0) and (Player
.GetX
- mx
[i
] < 0) or (mpos
[i
] = 1) and (Player
.GetX
- mx
[i
] > 0) then
184 if Phy
.RayTraced(mx
[i
], my
[i
], Player
.GetX
, Player
.GetY
) then
190 if mc
[i
] = stay
then begin
193 if (mb
[i
] <= 0) and (Random(100) <= 2) then
195 mb
[i
] := walkTime
+ Random(walkTime
);
196 mc
[i
] := walkleft
+ Random(2); (* Случайный разворот *)
198 end else if mc
[i
] = walkleft
then begin
199 if IsSolidStep(i
, -speed
) then Jump(i
, -speed
);
201 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
202 if mb
[i
] <= 0 then mc
[i
] := stay
;
203 end else if mc
[i
] = walkright
then begin
204 if IsSolidStep(i
, speed
) then Jump(i
, speed
);
206 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
207 if mb
[i
] <= 0 then mc
[i
] := stay
;
208 end else if mc
[i
] = angry
then begin
209 if mb
[i
] <= 0 then begin
210 if Phy
.RayTraced(mx
[i
], my
[i
], Player
.GetX
, Player
.GetY
) then begin
211 (* Видижу игрока - устанавливаю время преследования *)
214 (* Игрока давно не было видно - ждём его некоторое время на месте *)
219 (* Бежим за игроком *)
220 if Player
.GetX
- mx
[i
] < 4 then begin
221 if IsSolidStep(i
, -speed
) then Jump(i
, -speed
);
223 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
224 end else if Player
.GetX
- mx
[i
] > 4 then begin
225 if IsSolidStep(i
, speed
) then Jump(i
, speed
);
227 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
235 procedure ZombyDraw(i
, camx
, camy
: integer);
239 frame
:= zombyAnim
[ma
[i
]];
240 DrawImage(zombyBody
[mpos
[i
]], mx
[i
] - 6 - camx
, my
[i
] - camy
);
241 DrawImage(zombyLegs
[mpos
[i
], frame
], mx
[i
] - 2 - camx
, my
[i
] + 20 - camy
);
244 (* ============= Public ============= *)
246 procedure Create(typ
, x
, y
: integer);
250 Assert((typ
>= 0) and (typ
<= lastType
));
251 Debug('Create mob ' + typ
+' @ ' + x
+ 'x' + y
);
252 for i
:= 0 to lastMob
do if mtype
[i
] = none
then
265 debug('Created mob is ' + i
);
268 Debug('Mob type ' + typ
+ ' not created');
271 function FindAndHit(damage
, x
, y
, w
, h
, addvx
, addvy
: integer) : integer;
275 for i
:= 0 to lastMob
do if mtype
[i
] <> none
then
276 if Phy
.IntersectRects(x
, y
, w
, h
, mx
[i
], my
[i
], GetW(i
), GetH(i
)) then
278 mvx
[i
] := mvx
[i
] + addvx
;
279 mvy
[i
] := mvy
[i
] + addvy
;
291 for i
:= 0 to lastMob
do if mtype
[i
] <> none
then
294 if typ
= zomby
then ZombyThink(i
);
295 if mhp
[i
] <= 0 then Die(i
);
303 for i
:= 0 to lastMob
do
311 procedure Draw(camx
, camy
:integer);
315 for i
:= 0 to lastMob
do if mtype
[i
] <> none
then
318 if typ
= zomby
then ZombyDraw(i
, camx
, camy
);
319 //SetColor(0, 0, 255);
320 //DrawRect(mx[i] - camx, my[i] - camy, GetW(i) - 1, GetH(i) - 1);
324 procedure LoadTextures(path
: string);
328 im
:= ld_tex('zombie_ani.png', path
, 'mobs/');
329 zombyBody
[0] := rotate_image_from_image(im
, 0, 0, 20, 22, 0);
330 zombyBody
[1] := rotate_image_from_image(im
, 21, 0, 20, 22, 0);
331 zombyLegs
[0, 0] := rotate_image_from_image(im
, 0, 52, 12, 12, 0);
332 zombyLegs
[0, 1] := rotate_image_from_image(im
, 13, 52, 12, 12, 0);
333 zombyLegs
[0, 2] := rotate_image_from_image(im
, 26, 52, 12, 12, 0);
334 zombyLegs
[1, 0] := rotate_image_from_image(im
, 39, 52, 12, 12, 0);
335 zombyLegs
[1, 1] := rotate_image_from_image(im
, 52, 52, 12, 12, 0);
336 zombyLegs
[1, 2] := rotate_image_from_image(im
, 65, 52, 12, 12, 0);
339 procedure FreeTextures
;
346 zombyBody
[i
] := nullimg
;
347 for j
:= 0 to 2 do zombyLegs
[i
, j
] := nullimg
;
355 for i
:= 0 to lastMob
do
357 write_byte(mtype
[i
]);
375 for i
:= 0 to lastMob
do
377 mtype
[i
] := read_byte
;
382 mpos
[i
] := read_byte
;
384 mjump
[i
] := readbool
;
395 for i
:= 0 to lastMob
do
412 InitTab(none
, 0, 0, 0, 0);
413 InitTab(zomby
, 8, 32, 10, 7);