652 lines
28 KiB
Plaintext
652 lines
28 KiB
Plaintext
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Olander's Siege System Include File
|
|
// os_inc
|
|
// by Don Anderson
|
|
// dandersonru@msn.com
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include "prc_inc_spells"
|
|
//#include "x0_i0_spells"
|
|
#include "x0_i0_position"
|
|
|
|
/******************************************************************************/
|
|
//::CONSTANTS
|
|
|
|
//Siege Weapon Types Tags
|
|
const string SIEGEARBALEST_LGT = "SiegeArbalestLgt";//Light Spear Siege
|
|
const string SIEGEARBALEST_HVY = "SiegeArbalestHvy";//Heavy Spear Siege
|
|
const string SIEGEBRICOLE = "SiegeBricole";//Light Stone Siege
|
|
const string SIEGECATAPULT_LGT = "SiegeCatapultLgt";//Fire and Acid Grenades
|
|
const string SIEGECATAPULT_HVY = "SiegeCatapultHvy";//Fire and Acid Grenades
|
|
const string SIEGECOUILLARD = "SiegeCouillard";//Heavy Stone Siege
|
|
const string SIEGEONAGER = "SiegeOnager";//Field Spread Effects like Oil and Caltrops
|
|
const string SIEGEPERRIERE = "SiegePerriere";//Medium Stone Siege
|
|
|
|
//Control Switch and Supply Distances
|
|
const float SIEGE_SWITCH = 60.0;
|
|
const float SIEGE_SUPPLY = 15.0;
|
|
|
|
//Siege Weapon Ranges (Max and Min)
|
|
const float MAXRANGE_SIEGEARBALEST_LGT = 30.0;
|
|
const float MINRANGE_SIEGEARBALEST_LGT = 0.0;
|
|
const float MAXRANGE_SIEGEARBALEST_HVY = 50.0;
|
|
const float MINRANGE_SIEGEARBALEST_HVY = 0.0;
|
|
const float MAXRANGE_SIEGEBRICOLE = 60.0;
|
|
const float MINRANGE_SIEGEBRICOLE = 20.0;
|
|
const float MAXRANGE_SIEGECATAPULT_LGT = 40.0;
|
|
const float MINRANGE_SIEGECATAPULT_LGT = 15.0;
|
|
const float MAXRANGE_SIEGECATAPULT_HVY = 60.0;
|
|
const float MINRANGE_SIEGECATAPULT_HVY = 15.0;
|
|
const float MAXRANGE_SIEGECOUILLARD = 90.0;
|
|
const float MINRANGE_SIEGECOUILLARD = 30.0;
|
|
const float MAXRANGE_SIEGEONAGER = 60.0;
|
|
const float MINRANGE_SIEGEONAGER = 30.0;
|
|
const float MAXRANGE_SIEGEPERRIERE = 75.0;
|
|
const float MINRANGE_SIEGEPERRIERE = 30.0;
|
|
|
|
//Load and Fire Times(Complete Cycle)
|
|
const float TIME_SIEGEARBALEST_LGT = 15.0;
|
|
const float TIME_SIEGEARBALEST_HVY = 15.0;
|
|
const float TIME_SIEGEBRICOLE = 30.0;
|
|
const float TIME_SIEGECATAPULT_LGT = 30.0;
|
|
const float TIME_SIEGECATAPULT_HVY = 20.0;
|
|
const float TIME_SIEGECOUILLARD = 15.0;
|
|
const float TIME_SIEGEONAGER = 25.0;
|
|
const float TIME_SIEGEPERRIERE = 30.0;
|
|
|
|
//Ammunintion Types
|
|
const int KEG = 1; //Siege Keg
|
|
const int FIRE = 2; //Fire Grenade
|
|
const int ACID = 3; //Acid Grenade
|
|
const int CALTROPS = 4; //Onager Caltrops Spread
|
|
const int OIL = 5; //Onager Oil Grenade
|
|
const int STONE = 6; //Siege Stone
|
|
const int HURL_ROCK = 471; //773Siege Stone (This is the Spell.2da row for this spell effect)
|
|
const int SPEAR = 7; //Arbalest Spear
|
|
const int BOLT = 794; //Arbalest Spear (This is the Spell.2da row for this spell effect)
|
|
|
|
const string ITEM_ACID_GRENADE = "ITCatapultAcid";
|
|
const string ITEM_FIRE_GRENADE = "ITCatapultFire";
|
|
const string ITEM_OIL_GRENADE = "ITOnagerOil";
|
|
const string ITEM_CAL_GRENADE = "ITOnagerCaltrops";
|
|
const string ITEM_SIEGE_STONE = "ITSiegeStone";
|
|
const string ITEM_ARB_SPEAR = "ITArbalestSpear";
|
|
|
|
//Blast Radius Per Ammunition Type
|
|
const float KEG_RADIUS = 10.0;
|
|
const float FIRE_RADIUS = 10.0;
|
|
const float ACID_RADIUS = 10.0;
|
|
const float STONE_RADIUS = 3.0;
|
|
const float SPEAR_RADIUS = 3.0;
|
|
const float SIEGE_ERRANT = 0.05;//This is the Error over Distance for Accuracy
|
|
//NOTE: Oil, and Caltrops are Per the AOE Spells
|
|
|
|
//Bludgeoning/Piercing/Slashing Blast Modifiers
|
|
const int B_MODIFIER = 16;//DC vs. D20 to avoid damage from ground spray
|
|
const int P_MODIFIER = 16;//DC vs. D20 to avoid damage from ground spray
|
|
const int S_MODIFIER = 12;//DC vs. D20 to avoid damage from ground spray
|
|
|
|
//::CONSTANTS
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
//::PROTOTYPES
|
|
|
|
//See below on each function for more information
|
|
|
|
// * ARTILLERY
|
|
void CreateFieldEffect(location lLoc, int nAmmo);
|
|
void FireBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo);
|
|
void AcidBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo);
|
|
void StoneBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo);
|
|
void OilBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo);
|
|
void ChokeBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo);
|
|
void CaltropSpread(location lLoc,float fImpactDelay,effect eImpact,int nSpell);
|
|
void SpearBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump,int nSpell,float fRadius,int nAmmo);
|
|
void SetFacingObject(object oTarget);
|
|
void ActivateSwitch();
|
|
void ActivateSiege();
|
|
void DeactivateSiege();
|
|
void InitiateSiege(object oSelf, location lLoc);
|
|
|
|
//::PROTOTYPES
|
|
/******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
//:: ARTILLERY FUNCTIONS
|
|
|
|
//Makes ground effects after siege artillery
|
|
void CreateFieldEffect(location lLoc, int nAmmo)
|
|
{
|
|
//Create a Scorchmark
|
|
if (nAmmo == KEG || nAmmo == FIRE || nAmmo == STONE)
|
|
{
|
|
object oScorch = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_weathmark",lLoc);
|
|
DelayCommand(60.0,DestroyObject(oScorch));
|
|
}
|
|
//Create a Dust Plume
|
|
if (nAmmo == KEG || nAmmo == FIRE || nAmmo == STONE)
|
|
{
|
|
object oPlume = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_dustplume",lLoc);
|
|
DelayCommand(20.0,DestroyObject(oPlume));
|
|
}
|
|
//Create a Small Flame
|
|
if (nAmmo == KEG || nAmmo == FIRE)
|
|
{
|
|
object oFlame = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_flamemedium",lLoc);
|
|
DelayCommand(15.0,DestroyObject(oFlame));
|
|
}
|
|
//Create Oil Marker
|
|
if (nAmmo == OIL)
|
|
{
|
|
object oOil = CreateObject(OBJECT_TYPE_PLACEABLE,"siegeoilmarker",lLoc);
|
|
DelayCommand(30.0,DestroyObject(oOil));
|
|
}
|
|
}
|
|
|
|
//Fire Grenade
|
|
void FireBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo)
|
|
{
|
|
ActionCastFakeSpellAtLocation(nSpell, lLoc, PROJECTILE_PATH_TYPE_BALLISTIC);
|
|
DelayCommand(fImpactDelay,CreateFieldEffect(lLoc,FIRE));
|
|
DelayCommand(fImpactDelay + 0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lLoc));
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBump, lLoc));
|
|
|
|
|
|
int nFDam = d20(6)+20;//Fire Damage
|
|
int nBDam = d10(1);//Bludgeoning Spray Damage
|
|
int nPDam = d10(1);//Piercing Spray Damage
|
|
int nSDam = d10(1);//Slashing Spray Damage
|
|
effect eFDam = EffectDamage(nFDam, DAMAGE_TYPE_FIRE, DAMAGE_POWER_PLUS_TWENTY);
|
|
effect eBDam = EffectDamage(nBDam, DAMAGE_TYPE_BLUDGEONING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect ePDam = EffectDamage(nPDam, DAMAGE_TYPE_PIERCING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eSDam = EffectDamage(nSDam, DAMAGE_TYPE_SLASHING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
|
|
float fDelay = 0.5;
|
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
while (GetIsObjectValid(oTarget))
|
|
{
|
|
int nType = GetObjectType(oTarget);
|
|
string sType = GetTag(oTarget);
|
|
|
|
//Check For Doors
|
|
if(nType == OBJECT_TYPE_DOOR)
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eFDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
//Check for other Siege Kegs
|
|
if(sType == "SiegeKeg")
|
|
{
|
|
int nKegDam = 20;
|
|
effect eKeg = EffectDamage(nKegDam, DAMAGE_TYPE_FIRE);
|
|
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eKeg, oTarget));
|
|
}
|
|
//Check for the Siege Oil Marker
|
|
if(sType == "SiegeOilMarker")
|
|
{
|
|
effect eDmg = EffectAreaOfEffect(AOE_PER_FOGFIRE);
|
|
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eDmg, lLoc,10.0);
|
|
}
|
|
//Check for other Placeables
|
|
if(nType == OBJECT_TYPE_PLACEABLE
|
|
&& (GetTag(oTarget) != "SiegeKeg"
|
|
|| GetTag(oTarget) != "WeatheringScorchMark"
|
|
|| GetTag(oTarget) != "FlameSmall"
|
|
|| GetTag(oTarget) != "DustPlume"
|
|
|| GetTag(oTarget) != "ShaftofLightWhite"
|
|
|| GetTag(oTarget) != "SiegeOilMarker"))
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eFDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
if(nType == OBJECT_TYPE_CREATURE)
|
|
{
|
|
//Adjust the damage based on the Reflex Save, Evasion and Improved Evasion.
|
|
//int nReflex = GetReflexSavingThrow(oTarget);
|
|
//Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eFDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
DelayCommand(fImpactDelay + 2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oTarget, 3.0));
|
|
SetIsTemporaryEnemy(oTarget,OBJECT_SELF,TRUE);
|
|
}
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
}
|
|
}
|
|
|
|
//Acid Grenade
|
|
void AcidBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo)
|
|
{
|
|
ActionCastFakeSpellAtLocation(nSpell, lLoc, PROJECTILE_PATH_TYPE_BALLISTIC);
|
|
DelayCommand(fImpactDelay,CreateFieldEffect(lLoc,ACID));
|
|
DelayCommand(fImpactDelay + 0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lLoc));
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBump, lLoc));
|
|
|
|
int nADam = d20(6)+20;//Acid Damage
|
|
int nBDam = d10(1);//Bludgeoning Spray Damage
|
|
int nPDam = d10(1);//Piercing Spray Damage
|
|
int nSDam = d10(1);//Slashing Spray Damage
|
|
effect eADam = EffectDamage(nADam, DAMAGE_TYPE_ACID, DAMAGE_POWER_PLUS_TWENTY);
|
|
effect eBDam = EffectDamage(nBDam, DAMAGE_TYPE_BLUDGEONING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect ePDam = EffectDamage(nPDam, DAMAGE_TYPE_PIERCING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eSDam = EffectDamage(nSDam, DAMAGE_TYPE_SLASHING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eVis = EffectVisualEffect(VFX_IMP_ACID_S);
|
|
float fDelay = 0.5;
|
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
while (GetIsObjectValid(oTarget))
|
|
{
|
|
int nType = GetObjectType(oTarget);
|
|
string sType = GetTag(oTarget);
|
|
|
|
//Check For Doors
|
|
if(nType == OBJECT_TYPE_DOOR)
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eADam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
//Check for other Placeables
|
|
if(nType == OBJECT_TYPE_PLACEABLE
|
|
&& (GetTag(oTarget) != "SiegeKeg"
|
|
|| GetTag(oTarget) != "WeatheringScorchMark"
|
|
|| GetTag(oTarget) != "FlameSmall"
|
|
|| GetTag(oTarget) != "DustPlume"
|
|
|| GetTag(oTarget) != "ShaftofLightWhite"
|
|
|| GetTag(oTarget) != "SiegeOilMarker"))
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eADam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
if(nType == OBJECT_TYPE_CREATURE)
|
|
{
|
|
//Adjust the damage based on the Reflex Save, Evasion and Improved Evasion.
|
|
//int nReflex = GetReflexSavingThrow(oTarget);
|
|
//Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eADam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
DelayCommand(fImpactDelay + 2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oTarget, 3.0));
|
|
SetIsTemporaryEnemy(oTarget,OBJECT_SELF,TRUE);
|
|
}
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
}
|
|
}
|
|
|
|
//Siege Stone
|
|
void StoneBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo)
|
|
{
|
|
ActionCastFakeSpellAtLocation(nSpell, lLoc, PROJECTILE_PATH_TYPE_BALLISTIC);
|
|
DelayCommand(fImpactDelay,CreateFieldEffect(lLoc,STONE));
|
|
DelayCommand(fImpactDelay + 0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lLoc));
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBump, lLoc));
|
|
|
|
int nBDam = d20(10)+80;//Bludgeoning Damage
|
|
int nPDam = d10(1);//Piercing Spray Damage
|
|
int nSDam = d10(1);//Slashing Spray Damage
|
|
effect eBDam = EffectDamage(nBDam, DAMAGE_TYPE_BLUDGEONING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect ePDam = EffectDamage(nPDam, DAMAGE_TYPE_PIERCING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eSDam = EffectDamage(nSDam, DAMAGE_TYPE_SLASHING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eVis = EffectVisualEffect(VFX_IMP_SLOW);
|
|
float fDelay = 0.5;
|
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
while (GetIsObjectValid(oTarget))
|
|
{
|
|
int nType = GetObjectType(oTarget);
|
|
string sType = GetTag(oTarget);
|
|
|
|
//Check For Doors
|
|
if(nType == OBJECT_TYPE_DOOR)
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
//Check for other Placeables
|
|
if(nType == OBJECT_TYPE_PLACEABLE
|
|
&& (GetTag(oTarget) != "SiegeKeg"
|
|
|| GetTag(oTarget) != "WeatheringScorchMark"
|
|
|| GetTag(oTarget) != "FlameSmall"
|
|
|| GetTag(oTarget) != "DustPlume"
|
|
|| GetTag(oTarget) != "ShaftofLightWhite"
|
|
|| GetTag(oTarget) != "SiegeOilMarker"))
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
if(nType == OBJECT_TYPE_CREATURE)
|
|
{
|
|
//Adjust the damage based on the Reflex Save, Evasion and Improved Evasion.
|
|
//int nReflex = GetReflexSavingThrow(oTarget);
|
|
//Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oTarget, 3.0));
|
|
SetIsTemporaryEnemy(oTarget,OBJECT_SELF,TRUE);
|
|
}
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
}
|
|
}
|
|
|
|
//Oil Grenade
|
|
void OilBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump, int nSpell,float fRadius,int nAmmo)
|
|
{
|
|
ActionCastFakeSpellAtLocation(nSpell, lLoc, PROJECTILE_PATH_TYPE_BALLISTIC);
|
|
DelayCommand(fImpactDelay,CreateFieldEffect(lLoc,OIL));
|
|
DelayCommand(fImpactDelay + 0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lLoc));
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBump, lLoc));
|
|
|
|
effect eDmg = EffectAreaOfEffect(AOE_PER_GREASE);
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eDmg, lLoc,30.0));
|
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE);
|
|
while (GetIsObjectValid(oTarget))
|
|
{
|
|
int nType = GetObjectType(oTarget);
|
|
string sType = GetTag(oTarget);
|
|
|
|
SetIsTemporaryEnemy(oTarget,OBJECT_SELF,TRUE);
|
|
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE);
|
|
}
|
|
}
|
|
|
|
//Caltrop Grenade
|
|
void CaltropSpread(location lLoc,float fImpactDelay,effect eImpact,int nSpell)
|
|
{
|
|
//This is a customised version of Biowares x0_s3_caltrops script
|
|
ActionCastFakeSpellAtLocation(nSpell, lLoc, PROJECTILE_PATH_TYPE_BALLISTIC);
|
|
DelayCommand(fImpactDelay + 0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lLoc));
|
|
|
|
effect eDmg = EffectAreaOfEffect(37, "x0_s3_calEN", "x0_s3_calHB", "");
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, eDmg, lLoc));
|
|
|
|
object oVisual = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_invisobj", lLoc);
|
|
|
|
object oAOE = GetNearestObjectToLocation(OBJECT_TYPE_AREA_OF_EFFECT, lLoc);
|
|
if (GetIsObjectValid(oAOE) == TRUE)
|
|
{
|
|
SetLocalObject(oAOE, "X0_L_IMPACT", oVisual);
|
|
}
|
|
|
|
effect eFieldOfSharp = EffectVisualEffect(VFX_DUR_CALTROPS);
|
|
DelayCommand(fImpactDelay + 1.5,ApplyEffectToObject(DURATION_TYPE_PERMANENT, eFieldOfSharp, oVisual));
|
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, lLoc, TRUE, OBJECT_TYPE_CREATURE);
|
|
while (GetIsObjectValid(oTarget))
|
|
{
|
|
int nType = GetObjectType(oTarget);
|
|
string sType = GetTag(oTarget);
|
|
|
|
SetIsTemporaryEnemy(oTarget,OBJECT_SELF,TRUE);
|
|
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 5.0, lLoc, TRUE, OBJECT_TYPE_CREATURE);
|
|
}
|
|
}
|
|
|
|
//Siege Arbalest Spear
|
|
void SpearBlast(location lLoc,float fImpactDelay,effect eImpact,effect eBump,int nSpell,float fRadius,int nAmmo)
|
|
{
|
|
ActionCastFakeSpellAtLocation(nSpell, lLoc, PROJECTILE_PATH_TYPE_HOMING);
|
|
DelayCommand(fImpactDelay,CreateFieldEffect(lLoc,8));
|
|
DelayCommand(fImpactDelay + 0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lLoc));
|
|
DelayCommand(fImpactDelay + 1.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBump, lLoc));
|
|
|
|
int nBDam = d10(1);//Bludgeoning Damage
|
|
int nPDam = d20(6)+50;//Piercing Damage
|
|
int nSDam = d10(1);//Slashing Damage
|
|
effect eBDam = EffectDamage(nBDam, DAMAGE_TYPE_BLUDGEONING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect ePDam = EffectDamage(nPDam, DAMAGE_TYPE_PIERCING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eSDam = EffectDamage(nSDam, DAMAGE_TYPE_SLASHING, DAMAGE_POWER_PLUS_FIVE);
|
|
effect eVis1 = EffectVisualEffect(VFX_COM_BLOOD_CRT_RED);
|
|
effect eLin1 = EffectLinkEffects(eVis1, ePDam);
|
|
float fDelay = 0.5;
|
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
while (GetIsObjectValid(oTarget))
|
|
{
|
|
int nType = GetObjectType(oTarget);
|
|
string sType = GetTag(oTarget);
|
|
|
|
//Check For Doors
|
|
if(nType == OBJECT_TYPE_DOOR)
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
//Check for other Placeables
|
|
if(nType == OBJECT_TYPE_PLACEABLE
|
|
&& (GetTag(oTarget) != "SiegeKeg"
|
|
|| GetTag(oTarget) != "WeatheringScorchMark"
|
|
|| GetTag(oTarget) != "FlameSmall"
|
|
|| GetTag(oTarget) != "DustPlume"
|
|
|| GetTag(oTarget) != "ShaftofLightWhite"
|
|
|| GetTag(oTarget) != "SiegeOilMarker"))
|
|
{
|
|
if (!GetPlotFlag(oTarget))
|
|
{
|
|
// Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
}
|
|
}
|
|
if(nType == OBJECT_TYPE_CREATURE)
|
|
{
|
|
//Adjust the damage based on the Reflex Save, Evasion and Improved Evasion.
|
|
//int nReflex = GetReflexSavingThrow(oTarget);
|
|
//Apply effects to the currently selected target.
|
|
DelayCommand(fImpactDelay + 1.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eLin1, oTarget));
|
|
DelayCommand(fImpactDelay + 1.6, ApplyEffectToObject(DURATION_TYPE_INSTANT, eBDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.7, ApplyEffectToObject(DURATION_TYPE_INSTANT, ePDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.8, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSDam, oTarget));
|
|
DelayCommand(fImpactDelay + 1.9, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oTarget, 3.0));
|
|
SetIsTemporaryEnemy(oTarget,OBJECT_SELF,TRUE);
|
|
}
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRadius, lLoc, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
|
}
|
|
}
|
|
|
|
//Used to turn the Siege Weapon to its current target
|
|
void SetFacingObject(object oTarget)
|
|
{
|
|
vector vFace = GetPosition(oTarget);
|
|
SetFacingPoint(vFace);
|
|
}
|
|
|
|
void SetGroundingFacing(object oSiege, object oPC)
|
|
{
|
|
location lLoc = GetLocation(oPC);
|
|
float fFace = GetFacing(oPC);
|
|
AssignCommand(oPC,ActionMoveAwayFromLocation(lLoc,TRUE,1.5));
|
|
AssignCommand(oSiege,DelayCommand(2.0,SetFacing(fFace)));
|
|
}
|
|
|
|
void ActivateSwitch()
|
|
{
|
|
DelayCommand(0.1, PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
|
|
DelayCommand(2.0, PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
|
|
}
|
|
|
|
//Initiate Local Siege Weapons
|
|
void InitiateSiege(object oSwitch, location lLoc)
|
|
{
|
|
//Find all Light Arbalest within 60 Meters
|
|
int nNth = 1;
|
|
object oLArbalest = GetNearestObjectByTag(SIEGEARBALEST_LGT,oSwitch,nNth);
|
|
while(oLArbalest != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oLArbalest);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_arbl",oLArbalest);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oLArbalest = GetNearestObjectByTag(SIEGEARBALEST_LGT,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Heavy Arbalest within 60 Meters
|
|
nNth = 1;
|
|
object oHArbalest = GetNearestObjectByTag(SIEGEARBALEST_HVY,oSwitch,nNth);
|
|
while(oHArbalest != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oHArbalest);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_arbh",oHArbalest);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oHArbalest = GetNearestObjectByTag(SIEGEARBALEST_HVY,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Bricole within 60 Meters
|
|
nNth = 1;
|
|
object oBricole = GetNearestObjectByTag(SIEGEBRICOLE,oSwitch,nNth);
|
|
while(oBricole != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oBricole);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_bri",oBricole);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oBricole = GetNearestObjectByTag(SIEGEBRICOLE,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Light Catapult within 60 Meters
|
|
nNth = 1;
|
|
object oLCatapult = GetNearestObjectByTag(SIEGECATAPULT_LGT,oSwitch,nNth);
|
|
while(oLCatapult != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oLCatapult);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_catl",oLCatapult);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oLCatapult = GetNearestObjectByTag(SIEGECATAPULT_LGT,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Heavy Catapult within 60 Meters
|
|
nNth = 1;
|
|
object oHCatapult = GetNearestObjectByTag(SIEGECATAPULT_HVY,oSwitch,nNth);
|
|
while(oHCatapult != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oHCatapult);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_cath",oHCatapult);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oHCatapult = GetNearestObjectByTag(SIEGECATAPULT_HVY,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Couillards within 60 Meters
|
|
nNth = 1;
|
|
object oCouillard = GetNearestObjectByTag(SIEGECOUILLARD,oSwitch,nNth);
|
|
while(oCouillard != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oCouillard);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_cou",oCouillard);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oCouillard = GetNearestObjectByTag(SIEGECOUILLARD,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Onagers within 60 Meters
|
|
nNth = 1;
|
|
object oOnager = GetNearestObjectByTag(SIEGEONAGER,oSwitch,nNth);
|
|
while(oOnager != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oOnager);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_ona",oOnager);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oOnager = GetNearestObjectByTag(SIEGEONAGER,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
|
|
//Find all Perriere within 60 Meters
|
|
nNth = 1;
|
|
object oPerriere = GetNearestObjectByTag(SIEGEPERRIERE,oSwitch,nNth);
|
|
while(oPerriere != OBJECT_INVALID)
|
|
{
|
|
float fDist = GetDistanceToObject(oPerriere);
|
|
if(fDist <= 60.0) ExecuteScript("os_arm_per",oPerriere);
|
|
if(nNth <= 10)
|
|
{
|
|
nNth++;
|
|
oPerriere = GetNearestObjectByTag(SIEGEPERRIERE,oSwitch,nNth);
|
|
}
|
|
else break;
|
|
}
|
|
}
|
|
|
|
//:: ARTILLERY FUNCTIONS
|
|
/******************************************************************************/
|
|
|
|
//void main (){}
|