Home   Help Search Login Register  

Author Topic: Sniper script issues  (Read 876 times)

0 Members and 1 Guest are viewing this topic.

Offline KTottE

  • Former Staff
  • ****
Sniper script issues
« on: 06 Jan 2003, 22:36:17 »
Right, so I'm working on a script for snipers. I'm doing it so that it can be implemented easily, as easily as possible, as a matter of fact. I want the end-user interaction with it to consist of him placing the needed units, one trigger, then passing the correct arguments to the script.

Right, so the story behind it is this:
I have a friendly group, an enemy sniper, and a trigger.
Whenever the friendly group enters the trigger (it's MP, so they are the only west soldiers in the area) enters the trigger, I want to launch the script, and have the sniper go active.
Arguments I'm passing to the script:

Groupname (name of friendly group)
Snipername (name of sniper)

Now, I'm going to implement this:

- Target AI before human players (it's a coop)
- If leader is AI, then target him first of all
- Select target at random
- Slow down shooting speed  (they get off five rounds pretty quick with that Mosin Nagant, and I don't want the squad eliminated right away, just keep them on their toes)

Right, so I want this dynamic. As dynamic as can be. My goal is no mission-maker interaction with the script file itself.
So, what I'm thinking so far is:

- create two lists, one with human players, one with AI soldiers.
- if there are troops in the AI list, the sniper targets those.
- if not, target the human players.
- use a delay or somesuch to slow down firing speed.

Now, has anyone got any ideas on this?

What I want is dynamics, so can I use:

_numGuys = Count _listName
_randomNum = Random _numGuys

To select a number at random, based on the number of guys (say it's 12, say it's 10, or even 5) being the maximum?
(_listName of course contains all the guys already, and I'm using the mod command to produce whole integers)

I've been trying to get this to work all afternoon, and now I'm fed up with it ;D

Can I use an evenHandler to detect when the sniper fires, and then use some sort of delay function to stop him from firing again for X number of seconds?

Help me out guys, 'cause this will help you out. I'm gonna fix this, and submit it to the ed depot for everyone's benefit :)
"Life is not a journey to the grave with the intention of arriving safely in a pretty and well preserved body, but rather to skid in broadside, thoroughly used up, totally worn out, and loudly proclaiming 'WOW What a Ride!'"

Offline Ranger

  • Members
  • *
  • Hoo-ah!
Re:Sniper script issues
« Reply #1 on: 07 Jan 2003, 00:22:29 »
Try the following code.  If you use it, and if you can get it to work (it is completely untested), all I ask is that you give me credit for the code that I have done for whatever parts that you do use.  Again, it is untested, so you probably will have to fiddle with it a bit before it works properly.  Good luck!

Code: [Select]
; Code by Ranger

; Initialize the two lists (arrays): AI units and player units.

_AIUnits = []
_playerUnits = []

; Initialize the _fired local variable.

_fired = 0

; Get the name of the group and the sniper.

_squad = _this select 0
_sniper = _this select 1

; Order the sniper never to fire so that he won't fire before he is supposed to do so.

_sniper setCombatMode "BLUE"

; Add an event handler to the sniper that checks if the sniper has fired.
; *** Note: I'm not 100% sure that you can use a local variable with this code.

_sniper addEventHandler ["fired",{_fired = 1}]

; Make an array of all units in the group.

_allUnits = units _squad

; Count the number of units in the squad.

_i = count _allUnits

#MakeLists

; Decrement _i by 1.

_i = _i - 1

; Check if the unit stored in array element _i is a player.  If so, put the unit in the
; player array.

? (_allUnits select _i == player) : _playerUnits = _playerUnits + (_allUnits select _i)

; Otherwise, put the unit in the AI array.

? (_allUnits select _i != player) : _AIUnits = _AIUnits + (_allUnits select _i)

; Check if _i < 1.  If so, choose the target.

? (_i < 1) : goto "ChooseTarget"

; Otherwise, loop again and check the next unit.

goto "MakeLists"

; Make the sniper select a target.

#ChooseTarget

; Check to see if the sniper is dead.  If he is, exit the script.

? (not alive _sniper) : exit

; If there are AI units, target them first.

? (count _AIUnits > 0) : goto "TargetAI"

; Otherwise, target player units, if any.

? (count _playerUnits > 0) : goto "TargetPlayer"

; If there are no targets left, exit the script.

exit

; Randomly determine which AI unit to target.

#TargetAI

; Count the number of AI units.

_numUnits = count _AIUnits

; Get a random whole number ranging from 0 to 1 less than the number of units.

_n = random (_numUnits)

; Loop until _n != _numUnits.

while "_n == _numUnits" do {_n = random (_numUnits )}

; Use the mod command to get a whole number.

_n = _n - (_n mod 1)

; Check to make sure that unit _n is not dead.  If it is dead, remove it from the units
; array and choose again.

? (not alive (_AIUnits select _n)) : _AIUnits = _AIUnits - (_AIUnits select _n); goto "TargetAI"

; Assign the chosen unit to the _target variable.

_target = _AIUnits select _n

; Set _isAI = 1 so that we know later that the target is AI.

_isAI = 1

; Goto the shooting code.

goto "OpenFire"

; Randomly determine which player unit to target.

#TargetPlayer

; Count the number of player units.

_numUnits = count _playerUnits

; Get a random whole number ranging from 0 to 1 less than the number of units.

_n = random (_numUnits)

; Loop until _n != _numUnits.

while "_n == _numUnits" do {_n = random (_numUnits )}

; Use the mod command to get a whole number.

_n = _n - (_n mod 1)

; Check to make sure that unit _n is not dead.  If it is dead, remove it from the units
; array and choose again.

? (not alive (_playerUnits select _n)) : _playerUnits = _playerUnits - (_playerUnits select _n); goto "TargetPlayer"

; Assign the chosen unit to the _target variable.

_target = _playerUnits select _n

; Set _isAI = 0 so that we know later that the target is not AI.

_isAI = 0

; Goto the shooting code.

goto "OpenFire"

; Make the sniper shoot at the chosen target.

#OpenFire

; Order the sniper to target the target.

_sniper doTarget _target

; Order the sniper to engage.

_sniper setCombatMode "YELLOW"

; Order the sniper to fire.

_sniper doFire _target

; Wait until the sniper has fired before continuing.

@ _fired

; Reset the _fired variable to 0.

_fired = 0

; Order the sniper never to fire so that he will hold fire briefly.

_sniper setCombatMode "BLUE"

; Delay for a few seconds so that the sniper doesn't wipe out the entire group too
; quickly.

~2

; Check if the target is still alive.  If so, fire again.

? (alive _target) : goto "OpenFire"

; Otherwise, remove the unit from the appropriate array and choose a new target.

? (_isAI) : _AIUnits = _AIUnits - _target
? (not _isAI) : _playerUnits = _playerUnits - _target

goto "ChooseTarget"

Edit: Changed code to use an event handler.  Added a check to see if the sniper is dead.
« Last Edit: 07 Jan 2003, 00:51:23 by Ranger »
Ranger

Offline KTottE

  • Former Staff
  • ****
Re:Sniper script issues
« Reply #2 on: 07 Jan 2003, 00:56:43 »
Right, I'll test that, and see if I need to modify it somehow, then I'll upload it to the Ed Depot under both our names. If no changes are made, I'll just make an example mission and give all the credit to you.

*waves*
"Life is not a journey to the grave with the intention of arriving safely in a pretty and well preserved body, but rather to skid in broadside, thoroughly used up, totally worn out, and loudly proclaiming 'WOW What a Ride!'"

Offline Ranger

  • Members
  • *
  • Hoo-ah!
Re:Sniper script issues
« Reply #3 on: 07 Jan 2003, 01:19:58 »
Sounds good.  I hope you can get it to work. :)

If you can find ways to optimize the code, naturally feel free to do so.  I just wrote what I think will work, but of course there might be better ways to do some of the things.
Ranger

Offline KTottE

  • Former Staff
  • ****
Re:Sniper script issues
« Reply #4 on: 07 Jan 2003, 22:34:13 »
Right, tested it "as is", and there are some problems.

1) The sniper will target everyone

2) There's no delay in the firing


Now, I'm thinking of doing more than one script.
One main one that starts whenever the trigger is activadet, and this one in turn executes the specific scripts. And I might even do a function out of it.

Anyway, what I'm thinking is this:

A function or a script for just the firing. Make global variables which you pass on to this function or script, which stores group name, sniper name and whatnot.
I'm also thinking about this, have the main script check it it's AI or not, then divide into two different arrays.

sPlayerArray and sAIArray respectively.

If sAIArray contains more than 0 units, then it get passed first to the shooting script.

[sAIArray] exec {shootScript.sqs}

then shootScript will pick up that array, randomize the values in it, and shoot at the first one. I think this is easier than doing it the other way, which is extract all values then randomize it.
Rather randomize the list, then run through it from top to bottom.

Oh, and I'm gonna implement a feature, where you can specify how many rounds the sniper should shoot
then pass that along to shootScript.sqs

wantedShots = _this select 2

...

[sAIArray, wantedShots] exec {shootScript.sqs}


Now, what shootScript should do is that it picks up all the params sent to it.

sAIArray and wantedShots, first we randomize the content of sAIArray (or if there should be an .sqf function which does this, and then pass everything along to shootScript.sqs) and so on.
Then we set up a counter with wantedShots.
Each time the sniper fires, shotsFired = shotsFired + 1
And
?(shotsFired >= wantedShots) : exit

And last, but not least, the delay. It's not working at all, so we need to sort that out as well.
Maybe a timer thingy?
Detect time since last shot, and don't move on until _timeSinceFired >= 5
(5 being seconds)

*falls off chair*

I need to brush up on my script skills.
"Life is not a journey to the grave with the intention of arriving safely in a pretty and well preserved body, but rather to skid in broadside, thoroughly used up, totally worn out, and loudly proclaiming 'WOW What a Ride!'"

Offline Ranger

  • Members
  • *
  • Hoo-ah!
Re:Sniper script issues
« Reply #5 on: 07 Jan 2003, 23:25:37 »
Right, tested it "as is", and there are some problems.

1) The sniper will target everyone

2) There's no delay in the firing

Okay, I could have guessed there would be issues.  :-\

Anyway, did you try fiddling with it at all to make it work?  Some things to try:

- Change _fired to a global variable, fired.  Use the publicVariable command after every instance that this variable is updated.

- Try putting in a larger delay in the script to see if that makes any difference.  Maybe it 10 for a more extreme wait.

- Do AI units fire when in the Never Fire combat mode but ordered to fire with DoFire?  If so, then leave the sniper in the Never Fire mode so that he doesn't target anyone else.

- Instead of using the fired variable, count how many rounds the sniper has left and see if it has changed (indicating that he has fired).

Just some ideas.  Unfortunately, I can't test any of this for the next several days, if not even a full week or more.
Ranger

Offline KTottE

  • Former Staff
  • ****
Re:Sniper script issues
« Reply #6 on: 07 Jan 2003, 23:44:49 »
Well, I'm gonna try that with the fired variable, because that's pretty much the only thing I didn't fiddle with.

I did try changing to a ~10 second delay, but no result.
"Life is not a journey to the grave with the intention of arriving safely in a pretty and well preserved body, but rather to skid in broadside, thoroughly used up, totally worn out, and loudly proclaiming 'WOW What a Ride!'"

Liquid_Silence

  • Guest
Re:Sniper script issues
« Reply #7 on: 08 Jan 2003, 02:24:01 »
Couldn't you just
Code: [Select]
sniper disableAI "autotarget"'cause then he would only fire at a target that you gave him...

Offline KTottE

  • Former Staff
  • ****
Re:Sniper script issues
« Reply #8 on: 09 Jan 2003, 21:36:23 »
Yes, but that only solves the problem of him firing wildly, there are other issues. Which I sadly haven't gotten around to looking at yet, as I've been away from comp and so on.

I'm gonna check this out during the weekend, and hope for the best.
"Life is not a journey to the grave with the intention of arriving safely in a pretty and well preserved body, but rather to skid in broadside, thoroughly used up, totally worn out, and loudly proclaiming 'WOW What a Ride!'"

Fox2

  • Guest
Re:Sniper script issues
« Reply #9 on: 03 Feb 2003, 07:06:15 »
Perhaps this might work for delaying shots or controlling how many shots you want him to take at a time. Initialize your sniper's combat mode to blue in the editor, then when you want him to shoot, set his combat mode to yellow. To control how many shots he makes, just keep track of how many bullets he has.

Code: [Select]

_shotstaken
_delay = 10

#Loop

_ammo = _sniper ammo "SVDDragunov"

_sniper SetCombatMode "yellow"
@(_sniper ammo "SVDDragunov") < _ammo - _shotstaken
_ammo = _sniper ammo "SVDDragunov"
_sniper setcombatmode "blue"

~_delay

goto "Loop"

The above code will cause the sniper to fire 3 shots every 10 seconds. Adjust variables as you wish. Remember to set the _shotstaken variable one lower than the number of shots you want him to take. For instance, if you want him to take 5 shots, initialize _shotstaken to 4.

Offline Ranger

  • Members
  • *
  • Hoo-ah!
Re:Sniper script issues
« Reply #10 on: 03 Feb 2003, 18:07:00 »
Initialize your sniper's combat mode to blue in the editor, then when you want him to shoot, set his combat mode to yellow.

Did you read the original script that I wrote for KTotte?  In that (non-working) script, I already included what you suggest here.
Ranger

Fox2

  • Guest
Re:Sniper script issues
« Reply #11 on: 03 Feb 2003, 18:41:50 »
Well, hot damn. Sorry 'bout that. Nothing like feeling stupid to make your Monday morning great.  ;D