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
, items
;
37 mtype
, mx
, my
, mvx
, mvy
, mpos
, mhp
, ma
, mb
, mc
: array [0..lastMob
] of integer;
38 mjump
: array [0..lastMob
] of boolean;
39 tw
, th
, thp
, tjump
: array [none
..lastType
] of integer;
41 zombyBody
: array [0..1] of image
;
42 zombyLegs
: array [0..1, 0..2] of image
;
43 zombyAnim
: array [0..lastZombyFrame
] of integer;
45 procedure UseObject(i
: integer);
47 Phy
.LoadObject(mx
[i
], my
[i
], tw
[mtype
[i
]], th
[mtype
[i
]], mvx
[i
], mvy
[i
], mjump
[i
]);
50 procedure UpdateObject(i
: integer);
54 mvx
[i
] := Phy
.GetVelX
;
55 mvy
[i
] := Phy
.GetVelY
;
56 mjump
[i
] := Phy
.GetJmp
;
59 procedure InitTab(typ
, w
, h
, hp
, jump
: integer);
61 assert((typ
>= 0) and (typ
<= lastType
));
68 function GetW(i
: integer) : integer;
70 result
:= tw
[mtype
[i
]];
73 function GetH(i
: integer) : integer;
75 result
:= th
[mtype
[i
]];
78 function GetMaxHp(i
: integer) : integer;
80 result
:= thp
[mtype
[i
]];
83 function GetJumpHeight(i
: integer) : integer;
85 result
:= tjump
[mtype
[i
]];
88 function IsSolidStep(i
, vec
: integer) : boolean;
92 if vec
< 0 then x
:= (mx
[i
] - 8) / 16;
93 else if vec
> 0 then x
:= (mx
[i
] + GetW(i
) + 4) / 16;
94 else x
:= (mx
[i
] + GetW(i
) / 2) / 16;
95 y
:= (my
[i
] + GetH(i
) - 8) / 16;
96 result
:= Phy
.IsSolid(x
, y
, mvx
[i
] + vec
, mvy
[i
]);
99 procedure Swim(i
, vec
: integer);
101 if Phy
.MapCollType(50, mx
[i
], my
[i
], GetW(i
), GetH(i
) / 2) or
102 Phy
.MapCollType(51, mx
[i
], my
[i
], GetW(i
), GetH(i
) / 2)
104 if (vec
<> 0) and IsSolidStep(i
, vec
) then mvy
[i
] := -10 else mvy
[i
] := -2;
108 procedure Step(i
, vec
: integer);
113 mvx
[i
] := mvx
[i
] + vec
;
118 mvx
[i
] := mvx
[i
] + vec
;
123 procedure Jump(i
, vec
: integer);
126 Phy
.JumpObj(GetJumpHeight(i
));
130 function CollisionWithPlayer(i
: integer) : boolean;
132 result
:= CollTwoObj(
133 mx
[i
], my
[i
], GetW(i
), GetH(i
),
134 Player
.GetX
, Player
.GetY
, Player
.GetW
, Player
.GetH
138 procedure Die(i
: integer);
142 x
:= mx
[i
] + GetW(i
) / 2;
143 y
:= my
[i
] + GetH(i
) / 2;
144 if mtype
[i
] = zomby
then
146 Drop
.Create(Items
.rottenMeat
, x
, y
, Random(3));
151 procedure Hit(i
, damage
: integer);
153 mhp
[i
] := mhp
[i
] - damage
;
154 if mhp
[i
] <= 0 then Die(i
);
157 (** ZombyThink -- мозги зомби **)
158 (** ma = Кадр анимации **)
159 (** mb = Таймер действий **)
160 (** mc = Состояние **)
162 procedure ZombyThink(i
: integer);
175 // Debug('state: ' + mc[i] + ' / anim ' + ma[i] + ' / ticks ' + mb[i]);
178 if mb
[i
] < 0 then mb
[i
] := 0;
179 if CollisionWithPlayer(i
) then Player
.BiteIt(bite
, mvx
[i
]);
181 (* Вижу игрока - сразу агрюсь и бегу за ним некоторое время *)
182 if (mpos
[i
] = 0) and (Player
.GetX
- mx
[i
] < 0) or (mpos
[i
] = 1) and (Player
.GetX
- mx
[i
] > 0) then
183 if Phy
.CanSeeObj(mx
[i
], my
[i
], Player
.GetX
, Player
.GetY
) then
189 if mc
[i
] = stay
then begin
192 if (mb
[i
] <= 0) and (Random(100) <= 2) then
194 mb
[i
] := walkTime
+ Random(walkTime
);
195 mc
[i
] := walkleft
+ Random(2); (* Случайный разворот *)
197 end else if mc
[i
] = walkleft
then begin
198 if IsSolidStep(i
, -speed
) then Jump(i
, -speed
);
200 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
201 if mb
[i
] <= 0 then mc
[i
] := stay
;
202 end else if mc
[i
] = walkright
then begin
203 if IsSolidStep(i
, speed
) then Jump(i
, speed
);
205 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
206 if mb
[i
] <= 0 then mc
[i
] := stay
;
207 end else if mc
[i
] = angry
then begin
208 if mb
[i
] <= 0 then begin
209 if Phy
.CanSeeObj(mx
[i
], my
[i
], Player
.GetX
, Player
.GetY
) then begin
210 (* Видижу игрока - устанавливаю время преследования *)
213 (* Игрока давно не было видно - ждём его некоторое время на месте *)
218 (* Бежим за игроком *)
219 if Player
.GetX
- mx
[i
] < 4 then begin
220 if IsSolidStep(i
, -speed
) then Jump(i
, -speed
);
222 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
223 end else if Player
.GetX
- mx
[i
] > 4 then begin
224 if IsSolidStep(i
, speed
) then Jump(i
, speed
);
226 ma
[i
] := (ma
[i
] + 1) mod lastZombyFrame
;
234 procedure ZombyDraw(i
, camx
, camy
: integer);
238 frame
:= zombyAnim
[ma
[i
]];
239 DrawImage(zombyBody
[mpos
[i
]], mx
[i
] - 6 - camx
, my
[i
] - camy
);
240 DrawImage(zombyLegs
[mpos
[i
], frame
], mx
[i
] - 2 - camx
, my
[i
] + 20 - camy
);
243 (* ============= Public ============= *)
245 procedure Create(typ
, x
, y
: integer);
249 Assert((typ
>= 0) and (typ
<= lastType
));
250 Debug('Create mob ' + typ
+' @ ' + x
+ 'x' + y
);
251 for i
:= 0 to lastMob
do if mtype
[i
] = none
then
264 debug('Created mob is ' + i
);
267 Debug('Mob type ' + typ
+ ' not created');
270 function FindAndHit(damage
, x
, y
, w
, h
, addvx
, addvy
: integer) : integer;
274 for i
:= 0 to lastMob
do if mtype
[i
] <> none
then
275 if CollTwoObj(x
, y
, w
, h
, mx
[i
], my
[i
], GetW(i
), GetH(i
)) then
277 mvx
[i
] := mvx
[i
] + addvx
;
278 mvy
[i
] := mvy
[i
] + addvy
;
290 for i
:= 0 to lastMob
do if mtype
[i
] <> none
then
293 if typ
= zomby
then ZombyThink(i
);
294 if mhp
[i
] <= 0 then Die(i
);
302 for i
:= 0 to lastMob
do
310 procedure Draw(camx
, camy
:integer);
314 for i
:= 0 to lastMob
do if mtype
[i
] <> none
then
317 if typ
= zomby
then ZombyDraw(i
, camx
, camy
);
318 //SetColor(0, 0, 255);
319 //DrawRect(mx[i] - camx, my[i] - camy, GetW(i) - 1, GetH(i) - 1);
323 procedure LoadTextures(path
: string);
327 im
:= ld_tex('zombie_ani.png', path
, 'mobs/');
328 zombyBody
[0] := rotate_image_from_image(im
, 0, 0, 20, 22, 0);
329 zombyBody
[1] := rotate_image_from_image(im
, 21, 0, 20, 22, 0);
330 zombyLegs
[0, 0] := rotate_image_from_image(im
, 0, 52, 12, 12, 0);
331 zombyLegs
[0, 1] := rotate_image_from_image(im
, 13, 52, 12, 12, 0);
332 zombyLegs
[0, 2] := rotate_image_from_image(im
, 26, 52, 12, 12, 0);
333 zombyLegs
[1, 0] := rotate_image_from_image(im
, 39, 52, 12, 12, 0);
334 zombyLegs
[1, 1] := rotate_image_from_image(im
, 52, 52, 12, 12, 0);
335 zombyLegs
[1, 2] := rotate_image_from_image(im
, 65, 52, 12, 12, 0);
338 procedure FreeTextures
;
345 zombyBody
[i
] := nullimg
;
346 for j
:= 0 to 2 do zombyLegs
[i
, j
] := nullimg
;
354 for i
:= 0 to lastMob
do
356 write_byte(mtype
[i
]);
374 for i
:= 0 to lastMob
do
376 mtype
[i
] := read_byte
;
381 mpos
[i
] := read_byte
;
383 mjump
[i
] := readbool
;
394 for i
:= 0 to lastMob
do
411 InitTab(none
, 0, 0, 0, 0);
412 InitTab(zomby
, 8, 32, 10, 7);