//:://///////////////////////////////////////////// //:: Spell Include: Teleportation Circle //:: spinc_telecircle //:://///////////////////////////////////////////// /** @file Handles the internal functioning of the Teleportation Circle -type spells, powers and SLAs. @author Ornedan @date Created - 2005.11.12 @date Modified - 2006.06.04 */ //::////////////////////////////////////////////// //::////////////////////////////////////////////// #include "prc_inc_spells" #include "prc_inc_teleport" ////////////////////////////////////////////////// /* Constant defintions */ ////////////////////////////////////////////////// // Internal constants const string TC_CASTERLEVEL = "PRC_TeleportCircle_CasterLvl"; const string TC_ISVISIBLE = "PRC_TeleportCircle_IsVisible"; const string TC_ISEXTENDED = "PRC_TeleportCircle_Extended"; const string TC_FIRSTSTAGE_DONE = "PRC_TeleportCircle_FirstPartDone"; const string TC_LOCATION = "PRC_TeleportCircle_TargetLocation"; const int TC_NUM_TRAPS = 4; ////////////////////////////////////////////////// /* Function prototypes */ ////////////////////////////////////////////////// /** * Runs the using of a Teleportation Circle (-like) spell / power / SLA. * The destination is gotten using a conversation or, if active, the * caster's quickselection. * NOTE: You will need to call spellhook / powerhook / specific-whatever * before this function. * * * @param oCaster The creature using a spell / power / SLA create * a Teleportation Circle * @param nCasterLvl The creature's caster / manifester level in regards to * this use * @param bVisible Whether the circle should be visible or not. A visible circle * is marked with VFX and has a detection DC of 0. A hidden circle * has a detection DC of 34. * @param bExtended Whether this use of Teleportation Circle had the Extend Metaeffect * applied to it. */ void TeleportationCircle(object oCaster, int nCasterLvl, int bVisible, int bExtended); /********************\ * Internal Functions * \********************/ /** * Does the actual creation of the circle. Called once the user has specified * the target location to use. * * @param oCaster creature using Teleportation Circle */ void TeleportationCircleAux(object oCaster); ////////////////////////////////////////////////// /* Function defintions */ ////////////////////////////////////////////////// void TeleportationCircleAux(object oCaster) { // Retrieve the target location from the variable location lCircleTarget = GetLocalLocation(oCaster, TC_LOCATION); location lTarget; int bVisible = GetLocalInt(oCaster, TC_ISVISIBLE); int nCasterLvl = GetLocalInt(oCaster, TC_CASTERLEVEL); int bExtended = GetLocalInt(oCaster, TC_ISEXTENDED); float fDuration = nCasterLvl * 10 * 60.0f * (bExtended ? 2 : 1); float fFacing = GetFacing(oCaster); float fDistance = FeetToMeters(5.0f) + 0.2; vector vTarget = GetPosition(oCaster); vTarget.x += cos(fFacing) * fDistance; vTarget.y += sin(fFacing) * fDistance; lTarget = Location(GetArea(oCaster), vTarget, fFacing); // Create the actual circle, in front of the caster ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectAreaOfEffect(AOE_PER_TELEPORTATIONCIRCLE, "prc_telecirc_oe"), lTarget, fDuration ); // Get an object reference to the newly created AoE object oAoE = MyFirstObjectInShape(SHAPE_SPHERE, 1.0f, lTarget, FALSE, OBJECT_TYPE_AREA_OF_EFFECT); while(GetIsObjectValid(oAoE)) { // Test if we found the correct AoE if(GetTag(oAoE) == Get2DACache("vfx_persistent", "LABEL", AOE_PER_TELEPORTATIONCIRCLE) && !GetLocalInt(oAoE, "PRC_TeleCircle_AoE_Inited") ) { break; } // Didn't find, get next oAoE = MyNextObjectInShape(SHAPE_SPHERE, 1.0f, lTarget, FALSE, OBJECT_TYPE_AREA_OF_EFFECT); } if(DEBUG) if(!GetIsObjectValid(oAoE)) DoDebug("ERROR: Can't find area of effect for Teleportation Circle!"); // Store data on the AoE SetLocalLocation(oAoE, "TargetLocation", lCircleTarget); SetLocalInt(oAoE, "IsVisible", bVisible); // Make the AoE initialise the trap trigger and possibly the VFX heartbeat ExecuteScript("prc_telecirc_aux", oAoE); // A VFX (momentary, circular, impressive :D ) at the circle's location. // Do even if hidden circle so that the caster knows where it really ended up DrawRhodonea(DURATION_TYPE_INSTANT, VFX_IMP_HEAD_MIND, lTarget, FeetToMeters(5.0f), 0.25, 0.0, 180, 12.0, 4.0, 0.0, "z"); // Cleanup DeleteLocalInt(oCaster, TC_CASTERLEVEL); DeleteLocalInt(oCaster, TC_ISVISIBLE); DeleteLocalInt(oCaster, TC_ISEXTENDED); DeleteLocalInt(oCaster, TC_FIRSTSTAGE_DONE); DeleteLocalLocation(oCaster, TC_LOCATION); } void TeleportationCircle(object oCaster, int nCasterLvl, int bVisible, int bExtended) { if(DEBUG) DoDebug("spinc_telecircle: Running TeleportationCircle()" + (GetLocalInt(oCaster, TC_FIRSTSTAGE_DONE) ? ": ERROR: Called while in second stage!":"") + "\n" + "oCaster = " + DebugObject2Str(oCaster) + "\n" + "nCasterLvl = " + IntToString(nCasterLvl) + "\n" + "bVisible = " + DebugBool2String(bVisible) + "\n" + "bExtended = " + DebugBool2String(bExtended) + "\n" ); // Get whether we are executing the first or the second part of the script if(!GetLocalInt(oCaster, TC_FIRSTSTAGE_DONE)) { // Store the caster level SetLocalInt(oCaster, TC_CASTERLEVEL, nCasterLvl); // Store the spellID SetLocalInt(oCaster, TC_ISVISIBLE, bVisible); // Store whether the spell is extended SetLocalInt(oCaster, TC_ISEXTENDED, bExtended); // Mark the first part done SetLocalInt(oCaster, TC_FIRSTSTAGE_DONE, TRUE); // Now, get the location to have the circle point at. ChooseTeleportTargetLocation(oCaster, "prc_telecirc_aux", TC_LOCATION, FALSE, TRUE); } } // Test main //void main(){}