Jump to content
Sign in to follow this  
domcho

Script for ending mission if player kills friendly units or civilians

Recommended Posts

Hi, guys. I made a script which makes the mission end if the player kills a friendly unit or a civilian. The script is:

friendlydead = 1
_counter = 10000
_oldrating = 0;
_newrating = 0;
_difference= 0;

#start
_oldrating = rating player
~1
_newrating = rating player

_difference = (_oldrating - _newrating)



?_difference >1:friendlydead = friendlydead-1 
_counter=_counter-1
?_counter>0:goto"start"
exit

Now you need to do the following thing in order for the script to activate.

1st put the in the player's or any other existing unit's initialization box:

this exec "nameofscript.sqs"

where "nameofscript.sqs" is the name of the script.sqs that you're using. This must be done so the script runs while you are playing.

2nd make a trigger:

Activation:None

Type:End #1

Condition box:friendlydead == 0

This will force the mission to end. But note that if you use the command player addRating -(number) where (number) is a number this will also end the mission. Basically the script indicates if the player lost rating, so if he did then the mission ends. A player looses rating if he:

Kills a friendly unit

Kills a civilian

Or the mission maker made something reduce the player's rating with the addRating -(number) command. However it is not a problem to use addRating with a positive number (that is above 0)

If you want to change the number of friendly units and/or civilians that you can kill before the mission ends simply edit the 1st line in the script. For example if your mission is to end if you kill 3 friendly units and/or civilians, make it like this:

friendlydead = [color="Red"]3[/color]

If you want to to make a warning when the player kills a friendly unit or a civilian then make a trigger which will be like this:

Activation:None

Type:None

Condition box:friendlydead == 2 (if in the script you set friendlydead = 3 then this will activate the warning message when you kill 1 friendly unit or civilian, but this will activate only once. For the other time that you want the waring to activate you will need to type in another trigger's condition box friendlydead == 1)

On Activation box: put warning message here (for example if I am playing on the West side I will add in the activation box:

[west, "HQ"] sideChat "Watch your fire"

which will make papa bear send a message on the side chat, but you can make whatever warning you want.

I hope this is useful for your missions. :)

Edited by Domcho

Share this post


Link to post
Share on other sites

hi,

Agree with Pulverizer, your script based on addRating is not reliable and some unwanted stuff could happen. To do what you want you have to use an addEventHandler killed.

something like:

init.sqs

;********************************
;init Script by Nikiller v0.9b
;contact: nikillerofp@hotmail.fr
;********************************

nik_civilian=[c1,c2,c3,c4,c5,c6,c7,c8,c9]

;-----------------------------------------------------------------------------------------
; Civilian killed
;-----------------------------------------------------------------------------------------
nik_friendlyfirecivil=0
{_x addeventhandler ["killed",{nik_friendlyfirecivil=nik_friendlyfirecivil+1; publicVariable "nik_friendlyfirecivil"; hint format ["%2 was killed by %1\n\nYOU KILLED AN INNOCENT CIVILIAN\n\nWATCH YOUR FIRE %1!",name (_this select 1),name (_this select 0)]}]} forEach nik_civilian

Add a end trigger with a condition something like: nik_friendlyfirecivil==3

Don't forget to make a corresponding debriefing section in your briefing.html

But I don't like this solution because the civilians can be killed by an enemy AI grenade and player may not understand why the mission ends. Moreover this solution doesn't work for friendly fire.

IMHO, the best way is to check if the unit has been killed by the value player. Have a look here. I think this solution is more reliable than the others.

cya.

Nikiller.

Share this post


Link to post
Share on other sites
hi,

Agree with Pulverizer, your script based on addRating is not reliable and some unwanted stuff could happen. To do what you want you have to use an addEventHandler killed.

something like:

init.sqs

;********************************
;init Script by Nikiller v0.9b
;contact: nikillerofp@hotmail.fr
;********************************

nik_civilian=[c1,c2,c3,c4,c5,c6,c7,c8,c9]

;-----------------------------------------------------------------------------------------
; Civilian killed
;-----------------------------------------------------------------------------------------
nik_friendlyfirecivil=0
{_x addeventhandler ["killed",{nik_friendlyfirecivil=nik_friendlyfirecivil+1; publicVariable "nik_friendlyfirecivil"; hint format ["%2 was killed by %1\n\nYOU KILLED AN INNOCENT CIVILIAN\n\nWATCH YOUR FIRE %1!",name (_this select 1),name (_this select 0)]}]} forEach nik_civilian

Add a end trigger with a condition something like: nik_friendlyfirecivil==3

Don't forget to make a corresponding debriefing section in your briefing.html

But I don't like this solution because the civilians can be killed by an enemy AI grenade and player may not understand why the mission ends. Moreover this solution doesn't work for friendly fire.

IMHO, the best way is to check if the unit has been killed by the value player. Have a look here. I think this solution is more reliable than the others.

cya.

Nikiller.

Well yes, your script is awesome but you have to name all the units that get killed. That's the thing that makes it bad, because if I have lots of units on the battlefield I will have to name each one of them and put their name in the 1st script. As pulverizer said about losing rating by destroying vehicles, I didn't know that. :eek:

Share this post


Link to post
Share on other sites

hi,

Well yes, your script is awesome but you have to name all the units that get killed.

No you don't need to give a name to each unit. You can call the addEventHandler in the unit's init field. Just replace the unit's name by this.

unit's init field

this addeventhandler ["killed",{nik_friendlyfirecivil=nik_friendlyfirecivil+1; publicVariable "nik_friendlyfirecivil"; hint format ["%2 was killed by %1\n\nYOU KILLED AN INNOCENT CIVILIAN\n\nWATCH YOUR FIRE %1!",name (_this select 1),name (_this select 0)]}]

But with this way your mission file size will be bigger than if you use {_x} forEach way. The mission loading time is longer and it is performance hungry. For example it takes less space and it's faster to calculate for a computer to write 2*5=10 than 2+2+2+2+2=10.

That's the thing that makes it bad, because if I have lots of units on the battlefield I will have to name each one of them and put their name in the 1st script.

If you really want to have a total control on a mission it is recommanded to name each units or at least give a name to each group and make arrays of them, it's a question of performance in singleplayer and more still in multiplayer.

cya.

Nikiller.

Edited by Nikiller

Share this post


Link to post
Share on other sites
hi,

No you don't need to give a name to each unit. You can call the addEventHandler in the unit's init field. Just replace the unit's name by this.

unit's init field

this addeventhandler ["killed",{nik_friendlyfirecivil=nik_friendlyfirecivil+1; publicVariable "nik_friendlyfirecivil"; hint format ["%2 was killed by %1\n\nYOU KILLED AN INNOCENT CIVILIAN\n\nWATCH YOUR FIRE %1!",name (_this select 1),name (_this select 0)]}]

But with this way your mission file size will be bigger than if you use {_x} forEach way. The mission loading time is longer and it is performance hungry. For example it takes less space and it's faster to calculate for a computer to write 2*5=10 than 2+2+2+2+2=10.

If you really want to have a total control on a mission it is recommanded to name each units or at least give a name to each group and make arrays of them, it's a question of performance in singleplayer and more still in multiplayer.

cya.

Nikiller.

Okay thanks :yay: btw do you know how can I spawn smoke(grey/red/green) at a marker position. I don't know the code to put in the script.sqs for spawning things. Can you please tell me. Thanks.

Share this post


Link to post
Share on other sites

foo="SmokeShell" camCreate getMarkerPos "my_marker"

then "SmokeShellRed" and "SmokeShellGreen" respectively.

Stuff created with camCreate is local only in multiplayer so that's good for superficial things. CreateVehicle does the same but is global so you can easily create mp-synced random artillery explosions for instance. Just beware that if createVehicle is executed on every client, its effect will be multiplied.

Share this post


Link to post
Share on other sites
foo="SmokeShell" camCreate getMarkerPos "my_marker"

then "SmokeShellRed" and "SmokeShellGreen" respectively.

Stuff created with camCreate is local only in multiplayer so that's good for superficial things. CreateVehicle does the same but is global so you can easily create mp-synced random artillery explosions for instance. Just beware that if createVehicle is executed on every client, its effect will be multiplied.

Thanks, it works great :yay: :yay:

Share this post


Link to post
Share on other sites

Btw to easily generate arrays of units, use list trigger_name and thislist on the trigger activation.

Eg 1:

trigger activated by east once, covering all east soldiers:

onActivation: {_x setSkill (0.4+random 0.4)} forEach thislist; east_units = +thislist

Eg 2:

trigger activated by east once, covering some area where you want to detect east soldiers

name: trig_zone_a

then from a script you can update the array at any time:

#loop
_zA = +list trig_zone_a
_cm = "Man" countType _zA
_ct = "Tank" countType _zA

?_cm+_ct>0: hint format ["%1 east soldiers and %2 tanks inside Zone A", _cm, _ct]
~60
goto "loop"

Share this post


Link to post
Share on other sites

Sorry that I reply to this very old thread..

But I need help.. I want to make that if an player (PvP mission) kills an enemy it will pay them.

There's an pay system in it to buy weapons. I want to create that if you kill an enemy you will get +100 money on variable money in intializeplayer.sqf

How can I do this the best?

Thanks in advance!

Sorry for this old thread..

Kind regards,

Brian

Share this post


Link to post
Share on other sites

It would have been better to post a new thread on this.

The answer to your question is unfortunately quite complicated due to something called locality.

Certain events (like a player dying) can only be detected reliably on a single machine (the machine of the player who was killed, i.e. the victim) due to the locality of killed eventhandlers. When you try to implement an auxilliary scoring system, you are trying to find out who killed a player on the victim's machine, then you really need to some how transfer your "currency" to the killer's machine in order for them to spend it (because until you do the killer's machine won't know they killed the victim). This can be done, normally by manually transmitting data over the network using the publicvariable command, these are notoriously unreliable when used incorrectly due to their low bandwidth priority versus game engine data and general inefficiency. There are other methods as well as publicvariable like using the position of a game logic (which is more reliable but less efficient bandwidth wise).

For multiplayer it's not good enough for your scoring system to work 95% of the time, because this will quickly upset players who find themselves robbed of kills. So you are faced with the challenge of creating an incredibly reliable synchronisation system with very little in the way of methods to efficiently and reliably transfer that data.

To actually test this out you really need a couple of PCs to actually watch debug information from your scripts when running a multiplayer game. Because of locality many things you take for granted in SP will work completely differently in MP or not at all.

Once you've got your head around locality. I suggest you read up about adding a killed eventhandler to a unit first, since this is what you need to link a victim to their killer. You would then need to add a script that monitors global score variables transmitted via publicvariable or some other means to control each player's score.

I am going to (shamelessly) recommend you read the editor guide included in my mod Modern War Crisis. The mod includes among other things a scripting framework to implement persistent in-game currency (a BLOPS style Create-a-Class system) and killstreak rewards for players. The editor guide goes into excruciating detail on how the framework operates at a low level, so even if you want to make your own from scratch, it's thoroughly useful.

Edited by *Zeewolf*

Share this post


Link to post
Share on other sites
It would have been better to post a new thread on this.

The answer to your question is unfortunately quite complicated due to something called locality.

Certain events (like a player dying) can only be detected reliably on a single machine (the machine of the player who was killed, i.e. the victim) due to the locality of killed eventhandlers. When you try to implement an auxilliary scoring system, you are trying to find out who killed a player on the victim's machine, then you really need to some how transfer your "currency" to the killer's machine in order for them to spend it (because until you do the killer's machine won't know they killed the victim). This can be done, normally by manually transmitting data over the network using the publicvariable command, these are notoriously unreliable when used incorrectly due to their low bandwidth priority versus game engine data and general inefficiency. There are other methods as well as publicvariable like using the position of a game logic (which is more reliable but less efficient bandwidth wise).

For multiplayer it's not good enough for your scoring system to work 95% of the time, because this will quickly upset players who find themselves robbed of kills. So you are faced with the challenge of creating an incredibly reliable synchronisation system with very little in the way of methods to efficiently and reliably transfer that data.

To actually test this out you really need a couple of PCs to actually watch debug information from your scripts when running a multiplayer game. Because of locality many things you take for granted in SP will work completely differently in MP or not at all.

Once you've got your head around locality. I suggest you read up about adding a killed eventhandler to a unit first, since this is what you need to link a victim to their killer. You would then need to add a script that monitors global score variables transmitted via publicvariable or some other means to control each player's score.

I am going to (shamelessly) recommend you read the editor guide included in my mod Modern War Crisis. The mod includes among other things a scripting framework to implement persistent in-game currency (a BLOPS style Create-a-Class system) and killstreak rewards for players. The editor guide goes into excruciating detail on how the framework operates at a low level, so even if you want to make your own from scratch, it's thoroughly useful.

Thanks mate.

I did used some of the killed eventhandler and stuff but didn't know how to create it with adding an new variable.

Will look into that modern war crisis as you said :)

Thank you!

Brian

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
Sign in to follow this  

×