jhonenglish 2 Posted February 3, 2021 Hello, im making a stealth mission where if my guys get detected they lose, but i want them to have a chance to kill the the ai who spotted them before he communicates to the rest of his fellow ai waht he saw, for this i tried to set the condition on my trigger Timeout for 20 sec, so that the condition of the guys being spotted by enemeis must happen for at least 20 sec before it triggers, the problem is that even if we kill the ai within a short time we are still considered spwaned. any suggestions how to make thai forget us after we killed the ai who spotted and there is no other ai around? Share this post Link to post Share on other sites
AZCoder 921 Posted February 3, 2021 try this https://community.bistudio.com/wiki/forgetTarget of course if the AI can still see you, their awareness will just change back quickly 2 Share this post Link to post Share on other sites
jhonenglish 2 Posted February 4, 2021 but how do i make them forget only when i killed the spotter in a certain amount of time Share this post Link to post Share on other sites
jhonenglish 2 Posted February 4, 2021 12 hours ago, AZCoder said: try this https://community.bistudio.com/wiki/forgetTarget of course if the AI can still see you, their awareness will just change back quickly but how do i make them forget only when i killed the spotter in a certain amount of time Share this post Link to post Share on other sites
ZaellixA 383 Posted February 4, 2021 Well, you can use an event handler for this purpose and try to make the whole group forget about the target. If they can still see the target, they will revert back to the previous (most probably aggressive) behavior. This could possibly look like (inside each unit's init field) // Add the event handler to the unit this addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Run the forgetTarget command for all units of the group (units (group _unit)) apply {_x forgetTarget _killer}; }]; Now, this is very naive and there's a lot of room for improvement. One major issue here is that the units will "forget" about the killer but not the rest of the units they "know about". So, this may serve as a base for further development, depending on your needs. If this is intended for solo ("lone wolf") SP missions it will most probably work quite OK for isolated groups. Otherwise, further refinement is needed. Furthermore, if you intend to use it with all AI units you should most probably find a better way (than the init field) to add the event handler to the units. Please note that the provided code snippet is not tested and it should be treated with caution. Feel free to ask for more help and/or clarifications if the need arises. 1 Share this post Link to post Share on other sites
jhonenglish 2 Posted February 4, 2021 11 hours ago, ZaellixA said: Well, you can use an event handler for this purpose and try to make the whole group forget about the target. If they can still see the target, they will revert back to the previous (most probably aggressive) behavior. This could possibly look like (inside each unit's init field) // Add the event handler to the unit this addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Run the forgetTarget command for all units of the group (units (group _unit)) apply {_x forgetTarget _killer}; }]; Now, this is very naive and there's a lot of room for improvement. One major issue here is that the units will "forget" about the killer but not the rest of the units they "know about". So, this may serve as a base for further development, depending on your needs. If this is intended for solo ("lone wolf") SP missions it will most probably work quite OK for isolated groups. Otherwise, further refinement is needed. Furthermore, if you intend to use it with all AI units you should most probably find a better way (than the init field) to add the event handler to the units. Please note that the provided code snippet is not tested and it should be treated with caution. Feel free to ask for more help and/or clarifications if the need arises. Thx, how do i get the unit and killer? these variables change cause any player can kill anu ai. ive thought maby to do somthing like this: ----------------------------- waitUntil {{alive _x} count units _myGroup == 0}; _enemy Group forgetTarget _myPlayer; ------------------------------- worked, but the problem is that now i need to define all the enemy groups and set a code for each: while {true} do { waitUntil {({alive _x} count units A == 0) or ({alive _x} count units B == 0)}; A forgetTarget player1; B forgetTarget player1; } Share this post Link to post Share on other sites
ZaellixA 383 Posted February 5, 2021 Well, if you have a look at the event handler you'll see that they area passed to the code that will be run when the event handler is called automatically. So, all you have to do is get them as input parameters (this is what the params["_unit", "_killer"] line does). Just to clarify a bit, the event handler is first "added" to the unit (in the example above this refers to the unit as it is given in the init field) and is called when the unit is killed (there are other event handlers which are called on different "events" - this is what the first variable "Killed" defines). The code provided as the second argument will be executed when the handler is called/triggered (please don't confuse the event handler "triggering" with the triggers used in the game, they are not the same thing). For each event handler some variables are passed as input parameters to the code. In the "Killed" event handler the first two are the unit that got killed (_unit) and the unit that did the killing (_killer). So, this is how you get the units. So, the first line in the code (to be executed when the event handler is called) is to get the two units. In the next (and last) line I get the units in the group of the unit that was killed (in an array) and apply a command (forgetTarget) to each one of them. So, when the unit is killed, all the units in its group will "forget" the unit that did the killing (of course if the unit is visible, they will immediately go back to "know" about it). As I said, this is a wee bit naive and rather unrealistic. Nevertheless, I believe that this a quite good way to tackle the issue. In order to add the event handler to all units you could possibly do something like (the example is for all units that are not in the player's side) // Get all units that are not in the player's side private _enemies = allUnits select {!((side _x) isEqualTo playerSide)}; // Add the event handler to all the units _enemies apply { _x addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Run the forgetTarget command for all units of the group (units (group _unit)) apply {_x forgetTarget _killer}; }]; }; Now, of course you could code a more complex behavior than that. One example could be to make all units on the side of the killed unit to forget about the killer. In this way you could make all units on the side of the killed unit to forget about the unit that did the killing. In this way, all units (or someone in their group) that do not have line of sight to the killer will lose track of him, with the units (and their groups) that can see the killer keep up the fight (they will forget and immediately go back to "know" again). This could be done like (presenting only the code for the event handler) _x addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Get the units on the side of the dead unit private _enemies = allUnits select {(side _x) isEqualTo (side _unit)}; // Run the forgetTarget command for all units of the group _enemies apply {_x forgetTarget _killer}; }]; So, in this way, you apply the forgetTarget command to all the units on the side of the dead unit. One more thing you could possibly do is to apply the forgetTarget command to all the units on the side of the dead unit for all units in the group of the killer (I believe that if a unit knows about another unit it automatically knows about all the units in the spotted unit's group. I am not 100% sure about it though so you will have to check that). This could look like (again I only present the code for the event handler) _x addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Get the units on the side of the dead unit private _enemies = allUnits select {(side _x) isEqualTo (side _unit)}; // Run the forgetTarget command for all units of the group _enemies apply { // Get the current enemy in a variable to be used in the forEach below private _curEnemy = _x; // Get the units in the killer's group private _killGroup = units (group _killer); // Apply the forget target for each unit in killer's group { // Forget the unit of killer's group _curEnemy forgetTarget _x; } forEach _killGroup; }; }]; Please note that all code presented here is not tested and should be treated with caution. I hope that this provides some help and clarification somehow. Do not hesitate to ask again if this does not solve your problem, help or you may need further assistance. 1 Share this post Link to post Share on other sites
jhonenglish 2 Posted February 6, 2021 21 hours ago, ZaellixA said: Well, if you have a look at the event handler you'll see that they area passed to the code that will be run when the event handler is called automatically. So, all you have to do is get them as input parameters (this is what the params["_unit", "_killer"] line does). Just to clarify a bit, the event handler is first "added" to the unit (in the example above this refers to the unit as it is given in the init field) and is called when the unit is killed (there are other event handlers which are called on different "events" - this is what the first variable "Killed" defines). The code provided as the second argument will be executed when the handler is called/triggered (please don't confuse the event handler "triggering" with the triggers used in the game, they are not the same thing). For each event handler some variables are passed as input parameters to the code. In the "Killed" event handler the first two are the unit that got killed (_unit) and the unit that did the killing (_killer). So, this is how you get the units. So, the first line in the code (to be executed when the event handler is called) is to get the two units. In the next (and last) line I get the units in the group of the unit that was killed (in an array) and apply a command (forgetTarget) to each one of them. So, when the unit is killed, all the units in its group will "forget" the unit that did the killing (of course if the unit is visible, they will immediately go back to "know" about it). As I said, this is a wee bit naive and rather unrealistic. Nevertheless, I believe that this a quite good way to tackle the issue. In order to add the event handler to all units you could possibly do something like (the example is for all units that are not in the player's side) // Get all units that are not in the player's side private _enemies = allUnits select {!((side _x) isEqualTo playerSide)}; // Add the event handler to all the units _enemies apply { _x addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Run the forgetTarget command for all units of the group (units (group _unit)) apply {_x forgetTarget _killer}; }]; }; Now, of course you could code a more complex behavior than that. One example could be to make all units on the side of the killed unit to forget about the killer. In this way you could make all units on the side of the killed unit to forget about the unit that did the killing. In this way, all units (or someone in their group) that do not have line of sight to the killer will lose track of him, with the units (and their groups) that can see the killer keep up the fight (they will forget and immediately go back to "know" again). This could be done like (presenting only the code for the event handler) _x addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Get the units on the side of the dead unit private _enemies = allUnits select {(side _x) isEqualTo (side _unit)}; // Run the forgetTarget command for all units of the group _enemies apply {_x forgetTarget _killer}; }]; So, in this way, you apply the forgetTarget command to all the units on the side of the dead unit. One more thing you could possibly do is to apply the forgetTarget command to all the units on the side of the dead unit for all units in the group of the killer (I believe that if a unit knows about another unit it automatically knows about all the units in the spotted unit's group. I am not 100% sure about it though so you will have to check that). This could look like (again I only present the code for the event handler) _x addEventHandler["Killed", { // Get the unit and the killer params["_unit", "_killer"]; // Get the units on the side of the dead unit private _enemies = allUnits select {(side _x) isEqualTo (side _unit)}; // Run the forgetTarget command for all units of the group _enemies apply { // Get the current enemy in a variable to be used in the forEach below private _curEnemy = _x; // Get the units in the killer's group private _killGroup = units (group _killer); // Apply the forget target for each unit in killer's group { // Forget the unit of killer's group _curEnemy forgetTarget _x; } forEach _killGroup; }; }]; Please note that all code presented here is not tested and should be treated with caution. I hope that this provides some help and clarification somehow. Do not hesitate to ask again if this does not solve your problem, help or you may need further assistance. Thanks alot, im only just started coding so htis is alot of help! 1 Share this post Link to post Share on other sites
Play3r 147 Posted February 12, 2021 Nm @ZaellixA Nm = Never mind. I wrote my answer in the wrong topic 😁 1 Share this post Link to post Share on other sites