News: Welcome back to Bullworth! If you haven't already, you will need to reset your password..


Author Topic: luac: luascript.lua:1: unexpected symbol near `∩'  (Read 7652 times)

0 Members and 1 Guest are viewing this topic.

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
luac: luascript.lua:1: unexpected symbol near `∩'
« on: July 13, 2016, 08:13:05 PM »
I keep getting this problem whenever I try to put my script into ArcRace 1. I've done all the tasks to compile the scripts, but when I get to the part where I need to use the Command Prompt, it shows me the error. If anyone could help, it would be much appreciated.
Basically what the mission is, is a brawl between the greasers and the socs AKA Preppies. I wanted to make this mission because I loved the outsiders.

Here is my code:

ImportScript("\\Library\\LibTable.lua")
ImportScript("\\Library\\LibPed.lua")
local l_0_0 = false

MissionSetup = function()
  local l_1_0 = 480.52
  local l_1_1 = -200.43
  local l_1_2 = 2.91
 
  AreaTransitionXYZ(0, l_1_0, l_1_1, l_1_2)
  PlayerSetHealth(2000)
  PedSetTypeToTypeAttitude(4, 13, 4)
  PedSetTypeToTypeAttitude(5, 13, 0)
  PedSetTypeToTypeAttitude(4, 5, 0)
 
  Peanut = PedCreateXYZ(21, 478.22 , -200.73 , 2.95)
  PedSetHealth(Peanut, 2000)
 
  Hal = PedCreateXYZ(22, 475.22 , -202.22 , 3.00)
  PedSetHealth(Hal, 2000)
 
  Johnny = PedCreateXYZ(23, 473.29 , -203.48 , 3.05)
  PedSetHealth(Johnny, 2000)
 
  Lefty = PedCreateXYZ(24, 470.14 , -205.18 , 3.10)
  PedSetHealth(Lefty, 2000)
 
  Lucky = PedCreateXYZ(26, 467.81 , -205.71 , 3.14)
  PedSetHealth(Lucky, 2000)
 
  Vance = PedCreateXYZ(27, 468.27 , -203.03 , 3.12)
  PedSetHealth(Vance, 2000)
 
  Ricky = PedCreateXYZ(28, 470.92 , -202.25 , 3.08)
  PedSetHealth(Ricky, 2000)
 
  Norton = PedCreateXYZ(201, 478.92 , -199.85 , 2.93)
  PedSetHealth(Norton, 2000)
 
  Tad = PedCreateXYZ(31, 476.13 , -177.58 , 2.89)
  PedSetHealth(Tad, 2000)
 
  Chad = PedCreateXYZ(32, 474.31 , -179.63 , 2.91)
  PedSetHealth(Chad, 2000)
 
  Bif = PedCreateXYZ(33, 471.44 , -179.79 , 2.94)
  PedSetHealth(Bif, 2000)
 
  Justin = PedCreateXYZ(34, 468.77 , -180.30 , 2.95)
  PedSetHealth(Justin, 2000)
 
  Bryce = PedCreateXYZ(35, 466.05 , -181.25 , 2.99)
  PedSetHealth(Bryce, 2000)
 
  Darby = PedCreateXYZ(37, 463.08 , -181.66 , 3.00)
  PedSetHealth(Darby, 2000)
 
  Parker = PedCreateXYZ(40, 461.70 , -183.52 , 3.06)
  PedSetHealth(Parker, 2000)
 
  Chad = PedCreateXYZ(117, 464.72 , -183.13 , 3.04)
  PedSetHealth(Chad, 2000)
 
  Justin = PedCreateXYZ(118, 467.60 , -182.73 , 3.02)
  PedSetHealth(Justin, 2000)
end
MissionCleanup = function()
end
main = function()
  repeat
    Wait(0)
  until l_0_0 ~= true
  Wait(3000)
  MissionSucceed()
end

Offline DaBOSS54320

  • Hero Member
  • ****
  • Posts: 3,398
  • Gender: Female
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #1 on: July 13, 2016, 09:17:45 PM »
I don't recognize you... guess you're new huh? Wonderful to see new people interested in modding, welcome to the board!

Well first off I can tell you copied parts of this from an example script created by |XF|-MadmaN [AR]. This is quite alright for getting started but I would like to help explain to you that a lot of the things in your script are unnecessary. Those top 2 lines with ImportScript, you don't seem to use either of those libraries in your script, so there is no need to import them, and it in-fact wastes memory. It won't hurt that much to leave them in, but you can certainly take them out. Those "l_1_0" things are called variables, they're things you can store values in and can be named whatever you want. Again there's no error here, but I would like to point out that it is unnecessary to name them like that, and you could of named them something like "x", "y", and "z" since they do seem to be used as coordinates.

Now about that error you get when you try to compile your script (this is what I assume you're doing in the command line, using LuaC (lua compiler) to compile your script). I just tried to compile the script myself and got no errors, so it must be something that is only happening to you. I've no idea what that '∩' character is, but the error is basically saying that there is an '∩' somewhere in the script that there shouldn't be. What are you using to actually write your scripts? That may have something to do with it.
« Last Edit: July 13, 2016, 09:19:32 PM by DaBOSS54320 »

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #2 on: July 13, 2016, 11:06:53 PM »
Notepad ++

I basically copied this template from SWEGTA
Thanks for trying to help me too.
« Last Edit: July 14, 2016, 03:11:26 AM by CactusWalrus »

Offline UltimateGamer9

  • Full Member
  • ***
  • Posts: 190
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #3 on: July 14, 2016, 09:35:05 AM »
copy the script to another file and compile it again

Offline DaBOSS54320

  • Hero Member
  • ****
  • Posts: 3,398
  • Gender: Female
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #4 on: July 14, 2016, 11:24:45 AM »
Make sure encoding is set to UTF-8 or ANSI. I'm not sure why it would be different for you, but it's the only problem I can really think of.

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #5 on: July 14, 2016, 01:15:43 PM »
I'm sorry that I'm so inexperienced. It's my first time modding, but I honestly don't know how to set the encoding. I tried looking it up but found nothing.

Offline DaBOSS54320

  • Hero Member
  • ****
  • Posts: 3,398
  • Gender: Female
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #6 on: July 14, 2016, 10:10:38 PM »
Top of notepad, there should be a tab that reads "Encoding".

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #7 on: July 14, 2016, 11:19:13 PM »
It worked! Thank you so much!

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #8 on: July 15, 2016, 12:14:04 AM »
Sorry if I'm pestering you by asking so many questions. But now the mission just ends right away saying "You Passed!" and no fighting actually happens. I tried looking on Bully Board but could not find anything. I even tried looking a lua tutorial but didn't find anything. Do you know how to make it so that when all the Preppy peds I included are passed out, that results in the end of the mission? Thanks for the help.

Offline Rambo7

  • "Awesomely Kick-Ass Troll"
  • Full Member
  • ***
  • Posts: 404
  • Gender: Male
  • #ZAMBess
    • View Profile
    • My ModDB Page
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #9 on: July 15, 2016, 01:11:24 AM »
Try this, an example using three peds
Code: [Select]
MissionSetup = function()
  AreaTransitionXYZ(0, 480.52, -200.43, 2.91)
  PlayerSetHealth(2000)
end

MissionCleanup = function()
end

main = function()
  Peanut = PedCreateXYZ(21, 478.22 , -200.73 , 2.95)
  PedSetHealth(Peanut, 100)
  PedSetPedToTypeAttitude(Peanut,13,0)
  PedAttackPlayer(Peanut,1)
 
  Hal = PedCreateXYZ(22, 475.22 , -202.22 , 3.00)
  PedSetHealth(Hal, 100)
  PedSetPedToTypeAttitude(Hal,13,0)
  PedAttackPlayer(Hal,1)
 
  Johnny = PedCreateXYZ(23, 473.29 , -203.48 , 3.05)
  PedSetHealth(Johnny, 100)
  PedSetPedToTypeAttitude(Johnny,13,0)
  PedAttackPlayer(Johnny,1)
 
  repeat
Wait(0)
  until (not PedIsValid(Peanut) or PedIsDead(Peanut)) and
  (not PedIsValid(Hal) or PedIsDead(Hal)) and
  (not PedIsValid(Johnny) or PedIsDead(Johnny))

  MissionSucceed()
end

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #10 on: July 15, 2016, 01:57:37 AM »
I'll try it, thanks dude!

Offline DaBOSS54320

  • Hero Member
  • ****
  • Posts: 3,398
  • Gender: Female
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #11 on: July 15, 2016, 01:33:19 PM »
Sorry if I'm pestering you by asking so many questions. But now the mission just ends right away saying "You Passed!" and no fighting actually happens. I tried looking on Bully Board but could not find anything. I even tried looking a lua tutorial but didn't find anything. Do you know how to make it so that when all the Preppy peds I included are passed out, that results in the end of the mission? Thanks for the help.

You're not pestering me, I actually like to see new modders who want to learn.

How the script runs...
Notice your script is divided up into functions, those functions are basically bits of code that won't run until the function is called. You can call a function by putting its name followed by (), or some functions will also get called by Bully. In your case with this ArcRace1.lur script, Bully will first call the MissionSetup function, followed by main, and then MissionCleanup when the mission/script ends (when the player dies, gets busted, or when the main function ends).

Those are the only 3 functions Bully will actually call on its own, and they're all meant for a specific purpose.
MissionSetup: This is meant to set your mission up, doing things such as setting the player position or spawning peds.
main: This is where your script will spend most of its time, and it shouldn't end until you want the mission to be over.
MissionCleanup: This is meant to clean things up, move the player back somewhere after the mission is done, or whatever else.

When I say "it shouldn't end until you want the mission to be over", note that a function will end as soon as the script gets to the bottom of it, after it runs all the code inside it. To stop it from ending, we'll need to make a loop. I notice you already have one but it's not very useful how you have it set up. Try something more like this...

Code: [Select]
main = function()
  while true do
    Wait(0)
  end
end

This is called a while loop. It will run the code between "do" and "end" repeatedly while the condition between "while" and "do" evaluates to true. I explicitly put the value true there so it will just keep running, however you could also do other things to get whether or not it should be running. However we want it to only run while the peds are alive, so we'll have to do something a bit more.



Making sure the peds are alive
You could call a function, such as PedIsDead. This function is created by Bully and for you to use whenever you want. The function returns true if the specified ped is dead, and false otherwise. You specify the ped you want to check inside the () when calling it. However before we do that... realize that what we want is for the loop to keep running while the ped is NOT dead. Well, we can use "not" to invert the value of the boolean (a boolean value is just a value that is true or false). So if we do this: "not PedIsDead(ped)" and ped is not dead, PedIsDead will still end up returning false, but the "not" will flip that to "true" instead, so the value we end with is "true".
So now we can add that to the main loop as well...

Code: [Select]
main = function()
  while not PedIsDead(Peanut) do
    Wait(0)
  end
end

But.... another problem. We have more than one ped we want to check! No fear, we can simply use "or". "or" will just make sure one of the two values are true, and return true if so and false otherwise. Some examples...
(true or true) -- this evaluates to true
(true or false) -- this evaluates to true
(false or false) -- this evaluates to false

Notice we end with "true" as long as one of the two are true, and as before, we can also use function calls to get those true/false values and even use "not". We can also use multiple "or"s!.
So we could do this now:
Code: [Select]
main = function()
  while not PedIsDead(Peanut) or not PedIsDead(Hal) or not PedIsDead(Johnny) or not PedIsDead(Lefty) or not PedIsDead(Lucky) or not PedIsDead(Vance) or not PedIsDead(Ricky) or not PedIsDead(Norton) or not PedIsDead(Tad) or not PedIsDead(Chad) or not PedIsDead(Bif) or not PedIsDead(Justin) or not PedIsDead(Byrce) or not PedIsDead(Darby) or not PedIsDead(Parker) do
    Wait(0)
  end
end

And this will keep the "main loop" (what we call the while loop when it's the main loop of the script) running as long as any of the peds are still alive (not dead).



Waiting
This isn't actually related to your problem but I still would like to discuss it so you understand how it works. All we actually do in the while loop is wait... but what does waiting do? Well "Wait" is a function we can call to suspend our script for a certain amount of time so that Bully can run the other scripts and also do other things in the game. It's very important to wait because if we don't, the game will be stuck in our script, causing the game to freeze. The time to wait is specified in milliseconds. If we use 0 (like we do here) it will only wait a single frame, meaning if we just keep waiting 0ms, the script will continue to run only once every frame. Here's basically how we have our main loop set up to work:
 1. Check if any of the peds are still alive, if so, continue to #2, otherwise #3.
 2. Wait for a single frame, then return to #1 (the while loop will keep running until the expression between "while" and "do" ends up being "false".
 3. The while loop ended, then the function ends, meaning the whole mission will now end.

So we basically check every single frame that the peds are alive. And that's really all there is to it, nothing else you have to do here, just wanted to explain how Wait works and why we have to use it. All we do in this while loop is wait since we don't need to really do anything else, but if you wanted other code to run each frame, you could put it inside the while loop along with Wait. Put it before Wait if you want it to run before the script suspends and a frame is passed, or after if you want it after. Very important for timing things later on as you'll see in future projects.



Ped validity
When you spawn a ped using the PedCreateXYZ function, it is said to be a mission ped, meaning it will not be deleted when you go far away from it like most peds. However it WILL be deleted after it is killed for a while, fading away like all the other peds. This is actually a problem for us since if we check if an invalid (deleted) ped is dead, the script will actually crash! (the game won't crash, but the script would stop running). This is because it doesn't even realize the ped is invalid before it checks if they are dead, so it fails to get if they are actually dead since they don't even exist. We can fix this by using the PedIsValid function. This function works much like PedIsDead. It returns true while the ped is valid (even if they are dead, just not deleted), and false otherwise. So we'll have to check that each ped is valid BEFORE checking if they are dead. If a ped is invalid, we can assume they're dead or at least out of the fight now so we can count them dead. So we'll want to modify our script to keep the main loop running while any of the peds are valid AND not dead. We can do this using "and", it works a lot like "or" only it checks that BOTH are true instead of either.
Code: [Select]
main = function()
  while PedIsValid(Peanut) and not PedIsDead(Peanut) do
    Wait(0)
  end
end

For the sake of simplicity here I only put Peanut here for now, but you'd also put together all the other peds with it. But before that... there are two more things we need to discuss.



Short circuiting
Something you may be thinking is that in the above example, we still check if Peanut is dead. So even if PedIsValid returns false, we'd still check. This is actually FALSE. If PedIsValid is false, PedIsDead is actually never called. This is because of a concept called short circuiting. It deals with both "and" and "or". It basically means that once "and"/"or" got it's answer, it won't waste processing power checking if the other operand is true/false since it already got its answer. I think this would best be explained through some examples...
  true or false -- here, it first checks the left operand, "true". Since "or" only needs one value to be true, we already know it will evaluate to regardless of what the right operand is. So, the right one will not even be checked!
  false and true -- here, it first checks the left operand, "false". Since "and" needs both values to be true and one of them already isn't, we already have our answer, so it won't even check the right operand.
  true and false -- here is an example where it would actually need to check the right operand.
  false or true -- and here is another. it doesn't already have it's answer from the left, so it needs to check the right.

Okay so what? A little speed boost? Well that's not the only way it affects us... because if we use functions...
  true or PedIsDead(ped) -- here, it already got the answer from the left, so it never checks the right, the function won't even be called!
  false or PedIsDead(ped) -- this example however, it will be called.
  PedIsValid(ped) or PedIsDead(ped) -- here it will ONLY call PedIsDead if PedIsValid returns false, since if it returned true, we'd already have our answer.
  PedIsDead(ped) or true -- even though we know this will always be true, the script always checks the left side first. So PedIsDead will be called here, but since we have "or true", it'll always end up being true anyways.

Because of this, it works fine when we do something like this:
  PedIsValid(Peanut) and not PedIsDead(Peanut)

Because Peanut would have to be valid before PedIsDead gets called, and if he weren't valid, then PedIsDead would never be called.
The point of teaching you this is so you understand why order is important, especially with PedIsValid.



Order of operations
Alright so now we can check if peds are dead without the script crashing, so now we can make the full while loop, right? Just something like...
Code: [Select]
main = function()
  while PedIsValid(Peanut) and not PedIsDead(Peanut) or PedIsValid(Hal) and not PedIsDead(Hal) or PedIsValid(Johnny) and not PedIsDead(Johnny) or PedIsValid(Lefty) and not PedIsDead(Lefty) or PedIsValid(Lucky) and not PedIsDead(Lucky) or PedIsValid(Vance) and not PedIsDead(Vance) or PedIsValid(Ricky) and not PedIsDead(Ricky) or PedIsValid(Norton) and not PedIsDead(Norton) or PedIsValid(Tad) and not PedIsDead(Tad) or PedIsValid(Chad) and not PedIsDead(Chad) or PedIsValid(Bif) and not PedIsDead(Bif) or PedIsValid(Justin) and not PedIsDead(Justin) or PedIsValid(Byrce) and not PedIsDead(Byrce) or PedIsValid(Darby) and not PedIsDead(Darby) or PedIsValid(Parker) and not PedIsDead(Parker) do
    Wait(0)
  end
end

Yeah, that'd work actually. But I would like to still teach you something related to why it works.
Let's say we have something like this:
  x and y or z

How do we know if it'll check it like this:
  x and (y or z)

Or like this:
  (x and y) or z

Well, order of operations. Something you probably learned in math too. It exists in LUA too, "and" is evaluated before "or", so how we have our code it will work. But I still wanted to just explain this little bit in case it confused you while looking at the code.

Another note too, if you want "or" to evaluate first, you can type the () just like I did and it will evaluate first. So...
  x and (y or z)

This will force the script to evaluate y or z first, then check "x and (whatever x or z evaluated to)".
Since "and" is by default evaluated before "or", something like this:
  x and y or z

Is equal to this:
  (x and y) or z

HOWEVER, it can still be a lot easier to read if we put the () anyways. This is up to you if you want to do it or not, it is not at all needed, but it will make things look a bit better. So we could have something like...
  (PedIsValid(Peanut) and not PedIsDead(Peanut)) or (PedIsValid(Hal) and not PedIsDead(Hal))

That way each ped neatly gets their own (). But since we only use "and" in there anyways, the () are not needed at all. So the code is fine as it is now, but I thought it'd still be nice to teach you this.



Custom functions
Holy shit, can we address how fucking tedious it was for me to type that huge while loop? Very. The code works as it is now, but there is a better and neater way we could do it. Image it like this...
Code: [Select]
main = function()
  while AnyPedIsAlive(Peanut,Hal,Johnny,Left,Lucky,Vance,Ricky,Norton,Tad,Chad,Bif,Justin,Bryce,Darby) do
    Wait(0)
  end
end

So much neater right? Well... sadly no function exists. But, we could make one! We start by making the function like any other, but we also add a few more things to it.
Code: [Select]
AnyPedIsAlive = function(...)
  return value
end

The "..." means there can be any number of arguments (arguments are the values we put inside the () when calling the function. However this concept may be a bit hard for us to start on so let's instead look at a simple example of a custom function that takes two arguments, and returns one value.
Code: [Select]
addition = function(a,b)
  local c = a+b
  return c
end

test = addition(10,20)

It's a very simple layout, we first create the function like any other and put code in it like any other. The only thing new to you should be the parameters we put in (), and the return value. You may be wondering why I said parameters rather than arguments too... let me explain that real quick.
  Parameters are the names of variables used inside a function.
  Arguments are values that you give to those parameters when calling the function.

So "a" and "b" are parameters, and "10" and "20" are arguments. When we call the function like this "addition(10,20)", "a" gets filled in with the value 10, and "b" gets filled in with the value 20. Then it adds them together, storing the result in "c", then returning "c". We could of also done "return a+b" and it would of worked the same way.  So when the function gets to that "return", it exits the function (so any code after return, will not run), and it returns the value after return (you don't have to specify a value after return, if you don't, then the function just won't return anything). This returned value works just like the true/false returned by PedIsDead. Except rather than using it with a while loop, we just store it in a variable called "test". So now "test" has the value 30. Simple enough right?



Local variables
Short side discussion too, you may be wondering what "local" means in that script, and why we didn't use it for "test". Well, "local" is a keyword that we use when we create a variable if we want it to be local to a certain function. This means it can only be used inside the function. If we don't specify "local", the variable will be global, meaning it can be used anywhere inside the script. For example if we did not make "c" local in that example, we'd be able to later use "c" and it'd still have 30. Or if we called "addition" again, c would be replaced with the new value. But since we made it local, we can't use it from outside the function, which makes sense. Also note if you change a local variable, you do not need to specify local again. For example...
  local x = 10
  local x = 20 -- wrong

Only specify it once, and it will stay local.
  local x = 10
  x = 20 -- still local to whatever function this code is in

Nothing you need to do with this either just thought I'd explain it too since we used a local variable. Oh and also note that function parameters are always local, so we cannot use "a" and "b" outside of the function either.



Tables
A table is a special kind of value that holds multiple values. There is a lot of depth in this topic, but I'll try to stay on track here since this post is already getting long. Here's an example:
  {10,50}

{} creates a table, and values in between it set the initial values for it. We can also make a variable refer to a table like this:
  t = {20,60}

Now "t" refers to the created table. We can get certain values from the table using [index].
  t = {50,100,150}
  t[1] -- this is 50
  t[2] -- this is 100
  t[3] -- this is 150
  t[4] -- invalid

We can also store peds in a table.
  t = {Peanut,Hal,Johnny}

When we do this, the script will get the value of "Peanut" (a unique number referring to the created ped), and put it in the table, and do the same for each other value.
Note that if we change any of the variables, the value in the table will NOT change. For example...
  x = 10
  t = {x} -- takes the value of 'x' at this time and copies it into the table
  t[1] -- equal to 10
  x = 50 -- x is now 50
  t[1] -- is still 10



Custom functions with many arguments
Okay so tables are great, but why teach you them? Because it is how we can get multiple arguments into a function. Check it out:
Code: [Select]
PrintNames = function(peds)
  -- just like before, "peds" is a parameter to the function that we will fill in with a table when calling it.
  local i = 1 -- start 'i' at 1
  while i <= table.getn(peds) do -- table.getn returns the size of a table, the amount of values in it. while 'i' is less than or equal to that, we have a valid value we can get.
    TextPrintString(PedGetName(peds[i],2,1) -- get the name of peds[i].
    Wait(2000) -- wait for the name to show for a bit
    i = i + 1 -- increment i for use with the next ped in the table
  end
end

PrintNames({Peanut,Hal,Johnny})

In this example I use something called comments, it is a very simple concept, I just type "--" and the rest of the line becomes a comment. I use this to make comments about certain parts of the code. LUA ignores comments, they are just for scripters to read.
It's not a very useful example, but it's a simple one for demonstrating the idea. We create a table with Peanut, Hal, and Johnny in it, and pass that table as an argument to the PrintNames function. That table fills in the "peds" parameter, and we use that "peds" table like the other tables, only this time we use a variable to access the values in it instead. It's basically the same idea though, if 'i' is 1, then it's the same as peds[1]. This basically just loops through every ped in the table, doing the code in the while loop on each ped. Saves a lot of script space and effort since we only have to write the code one, and it gets done on each ped. PedGetName by the way is just a simple function that returns the name of a ped. Now... about that "..." parameter.

Code: [Select]
PrintNames = function(...)
  -- ... is a special thing we can make as a parameter. It takes multiple arguments and puts them all into a table called "arg".
  local i = 1 -- start 'i' at 1
  while i <= table.getn(arg) do -- table.getn returns the size of a table, the amount of values in it. while 'i' is less than or equal to that, we have a valid value we can get.
    TextPrintString(PedGetName(arg[i],2,1) -- get the name of peds[i].
    Wait(2000) -- wait for the name to show for a bit
    i = i + 1 -- increment i for use with the next ped in the table
  end
end

-- Notice this time I don't create a table, I just pass multiple values into the function. The ... parameter takes all of these and puts it in a local table called "arg" for the function, as explained above.
PrintNames(Peanut,Hal,Johnny)

Very similar to the last example really, only notice I don't need to create my own table when calling the function, and we change "peds" to be "arg", "arg" is a table that gets filled in with all the values passed to the function when using "..." as the only parameter.



If statements
This is a very simple concept, so we'll make it brief. An if statement is very similar to a while loop with syntax, except it only runs once (it's not a loop). For example...
  if true then
    -- code
  end

Notice instead of "do" we use "then", and instead of "while" we use "if". These are the only changes to syntax, but also note that the body of the if statement ("--code") will only run once if the expression between "if" and "then" is true. If it's not true, then it won't even run once (just like the while loop) and it'll just go straight to the end.



Finally, the AnyPedIsAlive function
Now, we can finally make the function we talked about before. It will only use concepts we've covered before, so there is nothing new to really learn now. I will still comment the code so you understand what is happening.
Code: [Select]
AnyPedIsAlive = function(...)
  local i = 1
  while i <= table.getn(arg) do
    if PedIsValid(arg[i]) and not PedIsDead(arg[i]) then
      -- The ped is valid and not dead, meaning they are alive. Return true.
      return true
    end
    i = i + 1
  end
 
  -- If the function gets here and still hasn't returned (remember if it returned above, then the script wouldn't make it to this part of the function) then none of the peds must be alive, return false.
  return false
end

There it is, wonderful isn't it? Now just a few more things before we get your final fixed script going...



Variable names
I notice in your script you use the same variable name multiple times. "Chad" in MissionSetup for example. You create two peds of him which is fine, but you only have one variable for storing the ped in. So the second one ends up overwriting the first one.
Code: [Select]
function MissionSetup()
  Chad = PedCreateXYZ(32, 474.31 , -179.63 , 2.91)
  -- Okay, Chad is now a variable that refers to a created ped.
  PedSetHealth(Chad, 2000)
 
  Chad = PedCreateXYZ(117, 464.72 , -183.13 , 3.04)
  -- Wait, the value of Chad just changed to a new ped. The old value is lost, the old ped still exists, but we no longer have access to him!
  PedSetHealth(Chad, 2000)
end

We can fix it easily by calling him Chad2. Same with the other duplicates you have.



Ped limit
Sadly this game has a pretty small max amount of peds, if more are spawned, the game will crash. The max amount is 26, and you create 17. This is fine but, the problem may occur when you take into account there is usually around 5-15 freeroam peds spawned at once, which can and will end up creating more than 26 peds, and crashing your game. The fix for this is simple though, let's just stop the game from creating more peds! This is done through a function called StopPedProduction. It takes one argument, true or false, and it specifies whether or not it should be stopped or resumed.
  StopPedProduction(true) -- stop freeroam peds from spawning
  StopPedProduction(false) -- start freeroam ped spawning

We'll stop it in MissionSetup, and start it in MissionCleanup, simple.
Oh but another problem is this will only stop peds, NOT delete the current ones. Luckily there is a function to delete all the freeroam peds (not mission peds though). AreaClearAllPeds. It takes no arguments, and just does what you'd expect. We'll call it once before creating our mission's peds, and after stopping production.



Conclusion
I know I've probably went on a lot longer than you expected and I'm sorry if you wanted a more direct answer, but I can tell you're new but want to learn so I wanted to help as much as I could. Not just showing you the answer but teaching you everything that goes along with it, along with some other things along the way. I hope it really helps, and I hope to see you make some really awesome mods in the future too. Good luck and happy modding!



The final script
Code: [Select]
MissionSetup = function()
  local x = 480.52
  local y = -200.43
  local z = 2.91
 
  AreaTransitionXYZ(0, x, y, z)
  PlayerSetHealth(2000)
  PedSetTypeToTypeAttitude(4, 13, 4)
  PedSetTypeToTypeAttitude(5, 13, 0)
  PedSetTypeToTypeAttitude(4, 5, 0)
 
  StopPedProduction(true)
  AreaClearAllPeds()
 
  Peanut = PedCreateXYZ(21, 478.22 , -200.73 , 2.95)
  PedSetHealth(Peanut, 2000)
 
  Hal = PedCreateXYZ(22, 475.22 , -202.22 , 3.00)
  PedSetHealth(Hal, 2000)
 
  Johnny = PedCreateXYZ(23, 473.29 , -203.48 , 3.05)
  PedSetHealth(Johnny, 2000)
 
  Lefty = PedCreateXYZ(24, 470.14 , -205.18 , 3.10)
  PedSetHealth(Lefty, 2000)
 
  Lucky = PedCreateXYZ(26, 467.81 , -205.71 , 3.14)
  PedSetHealth(Lucky, 2000)
 
  Vance = PedCreateXYZ(27, 468.27 , -203.03 , 3.12)
  PedSetHealth(Vance, 2000)
 
  Ricky = PedCreateXYZ(28, 470.92 , -202.25 , 3.08)
  PedSetHealth(Ricky, 2000)
 
  Norton = PedCreateXYZ(201, 478.92 , -199.85 , 2.93)
  PedSetHealth(Norton, 2000)
 
  Tad = PedCreateXYZ(31, 476.13 , -177.58 , 2.89)
  PedSetHealth(Tad, 2000)
 
  Chad = PedCreateXYZ(32, 474.31 , -179.63 , 2.91)
  PedSetHealth(Chad, 2000)
 
  Bif = PedCreateXYZ(33, 471.44 , -179.79 , 2.94)
  PedSetHealth(Bif, 2000)
 
  Justin = PedCreateXYZ(34, 468.77 , -180.30 , 2.95)
  PedSetHealth(Justin, 2000)
 
  Bryce = PedCreateXYZ(35, 466.05 , -181.25 , 2.99)
  PedSetHealth(Bryce, 2000)
 
  Darby = PedCreateXYZ(37, 463.08 , -181.66 , 3.00)
  PedSetHealth(Darby, 2000)
 
  Parker = PedCreateXYZ(40, 461.70 , -183.52 , 3.06)
  PedSetHealth(Parker, 2000)
 
  Chad2 = PedCreateXYZ(117, 464.72 , -183.13 , 3.04)
  PedSetHealth(Chad, 2000)
 
  Justin2 = PedCreateXYZ(118, 467.60 , -182.73 , 3.02)
  PedSetHealth(Justin, 2000)
end
MissionCleanup = function()
  StopPedProduction(false)
end
AnyPedIsAlive = function(...)
  local i = 1
  while i <= table.getn(arg) do
    if PedIsValid(arg[i]) and not PedIsDead(arg[i]) then
      -- The ped is valid and not dead, meaning they are alive. Return true.
      return true
    end
    i = i + 1
  end
 
  -- If the function gets here and still hasn't returned (remember if it returned above, then the script wouldn't make it to this part of the function) then none of the peds must be alive, return false.
  return false
end
main = function()
  -- Wait for all the enemies to die:
  while AnyPedIsAlive(Chad,Chad2,Bif,Justin,Justin2,Bryce,Darby) do
    Wait(0)
  end
 
  -- Complete the mission:
  MissionSucceed()
end

Offline CactusWalrus

  • Newbie
  • *
  • Posts: 0
  • Gender: Male
    • View Profile
Re: luac: luascript.lua:1: unexpected symbol near `∩'
« Reply #12 on: July 15, 2016, 03:21:50 PM »
I really appreciate all the help! Without you guys, I never would've been able to figure any of this out.