Broadus to me it looks someone needs to learn how to use methods

not that you can't do it the way you try to do it but it's 3x the work and asking for trouble.
A method can be used to execute the same bit of code at any time, usually with different parameters. As you basically have 20x the same code, the repeating bits should be put in a method. Only one method is then required, and called 20x.
A small lesson in script structuring
A script naturally is divided into
threads, pieces of code that start with a
label and end with 'end'. A label is the name of the thread followed by a :. Example of a full script structure:
Code: Select all
main:
// code here
end
somethreadname1:
// code here
end
somethreadname2:
// code here
end
Up to as many threads as you need. Although mohaa allows you to be sloppy without complaining, it's very wise and practical to stick to this structure at all times. All code between thread start and end should be indented, so you can identify the start and end of each thread.
The first thread is run automatically when the script is called. Any other threads are not run unless called.
Common mistakes:
Forgetting a label (especially the first one ('main')).
Forgetting an 'end' (especially for the first thread).
Putting code between threads (very bad).
Using the labels to 'goto' to (very bad).
Although you will find these mistakes in the stock scripts, it doesn't justify them. I think most of the scripts in mohaa were made by mappers with none or limited programming experience, and many of their practices are best not followed.
Threads
Now on to how to use threads.
Call a thread using 'thread'. This will launch the thread as a seperate process.
Call a thread using 'waitthread'. This way it is a method in the same process. The caller thread will wait till the callee has finished executing. A method may also
return a value it calculated to the caller thread.
The commands 'exec' and 'waitexec' are best not used. Especially waitexec is tricky.. it waits for the called
thread group, instead of waiting for a specific thread, which is usually unexpected. If you want to know more about thread groups, do a search
Example of thread usage
This one is obviously very basic.
Code: Select all
main:
waitthread example_method
end
example_method:
println "example_method"
end
You can also send
parameters to a thread. This is done by expanding the thread definition. You can
return a value by expanding the thread end line.
Code: Select all
main:
local.three = waitthread method_add 1 2
local.five = waitthread method_add 2 3
println "1 + 2 = " local.three "; 2 + 3 = " local.five
end
// returns number1 + number2
method_add local.number1 local.number2:
local.result = local.number1 + local.number2
end local.result
Ofcourse this is a bit of a useless thread, but I think it makes sense as an example.
The labels 'number1', 'number2' and 'result' are arbitrary.
Again some hints:
Be very careful calling the same thread from within it. This creates a recursive structure, which is usually not desired. In many cases it's far better to place the contents of a thread entirely in a
while loop.
A recursive structure with 'waitthread' will crash with a
stack overflow unless there is a way out of the loop, for example and end inside the thread which is executed when certain conditions are met.
A recursive structure with 'thread' will not crash, but is
very sloppy and inefficient.
Always replace such a construction with a
while loop, it is always possible.
Never use the
goto command at all. It violates thread structure and is a lazy way to avoid learning something
Now to your case. This requires using both waitthread and thread. Put all the repetitive code inside a method:
Code: Select all
// makes a guy with specified model, origin gun, and returns him
spawn_a_guy local.model local.origin local.gun:
local.guy = spawn local.model origin local.origin gun local.gun
local.guy.health = 1
local.guy thread global/friendly.scr::friendlythink
local.guy.friendtype = 1
local.guy.distance = 200
local.guy.accuracy = 0
local.guy type_attack "running"
end local.guy
'end local.guy' returns a
reference to the caller script.
Now you can easily spawn lots of guys by putting this in your main thread (or some other active thread):
Code: Select all
for(local.i = 1; local.i <= 20; local.i++)
{
local.person[local.i] = waitthread spawn_a_guy "human/sovietlevel1.tik" (5131.96 7600.09 -159.88) "nagant rifle"
}
If you now want to have em respawn, you can either add a thread to the for loop or to the spawn_a_guy method. Best do it like this:
Code: Select all
for(local.i = 1; local.i <= 20; local.i++)
{
thread respawning_guy "human/sovietlevel1.tik" (5131.96 7600.09 -159.88) "nagant rifle"
}
(...)
end
respawning_guy local.model local.origin local.gun:
local.last_position = local.origin
while(1)
{
local.guy = waitthread spawn_a_guy local.model local.last_position local.gun
while(isAlive local.guy)
{
local.last_position = local.guy.origin
waitframe
}
// respawn with a small delay (2-4 secs)
wait 2.0
wait (randomfloat 2.0)
}
end
This should help some
