Forum

> > CS2D > Scripts > '}' expected (to close line '{' at line 63)
Forums overviewCS2D overview Scripts overviewLog in to reply

English '}' expected (to close line '{' at line 63)

12 replies
To the start Previous 1 Next To the start

old '}' expected (to close line '{' at line 63)

D-D3ADxPro
User Off Offline

Quote
I was bored, so I decided to make a minecraft npc script using weiwen's monster lua script. Tested it but none of the monsters spawned. Checked in console and it said

1
'}' expected (to close line '{' at line 63) near 'parse'

Heres the full code:

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
Monster = {name = 'Monster', health = 100, image = 'gfx/weiwen/circle.png', scalex = 1, scaley = 1, atk = 1, def = 1, spd = 5, x = 0, y = 0, ang = 0, imgang = 0, exp = 5, money = 50, type = 'monster', loot = {}}
MONSTERS = {}
local t = 0

local SPAWNS = {
	FULLMAP = {{1, 34}, {18, 51}},
	BOTTOMHALF = {{9, 58}, {64, 58}},
	BOTTOMMAP = {{5, 71}, {55, 70}},
}

CONFIG.MONSTERS = {
	{
		name = 'Zombie', health = 100, image = 'gfx/minecraft_npc/zombie.png', scalex = 2, scaley = 2, r = 136, g = 224, b = 32, 
		atk = 1.9, def = 2.1, spd = 6, atkspd = 8, x = 0, y = 0, ang = 0, imgang = 0, runat = 10, 
		spawnchance = {['rpg_mapb'] = {5}}, 
		spawn = {
			['rpg_mineraft'] = {SPAWNS.BOTTOMHALF}
		}, 
		exp = 25, money = 67, loot = {{chance = 5000, id = 102}, {chance = 250, id = 221}}, 
	}, 
	{
		name = 'Spider', health = 100, image = 'gfx/minecraft_npc/spider.png', scalex = 2, scaley = 2, 
		atk = 2.2, def = 1.8, spd = 6, atkspd = 8, x = 0, y = 0, ang = 0, imgang = 0, runat = 10,  
		spawnchance = {['rpg_mapb'] = {5}}, 
		spawn = {
			['rpg_mapb'] = {SPAWNS.BOTTOMMAP}
		}, 
		exp = 34, money = 24, loot = {{chance = 5000, id = 100}, {chance = 250, id = 222}}, 
	}, 
	{
		name = 'Creeper', health = 100, image = 'gfx/minecraft_npc/creeper.png', scalex = 2, scaley = 2, 
		atk = 1.9, def = 2.3, spd = 6, atkspd = 8, x = 0, y = 0, ang = 0, imgang = 0, runat = 10, 
		spawnchance = {['rpg_minecraft'] = {5}}, 
		spawn = {
			['rpg_mapb'] = {SPAWNS.FULLMAP}
		}, 
		exp = 45, money = 78, loot = {{chance = 5000, id = 101}, {chance = 250, id = 223}}, 
		spc = {1000, function(self) 
			if self.health < 20 then
				radiusmsg("Creeper uses selfdestruct!", self.x, self.y)
				parse('explosion ' .. self.x .. ' ' .. self.y .. ' 128 80')
				parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 100 128 255 128 0')
				parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 100 128 255 255 0')
				self:destroy()
			end
		end},
	}, 
	{
		name = 'Zombie Pigman', health = 100, image = 'gfx/minecraft_npc/zombie pigman.png', scalex = 1.5, scaley = 1.5, r = 104, g = 152, b = 40, 
		atk = 3.1, def = 2.2, spd = 7, atkspd = 10, x = 0, y = 0, ang = 0, imgang = 0, runat = 20, 
		spawnchance = {['rpg_minecraft'] = {32}}, 
		spawn = {
			['rpg_mapb'] = {SPAWNS.FULLMAP}
		}, 
		exp = 5, money = 30, loot = {{chance = 8000, id = 1}},
		spc = {750, function(self, id, dist) 
			if dist <= 96 then
				radiusmsg("Zombie Pigman uses horn attack!", self.x, self.y)
				self:hit(id, 20)
			end
		end},
	}, 
	{
		name = 'Skeleton', health = 100, image = 'gfx/minecraft_npc/skeleton.png', scalex = 1.5, scaley = 1.5, r = 104, g = 152, b = 40, 
		atk = 2.2, def = 1.1, spd = 7, atkspd = 10, x = 0, y = 0, ang = 0, imgang = 0, runat = 20, 
		spawnchance = {['rpg_mapb'] = {100}}, 
		spawn = {
			['rpg_minecraft'] = {SPAWNS.FULLMAP}
		}, 
		exp = 100, money = 100, loot = {{chance = 8000, id = 1}},
		radiusmsg("Skeleton uses arrow!", self.x, self.y)
			parse('explosion ' .. self.x .. ' ' .. self.y .. ' 96 40')
			parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 100 96 255 255 255')
			parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 75 96 128 128 255')
			end
		end},
	}, 
}

CONFIG.MONSTERSKILLS = {
	endAgility = function(id)
		self = MONSTERS[tonumber(id)]
		self.spd = self._spd
		self._spd = nil
		imagecolor(self.image, 255, 255, 255)
		self.agility = nil
	end,
	endRage = function(id)
		self = MONSTERS[tonumber(id)]
		self.atk = self._atk
		self._atk = nil
		imagecolor(self.image, 255, 255, 255)
		self.rage = nil
	end,
	endHarden = function(id)
		self = MONSTERS[tonumber(id)]
		self.def = self._def
		self._def = nil
		imagecolor(self.image, 255, 255, 255)
		self.harden = nil
	end,
}

addhook("attack", "MONSTERattack")
function MONSTERattack(id)
	if gettile(PLAYERS[id].x, PLAYERS[id].y).SAFE or gettile(PLAYERS[id].x, PLAYERS[id].y).NOMONSTERS then
		return
	end
	if inarray({400, 401, 402, 403, 404}, PLAYERS[id].Equipment[7]) then
		message(id, "You may not attack on a horse.")
		return
	end
	local weapon, closest = player(id, 'weapontype')
	for _, m in ipairs(MONSTERS) do
		local x, y = player(id, 'x'), player(id, 'y')
		local dist = math.sqrt((m.x-x)^2+(m.y-y)^2)
		if dist <= (closest and closest[2] or (CONFIG.WEAPONRANGE[weapon] or CONFIG.WEAPONRANGE[50])) then
			local rot = player(id, 'rot')
			if math.abs(math.rad(rot) - math.atan2(y-m.y, x-m.x) + math.pi/2)%(2*math.pi) <= (CONFIG.WEAPONWIDTH[weapon] or CONFIG.WEAPONRANGE[50]) then
				closest = {m, dist}
			end
		end
	end
	if closest then
		closest[1]:damage(id, math.ceil(20*((PLAYERS[id].Level+50)*PLAYERS[id].tmp.atk/closest[1].def)/math.random(60, 140)), weapon)
	end
end

addhook("ms100", "MONSTERms100")
function MONSTERms100()
	t = t + 1
	if t % 100 == 0 then
		while #MONSTERS < CONFIG.MAXMONSTERS do
			local rand, spawnNo, mapName
			while true do 
				rand = math.random(#CONFIG.MONSTERS)
				mapName = CONFIG.MONSTERS[rand].spawn[map'name'] and map'name' or CONFIG.DEFAULTMAP
				spawnNo = math.random(#CONFIG.MONSTERS[rand].spawn[mapName])
				if math.random(0, 100) < CONFIG.MONSTERS[rand].spawnchance[mapName][spawnNo] then
					break
				end
			end 
			local m = deepcopy(CONFIG.MONSTERS[rand])
			local x, y, tilex, tiley
			local spawn = m.spawn[mapName][spawnNo]
			repeat
				tilex, tiley = math.random(spawn[1][1], spawn[2][1]), math.random(spawn[1][2], spawn[2][2])
			until not gettile(tilex, tiley).SAFE and 
				  not gettile(tilex, tiley).NOMONSTERS and 
				  tile(tilex, tiley, "walkable") and 
				  tile(tilex, tiley, "frame") ~= 34
			m.x, m.y = math.floor(tilex*32+16), math.floor(tiley*32+16)
			Monster:new(m)
		end
	end
	for _, m in ipairs(MONSTERS) do
		if t % m.atkspd == 0 then
			m.target = nil
			local closest
			for _, p in ipairs(table.shuffle(player(0, 'table'))) do
				if player(p, 'health') > 0 and 
					not gettile(PLAYERS[p].x, PLAYERS[p].y).SAFE and 
					not gettile(PLAYERS[p].x, PLAYERS[p].y).NOMONSTERS then
					local dist = math.sqrt((player(p, 'x')-m.x)^2 + (player(p, 'y')-m.y)^2)
					if dist < 400 then
						if not closest or dist < closest[2] then
							closest = {p, dist}
						end
					end
				end
			end
			if closest then
				local dist = closest[2]
				if dist < 400 then
					m.target = closest[1]
					if m.spc and math.random(10000) <= m.spc[1] then
						m.spc[2](m, m.target, dist)
					elseif dist <= (m.range or 32) then
						m:hit(m.target, 10)
					end
				end
			end
		end
		m.imgang = math.sin(t/2.5*math.pi) * 15
		if m.target and player(m.target, 'exists') and player(m.target, 'health') > 0 and 
			not gettile(PLAYERS[m.target].x, PLAYERS[m.target].y).SAFE and 
			not gettile(PLAYERS[m.target].x, PLAYERS[m.target].y).NOMONSTERS then
			xdist, ydist = player(m.target, 'x') - m.x, player(m.target, 'y') - m.y
			local dist = math.sqrt(xdist^2 + ydist^2)
			if dist < 400 then
				m.ang = math.atan2(ydist, xdist)-math.pi/2+math.random(-1, 1)/2
			else
				m.target = nil
			end
		end
		if not m.target then
			m:rot(math.random(-1, 1)/2)
		end
		if not m:move(m:rot(), m.health > m.runat and 1 or -1) then
			repeat until m:move(math.rad(math.random(360)), 1)
		end
	end
end

function Monster:new(m)
	if not (m.x or m.y) then return false end
	m.image = image(m.image, m.x, m.y, 0)
	imagescale(m.image, m.scalex, m.scaley)
	setmetatable(m, self)
	self.__index = self
	local n = #MONSTERS+1
	MONSTERS[#MONSTERS+1] = m
	m.id = n
	return m
end

function Monster:pos(x, y)
	if not x and not y then
		return self.x, self.y
	else
		self.x, self.y = x or self.x, y or self.y
		imagepos(self.image, self.x, self.y, self.imgang)
	end
	return true
end

function Monster:move(dir, amt)
	local x, y = -math.sin(dir)*amt*self.spd, math.cos(dir)*amt*self.spd
	local x, y = self.x+x, self.y+y
	local tilex, tiley = math.floor(x/32), math.floor(y/32)
	if tile(tilex, tiley, 'walkable') and tile(tilex, tiley, 'frame') ~= 34 and 
		not gettile(tilex, tiley).SAFE and 
		not gettile(tilex, tiley).NOMONSTERS then
		self:pos(x, y)
		return true
	else
		self:rot(math.random(-1, 1)*math.pi/2)
		return false
	end
end

function Monster:damage(id, dmg, wpntype)
	if not PLAYERS[id].Tutorial.damagem then
		message(id, "You have attacked a monster! Good job! Keep on attacking it until it dies.", "255128000")
		PLAYERS[id].Tutorial.damagem = true
	end
	local wpnName
	if weapon == 251 then
		wpnName = 'rune'
	elseif weapon == 46 then
		wpnName = 'firewave'
		dmg = dmg/5
	else
		wpnName = PLAYERS[id].Equipment[3] and ITEMS[PLAYERS[id].Equipment[3]].name or 'dagger'
	end
	self.health = self.health - dmg
	--print(player(id, 'name') .. ' deals ' .. dmg .. ' damage to ' .. self.name .. ' usng a ' .. wpnName .. '.')
	if self.health <= 0 then
		if not PLAYERS[id].Tutorial.killm then
			message(id, "Congratulation! You have killed your first monster. You can proceed to pick up the loot by using the drop weapon button (default G)", "255128000")
			PLAYERS[id].Tutorial.killm = true
		end
		addexp(id, math.floor(self.exp*CONFIG.EXPRATE))
		self:die()
	else
		parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 0 ' .. self.scaley .. ' ' .. (self.r and (self.r .. ' ' .. self.g .. ' ' .. self.b) or '192 0 0'))
	end
	radiussound("weapons/machete_hit.wav", self.x, self.y)
	return true
end

function Monster:hit(id, dmg)
	if not PLAYERS[id].Tutorial.hitm then
		message(id, "A monster is attacking you! You can fight back by swinging your weapon at it.", "255128000")
		PLAYERS[id].Tutorial.hitm = true
	end
	if player(id, 'weapontype') == 41 and (math.abs(math.rad(player(id, 'rot')) - math.atan2(player(id, 'y')-self.y, player(id, 'x')-self.x) + math.pi/2)%(2*math.pi) <= math.pi*2/3) then
		EXPhit(id, self, -1, dmg/4)
		radiussound("weapons/ricmetal" .. math.random(1,2) .. ".wav", self.x, self.y)
	else
		EXPhit(id, self, -1, dmg)
		radiussound("weapons/knife_hit.wav", self.x, self.y)
	end
	return true
end

function Monster:die(id)
	local size = self.scalex+self.scaley
	parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' ' .. size .. ' 64 ' .. (self.r and (self.r .. ' ' .. self.g .. ' ' .. self.b) or '192 0 0'))
	local tilex, tiley = math.floor(self.x/32), math.floor(self.y/32)
	spawnitem(1337, tilex, tiley, math.floor(self.money*math.random(50, 150)/100)*CONFIG.MONEYRATE)
	for _, loot in ipairs(self.loot) do
		local chance = math.random(10000)
		if chance <= loot.chance then
			spawnitem(loot.id, tilex, tiley)
		end
	end
	radiussound("weapons/c4_explode.wav", self.x, self.y)
	self:destroy()
end

function Monster:destroy()
	freeimage(self.image)
	local found
	table.remove(MONSTERS, self.id)
	for i, m in ipairs(MONSTERS) do
		m.id = i
	end
	return true
end

function Monster:rot(rot)
	if not rot then
		return self.ang
	else
		self.ang = (self.ang+rot)%(math.pi*2)
	end
	return true
end

old Re: '}' expected (to close line '{' at line 63)

Avo
User Off Offline

Quote
Take a look at the end of CONFIG.MONSTERS table(skeleton part):
(I will use spoiler tag to bold it for you)
Spoiler >

(underlined "end" shouldn't be there)
Shouldn't radiusmsg and other commands be in a function? I'm not a specialist, but in my opinion it should be something like:
Spoiler >

I removed additional "end", too. I didn't test it, but should work.
Edit: damn you, mafia_man.

old Re: '}' expected (to close line '{' at line 63)

mafia_man
User Off Offline

Quote
user D-D3ADxPro has written
user Avo: and user mafia_man: Did that, but it's still giving me errors.

user mafia_man:'s error
1
LUA ERROR: maps/rpg_minecraft.lua:79: attempt to index global 'CONFIG' (a nil value)

And user Avo:'s error
1
LUA ERROR: maps/rpg_minecraft.lua:72: '}' expected (to close '{' at line 64) near 'spc'

Soz I am to lazy to look at this shit again...
Try to be carefull when editing next time.

old Re: '}' expected (to close line '{' at line 63)

D-D3ADxPro
User Off Offline

Quote
Still doesn't work. I added 2 more monsters.

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
name = 'Skeleton', health = 100, image = 'gfx/minecraft_npc/skeleton.png', scalex = 1.5, scaley = 1.5, r = 104, g = 152, b = 40, 
		atk = 2.2, def = 1.1, spd = 7, atkspd = 10, x = 0, y = 0, ang = 0, imgang = 0, runat = 20, 
		spawnchance = {['rpg_mapb'] = {100}}, 
		spawn = {
			['rpg_minecraft'] = {SPAWNS.FULLMAP}
		}, 
		exp = 100, money = 100, loot = {{chance = 8000, id = 1}},
		spc = {750, function(self, id, dist) 
			radiusmsg("Skeleton uses arrow!", self.x, self.y)
			parse('explosion ' .. self.x .. ' ' .. self.y .. ' 96 40')
			parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 100 96 255 255 255')
			parse('effect "colorsmoke" ' .. self.x .. ' ' .. self.y .. ' 75 96 128 128 255')
		end}
	}, 
	{ 
		name = 'Enderman' health = 150 image = 'gfx/minecraft_npc/enderman.png', scalex = 1.5, scaley = 1.5, r = 104, g = 152, b = 40,
		atk = 4.7, def = 3.2, spd = 4, atkspd = 7, x = 0, y = 0, ang = 0, imgang = 0, runat = 20,
		spawnchance = {['rpg_minecraft'] = {35}},
		spawn = {
			['rpg_minecraft'] = {SPAWNS.FULLMAP}
		},
		exp = 98, money = 64, loot = {{chance = 8000, id = 1}},
			if dist <= 64 and not PLAYERS[id].tmp.paralyse then
				radiusmsg("Enderman uses eye!", self.x, self.y)
				PLAYERS[id].tmp.paralyse = true
				msg2(id, "You are paralysed.")
				parse("effect \"colorsmoke\" " .. player(id, 'x') .. " " .. player(id, 'y') .. " 5 5 64 0 64")
				timer(3000, "rem.paralyse", id)
			elseif dist <= 32 then
				self:hit(id, 10)
			end
		end}
	},
	{
		name = 'Herobrine' health = 250 image = 'gfx/minecraft_npc/herobrine.png', scalex = 15, scaley = 1.5, r = 104, g = 152, b = 40,
		atk = 5.5, def = 4.2, spd = 8, atkspd = 10, x = 0, y = 0, ang = 0, imgang = 0, runat = 20,
		spawnchance = {{'rpg_minecraft'] = {5}},
		spawn = {
			['rpg_minecraft'] = {SPAWNS.FULLMAP}
		},
		exp = 200, money = 1500, loot = {{chance = 8000, id = 1}},
			if dist <= 96 then
				radiusmsg("Herobrine uses ??????????!", self.x, self.y)
				self:hit(id, 20)
				end
		end}
	}, 
}

But now, i get an error that says

1
LUA ERROR: maps/rpg_minecraft.lua:80: '}' expected (to close '{' at line 79 near 'health'
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview