Jump to content
legion7698

Trouble with a pepperpotting script

Recommended Posts

Hey all,

I'm trying to use a pepperpot/rush/whatever you know it as script I found on this website made by General Barron. The script works fine but to exec it you have to put the unit who's doing said action, the direction and the distance. Now since the unit they have to pepperpot to will appear from anywhere I want to make this dynamic. So to this effect I do the following.

I place the pepperpotting units down as three squads, en1, en2 and en3 on the resistance side. I then place the unit they will pepperpot to down on the west side (unamed as the final mission will have multiply but I'm only using one to test the script). I then put a trigger down with the paremters of west detected by resistance and on the activation field I put

[this] exec "Attack.sqs"

that then executes the Attack.sqs script which is as follows.

_group = _this select 0

{_x disableAI "TARGET"} foreach units en1
{_x disableAI "TARGET"} foreach units en2
{_x disableAI "TARGET"} foreach units en3

en1 dotarget _group
en2 dotarget _group
en3 dotarget _group

_dir1 = getdir en1
_dir2 = getdir en2
_dir3 = getdir en3

_dis1 = en1 distance _group
_dis2 = en2 distance _group
_dis3 = en3 distance _group

[en1, _dir1, _dis1] exec {rush.sqs}
[en2, _dir2, _dis2] exec {rush.sqs}
[en3, _dir3, _dis3] exec {rush.sqs}

My problem is it constantly falling over on the distance command and when I comment out the distance and put a fixed number it then falls over the dotarget command.

Also for those interested here it the pepperpot.

;========================================================
;     Rush.sqs v1.0
;
;     By General Barron
;     aw_barron@hotmail.com
;     8/11/04
;========================================================
;
;    This script will cause the squad to execute a basic infantry maneuver: a 
;squad rush. Part of the squad will run forward, while the rest of the squad lies 
;down to cover them. Those rushing forward will lie down, and cover those 
;behind them while they get up to rush, and so on. 
;     To stop the rush manually, set the group's formation to any formation other than 
;"line". It is best to execute this script when the group is already in line formation, but
;that is not required.
;
;TO CALL THE SCRIPT:
;     [group, direction, distance] exec {rush.sqs}
;In any init/activation field/script, where "group" is the name of the group to 
;execute the rush and "direction" is the compass heading you want the rush 
;to be oriented. "Distance" is the maximum distance in that direction the group
;will rush (in meters). If you only want to stop the formation manually, via script or trigger, 
;simply place a number like "9999" in for distance.
;
;FOR A RETREAT:
;   A retreat is basically the same as a rush, only instead of the units laying down facing in the
;direction of the rush, they face the opposite direction (to cover their buddies as they run away from
; the enemy). To call a retreat, instead of a rush, simply put a NEGATIVE DISTANCE in.
;IMPORTANT NOTE: The movement will still be in the direction given, even though the distance is negative!
;For example: [group1, 90, -100] exec "rush.sqs"
;   Will execute a retreat that will go 100 meters east.
;
;NOTES FOR BEST RESULTS
;   Think of this script as a replacement for a waypoint. Instead using a waypoint in the middle 
;of a town to get the AI to attack, use this script: First move the AI close to the town via waypoints, 
;then have the AI rush the remaining distance (a couple hundred meters or so) via this script.
;The result is a much more organized and realistic assualt.
;   To prevent OFP's default AI from taking over the script, I suggest you use the "disableAI"
;command when you call this script. Use the following line right before you call the script:
;      {_x disableAI "TARGET"} foreach units *group name*
;    I also suggest that you use high-dispersion magazines in missions using this script.
;Due to OFP's lack of cover, lack of suppressive fire, and the AI's super-accuracy with weapons, 
;rushes and retreats done by this script just aren't as effective as they are in real life. 
;High-dispersion help balance these problems.
;========================================================

;-------------------------
#Group_Init
;-------------------------
? count _this == 4 : goto "Unit_Init"
;   Error message if missing params
?count _this != 3 : hint "RUSH.SQS PARAMETER ERROR: EXITING SCRIPT"; exit

_group = _this select 0
_axis = _this select 1
_rushDist = _this select 2

{_x disableAI "TARGET"} foreach units _group

{_x allowFleeing 0.5} foreach units _group

;   End any other rush/retreat scripts that are running.
;?formation _group == "LINE" : _group setformation "WEDGE"
;@formation _group == "WEDGE"

;   formation = "line" indicates group is rushing
_group setFormation "LINE"
@formation _group == "LINE"

;   Execute the script on each member of the group. Pass it three variables so it
;   knows to jump to the right spot.
{ [_x,_axis,_rushDist,0] exec {rush.sqs} } foreach units _group

;-------------------------
;   Define functions to be used in script. Global variable is used, since function only needs to be defined once for all instances of the script.

;   Function used to find the distance a unit is from a line, designated by a position and a direction (i.e. line running to the left and right of a unit)
GENB_distFunction = {private ["_x1","_x2","_y1","_y2","_dir","_dist"]; _x1 = _this select 0; _y1 = _this select 1; _x2 = _this select 3; _y2 = _this select 4; _dir = ((_x2 - _x1) atan2 (_y2 - _y1)) + 90 - (_this select 2); _dist = (sqrt((_x2 - _x1)^2 + (_y2 - _y1)^2)) * sin _dir; _dist}
;   Function used to find the average distance the squad members are from an imaginary line running left and right of where the leader stood at the beginning of the script
GENB_avgDistFunction = {private ["_xpos","_ypos","_axis","_units","_avgdist"]; _xpos = _this select 0; _ypos = _this select 1; _axis = _this select 2; _units = _this select 3; _avgdist = 0; { if (alive _x) then {_avgdist = _avgdist + ([_xpos,_ypos,_axis,getpos _x select 0, getpos _x select 1] call GENB_distFunction)} } foreach _units; if (({alive _x} count _units) != 0) then {_avgdist = _avgdist / ({alive _x} count _units)}; _avgdist}
;-------------------------
exit

;-------------------------
#Unit_Init
;-------------------------

_man = _this select 0

;   Adding (almost always) prevents a harmless error from calling _distFunction on leader before he moves.
_xpos = ((getpos leader _man) select 0) + 1
_ypos = ((getpos leader _man) select 1) + 1
_axis = _this select 1

;   maximum distance the group will rush forward, in meters. Script will exit once the group is about this far from their starting point, (or if formation is changed).
_rushDist = _this select 2

;   maximum distance away from the center of the group a individual member can be. A maxDist of 20 means
;   that the group will spread out a maximum of 40 meters from the front man to the rear man while rushing.
_maxDist = 10

;   Set up behaviours for unit
_man setBehaviour "COMBAT"
_man setSpeedMode "LIMITED"
_man setUnitPos "DOWN"
if (_rushDist >= 0) then {_man dowatch [(getpos _man select 0) + 99999 * (sin _axis), (getpos _man select 1) + 99999 * (cos _axis)]; _man setCombatMode "YELLOW"; _retreatBonus = 0} else {_man dowatch [(getpos _man select 0) + -99999 * (sin _axis), (getpos _man select 1) + -99999 * (cos _axis)]; _man setCombatMode "GREEN"; _retreatBonus = 2}
_rushDist = abs(_rushDist)

;   About a third of the squad will rush immediately, the rest will wait a short time.
? random 1 < 0.33 : goto "RUSH"
;   @ is used instead of ~ so that if the formation is changed (to end the script), the script will end immediately (it will skip through all the delays).
_waitTill = _time + random 8
@(_time >= _waitTill) OR formation _man != "LINE"

;-------------------------
#RUSH
;-------------------------

;(2 + random 2)

;   Get the unit up and start him running forward.
~5
_man setUnitPos "UP"
_man domove [(getpos _man select 0) + 100 * (sin _axis), (getpos _man select 1) + 100 * (cos _axis)]
_waitTill = _time + 3
@(_time >= _waitTill) OR formation _man != "LINE"
;   If the unit is too far behind the rest of the squad, keep him running.
?alive _man AND (([_xpos,_ypos,_axis,getpos _man select 0, getpos _man select 1] call GENB_distFunction) - ([_xpos,_ypos,_axis,units _man] call GENB_avgDistFunction)) < (_maxDist * -1) : goto "RUSH"

;   Get the unit down.
_man setUnitPos "DOWN"
_waitTill = _time + 3
@(_time >= _waitTill) OR formation _man != "LINE"
dostop _man


;   Wait until the unit is too far forward of his group, this will make him wait until his squad (an average of their positions) has caught up within _maxDist of him.
@ !(alive _man) OR (([_xpos,_ypos,_axis,getpos _man select 0, getpos _man select 1] call GENB_distFunction) - ([_xpos,_ypos,_axis,units _man] call GENB_avgDistFunction)) < _maxDist OR formation _man != "LINE"

;   Stay down for a short time, then repeat. Exit if the unit is dead or formation is set to anything other than "line".
_waitTill = _time + 5
@(_time >= _waitTill) OR formation _man != "LINE"

?alive _man AND (formation _man) == "LINE" AND ([_xpos,_ypos,_axis,units _man] call GENB_avgDistFunction) < _rushDist : goto "RUSH"

_man domove getpos _man
_man setunitpos "AUTO"
exitWith

regards,

LEGION7698.

Share this post


Link to post
Share on other sites
en1 dotarget _group

en2 dotarget _group

en3 dotarget _group

{_x dotarget _group}foreach units en1

{_x dotarget _group}foreach units en2

{_x dotarget _group}foreach units en3

_dis1 = en1 distance _group

_dis2 = en2 distance _group

_dis3 = en3 distance _group

_dis1 = leader en1 distance _group

_dis2 = leader en2 distance _group

_dis3 = leader en3 distance _group

Share this post


Link to post
Share on other sites

haven't tested Red Baron's script, but it says in the comments that the direction you need to feed in the parameters is the direction of the charge.

your script gives the direction of the group leaders at the time they detect the threat (I assume en1,en2 and en3 are group leaders). try adding a small pause to allow the leaders to turn and face the target (~2) so that when you call the script, they are looking in the right direction. this might not work however if you are using the disableAI command

also, you could eliminate the dotarget ,getdir and disableAI commands by using this function and adjusting your script

_dirToTarget1 = [en1,_group] call AngleFacingDiff.sqf
_dir1 = (getdir en1) + _dirToTarget1

Share this post


Link to post
Share on other sites

group cannot be used as an object for determing distance nor can group name alone be used in dotarget.

group is considered an array. So all array considerations must be used in determining distance - etc...

Share this post


Link to post
Share on other sites

@WW2Weasel

actually, group is considered as a group not as an array :)

units group is an actual array comprised of the units of the group.

but to stay on the subject, "_group" in Legion's script, is not an actual group, rather the first element of the trigger he uses in editor

_group = _this select 0

in this case he hoped it would be the first West unit detected by Resistance inside the trigger area, so all calculations of distance would be unit-to-unit

@LEGION7698

thislist exec "Attack.sqs"

will execute the script with the trigger's list, not

[this] exec "Attack.sqs"

I did a little testing and [this] when executed from the activation field of the trigger gave me a false status only. Not really sure what the false status means, but it's safe to assume it's not the enemy unit you are looking for :D

You could also skip a line or two in the script by executing

(thislist select 0) exec "Attack.sqs"

this runs the script with the first unit in the trigger list already defined and you can refer to the enemy unit inside the script simply as "_this"

for future reference, I suggest you try to name your variables with easily recognizable names that help you understand what the variable represents, to avoid mistakes. If a year from now you go back to that script and see "_group" you most likely think it represents a group and not a unit :)

Share this post


Link to post
Share on other sites

Hey guys,

Cheers for the help and advice. Its now working perfectly.

regards,

LEGION7698.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×