Jump to content
doubleblind

Delete Destroyed Building

Recommended Posts

Is there a specific way to delete destroyed (script-spawned) buildings such as cargo posts or cargo house? I'm trying to write a cleanup script but it fails to delete buildings such as the cargo post if they've been destroyed.

Share this post


Link to post
Share on other sites

When a building is destroyed, it is disappeared and a new building (a ruined version) is created by the engine in its place.

 

_allruins = allMissionObjects 'Ruins';

Share this post


Link to post
Share on other sites

Anyone have any examples or experience using this new event handler BuildingChanged?? I'm curious but sadly I haven't found much documentation outside of the biki.  https://community.bistudio.com/wiki/Arma_3:_Event_Handlers/addMissionEventHandler#BuildingChanged

 

I wanted to have a vip set of buildings, hotel, church etc. that when destroyed it will link to a reputation script to punish players for destroying structures. Stuck on this issue...

 

The basic idea is to just add new mission handler and subtract reputation then. Then check how often it's called, whether it covers edge cases and whether the "isRuin" flag works as expected, since that could be used to add extra penalty for fully destroying a building. Then it's just a case of adding an array which gives you the mapping from building string to the modifier.

Share this post


Link to post
Share on other sites

For example, if you place in a trigger, always true (instead of this):

addMissionEventHandler ["buildingChanged",{hint format ["%1", _this]}]

then run the game, place a charge not too far from Stratis airport tower, and blow it, you obtain:

[17d12ff1600# 524599: airport_tower_f.p3d,17d213d2b00# 1780149: airport_tower_dam_f.p3d,false]

 

Unfortunately, there is no data for the unit who blew the charge.

 

My workaround:

{ _x addEventHandler ["hit", {(_this select 0) setVariable ["guilty",(_this select 1)]} ] } forEach (nearestObjects [player, ["house"],200]);
addMissionEventHandler ["buildingChanged",{hint format ["%1",(_this select 0) getVariable ["guilty",objNull]]}]

 

Just pay attention for the objects you want to survey with the hit EH (here house within 200m at position start of the player. You can add a loop scouting for houses or else while in game. I hope this is understandable.

 

Share this post


Link to post
Share on other sites
7 hours ago, breech99 said:

Anyone have any examples or experience using this new event handler BuildingChanged?? I'm curious but sadly I haven't found much documentation outside of the biki.  https://community.bistudio.com/wiki/Arma_3:_Event_Handlers/addMissionEventHandler#BuildingChanged

 

I wanted to have a vip set of buildings, hotel, church etc. that when destroyed it will link to a reputation script to punish players for destroying structures. Stuck on this issue...

 

The basic idea is to just add new mission handler and subtract reputation then. Then check how often it's called, whether it covers edge cases and whether the "isRuin" flag works as expected, since that could be used to add extra penalty for fully destroying a building. Then it's just a case of adding an array which gives you the mapping from building string to the modifier.

 

Hey Breech, I've been using BuildingChanged on a database script of mine (I'm making destroyed map objects persistent).  That EH does not return who destroyed it - only new object, old object and if its ruined.  I suggest adding a killed event handler to the targets of interest to trigger what your going for.  Keep in mind, Killed may fire when its transitioning between new and partially destroyed, however it usually only happens when this is making a gaping hole in the side.

Share this post


Link to post
Share on other sites
On 4/3/2017 at 7:47 PM, doubleblind said:

@killzone_kid Thank you! Looks like that EH was just released - I didn't even know it exists!

 

The issue with that EH is it returns on every building destroy phase.  Here is my workaround for one of my database scripts.

 

On initServer.sqf

addMissionEventHandler ["BuildingChanged",{[_this select 0,_this select 1,_this select 2] call db_fnc_mapbuildings;}]; //Handles db_fnc_mapbuildings

On db_fnc_mapbuildings (or whatever name you give it in your functions libary)

if (isnil "MapDamage") then {
	MapDamage = [];			
}; //Create our MD variable if we haven't already.

private _object = _this select 0;
private _newobject = _this select 1;
private _ruin = _this select 2;
private _netID = netid _object;

if (_ruin) then {
//It's completely destroyed, based on the return from the mission event handler.

	//If its not a native map object, see if it's a product of a previously recorded destruction.
	if ((netid _object find "-") == -1) then { //Not a native.  
		if !((MapDamage select {_x select 1 == netid _object}) isEqualTo []) then {
			_oldobject = ((MapDamage select {_x select 1 == netid _object}) select 0) select 0;//This should return the netID of its original object
			
			//This code here will run if the item passed was not native, but was a product of a native object decaying into ruin.
			
		} else {
			
			//This code here will run if it was not a map object and not a product of a map object decaying into ruin.
			//AKA a script placed item dieing completely.
			//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
			
		};
	} else { 
		//It is a native object being placed as ruined.
	};
} else {
//It's only partially damaged.
	//If its not a native map object, see if it's a product of a previously recorded destruction.
	if ((netid _object find "-") == -1) then { 
		if !((MapDamage select {_x select 1 == netid _object}) isEqualTo []) then {
			_oldobject = str (MapDamage select {_x select 1 == netid _object}) select 0;
			
			//Its a native map object passing through another phase of its destruction, but is not ruined yet.
			
		} else {
		
			//It was never a native map object and it's not completely ruined.
			//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		};
	} else {
		//A native map object produced a non-native object.
		MapDamage pushBack [netid _object,netid _newobject];

	};
};

I've tested it lightly, but it hasn't seen much usage yet.  The sections your interested in have a bunch of Xes in it.

Even though your not interested in half-dead structures, the whole thing is needed to keep track of what are byproducts of the native map structures.

 

Hope that helps!

Share this post


Link to post
Share on other sites
16 hours ago, wyattwic said:

 

Hey Breech, I've been using BuildingChanged on a database script of mine (I'm making destroyed map objects persistent).  That EH does not return who destroyed it - only new object, old object and if its ruined.  I suggest adding a killed event handler to the targets of interest to trigger what your going for.  Keep in mind, Killed may fire when its transitioning between new and partially destroyed, however it usually only happens when this is making a gaping hole in the side.

Yes, definitely the idea. For other event handler conditions I have a addEventHandler and  a RemoveEventHandler to prevent spamming. Just marking for destroyed building condition and not every point of structure damage. Would only be applied to like a church, hotel, uncommon structures around a mission area like a weapon cache or something.

Share this post


Link to post
Share on other sites

Then it could be easy to use the above block of code I gave, and in the section that correctly applies to the structures your looking for do something like "if (typeof _object in ["VIPbuilding1","VIPbuilding2","so and so on") then {whatever takes away from the rating for you}".

 

Good luck!  I'd love to see the final code!

 

Share this post


Link to post
Share on other sites

@pierremgi 

What are you talking about "There is no way to check who blew the charge".

The "HandleDamage" event handler for instance. 

Quote

source: Object - The source unit that caused the damage.

 

Share this post


Link to post
Share on other sites
1 hour ago, Midnighters said:

@pierremgi 

What are you talking about "There is no way to check who blew the charge".

The "HandleDamage" event handler for instance. 

 

Welcome after battle! You should read my post again. It was in the buildingChanged context.

I took time to add a workaround with a Hit EH code which works fine.

HandleDamage has also a source, but I think Hit EH is sufficient enough, Killed works also for a total destruction. On the other hand, I didn't test with handleDamage as far as it seems to me there is no hitpoint on a building.

Share this post


Link to post
Share on other sites
3 hours ago, pierremgi said:

Welcome after battle! You should read my post again. It was in the buildingChanged context.

I took time to add a workaround with a Hit EH code which works fine.

HandleDamage has also a source, but I think Hit EH is sufficient enough, Killed works also for a total destruction. On the other hand, I didn't test with handleDamage as far as it seems to me there is no hitpoint on a building.

Why check buildingChanged for destruction if you can just use hit or handleDamage , i dont follow. 

Share this post


Link to post
Share on other sites

It was just an example answering at the 4 posts above mine, about this EH. You're right, EH hit can do the trick alone.

The only difference is, with a "2 level" EH like on my example, you're waiting for a different aspect of the building. So, too little hits are not taken into account. Generally, you have 1 or 2 steps before a complete destruction. This could help for penalty on players.

The "straight-in" single EH to remove a destroyed building is "killed".

  • Like 1

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

×