Forum

> > CS2D > Scripts > Script doesnt work without errors
Forums overviewCS2D overview Scripts overviewLog in to reply

English Script doesnt work without errors

18 replies
To the start Previous 1 Next To the start

old Script doesnt work without errors

Bowlinghead
User Off Offline

Quote
Hello,

Im hopeless trying to run my script.
The only thread that I found which applies to me is here but it doesnt help.

I am using Windows 7 (x64) and the archive version of CS2D on D:/CS2D/.
When I run my script it just says:
parsing Lua autorun script 'sys/lua/autorun/botcontrolnew.lua'

Nothing else even though I added a bunch of hooks.
I tried it with autoexec folder, executing by server.lua and executing it manually with mp_luaserver.

In the thread above it was because of wrong parameters in the hooks. Im 100% sure that this is not the case (script is below).

I am able to run example scripts and a test script but not my botcontrolnew script.

My script config:
server.lua executes samples/advertise.lua
test.lua >
botcontrolnew.lua >
Log >

I have to admit that I didnt test this script until this state and now I can´t test it because the server won´t accept the script.
I already tried to delete some code but with no effect.
Do you have some idea what could be wrong?
Thank you for reading

old Re: Script doesnt work without errors

Mora
User Off Offline

Quote
1
addhook("die","botCount.Hdie")
i didn't saw there "count", but "cont" only, maybe that's why? Also i didn't found a botCount table, only botCont

old Re: Script doesnt work without errors

Bowlinghead
User Off Offline

Quote
I fixed all botCount. errors but still the same.

New code:
More >


Is it maybe because Im using 1D arrays (line22 e.g.) and recreate them as a 2D array (line76 e.g.)?

old Re: Script doesnt work without errors

Dousea
User Off Offline

Quote
Happened to me a long ago. Can't tell you in specific but maybe it's a syntax error. I had a timer script but the script wouldn't run, with no error produced, so I made a thread about it. I remember that user DC helped me by debugging my script in BlitzMax and he sent me the error. Maybe user DC can help you.

About the "recreate them as 2D array", actually you don't recreate them as 2D array. You create a table (1D) then you insert objects (2D) into the table (1D), so basically 2Ds in 1D, if you know what I mean.

EDIT: I guess I found the problem. You create botCont table and trying to create local tables within the table. You can't do that, of course. You need to remove locals at line 19 to 23.

old Re: Script doesnt work without errors

Bowlinghead
User Off Offline

Quote
@user Cebra:
I checked for missing then´s and )´s. I dont find any, sadly.

@user Dousea:
I thought the same since arrays can be filled with every data type.
I deleted the locals in the global vars but still the same non-error.

@user VADemon:
You mean a syntax error by me or by DC?

@user Mami Tomoe:
Thanks my friend. I finally get red text in my console.

So the solution is that you shouldn´t use autorun when you debug.
Thank you all.

And I learned that you dont have to use the namespace in functions on local variables

old Re: Script doesnt work without errors

GeoB99
Moderator Off Offline

Quote
@user omg: It can happen sometimes when a script doesn't work at all but the Console doesn't print any Lua error message either. Most likely there is an unexpected behavior which does not impact the whole functionality of a script but it will not work as it is supposed to be so you have to check that for yourself. Just saying.

old Re: Script doesnt work without errors

Bowlinghead
User Off Offline

Quote
@user GeoB99: , @user VADemon:
Actually the errors where found by CS2D but not printed because of autorun.

In line 92 for e.g. I wrote: botCont.cvalues = {}
Which would be something unlogical like: botCont.ChangeStats().botCont.cvalues
So local variables in a function dont have to be in a namespace since they are already in there AND they get deleted soon anyway.

I read somewhere on US.de that using namespaces for your script is better for the compatibility because you can have multiple variables with the same name in different namespaces.

Anyway, do you have tips for my code?
I feel a little bit lost inside of my code.

old Re: Script doesnt work without errors

Rainoth
Moderator Off Offline

Quote
@user Bowlinghead: Not autorun's fault. In the end it tries to execute a piece of code, regardless of how you try to execute it (with autorun or without). I had the same thing and I never use autorun. It's best to use 'lua' command and dofile scripts, it's convenient because u can click "up" later and 'restart' the script, very convenient if you're tweaking/fixing your script and dont want to restart the server over and over again.

old Re: Script doesnt work without errors

VADemon
User Off Offline

Quote
@user Bowlinghead: "reloading" only works well if you have a defined namespace which will be emptied after loading anew, eventually leaving work data untouched.

For example, you can reload a chat script script without problems. But if you reload a script with images, you'll have to take care of visible images and remove them first etc.


Regarding your code:
• Use more newlines.
Helps to structurize your code into logical parts between and inside functions. Look at botCont.ChangeStats(id1,id2)
• Choose more descriptive function names.
A perfect function name is literally self-explainable.

° botCont.IsBotPicked(bid) is not quite clear. You had to write a comment to explain what it does!
> IsPlayerControlled() or IsBotControlledByPlayer() - choose what you want and don't be too afraid of long function names. I'd rather type a few more letters than look up a function's description.


What is good that you already use "is***" for functions and "h***" for hooks. But: "is" is a prefix to functions that return boolean values (you should use boolean over numbers whenever possible) and hooks are commonly referred to as events, thus these functions usually start like "onKill" and so on. This last point is just my opinion though.

An example of function I consider being good enough to share >

old Re: Script doesnt work without errors

Dousea
User Off Offline

Quote
Did you remove all locals for botCont table, not only the lines that I told you? At line 19-23, 92-94, 130, and 194, also maybe other lines.

EDIT: Here. It may fix your problem. There's a syntax error at line 139 in your previous 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
botCont = {} -- namespace

--[[
	bool: true - player can only pick their own bots, false - player can pick opponent bots as well
]]
botCont.teamSensitive = false -- use 'true' for any kind of competitive gameplay

--[[ 
	bool: true - get the visual skin of the bot (NOT RECOMMENDED; glitchy), false - you probably wont get the skin that the bot had. (RECOMMENDED)
]]
botCont.skinGet = false -- if you use 'true' you will respawn/die until you have the skin of the bot which can be an unlimit process

--[[ 
	int: max amount of tries (respawn & die) to get the skin of the bot if bcSkinGet is true!
]]
botCont.skinTries = 4 -- if you use 0 you have unlimit tries (warning: in the worst case you will respawn & die forever)

-- global vars
botCont.freeBots = {}		 -- all available bots that a player can use
botCont.busyBots = {}		 -- all already used bots (every entry has bot-id and player-id)
botCont.isNewBot = false		 -- true - bot was added/kicked/used in this round, false - no bot was added/kicked/used in this round
botCont.teamChange = {}		-- {id,team} structure, for bcTeamSensitive
--Next update: local bcMaxBotPick = {}

-- list functions
function botCont.NewLists() -- saves all free bots in lists (trigger this function when you add bots)
	botCont.freeBots = {}
	for _,id in pairs(player(0,"tableliving")) do
		if (player(id,"bot")==true) and (botCont.IsBotPicked(id) == false) then
			botCont.freeBots[#botCont.freeBots + 1] = id
		end
	end
end

function botCont.IsBotPicked(bid) -- check if this bot ID is already picked by a player
	for i=1,#botCont.busyBots do
		if (botCont.busyBots[i][1] == bid) then
			return botCont.busyBots[i][2] -- return player id
		end
	end
	return 0 -- or 0 if nothing found
end

function botCont.IsPlayerPicked(id) -- check if this player id is actually a bot
	for i=1,#botCont.busyBots do
		if (botCont.busyBots[i][2] == id) then
			return botCont.busyBots[i][1]
		end
	end
	return 0
end

-- outsource functions
function botCont.CopyWeapons(id,id_source)
	for _,wpn in pairs(playerweapons(id)) do
		parse("strip "..id.." "..wpn)
	end
	for _,wpn in pairs(playerweapons(id_source)) do
		parse("equip "..id.." "..wpn)
	end
	parse("setweapon "..id.." "..player(id_source,"weapontype"))
end
function botCont.CopyWeapons2(id,wpn_array)
	for _,wpn in pairs(playerweapons(id)) do
		parse("strip "..id.." "..wpn)
	end
	for _,wpn in pairs(wpn_array) do
		parse("equip "..id.." "..wpn)
	end
	parse("setweapon "..id.." 50")
end

function botCont.SwapTeam(id)
	if (player(id,"team")==1) then
		parse("makect "..id)
		botCont.teamChange[#botCont.teamChange+1] = {id,1}
	elseif (player(id,"team")>=2) then
		parse("maket "..id)
		botCont.teamChange[#botCont.teamChange+1] = {id,2}
	elseif (player(bid,"team")==0) then
		if (math.random(0,1) == 0) then
			parse("makect "..id)
			botCont.teamChange[#botCont.teamChange+1] = {id,0}
		else
			parse("maket "..id)
			botCont.teamChange[#botCont.teamChange+1] = {id,0}
		end
	end
end

function botCont.ChangeStats(id1,id2) -- change whole stats-set (from bcCommands) of 2 players
	botCont.cvalues		 = {	"maxhealth",	 "health",	 "armor",	 "money",	 "score",	 "deaths",	 "speedmod"} -- all important stats of a player
	botCont.ccommands	 = {	"setmaxhealth",	"sethealth","setarmor",	"setmoney",	"setscore",	"setdeaths","speedmod"} -- all important commands to edit stats of a player
	local temp = {}
	for i=1,#botCont.ccommands do
		temp[i] = player(id1,botCont.cvalues[i])
		parse(botCont.ccommands[i].." "..id1.." "..player(id2,botCont.cvalues[i]))
		parse(botCont.ccommands[i].." "..id2.." "..temp[i])
	end
end

-- main functions
function botCont.PickBotAuto(id) -- find bid automatic and then do BcPickBot(id,bid)
	local bid
	for i=1,#botCont.freeBots do
		if (botCont.freeBots[i] ~= nil) then
			bid = botCont.freeBots[i]
			table.remove(botCont.freeBots,i)
			botCont.isNewBot = true
			break
		end
	end
	botCont.PickBot(id,bid)
end

function botCont.PickBot(id,bid) -- try to let id pick bid
	if (bid == nil) or (id == nil) or (id == bid) then return end
	
	botCont.busyBots[#botCont.busyBots+1] = {bid,id}
	if (botCont.IsBotPicked(bid) == false) then
		if (player(id,"health") <= 0) then
			-- correct teams
			if (player(id,"team") ~= player(bid,"team")) then 
				botCont.SwapTeam(id)
			end
			
			parse("spawnplayer "..id.." "..player(bid,"x").." "..player(bid,"y"))
			
			-- skin correction
			local counter = botCont.skinTries
			while (botCont.skinGet == true) do 
				if (player(id,"skin") == player(bid,"skin")) then
					break
				else
					parse("killplayer "..id)
					parse("setdeaths "..id.." "..player(id,"deaths")-1)
					parse("spawnplayer "..id.." "..player(bid,"x").." "..player(bid,"y"))
					counter = counter - 1
					if (counter == 0) then
						break
					end
				end
			end
			botCont.ChangeStats(id,bid)
			botCont.CopyWeapons(id,bid)
			parse("killplayer "..bid)
			parse("setdeaths "..bid.." "..player(bid,"deaths")-1)
			msg2(id,char(169).."033222033Bot Control Script: You are now the bot.")
		else
			msg2(id,char(169).."200033033Bot Control Script: You need to be dead to do this!")
		end
	end
end

-- hook functions
addhook("die","botCont.Hdie")
function botCont.Hdie(id)
	local bid = botCont.IsPlayerPicked(id)
	if (bid > 0) then
		botCont.ChangeStats(id,bid)
		for i=1,#botCont.busyBots do
			if (botCont.busyBots[i][2] == id) or (botCont.busyBots[i][1] == bid) then
				table.remove(botCont.busyBots,i)
			end
		end
	end
end
addhook("leave","botCont.Hjoin_leave")
addhook("join","botCont.Hjoin_leave")
function botCont.Hjoin_leave(id)
	if (player(id,"bot") == true) then
		botCont.isNewBot = true
	end
end

addhook("startround","botCont.Hstartround")
function botCont.Hstartround()
	for _, id in pairs(player(0,"tableliving")) do
		local bid = botCont.IsPlayerPicked(id)
		if (bid > 0) then
			-- Team Change
			if (botCont.teamSensitive == true) then
				for i=1,#botCont.teamChange do
					if (botCont.teamChange[i][1] == id) then
						botCont.SwapTeam(id)
						if (botCont.teamChange[i][2] == 0) then
							msg2(id,char(169).."200200200Bot Control Script: You aren´t Spectator anymore!")
						end
					end
				end
			end
			
			-- Weapon Change
			botCont.CopyWeapons(bid,id)
			botCont.CopyWeapons2(id,playerweapons(bid))
		end
	end
end

addhook("startround_prespawn","botCont.Hstartround_prespawn")
function botCont.Hstartround_prespawn()
	if (botCont.isNewBot == true) then
		botCont.NewLists()
		botCont.isNewBot = false
	end
	for i=1,#botCont.teamChange do
		if (botCont.teamChange[i] ~= nil) then
			botCont.SwapTeam(botCont.teamChange[i][1])
		end
	end
end

addhook("serveraction","botCont.Hserveraction")
function botCont.Hserveraction(id,b)
	if (b==1) then
		botCont.PickBotAuto(id)
	end
end

EDIT 2: Oops. I didn't read your post. I guess you found the solution. Ignore this post, if you want to.
edited 1×, last 18.01.16 08:59:06 am

old Re: Script doesnt work without errors

Bowlinghead
User Off Offline

Quote
@user VADemon:
So its basicly an object oriented class (except for the constructor and the addhooks I think)

And I agree with you on code conventions and longer names.
IsBotPicked(bid) was designed to be boolean but I decided to change that.

By the way, instead of minX,maxX,minY,maxY put X/Y as first letter xMin,xMax,yMin,yMax for better readability.

@user Dousea:
I prefer to remove the "botCont." namespace inside of the functions and just leave them as locals.
As far as I know your code may fix the errors but it will store all the variables inside of the botCont Array so they will be stored as long as the piece of code runs.
1
2
3
4
5
function botCont.SomeFunction() 
	local botCont.var1 = 5 		-- invalid
	local var1 = 7 			-- valid (and local)
	botCont.var1 = 11 		-- valid (but its stored as botCont.var1 and not as botCont.SomeFunction.var1)
end

old Re: Script doesnt work without errors

VADemon
User Off Offline

Quote
user Bowlinghead has written
By the way, instead of minX,maxX,minY,maxY put X/Y as first letter xMin,xMax,yMin,yMax for better readability.

You're right, I've done that occasionally for CS2D's "tilex" and "tiley", but I really need to stick to xTile variant.

user Bowlinghead has written
it will store all the variables inside of the botCont Array so they will be stored as long as the piece of code runs.

Often it's better to define a variable once and then use it. Most important example here is line 91/92 of your original code:
1
2
local botCont.cvalues = {     "maxhealth",      "health",      "armor",      "money",      "score",      "deaths",      "speedmod"} -- all important stats of a player
local botCont.ccommands = {     "setmaxhealth",     "sethealth","setarmor",     "setmoney",     "setscore",     "setdeaths","speedmod"} -- all important commands to edit stats of a player
Defining tables is an expensive operation (especially if you let Lua itself count how many elements you want to add, as written in your piece of code). So depending on how often this function will be called, it might be worth to permanently define these tables in your namespace.

It's about the golden mean between CPU/RAM usage. Sometimes you'll improve the execution speed a lot if you cache/store required data in RAM instead of checking through all values in for-loops. A quick example for this one:

Provided that you want to handle spawning of players entirely with your script (cs2d cmd spawnplayer). In this case it's wiser to check for map spawn locations once and store them than for-looping spawns on every spawn operation. (Although the benefit here would be within margin of error, but you get the idea)

old Re: Script doesnt work without errors

Dousea
User Off Offline

Quote
Actually I already aware of some variables that only be used inside a body (function) such botCont.temp and botCont.counter, so nothing to worry.
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview