Spoiler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
dofile("sys/lua/wrapper.lua") CREATURE = { ALIVE = {}, LIST = { { NAME = "Zombie", HITPOINT = 100, MOVESPEED = 6, VISION = 400, IMAGE = "gfx/npc/vortigaunt.bmp", SOUND = {}, HIT_MODE = 103, HIT_ZONE = 22, ATTACK = { DAMAGE = 0, RANGE = 32, SPEED = 0, TYPE = 0 }, SPAWN = { RATE = 100, TILE = {}, LIMIT = 5, POSITION = {{0, 0}, {100, 100}} } } } } hook("startround", function() CREATURE.ALIVE = {} end) hook("ms100", function() if #CREATURE.ALIVE < 5 then local creature, tile_x, tile_y = deepcopy(CREATURE.LIST[1]) repeat tile_x, tile_y = math.random(creature.SPAWN.POSITION[1][1], creature.SPAWN.POSITION[2][1]), math.random(creature.SPAWN.POSITION[1][2], creature.SPAWN.POSITION[2][2]) until tile(tile_x, tile_y, "walkable") creature.POSITION_X, creature.POSITION_Y = math.floor(tile_x * 32 + 16), math.floor(tile_y * 32 + 16) CREATURE:insert(creature) end for _, creature in pairs(CREATURE.ALIVE) do creature:update() end end) hook("hitzone", function(z, x, c, v, b, n, m) for _, creature in pairs(CREATURE.ALIVE) do msg("aaa") if z == creature.IMAGE then creature.HITPOINT = creature.HITPOINT - m if creature.HITPOINT <= 0 then creature:remove() end end return true end end) hook("hit", function(player_id, source, weapon_id, hit_damage) if type(source) == "table" then local health = player(player_id, "health") - hit_damage if health > 0 then parse("sethealth "..player_id.." "..health) else parse("customkill "..source.NAME.." \"kill\" "..player_id) end return 1 end end) function CREATURE:update() local target for _, player_id in pairs(shuffle(player(0, "table"))) do if player(player_id, "health") <= 0 then return end local distance = math.sqrt((player(player_id, "x") - self.POSITION_X) ^ 2 + (player(player_id, "y") - self.POSITION_Y) ^ 2) if distance > self.VISION then return end if not target or distance < target[2] then target = { player_id, distance } self.TARGET_ID = target[1] end end if self.TARGET_ID then if player(self.TARGET_ID, "health") > 0 then local distance_x, distance_y = player(self.TARGET_ID, "x") - self.POSITION_X, player(self.TARGET_ID, "y") - self.POSITION_Y local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) if distance <= self.VISION then self.MOVE_ROTATION = math.atan2(distance_y, distance_x) - math.pi / 2 + math.random(-1, 1) / 2 self.LOOK_ROTATION = math.deg(math.atan2(distance_y, distance_x)) + 90 if distance <= self.ATTACK.RANGE then msg("hit") end else self.TARGET_ID = nil end else self.TARGET_ID = nil end else self:rotate(math.random(-1, 1) / 2) end if not self:setpos(self:rotate(), self.HITPOINT > 0 and 1 or -1) then repeat until self:setpos(math.rad(math.random(360)), 1) end end function CREATURE:insert(creature) creature.IMAGE = image(creature.IMAGE, creature.POSITION_X, creature.POSITION_Y, 0) imagehitzone(creature.IMAGE, creature.HIT_MODE, -creature.HIT_ZONE / 2, -creature.HIT_ZONE / 2, creature.HIT_ZONE, creature.HIT_ZONE) setmetatable(creature, self) self.__index = self creature.INDEX = #CREATURE.ALIVE table.insert(CREATURE.ALIVE, creature) end function CREATURE:remove() freeimage(self.IMAGE) table.remove(CREATURE.ALIVE, self.INDEX) for index, creature in pairs(CREATURE.ALIVE) do creature.INDEX = index end end function CREATURE:setpos(rotation_angle, distance_factor) local position_x, position_y = self.POSITION_X + -math.sin(rotation_angle) * distance_factor * self.MOVESPEED, self.POSITION_Y + math.cos(rotation_angle) * distance_factor * self.MOVESPEED local tile_x, tile_y = math.floor(position_x / 32), math.floor(position_y / 32) if tile(tile_x, tile_y, "walkable") and tile(tile_x, tile_y, "frame") ~= 251 then if not self.TARGET_ID then self.LOOK_ROTATION = -math.deg(math.atan2((self.POSITION_X - position_x), (self.POSITION_Y - position_y))) end self.POSITION_X, self.POSITION_Y = position_x, position_y tween_move(self.IMAGE, 100, self.POSITION_X, self.POSITION_Y, self.LOOK_ROTATION) return true else self:rotate(math.random(-1, 1) * 2 / math.pi) return false end end function CREATURE:rotate(rotation) if not rotation then return self.MOVE_ROTATION else self.MOVE_ROTATION = (self.MOVE_ROTATION + rotation) % (2 * math.pi) end end
script is work fine, it just horde of zombies will merge into one tile when chasing the player, and the player will die in a single attack