Jump to content

Recommended Posts

How does one use the MissionEventHandler "BuildingChanged"?

I'm currently trying to make it so that when a building is damaged (and changes into its partly damaged form) a trigger is activated and props inside the building are deleted. Unfortunately, I'm having real trouble getting the script to work.

Please help!

Share this post


Link to post
Share on other sites

Are you actually using a mission trigger or is that just the way you are describing how you want it to happen?

Share this post


Link to post
Share on other sites

@Tankbuster
I was describing what I want to happen.

I was trying to add a condition to a trigger so that when the named building gets damaged and changes to the damaged building model, my trigger would fire.

But yeah, couldn't get it to work.

Share this post


Link to post
Share on other sites

You need to post your code. On the face of it, this should be fairly simple. The EH fires. One of it's sent data items is the building itself. From that, delete everything that isn't a man object inside the boundingbox

Share this post


Link to post
Share on other sites

@Tankbuster
So I was trying to follow the BuildingChanged Mission Event Handler

Condition: addMissionEventHandler [ "BuildingChanged",  {  "FIA_StoneShedGrey1_1",   <----------------------------- Here is where I get stuck, I don't understand how to use the addMissionEventHandler for BuildingChanged. (It shouldn't be a very complicated event)

On Activation: { deleteVehicle _x } forEach [ Object1_1, Object1_2, Object1_3, Object1_4, Object1_5, Object1_6 ];

Share this post


Link to post
Share on other sites

You are using a trigger. Unless someone else has better ideas, I would not use a trigger for this. You've fundamentally misunderstood how to apply the eventhandler.

 

The eventhandler needs to be put on the building itself. Look at the nearestbuilding family of commands ( and similar commands that return a building object) for how to get all the building objects, for example...

 

 

_mybuilding = nearestbuilding player;
_mybuilding addmissioneventhandler ["BuildingChanged", {params ["_o", "_buildingdamaged"]; **run some script to find and delete all objects inside _buildingdamaged here**}];

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

@Tankbuster
Ok, I've given it a go.

I have used the Edit Terrain Object Module to name the building which has the objects inside, because it is a map building.
The building has been named FIA_StoneShedGrey1_1 in the Object Variable Name section.

 

What I do not understand is that you have two names for the same building. (e.g. _mybuilding and _buildingdamaged)

I have tried creating a simple .sqf which will delete the named objects within the building...

//destroyProp.sqf

{ deleteVehicle _x } forEach [ P1, P2, P3, P4, P5 ];

Then I added this line of code to the Object Init of FIA_StoneShedGrey1_1

addmissioneventhandler [ "BuildingChanged", { params [ "_o", "FIA_StoneShedGrey1_1" ]; call "destroyProp.sqf" } ];

This would just give me a "Local Variable in Global Space" error.

Share this post


Link to post
Share on other sites

In my example, _buildingdamaged is a variable that contains a reference to the damaged building object. It is created by the EH. You can't put your own data in there.

I think you need to read up on what variables are and do in this game.

Share this post


Link to post
Share on other sites

@Tankbuster

 

On ‎8‎/‎12‎/‎2019 at 10:21 AM, Tankbuster said:

In my example, _buildingdamaged is a variable that contains a reference to the damaged building object. It is created by the EH. You can't put your own data in there.

I think you need to read up on what variables are and do in this game.

I now realise what you mean. When the original building gets damage, it basically gets "deleted" and a new building is placed in its position with the damage/destroyed model. Obviously, that now means that the "new" building in its place is not called the same thing as the "deleted" building.

I see now that you were showing me that I need to have a script which will name the "new" building which is now in the place of the "old" one.

Share this post


Link to post
Share on other sites

Sort of. Not all buildings show destruction like that. Many don't show any visual evidence of being damaged at all.

 

But here's something else to think about. This building you are watching for dstruction.. is there only one, or do you do this across many buildings? Also, how did you place the prop objects?

Share this post


Link to post
Share on other sites

@Tankbuster
Its about 4 building in a small area on a hill (small FIA stockpile/camp).
 

Two of the buildings have about 20 - 40 prop objects in. They are mostly simple objects, so they don't move. It follows very heavily the (style?) of the Laws of War campaign, which has a lot of props in the buildings to make it seem more lived in.

I just delete all of the objects in the specific building when it changes its state (destroyed).

Share this post


Link to post
Share on other sites
2 hours ago, rkemsley said:

@Tankbuster
Its about 4 building in a small area on a hill (small FIA stockpile/camp).
 

Two of the buildings have about 20 - 40 prop objects in. They are mostly simple objects, so they don't move. It follows very heavily the (style?) of the Laws of War campaign, which has a lot of props in the buildings to make it seem more lived in.

I just delete all of the objects in the specific building when it changes its state (destroyed).

 

I was looking for a solution for this exact problem a few days ago. I decided to overdo it by spicing the building destruction a bit. This is what I came up with:

b3lxFN_BldExpl = {
	params ["_bld","_r"];
	if (isNil "_r") then {_r = 20};
	private _houses = _bld nearobjects ["house",_r];
	private _roads =  _bld nearobjects ["road",_r];
	private _all = _bld nearobjects _r;
	private _objs = _all - (_houses + _roads);
	{deletevehicle _x} forEach (_all - [_bld]);	
	private _latF = {params ["_spr"];((random (_spr*100))/100) - ((random (_spr*100))/100)};
	for "_i" from 0 to 20 do {
		private _lats = 10;//SPRAY AMOUNT
		private _latx = [_lats] call _latF; 
		private _laty = [_lats] call _latF; 
		private _debris = "Land_CinderBlock_01_F" createvehicle (_bld getpos [5,random 360]);
		_debris setdir (random 360);
		_debris setvelocity [_latx,_laty,20 + random 5];		
	};
	private _hpos = [(getpos _bld) select 0, (getpos _bld) select 1, 30];
	for "_i" from 0 to 20 do {
		private _lats = 5;//SPRAY AMOUNT
		private _latx = [_lats] call _latF; 
		private _laty = [_lats] call _latF; 
		private _papers = (selectrandom ["Leaflet_05_Old_F","Leaflet_05_F"]) createvehicle (_hpos getpos [5,random 360]);
		_papers setdir (random 360);
		_papers setvelocity [_latx,_laty, 30 + random 50];
	};	

};

addMissionEventHandler ["BuildingChanged", { 
 params ["_previousObject", "_newObject", "_isRuin"]; if (_isRuin) then {[_newObject,20] call b3lxFN_BldExpl};
}];


	

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Ok, I found a really simple solution which requires only two triggers and a 100cm sphere

Sphere_StoneShedGrey1_1
Init: StoneShedGrey1_1 = nearestObject [ this, "Land_i_Stone_Shed_V1_F" ];

Trigger_1_1StoneShedGrey1_1
Condition: !alive StoneShedGrey1_1;
On Activation: StoneShedGrey1_2 = nearestObject [ Sphere_StoneShedGrey1_1, "Land_i_Stone_Shed_V1_dam_F" ];
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part01" select 0);
{ _x hideObjectGlobal false } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part02" select 0);

Trigger_1_2StoneShedGrey1_1
Condition: !alive StoneShedGrey1_2
On Activation: { deleteVehicle _x } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part01" select 0);
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part02" select 0);
{ _x hideObjectGlobal false } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part03" select 0);

Seems to have work consistently so far. However, untested in multiplayer.
Thank Eden Editor for its obscure tricks!! 

Share this post


Link to post
Share on other sites

For more complicated buildings I've been trying to write a script which will detect which Hitzone has been destroyed, then remove the objects accordingly.

Basically, I'm trying to make it so that when one side of the building it will be detected using getHitPointDamage. So it will only activate if getHitPointDamage gives a 1.

Here's my trigger, but I am struggling to write a piece of code which actually works.

{ !alive StoneHouseGrey1_1 } && { ( StoneHouseGrey1_1 getHitPointDamage "Dam_1" ) < 1 };

The theory should work, its just being able to put it down into a piece of code which actually works...

Share this post


Link to post
Share on other sites

Is this part really necessary?

1 hour ago, rkemsley said:

!alive StoneHouseGrey1_1

Share this post


Link to post
Share on other sites
8 minutes ago, b3lx said:

Is this part really necessary?

Nope, managed to get it working.

  • Like 2

Share this post


Link to post
Share on other sites
13 hours ago, rkemsley said:

Nope, managed to get it working.

Care to share the way you made it work for future reference to people who may face the same issue?

  • Like 1

Share this post


Link to post
Share on other sites

@ZaellixA
Yes, of course!

So, for simple buildings which only have a damaged state, then a ruined state, (e.g. Land_i_Stone_Shed_V1_F or Land_u_Addon_01_V1_F) you can use this method. (Probably a little ugly, but works consistently).

Quote

Sphere_StoneShedGrey1_1
Init: StoneShedGrey1_1 = nearestObject [ this, "Land_i_Stone_Shed_V1_F" ];

Trigger_1_1StoneShedGrey1_1
Condition: !alive StoneShedGrey1_1;
On Activation: StoneShedGrey1_2 = nearestObject [ Sphere_StoneShedGrey1_1, "Land_i_Stone_Shed_V1_dam_F" ];
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part01" select 0);
{ _x hideObjectGlobal false } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part02" select 0);

Trigger_1_2StoneShedGrey1_1
Condition: !alive StoneShedGrey1_2
On Activation: { deleteVehicle _x } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part01" select 0);
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part02" select 0);
{ _x hideObjectGlobal false } forEach (getMissionLayerEntities "StoneShedGrey1_1 - Part03" select 0);


For more complicated buildings, (e.g. Land_i_Stone_HouseSmall_V1_F or Land_i_House_Small_03_V1_F) you will have to use this method. (Similar to the first one, but with a few added stages).

Quote

Sphere_StoneHouseGrey1_1
Init: StoneHouseGrey1_1 = nearestObject [ this, "Land_i_Stone_HouseSmall_V1_F" ];

Trigger_1_1StoneHouseGrey1_1
Condition: !alive StoneHouseGrey1_1;
On Activation: StoneHouseGrey1_2 = nearestObject [ Sphere_StoneHouseGrey1_1, "Land_i_Stone_HouseSmall_V1_dam_F" ];

Trigger_1_2StoneHouseGrey1_1
Condition: StoneHouseGrey1_2 getHit "Dam_1" >= 1;
On Activation: StoneHouseGrey1_2 = nearestObject [ Sphere_StoneHouseGrey1_1, "Land_i_Stone_HouseSmall_V1_dam_F" ];
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part01" select 0);
{ _x hideObjectGlobal false } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part02" select 0);

Trigger_1_3StoneHouseGrey1_1
Condition: StoneHouseGrey1_2 getHit "Dam_2" >= 1;
On Activation: StoneHouseGrey1_2 = nearestObject [ Sphere_StoneHouseGrey1_1, "Land_i_Stone_HouseSmall_V1_dam_F" ];
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part03" select 0);
{ _x hideObjectGlobal false } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part04" select 0);

Trigger_1_4StoneHouseGrey1_1
Condition: !alive StoneHouseGrey1_2;
On Activation: { deleteVehicle _x } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part01" select 0);
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part02" select 0);
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part03" select 0);
{ deleteVehicle _x } forEach (getMissionLayerEntities "StoneHouseGrey1_1 - Part04" select 0);

 

Could be tidied up somewhat, but it works consistently as a first draft.

 

 

If you need any help understanding what is going on, feel free to ask :)

  • Like 2

Share this post


Link to post
Share on other sites

Oh, after some testing, this method does not work properly if you are pre damaging a map building which isn't damaged (if that makes sense??)...
For example, using the ModuleEditTerrainObject_F module.

It basically damages the building when the map loads up. So you need to name the initial (undamaged) building, then get a trigger to name it again when it gets "damaged" (basically destroying the initial building). It a strange method, but it does make sense.

  • Like 2

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

×