OFPEC Forum
Editors Depot - Mission Editing and Scripting => OFP - Editing/Scripting General => Topic started by: PivMan on 24 Jul 2013, 19:59:44
-
To be simple, I'm trying to have a unit be given random weapons of a range of my choosing with probabilities of my choosing. I want this to be done through a simple execution of a script in the initialization field for each unit. Forgive the manner in which I attempted this, it was the first approach that came to mind. Prepare for if statements galore and unorganized syntax. Oh, and I'm using FFUR SLX 2007.
First off, I state that I want to execute weapon.sqs in the unit's init field. That works fine at least.
weapon.sqs:
canhaveprimary = random(100)+1; //random number that determines if the unit gets a primary
canhavepistol = random(100)+1; //random number that determines if the unit gets a secondary
canhaverpg = random(100)+1; //random number that determines if the unit gets an rpg
canhavefrag = random(100)+1; //random number that determines if the unit gets a grenade
canhavebomb = random(100)+1; //random number that determines if the unit gets a satchel charge
canhavesmoke = random(100)+1; //random number that determines if the unit gets a smoke grenade
if (canhaveprimary > 50) then {[] exec "primaryrandom.sqs"}; //50% chance to execute script to distribute a random primary
if (canhavepistol <= 25) then {[] exec "pistolrandom.sqs"}; //25% chance to execute script to distribute a random sidearm
if (canhaverpg <= 5) then [{this addweapon "rpglauncher"} , {this addmagazine "rpglauncher"}]; //5% chance to distribute an rpg
if (canhavefrag <= 10) then {this addmagazine "handgrenade"}; //10% chance to distribute a grenade
if (canhavebomb <= 5) then {this addmagazine "pipebomb"}; //5% chance to distribute a satchel charge
if (canhavesmoke <= 10) then {this addmagazine "ffur_anm8"}; //10% chance to distribute a smoke
From this script two others can be executed:
primaryrandom.sqs:
primarygun = random(202); //same crappy system as before, just bigger
if (primarygun <= 10) then [{this addweapon "G36a"} , {this addmagazine "G36amag"}];
if (primarygun > 10 and <= 20) then [{this addweapon "steyr"} , {this addmagazine "steyrmag"}];
if (primarygun > 20 and <= 30) then [{this addweapon "xms"} , {this addmagazine "m4"}];
if (primarygun > 30 and <= 40) then [{this addweapon "fal"} , {this addmagazine "falmag"}];
if (primarygun > 40 and <= 50) then [{this addweapon "hkg3"} , {this addmagazine "hkg3mag"}];
if (primarygun > 50 and <= 60) then [{this addweapon "ak74"} , {this addmagazine "ak74"}];
if (primarygun > 60 and <= 70) then [{this addweapon "ak74su"} , {this addmagazine "ak74"}];
if (primarygun > 70 and <= 80) then [{this addweapon "ak47"} , {this addmagazine "ak47"}];
if (primarygun > 80 and <= 90) then [{this addweapon "ak47cz"} , {this addmagazine "ak47"}];
if (primarygun > 90 and <= 100) then [{this addweapon "svddragunov"} , {this addmagazine "svddragunov"}];
if (primarygun > 100 and <= 110) then [{this addweapon "bizon"} , {this addmagazine "bizonmag"}];
if (primarygun > 110 and <= 120) then [{this addweapon "ak47s"} , {this addmagazine "ak47"}];
if (primarygun > 120 and <= 130) then [{this addweapon "xms2"} , {this addmagazine "m4"}];
if (primarygun > 130 and <= 140) then [{this addweapon "m16s"} , {this addmagazine "m4"}];
if (primarygun > 140 and <= 150) then [{this addweapon "m24"} , {this addmagazine "m24mag"}];
if (primarygun > 150 and <= 165) then [{this addweapon "huntingrifle"} , {this addmagazine "huntingriflemag"} , {this addmagazine "huntingriflemag"}];
if (primarygun > 165 and <= 180) then [{this addweapon "kozlice"} , {this addmagazine "kozliceball"} , {this addmagazine "kozliceshell"}];
if (primarygun > 180 and <= 187) then [{this addweapon "ak47grenadelauncher"} , {this addmagazine "ak47"} , {this addmagazine "grenadelauncher"}];
if (primarygun > 187 and <= 194) then [{this addweapon "ak74grenadelauncher"} , {this addmagazine "ak74"} , {this addmagazine
"grenadelauncher"}];
if (primarygun > 194 and <= 199) then [{this addweapon "mm1"} , {this addmagazine "mm1magazine"}];
if (primarygun == 200) then [{this addweapon "pk"} , {this addmagazine "pk"}];
if (primarygun == 201) then [{this addweapon "m60"} , {this addmagazine "m60"}];
if (primarygun >= 202) then [{this addweapon "m240g_elc"} , {this addmagazine "m240g_elcmag"}];
pistolrandom.sqs:
pistolgun = random(100);
if (pistolgun <= 10) then [{this addweapon "cz75"} , {this addmagazine "cz75mag"}];
if (pistolgun > 10 and <= 20) then [{this addweapon "tokarev"} , {this addmagazine "tokarevmag"}];
if (pistolgun > 20 and <= 30) then [{this addweapon "m1911"} , {this addmagazine "m1911mag"}];
if (pistolgun > 30 and <= 40) then [{this addweapon "p228"} , {this addmagazine "p228mag"}];
if (pistolgun > 40 and <= 50) then [{this addweapon "beretta"} , {this addmagazine "berettamag"}];
if (pistolgun > 50 and <= 60) then [{this addweapon "glock"} , {this addmagazine "glockmag"}];
if (pistolgun > 60 and <= 65) then [{this addweapon "skorpion"} , {this addmagazine "skorpionmag"}];
if (pistolgun > 65 and <= 70) then [{this addweapon "ingram"} , {this addmagazine "ingrammag"}];
if (pistolgun > 70 and <= 85) then [{this addweapon "revolver"} , {this addmagazine "revolvermag"}];
if (pistolgun >= 85) then [{this addweapon "p2a1"} , {this addmagazine "white_flare_mag"}];
The game is giving me an 'invalid number used in expression' error, which likely means there's a consistent error in every script. Any ideas? Help would be much appreciated.
-
Tried out the passage that should give the unit the handgun, and found the following error:
(pistolgun > 10 and <= 20)
This should be:
(pistolgun > 10 and pistolgun <= 20)
I didn't try the weapon.sqs one, though. I hope this resolves the problem.
-
Yep, consistent error throughout. Big thank you on identifying the silly mistake. I'll test it out and get back to you in a sec.
E: Okay, it looks like that was one of an unknown amount of problems. I patched the scripts, but it's still giving me an error message (one I can't frustratingly read in its entirety) and not giving my character any weapons. Could it be the way I reference the unit? Does 'this' still apply when executing scripts through other scripts?
weapon.sqs
canhaveprimary = random(100)+1;
canhavepistol = random(100)+1;
canhaverpg = random(100)+1;
canhavefrag = random(100)+1;
canhavebomb = random(100)+1;
canhavesmoke = random(100)+1;
if (canhaveprimary > 50) then {[] exec "primaryrandom.sqs"};
if (canhavepistol <= 25) then {[] exec "pistolrandom.sqs"};
if (canhaverpg <= 5) then [{this addweapon "rpglauncher"} , {this addmagazine "rpglauncher"}];
if (canhavefrag <= 10) then {this addmagazine "handgrenade"};
if (canhavebomb <= 5) then {this addmagazine "pipebomb"};
if (canhavesmoke <= 10) then {this addmagazine "ffur_anm8"};
primaryrandom.sqs
primarygun = random(202);
if (primarygun <= 10) then [{this addweapon "G36a"} , {this addmagazine "G36amag"}];
if (primarygun > 10 and primarygun <= 20) then [{this addweapon "steyr"} , {this addmagazine "steyrmag"}];
if (primarygun > 20 and primarygun <= 30) then [{this addweapon "xms"} , {this addmagazine "m4"}];
if (primarygun > 30 and primarygun <= 40) then [{this addweapon "fal"} , {this addmagazine "falmag"}];
if (primarygun > 40 and primarygun <= 50) then [{this addweapon "hkg3"} , {this addmagazine "hkg3mag"}];
if (primarygun > 50 and primarygun <= 60) then [{this addweapon "ak74"} , {this addmagazine "ak74"}];
if (primarygun > 60 and primarygun <= 70) then [{this addweapon "ak74su"} , {this addmagazine "ak74"}];
if (primarygun > 70 and primarygun <= 80) then [{this addweapon "ak47"} , {this addmagazine "ak47"}];
if (primarygun > 80 and primarygun <= 90) then [{this addweapon "ak47cz"} , {this addmagazine "ak47"}];
if (primarygun > 90 and primarygun <= 100) then [{this addweapon "svddragunov"} , {this addmagazine "svddragunov"}];
if (primarygun > 100 and primarygun <= 110) then [{this addweapon "bizon"} , {this addmagazine "bizonmag"}];
if (primarygun > 110 and primarygun <= 120) then [{this addweapon "ak47s"} , {this addmagazine "ak47"}];
if (primarygun > 120 and primarygun <= 130) then [{this addweapon "xms2"} , {this addmagazine "m4"}];
if (primarygun > 130 and primarygun <= 140) then [{this addweapon "m16s"} , {this addmagazine "m4"}];
if (primarygun > 140 and primarygun <= 150) then [{this addweapon "m24"} , {this addmagazine "m24mag"}];
if (primarygun > 150 and primarygun <= 165) then [{this addweapon "huntingrifle"} , {this addmagazine "huntingriflemag"} , {this addmagazine "huntingriflemag"}];
if (primarygun > 165 and primarygun <= 180) then [{this addweapon "kozlice"} , {this addmagazine "kozliceball"} , {this addmagazine "kozliceshell"}];
if (primarygun > 180 and primarygun <= 187) then [{this addweapon "ak47grenadelauncher"} , {this addmagazine "ak47"} , {this addmagazine "grenadelauncher"}];
if (primarygun > 187 and primarygun <= 194) then [{this addweapon "ak74grenadelauncher"} , {this addmagazine "ak74"} , {this addmagazine "grenadelauncher"}];
if (primarygun > 194 and primarygun <= 199) then [{this addweapon "mm1"} , {this addmagazine "mm1magazine"}];
if (primarygun == 200) then [{this addweapon "pk"} , {this addmagazine "pk"}];
if (primarygun == 201) then [{this addweapon "m60"} , {this addmagazine "m60"}];
if (primarygun >= 202) then [{this addweapon "m240g_elc"} , {this addmagazine "m240gmag"}];
pistolrandom.sqs
pistolgun = random(100);
if (pistolgun <= 10) then [{this addweapon "cz75"} , {this addmagazine "cz75mag"}];
if (pistolgun > 10 and pistolgun <= 20) then [{this addweapon "tokarev"} , {this addmagazine "tokarevmag"}];
if (pistolgun > 20 and pistolgun <= 30) then [{this addweapon "m1911"} , {this addmagazine "m1911mag"}];
if (pistolgun > 30 and pistolgun <= 40) then [{this addweapon "p228"} , {this addmagazine "p228mag"}];
if (pistolgun > 40 and pistolgun <= 50) then [{this addweapon "beretta"} , {this addmagazine "berettamag"}];
if (pistolgun > 50 and pistolgun <= 60) then [{this addweapon "glock"} , {this addmagazine "glockmag"}];
if (pistolgun > 60 and pistolgun <= 65) then [{this addweapon "skorpion"} , {this addmagazine "skorpionmag"}];
if (pistolgun > 65 and pistolgun <= 70) then [{this addweapon "ingram"} , {this addmagazine "ingrammag"}];
if (pistolgun > 70 and pistolgun <= 85) then [{this addweapon "revolver"} , {this addmagazine "revolvermag"}];
if (pistolgun >= 85) then [{this addweapon "p2a1"} , {this addmagazine "white_flare_mag"}];
-
It's been a long time since I last did any complex scripting. But to me it does seem like the problem lies with the way you reference a unit.
if (canhavesmoke <= 10) then {this addmagazine "ffur_anm8"};
'this' should probably be replaced with a local variable, such as _unit.
At the moment, 'this' does not equate to a unit at all.
At the start of the script, put this:
_unit = _this select 0
Then replace 'this' in your 'IF' commands with _unit.
Hopefully that will fix the problem, which seems to be consistent in the scripts.
EDIT: You can still call the script from the units' init field, but like this:
[this] exec "gimmeweapons.sqs"
-
Commented code below.
; randomised weapon loadout
; created 24 July 2013
; updated 24 July 2013
; @author PivMan
; @author bedges
; call script using
; this exec "weapons.sqs"
; in init of unit
; unit is passed to script as _this
; create an array containing all the required primary weapons with their magazines
_primary_weapons = [["G36a", "G36amag"], ["steyr", "steyrmag"], ["xms", "m4"], ["fal", "falmag"], ["hkg3", "hkg3mag"], ["ak74", "ak74"], ["ak74su", "ak74"], ["ak47", "ak47"], ["ak47cz", "ak47"], ["svddragunov", "svddragunov"], ["bizon", "bizonmag"], ["ak47s", "ak47"], ["xms2", "m4"], ["m16s", "m4"], ["m24", "m24mag"], ["huntingrifle", "huntingriflemag", "huntingriflemag"], ["kozlice", "kozliceball", "kozliceshell"], ["ak47grenadelauncher", "ak47", "grenadelauncher"], ["ak74grenadelauncher", "ak74", "grenadelauncher"], ["mm1", "mm1magazine"], ["pk", "pk"], ["m60", "m60"], ["m240g_elc", "m240gmag"]]
; create an array containing all the required sidearms with their magazines
_sidearms = [["cz75", "cz75mag"], ["tokarev", "tokarevmag"], ["m1911", "m1911mag"], ["p228", "p228mag"], ["beretta", "berettamag"], ["glock", "glockmag"], ["skorpion", "skorpionmag"], ["ingram", "ingrammag"], ["revolver", "revolvermag"], ["p2a1", "white_flare_mag"]]
; should there be a primary weapon?
? (random 100 >= 50) : goto "primary"
#return_primary
; should there be a sidearm?
? (random 100 <= 25) : goto "pistol"
#return_pistol
; should there be a rocket launcher?
? (random 100 <= 50) : _this addmagazine "rpglauncher"; _this addweapon "rpglauncher"
; hand grenade?
? (random 100 <= 50) : _this addmagazine "handgrenade"
; satchel charge?
? (random 100 <= 50) : _this addmagazine "pipebomb"
; night vision?
? (random 100 <= 50) : _this addweapon "nvgoggles"
; don't forget the binoculars folks!
? (random 100 <= 50) : _this addweapon "binocular"
; whatever this is?
; ? (random 100 <= 50) : _this addmagazine "ffur_anm8"
; all done
exit
; choose a primary weapon at random
#primary
; use the total number of primary weapons in the array as the total
_r = random (count _primary_weapons)
; make it a whole number so we can use it as the array's index
_r = _r - (_r mod 1)
; select the part of the array at the random index
_weapon = _primary_weapons select _r
; the first element is the weapon, the second and third element the magazines
; we add the magazine first so that the weapon is automatically loaded when it's added
_this addmagazine (_weapon select 1)
_this addweapon (_weapon select 0)
; if there's more than one magazine listed in the selected array index, add it too
? (count _weapon > 2) : _this addmagazine (_weapon select 2)
; go back up to where we were in the script
goto "return_primary"
; choose a sidearm at random
#pistol
; use the total number of sidearms in the array as the total
_r = random (count _sidearms)
; make it a whole number so we can use it as the array's index
_r = _r - (_r mod 1)
; select the part of the array at the random index
_weapon = _sidearms select _r
; the first element is the weapon, the second and third element the magazines
; we add the magazine first so that the weapon is automatically loaded when it's added
_this addmagazine (_weapon select 1)
_this addweapon (_weapon select 0)
; go back up to where we were in the script
goto "return_pistol"
Tested and works fine. A few pointers:
- as Gruntage has mentioned, _local variables are better than global variables in most cases. Global variables take up more memory and you can eventually reach the maximum number, making saving a game basically impossible
- calling separate scripts is a bit wasteful unless they fulfill a generic purpose which can be reused elsewhere. In this particular case it's more efficient to condense it into a single script as above, and use #markers to jump within the script
- learn how to use arrays - they are incredibly handy
- more generally, when you find yourself copy/pasting something over and over and only changing one small thing each time, chances are there's a simpler and more elegant solution. Remember: make the computer work for you, not the other way around. SkyNet is still a few years from now
- housekeeping details like putting a date on your scripts can come in handy, especially to remind you after 3 years when you return to a script and cannot remember what the heck it does!
There are some useful resources (http://www.ofpec.com/COMREF/index.php?action=read&id=72) you can look at for further information. Reading other people's scripts can help too.
Hope this helps. Good luck! :good:
-
Solid copy, Bedges.
Thanks a ton both of you for taking the time to help me out with this. I really, really appreciate it. This mission has been in progress for days now and me and my friends can finally play it. Big thanks.
E: Oh, and the ffur_anm8 is the ANM8 smoke grenade. FFUR adds it as a hand thrown alternative to the standard launcher fired smoke shell.