I don't think destroyable buildings exist anywhere, and I can't really think of a good way to do them convincingly with tiles as opposed to placeables (I have in mind your remark about addressing the static nature of tilesets, above). We did do something similar to this, however, in a forested area, where the players were complaining about trees obstructing their view. We set the trees to be destroyable via fire spells through an area-specific spellhook.Several scorch marks and fires are spawned in randomly around the spot where the tree was. Pyromania is all in good fun, after all.
'> Here's the code for the spell hook, I imagine you could do much the same with building/ruined building places and rubble:
#include "hg_inc"
#include "x2_inc_switches"
void DestroyFire (object oFire) {
SetPlotFlag(oFire, FALSE);
DestroyObject(oFire);
}
void DestroyTree (object oTree) {
SetPlotFlag(oTree, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(EffectDeath()), oTree);
DestroyObject(oTree, 0.5);
}
void SpawnFire (location lLoc) {
object oObj;
switch (Random(4)) {
case 0: oObj = CreateObject(OBJECT_TYPE_PLACEABLE, "ph_burningcanopy", lLoc); break;
case 1: oObj = CreateObject(OBJECT_TYPE_PLACEABLE, "ph_burningcanop2", lLoc); break;
case 2: oObj = CreateObject(OBJECT_TYPE_PLACEABLE, "ph_burningcanop3", lLoc); break;
case 3: oObj = CreateObject(OBJECT_TYPE_PLACEABLE, "ph_burningcanop4", lLoc); break;
}
DelayCommand(IntToFloat(10 + Random(20)), DestroyFire(oObj));
}
void SpawnBlaze (vector vVec) {
object oArea = GetArea(OBJECT_SELF);
vector vVecNew;
location lLoc;
int i, nFires = 2 + d4();
for (i = 0; i < nFires; i++) {
vVecNew = Vector(vVec.x + (Random(11) - 5), vVec.y + (Random(11) - 5), vVec.z + ((Random(11) - 5) / 10.0));
lLoc = Location(oArea, vVecNew, 0.0);
SpawnFire(lLoc);
}
}
void main() {
int nSpellId = GetSpellId();
float fRadius;
switch (nSpellId) {
case SPELL_FIREBALL: fRadius = 20.0; break;
case SPELL_FIRE_STORM: fRadius = 30.0; break;
case SPELL_FLAME_STRIKE: fRadius = 15.0; break;
default: return;
}
object oTarget = GetSpellTargetObject();
location lTarget = GetSpellTargetLocation();
if (GetIsObjectValid(oTarget))
lTarget = GetLocation(oTarget);
float fDelay, fMaxDist = fRadius / 2.0;
vector vTarget, vSpell = GetPositionFromLocation(lTarget);
for (oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_PLACEABLE);
GetIsObjectValid(oTarget);
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lTarget, FALSE, OBJECT_TYPE_PLACEABLE)) {
if (!GetPlotFlag(oTarget) || GetFortitudeSavingThrow(oTarget) < 80)
continue;
vTarget = GetPosition(oTarget);
if (fabs(vTarget.x - vSpell.x) > fMaxDist || fabs(vTarget.y - vSpell.y) > fMaxDist)
continue;
fDelay = 1.0 + (Random(20) / 10.0);
DelayCommand(fDelay, ApplyVisualAtLocation(VFX_FNF_FIREBALL, GetLocation(oTarget)));
DelayCommand(fDelay + 0.2, SpawnBlaze(vTarget));
DelayCommand(fDelay + 0.1, DestroyTree(oTarget));
}
}
Funky