/** i_battle Include file with general purpose scripts for the battle kit J.D. Robertson, 2002 */ #include "prc_inc_spells" // Like TooFarFrom, but specify the object int TooFarFromO(object obj, float distance = 8.0) { return GetArea(OBJECT_SELF) != GetArea(obj) || (GetDistanceToObject(obj) > distance); } // Returns TRUE if the character is too far from the given waypoint. Note // that being in a different area is automatically too far away // TODO: Change the default value of distance (8.0) to whatever works for your module int TooFarFrom(string waypoint, float distance = 8.0) { object wp = GetNearestObjectByTag(waypoint); return TooFarFromO(wp); } // Keeps the character from falling below k_MIN_HITPOINTS hit points void DisallowDeath() { int hp = GetCurrentHitPoints(); int k_MIN_HITPOINTS = 60; //TODO: Tweak this value as needed for you scritps if (hp < k_MIN_HITPOINTS) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(k_MIN_HITPOINTS - hp), OBJECT_SELF); } // A battle is running in the current area int InBattle() { return GetLocalInt(GetArea(OBJECT_SELF), "BattleStarted") && !GetLocalInt(GetArea(OBJECT_SELF), "BattleFinished"); } // Calculates the distance between two vectors in 3 dimensions. Allows // catapults to work with hills float Get3DDistance(vector v1, vector v2) { return sqrt((v2.x - v1.x) * (v2.x - v1.x) + (v2.y - v1.y) * (v2.y - v1.y) + (v2.z - v1.z) * (v2.z - v1.z)); } // Applies damage from a catapult hit. This gets around the fact that a catupult // has a caster level of 0, so its fireballs do 0d6 damage. void ApplyDamage(vector center) { // Using GetFirstObjectInShape crashes the game (I think when the shape // crosses into an invalid area. Instead, use GetFirstObjectInArea // and check distances object hit = GetFirstObjectInArea(); while (GetIsObjectValid(hit)) { // Damage in a 5m radius sphere if ((OBJECT_TYPE_CREATURE == GetObjectType(hit)) && // TODO: Currently only damages creatures (for speed). Remove this line to damage placeables as well (Get3DDistance(center, GetPosition(hit)) < 10.0)) // TODO: This is the blast radius, feel free to tweak it { // Damage minus a reflex save int damage = d10(); // TODO: Change this value to whatever you want damage = PRCGetReflexAdjustedDamage(damage, hit, 14, SAVING_THROW_TYPE_FIRE); // Hit 'em ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(damage, DAMAGE_TYPE_FIRE), hit); } hit = GetNextObjectInArea(); } } // Causes the calling object to fire a catapult shell towards the waypoint // named XTarget, where X is the calling object's tag void FireCatapult() { // Offset somewhere from the center of the battle // TODO: Adjust the offsets to increase or decrease the area in which // blasts will land // NOTE: 2d20 = [1,40], - 20 gives [-19, 20] vector center = GetPosition(GetNearestObjectByTag(GetTag(OBJECT_SELF) + "Target")); center.x += d20(2) - 20; // +- 20m from the target wapoint center.y += d20(2) - 20; // +- 20m from the target wapoint // Get the target, and calculate the distance so we can estimate delay // TODO: This is just a guess. It doesn't always work correctly, especially over // short distances. Feel free to adjust the delay to make things work correctly for you. location target = Location(OBJECT_SELF, center, 180.0); float delay = Get3DDistance(GetPosition(OBJECT_SELF), center) / 10.0; // Fire! ActionDoCommand(ActionCastSpellAtLocation(SPELL_FIREBALL, target, METAMAGIC_ANY, TRUE, PROJECTILE_PATH_TYPE_BALLISTIC)); DelayCommand(delay, ApplyDamage(center)); }