Further file organization

Further file organization
This commit is contained in:
Jaysyn904
2023-08-23 22:11:00 -04:00
parent 3062876237
commit d87fe14826
22364 changed files with 0 additions and 3253 deletions

View File

@@ -0,0 +1,70 @@
//::///////////////////////////////////////////////
//:: [Dive Attack]
//:: [avar_dive.nss]
//:://////////////////////////////////////////////
/*
-2 AC +2 attack, double damage with peircing weapon
*/
//:://////////////////////////////////////////////
//:: Created By: Oni5115
//:: Created On: Sept. 24, 2004
//:://////////////////////////////////////////////
#include "prc_inc_combat"
//#include "prc_inc_util"
#include "prc_inc_skills"
void main()
{
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
if(!GetIsObjectValid(oTarget))
{
FloatingTextStringOnCreature("Invalid Target for Dive Attack", oPC, FALSE);
return;
}
// PnP rules use feet, might as well convert it now.
float fDistance = MetersToFeet(GetDistanceBetween(oPC, oTarget));
if(fDistance >= 7.0)
{
// perform the jump
if(PerformJump(oPC, GetLocation(oTarget), FALSE))
{
effect eACpen = EffectACDecrease(2);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eACpen, oPC, 6.0);
// get weapon information
object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
int iWeaponType = GetBaseItemType(oWeap);
int iNumSides = StringToInt(Get2DACache("baseitems", "DieToRoll", iWeaponType));
int iNumDice = StringToInt(Get2DACache("baseitems", "NumDice", iWeaponType));
int iCritMult = GetWeaponCritcalMultiplier(oPC, oWeap);
// deal double the damage
if(GetWeaponDamageType(oWeap) == DAMAGE_TYPE_PIERCING)
iNumDice *= 2;
struct BonusDamage sWeaponBonusDamage = GetWeaponBonusDamage(oWeap, oTarget);
struct BonusDamage sSpellBonusDamage = GetMagicalBonusDamage(oPC, oTarget);
// perform attack roll
string sMes = "*Dive Attack Miss*";
int iAttackRoll = GetAttackRoll(oTarget, oPC, oWeap, 0, 0, 2, TRUE, 3.1);
int bIsCritical = iAttackRoll == 2;
effect eDamage = GetAttackDamage(oTarget, oPC, oWeap, sWeaponBonusDamage, sSpellBonusDamage, 0, 0, bIsCritical, iNumDice, iNumSides, iCritMult);
if(iAttackRoll)
{
sMes = "*Dive Attack Hit*";
DelayCommand(3.2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
}
DelayCommand(3.3, FloatingTextStringOnCreature(sMes, oPC, FALSE));
}
}
else
{
FloatingTextStringOnCreature("Too close for Dive Attack", oPC, FALSE);
}
}

View File

@@ -0,0 +1,106 @@
//:://////////////////////////////////////////////
//:: Cave Entrance Conversation
//:: bdd_cave_conv
//:://////////////////////////////////////////////
/** @file
This allows the PC to attempt to climb down to the cave
@author Stratovarius
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
#include "prc_misc_const"
//////////////////////////////////////////////////
/* Constant definitions */
//////////////////////////////////////////////////
const int STAGE_BEGIN = 0;
//////////////////////////////////////////////////
/* Function definitions */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
int nStage = GetStage(oPC);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
{
if(DEBUG) DoDebug("bdd_cave_conv: Aborting due to error.");
return;
}
if(nValue == DYNCONV_SETUP_STAGE)
{
if(DEBUG) DoDebug("bdd_cave_conv: Running setup stage for stage " + IntToString(nStage));
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
if(DEBUG) DoDebug("bdd_cave_conv: Stage was not set up already. nStage: " + IntToString(nStage));
// Maneuver selection stage
if(nStage == STAGE_BEGIN)
{
SetHeader("As you stand on the rim of the basin, you notice a strange feature in the edge of the crater. It appears that the wide crack in the wall of the crater opens into a sand-lined cleft, and perhaps even a far deeper cave or tunnel.");
AddChoice("Climb Down (Climb DC 10)", 1, oPC);
AddChoice("Exit Conversation", -1, oPC);
MarkStageSetUp(STAGE_BEGIN, oPC);
}
}
// Do token setup
SetupTokens();
}
else if(nValue == DYNCONV_EXITED)
{
if(DEBUG) DoDebug("bdd_cave_conv: Running exit handler");
}
else if(nValue == DYNCONV_ABORTED)
{
// This section should never be run, since aborting this conversation should
// always be forbidden and as such, any attempts to abort the conversation
// should be handled transparently by the system
if(DEBUG) DoDebug("bdd_cave_conv: ERROR: Conversation abort section run");
}
// Handle PC response
else
{
int nChoice = GetChoice(oPC);
if(DEBUG) DoDebug("bdd_cave_conv: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " + IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
if(nStage == STAGE_BEGIN)
{
if (nChoice == 1)
{
if (GetIsSkillSuccessful(oPC, SKILL_CLIMB, 10))
{
JumpToLocation(GetLocation(GetWaypointByTag("bdd_cave_ent")));
}
else
{
AssignCommand(oPC, SpeakString("Your attempt to clamber down to the cave has gone poorly. Sliding, losing traction, and eventually tumbling, you splash into the thick dust of basin. Moments later, hands drag you deep into the dust."));
DelayCommand(6.0, PopUpDeathGUIPanel(oPC, TRUE, FALSE, 0, "Your attempt to clamber down to the cave has gone poorly. Sliding, losing traction, and eventually tumbling, you splash into the thick dust of basin. Moments later, hands drag you deep into the dust."));
}
}
// And we're all done
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
}
else
{
nStage = STAGE_BEGIN;
}
if(DEBUG) DoDebug("bdd_cave_conv: New stage: " + IntToString(nStage));
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}

View File

@@ -0,0 +1,16 @@
// Cave entrance
#include "inc_dynconv"
void main()
{
object oPC = GetEnteringObject();
int nRanks = GetSkillRank(SKILL_SPOT, oPC);
if (nRanks > 5) // Can actually succeed
{
if (GetIsSkillSuccessful(oPC, SKILL_SPOT, 26)) // Have to spot the cave opening
{
AssignCommand(oPC, ClearAllActions(TRUE));
StartDynamicConversation("bdd_cave_conv", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC);
}
}
}

View File

@@ -0,0 +1,535 @@
// Says the lines necessary for a given part of the area
#include "inc_vfx_const"
#include "prc_misc_const"
void SchoonerAttack(object oPC, object oSpawn);
void ForgeSpawn(object oPC, object oTrigger);
void XenoSpawn(object oPC);
void TaintSpawn(object oPC);
void ETReturnHome(object oPC)
{
CreateObject(OBJECT_TYPE_PLACEABLE, "prc_ea_return", GetLocation(oPC));
}
void SchoonerAttack(object oPC, object oSpawn)
{
if (!GetIsDead(oPC))
{
AssignCommand(oSpawn, ActionAttack(oPC));
DelayCommand(3.0, SchoonerAttack(oPC, oSpawn));
}
}
void Schooner(object oPC)
{
if (!GetLocalInt(GetModule(), "SchoonerSpawn"))
{
AssignCommand(oPC, SpeakString("Three desiccated, misshapen, humanoid forms crawl from beneath the battered vessel."));
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(GetWaypointByTag("bdd_schooner_ash")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(GetWaypointByTag("bdd_schooner_ash")));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(GetWaypointByTag("bdd_schooner_ash")));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 12) && !GetLocalInt(GetModule(), "AshenHusk"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Ashen husks lost their lives to unquenchable thirst. The evidence of their dry death is obvious as a supernatural deliquescent aura that harms those who cannot resist heatstoke.")));
SetLocalInt(GetModule(), "AshenHusk", TRUE);
}
else if (!GetLocalInt(GetModule(), "AshenHusk"))
{
DelayCommand(0.60, SetName(oSpawn1, " "));
DelayCommand(0.60, SetName(oSpawn2, " "));
DelayCommand(0.60, SetName(oSpawn3, " "));
}
SetLocalInt(GetModule(), "SchoonerSpawn", TRUE);
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
}
}
void FoyerSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "FoyerSpawn"))
{
AssignCommand(oPC, SpeakString("Below the sand that buried the foyer are the remains of shattered desks, broken shelves, chairs, and disintegrated paperwork <20> and three desiccated, misshapen, humanoid husks."));
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(GetWaypointByTag("bdd_foyer_ash")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(GetWaypointByTag("bdd_foyer_ash")));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(GetWaypointByTag("bdd_foyer_ash")));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 12) && !GetLocalInt(GetModule(), "AshenHusk"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Ashen husks lost their lives to unquenchable thirst. The evidence of their dry death is obvious as a supernatural deliquescent aura that harms those who cannot resist heatstoke.")));
SetLocalInt(GetModule(), "AshenHusk", TRUE);
}
else if (!GetLocalInt(GetModule(), "AshenHusk"))
{
DelayCommand(0.60, SetName(oSpawn1, " "));
DelayCommand(0.60, SetName(oSpawn2, " "));
DelayCommand(0.60, SetName(oSpawn3, " "));
}
SetLocalInt(GetModule(), "FoyerSpawn", TRUE);
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
}
}
void OfficeSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "OfficeSpawn"))
{
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "nw_shadow", GetLocation(GetWaypointByTag("bdd_office_shd")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "nw_shadow", GetLocation(GetWaypointByTag("bdd_office_shd")));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 13))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Shadows lurk in dark places, waiting for living prey to happen by. Unfortunately, today that's you.")));
}
else
{
DelayCommand(0.60, SetName(oSpawn1, " "));
DelayCommand(0.60, SetName(oSpawn2, " "));
}
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SetLocalInt(GetModule(), "OfficeSpawn", TRUE);
}
}
void VaultSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "VaultSpawn"))
{
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "nw_shfiend", GetLocation(GetWaypointByTag("bdd_vault_shd")));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 19))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Shadows fiends are the strongest of shadows, and their touch is deadly.")));
}
else
{
DelayCommand(0.60, SetName(oSpawn1, " "));
}
SchoonerAttack(oPC, oSpawn1);
SetLocalInt(GetModule(), "VaultSpawn", TRUE);
}
}
void ForgeSpawn(object oPC, object oTrigger)
{
object oTarget = GetFirstInPersistentObject(oTrigger, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget) && !GetLocalInt(GetModule(), "ForgeSpawn"))
{
if (GetIsPC(oTarget))
{
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn4 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn5 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn6 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn7 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn8 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn9 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn10 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
object oSpawn11 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 11) && !GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Asheratis are a people who live below the silky sands and dusts of suitable wastelands, rising to the surface to hunt for food, socialize and trade with other races, and make war upon their enemies. The skin of these asheratis appears blackened and rough.")));
SetLocalInt(GetModule(), "BDDAsherati", TRUE);
DelayCommand(0.60, SetName(oSpawn1, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn6, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn7, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn8, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn9, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn10, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn11, "Tainted Asherati"));
}
else if (GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(0.60, SetName(oSpawn1, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn6, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn7, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn8, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn9, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn10, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn11, "Tainted Asherati"));
}
CreateObject(OBJECT_TYPE_PLACEABLE, "bdd_tunnel", GetLocation(GetWaypointByTag("bdd_forge_tnt")));
SetLocalInt(GetModule(), "ForgeSpawn", TRUE);
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SchoonerAttack(oPC, oSpawn4);
SchoonerAttack(oPC, oSpawn5);
SchoonerAttack(oPC, oSpawn6);
SchoonerAttack(oPC, oSpawn7);
SchoonerAttack(oPC, oSpawn8);
SchoonerAttack(oPC, oSpawn9);
SchoonerAttack(oPC, oSpawn10);
SchoonerAttack(oPC, oSpawn11);
break;
}
//Select the next target within the spell shape.
oTarget = GetNextInPersistentObject(oTrigger, OBJECT_TYPE_CREATURE);
}
}
void XenoSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "XenoSpawn"))
{
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_xeno_tnt")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_xeno_tnt")));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_xeno_tnt")));
object oSpawn4 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_xeno_tnt")));
object oSpawn5 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_xeno_tnt")));
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SchoonerAttack(oPC, oSpawn4);
SchoonerAttack(oPC, oSpawn5);
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 11) && !GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Asheratis are a people who live below the silky sands and dusts of suitable wastelands, rising to the surface to hunt for food, socialize and trade with other races, and make war upon their enemies. The skin of these asheratis appears blackened and rough.")));
SetLocalInt(GetModule(), "BDDAsherati", TRUE);
DelayCommand(0.60, SetName(oSpawn1, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Tainted Asherati"));
}
else if (GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(0.60, SetName(oSpawn1, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Tainted Asherati"));
}
SetLocalInt(GetModule(), "XenoSpawn", TRUE);
DelayCommand(12.0, TaintSpawn(oPC));
}
}
void TaintSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "TaintSpawn"))
{
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
object oSpawn4 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
object oSpawn5 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
object oSpawn6 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
object oSpawn7 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(GetWaypointByTag("bdd_taint_tnt")));
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SchoonerAttack(oPC, oSpawn4);
SchoonerAttack(oPC, oSpawn5);
SchoonerAttack(oPC, oSpawn6);
SchoonerAttack(oPC, oSpawn7);
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 11) && !GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Asheratis are a people who live below the silky sands and dusts of suitable wastelands, rising to the surface to hunt for food, socialize and trade with other races, and make war upon their enemies. The skin of these asheratis appears blackened and rough.")));
SetLocalInt(GetModule(), "BDDAsherati", TRUE);
DelayCommand(0.60, SetName(oSpawn1, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn6, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn7, "Tainted Asherati"));
}
else if (GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(0.60, SetName(oSpawn1, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn6, "Tainted Asherati"));
DelayCommand(0.60, SetName(oSpawn7, "Tainted Asherati"));
}
SetLocalInt(GetModule(), "TaintSpawn", TRUE);
DelayCommand(12.0, XenoSpawn(oPC));
}
}
void ChangedSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "ChangedSpawn"))
{
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_chn", GetLocation(GetWaypointByTag("bdd_change_chn")));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_chn", GetLocation(GetWaypointByTag("bdd_change_chn")));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_chn", GetLocation(GetWaypointByTag("bdd_change_chn")));
object oSpawn4 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_chn", GetLocation(GetWaypointByTag("bdd_change_chn")));
object oSpawn5 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_chn", GetLocation(GetWaypointByTag("bdd_change_chn")));
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SchoonerAttack(oPC, oSpawn4);
SchoonerAttack(oPC, oSpawn5);
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 11) && !GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Asheratis are a people who live below the silky sands and dusts of suitable wastelands, rising to the surface to hunt for food, socialize and trade with other races, and make war upon their enemies. The skin of these asheratis appears blackened and rough.")));
SetLocalInt(GetModule(), "BDDAsherati", TRUE);
DelayCommand(0.60, SetName(oSpawn1, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Changed Asherati"));
}
else if (GetLocalInt(GetModule(), "BDDAsherati"))
{
DelayCommand(0.60, SetName(oSpawn1, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn2, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn3, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn4, "Changed Asherati"));
DelayCommand(0.60, SetName(oSpawn5, "Changed Asherati"));
}
SetLocalInt(GetModule(), "ChangedSpawn", TRUE);
}
}
void BlightSpawn(object oPC)
{
if (!GetLocalInt(GetModule(), "BlightSpawn"))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLOOD_FOUNTAIN), GetNearestObjectByTag("bdd_polyp", oPC), 6.0);
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(GetNearestObjectByTag("bdd_polyp", oPC)));
DestroyObject(GetNearestObjectByTag("bdd_polyp", oPC));
DelayCommand(0.25, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLOOD_FOUNTAIN), GetNearestObjectByTag("bdd_polyp", oPC), 6.0));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(GetNearestObjectByTag("bdd_polyp", oPC)));
DelayCommand(0.25, DestroyObject(GetNearestObjectByTag("bdd_polyp", oPC)));
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLOOD_FOUNTAIN), GetNearestObjectByTag("bdd_polyp", oPC), 6.0));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(GetNearestObjectByTag("bdd_polyp", oPC)));
DelayCommand(0.5, DestroyObject(GetNearestObjectByTag("bdd_polyp", oPC)));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 15) && !GetLocalInt(GetModule(), "DustBlight"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Although not especially intelligent, dustblights are wily wasteland hunters. They can move equally well through sand and above it, and they often lie in wait beneath a thin coating of sand for those unlucky enough to be deemed prey. These ones appear to be birthed from strange cocoons of tained coloration.")));
SetLocalInt(GetModule(), "DustBlight", TRUE);
}
else if (!GetLocalInt(GetModule(), "DustBlight"))
{
DelayCommand(0.60, SetName(oSpawn1, " "));
DelayCommand(0.60, SetName(oSpawn2, " "));
DelayCommand(0.60, SetName(oSpawn3, " "));
}
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SetLocalInt(GetModule(), "BlightSpawn", TRUE);
}
}
void BlightSpawn2(object oPC)
{
if (!GetLocalInt(GetModule(), "BlightSpawn2"))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLOOD_FOUNTAIN), GetNearestObjectByTag("bdd_polyp", oPC), 6.0);
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(GetNearestObjectByTag("bdd_polyp", oPC)));
DestroyObject(GetNearestObjectByTag("bdd_polyp", oPC));
DelayCommand(0.25, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLOOD_FOUNTAIN), GetNearestObjectByTag("bdd_polyp", oPC), 6.0));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(GetNearestObjectByTag("bdd_polyp", oPC)));
DelayCommand(0.25, DestroyObject(GetNearestObjectByTag("bdd_polyp", oPC)));
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_BLOOD_FOUNTAIN), GetNearestObjectByTag("bdd_polyp", oPC), 6.0));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(GetNearestObjectByTag("bdd_polyp", oPC)));
DelayCommand(0.5, DestroyObject(GetNearestObjectByTag("bdd_polyp", oPC)));
if (GetIsSkillSuccessful(oPC, SKILL_LORE, 15) && !GetLocalInt(GetModule(), "DustBlight"))
{
DelayCommand(3.0, AssignCommand(oPC, SpeakString("Although not especially intelligent, dustblights are wily wasteland hunters. They can move equally well through sand and above it, and they often lie in wait beneath a thin coating of sand for those unlucky enough to be deemed prey. These ones appear to be birthed from strange cocoons of tained coloration.")));
SetLocalInt(GetModule(), "DustBlight", TRUE);
}
else if (!GetLocalInt(GetModule(), "DustBlight"))
{
DelayCommand(0.60, SetName(oSpawn1, " "));
DelayCommand(0.60, SetName(oSpawn2, " "));
DelayCommand(0.60, SetName(oSpawn3, " "));
}
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SetLocalInt(GetModule(), "BlightSpawn2", TRUE);
}
}
void BDDGrantXP(object oPC)
{
object oTarget = GetFirstFactionMember(oPC);
while(GetIsObjectValid(oTarget))
{
GiveXPToCreature(oTarget, 4000);
oTarget = GetNextFactionMember(oPC);
}
}
void main()
{
object oPC = GetEnteringObject();
if (!GetIsObjectValid(oPC)) oPC = GetLastUsedBy();
object oTrigger = OBJECT_SELF;
string sTag = GetTag(oTrigger);
if (GetIsPC(oPC))
{
if (sTag == "bdd_schooner" && !GetLocalInt(GetModule(), "bdd_schooner"))
{
AssignCommand(oPC, SpeakString("What appears to be a schooner lies half buried in sand that has blown in through the wide-open end of this building."));
DelayCommand(4.0, Schooner(oPC));
SetLocalInt(GetModule(), "bdd_schooner", TRUE);
}
if (sTag == "bdd_well" && !GetLocalInt(GetModule(), "bdd_well"))
{
AssignCommand(oPC, SpeakString("The sound of trickling water echoes up from the bowels of this abandoned, chipped, and sandblasted stone well."));
SetLocalInt(GetModule(), "bdd_well", TRUE);
}
if (sTag == "bdd_shell")
AssignCommand(oPC, SpeakString("This adobe building is empty and doorless, its interior filled with drifting sand."));
if (sTag == "bdd_courtyard" && !GetLocalInt(GetModule(), "bdd_courtyard"))
{
AssignCommand(oPC, SpeakString("Adobe buildings squat around a sand-covered courtyard of adobe bricks. A stained and eroded well sits at the center of the courtyard. The buildings are in disrepair, many of them missing sections of roofing, others without doors, some tumbled down entirely. The entire complex is situated at the edge of a half-mile-wide crater with plunging stone walls that cradle a wide basin of gray-blue dust."));
SetLocalInt(GetModule(), "bdd_courtyard", TRUE);
}
if (sTag == "bdd_foyer" && !GetLocalInt(GetModule(), "bdd_foyer"))
{
AssignCommand(oPC, SpeakString("The missing door to this long foyer has allowed in the desert, which covers the floor in drifts and shallows, and piles up against three doors in this chamber. Bulges and drifts of sand reveal that many items lie below this blanket of dust."));
DelayCommand(4.0, FoyerSpawn(oPC));
SetLocalInt(GetModule(), "bdd_foyer", TRUE);
}
if (sTag == "bdd_ruins" && !GetLocalInt(GetModule(), "bdd_ruins"))
{
AssignCommand(oPC, SpeakString("The warehouse that once stood here is broken and empty, anything of value long since picked over or buried beneath the desert."));
SetLocalInt(GetModule(), "bdd_ruins", TRUE);
}
if (sTag == "bdd_enter" && !GetLocalInt(GetModule(), "bdd_enter"))
{
AssignCommand(oPC, SpeakString("The strange happenings and tales of the crater have piqued your interest, and here you find yourself, finally arriving at the outpost of the ill-fated wizard Ammavaru. May you have better luck than she."));
AddJournalQuestEntry("bdd_wastes", 1, oPC);
AddJournalQuestEntry("bdd_intro", 1, oPC);
SetLocalInt(GetModule(), "bdd_enter", TRUE);
}
if (sTag == "bdd_oil" && !GetLocalInt(GetModule(), "bdd_oil"))
{
AssignCommand(oPC, SpeakString("This chamber is stacked with rusting iron kegs under a thick layer of dust. By the strong odor of naphtha in the air and the oily slicks that saturate the floor, this chamber apparently holds lamp oil in great quantities."));
SetLocalInt(GetModule(), "bdd_oil", TRUE);
}
if (sTag == "bdd_filtrator" && !GetLocalInt(GetModule(), "bdd_filtrator"))
{
AssignCommand(oPC, SpeakString("A strange apparatus consisting of a netlike mesh of very fine lines stretches across a 5-foot-square metallic frame between two tall, wide wooden wheels. The device has a yoke, as if it might be possible to attach it behind a beast of burden. Hoppers, empty but for a residue of desert dust, are attached to each side of the frame. Various tools lie scattered on a nearby workbench."));
SetLocalInt(GetModule(), "bdd_filtrator", TRUE);
}
if (sTag == "bdd_office" && !GetLocalInt(GetModule(), "bdd_office"))
{
AssignCommand(oPC, SpeakString("The doors to this chamber are slightly ajar, and drifts of sand have layered the floor. The elements, even with their limited access, have not been kind to what might have once been an office. An overturned, rotting desk, a shattered cabinet, splintered chairs, and shredded wall hangings decorate this room. The debris gives rise to disquieting shadows that flit about the chamber."));
OfficeSpawn(oPC);
SetLocalInt(GetModule(), "bdd_office", TRUE);
}
if (sTag == "bdd_records")
AssignCommand(oPC, SpeakString("This is a series of entries in the record books of Ammavaru's mining expedition. It reads as follows:" + "\n\n" + "So far, the operation has been a great success. The basin did truly contain valuable metals, most prominently a scarlet metal that pierces the stony hides and rocky flanks of earth-aligned creatures." + "\n\n" + "50 pounds! 50! It's amazing how much of value came out of the sky. Most of it is in the vault now."));
if (sTag == "bdd_journal")
AssignCommand(oPC, SpeakString("A ripped and sand-scoured journal. It's fragmentary, but reads as follows:" + "\n\n" + "...three more disappeared yesterday. Went missing from their..." + "\n\n" + "...the barracks! Gone, in one night. We can't..." + "\n\n" + "...the sand. Look to the..." + "\n\n" + "The journal ends on that last, worrying, note."));
if (sTag == "bdd_forge")
{
if (!GetLocalInt(GetModule(), "ForgeSpawn")) AssignCommand(oPC, SpeakString("Machinery sprawls about this chamber, iron-sided and rust red. A layer of soft sand covers the floor, apparently drifting in from the smashed entrance. One piece of equipment, a large smelting furnace by the look of it, is topped and partially buried in the sand. A single other exit in the chamber remains sealed by a black iron door."));
DelayCommand(18.0, ForgeSpawn(oPC, oTrigger));
}
if (sTag == "bdd_forge_tun")
AssignCommand(oPC, JumpToLocation(GetLocation(GetWaypointByTag("bdd_cave_ent2"))));
if (sTag == "bdd_torn_page")
AssignCommand(oPC, SpeakString("A few pages torn from the ledger record and dropped from the corpse<73>s hand. On those pages is written the following record:" + "\n\n" + "<22>The creatures in the earth are asheratis<69>but they are changed! Some contamination in the stardust is toxic to them, driving them insane, and changing their flesh to abomination. I gave them the remaining kheferu ingots, then even my blade, Rive, hoping that would be barter enough for my life. But here I remain until death takes me. Curse this basin!<21>"));
if (sTag == "bdd_vault" && !GetLocalInt(GetModule(), "bdd_vault"))
{
AssignCommand(oPC, SpeakString("This small chamber contains a few pieces of refuse, as well as a makeshift bed, on which is huddled the brittle corpse of a human figure wearing heavy wraps. And the haunted spirit of what she once was."));
VaultSpawn(oPC);
SetLocalInt(GetModule(), "bdd_vault", TRUE);
}
if (sTag == "bdd_barracks" && !GetLocalInt(GetModule(), "bdd_barracks"))
{
AssignCommand(oPC, SpeakString("The broken shells of what were once barracks are now empty of all but drifting sand. Even a cursory glance shows them to be nothing more than ruined emptiness."));
SetLocalInt(GetModule(), "bdd_barracks", TRUE);
}
if (sTag == "bdd_xeno" && !GetLocalInt(GetModule(), "bdd_xeno"))
{
AssignCommand(oPC, SpeakString("This chamber, while covered in sand like the ruins above, has a more homely aspect, in large part due to piles of food being scattered about. It is also the home to several creatures, lounging in the sands."));
XenoSpawn(oPC);
SetLocalInt(GetModule(), "bdd_xeno", TRUE);
}
if (sTag == "bdd_taint" && !GetLocalInt(GetModule(), "bdd_taint"))
{
AssignCommand(oPC, SpeakString("By the look of the scattered tables, chests, cups, and other bits of domestic furniture, this chamber houses several humanoids. The refuse and garbage is striking in its quantity. As is the foulness emanating from the humanoids who swarm out of the sands."));
TaintSpawn(oPC);
SetLocalInt(GetModule(), "bdd_taint", TRUE);
}
if (sTag == "bdd_change" && !GetLocalInt(GetModule(), "bdd_change"))
{
AssignCommand(oPC, SpeakString("A faint, sickly sweet stench lingers in this chamber, which is bare of the sand prevalent in earlier chambers. Several humanoids are clustered in this chamber, huddled close together in a ring in the center of the area. A scabrous black layer covers their entire bodies, though it is cracked here and there, allowing a yellowish fluid to ooze and drip, spattering into vile pools on the rocky floor."));
ChangedSpawn(oPC);
SetLocalInt(GetModule(), "bdd_change", TRUE);
}
if (sTag == "bdd_blight" && !GetLocalInt(GetModule(), "bdd_blight"))
{
AssignCommand(oPC, SpeakString("A horribly cloying stench rolls away from the center of this chamber where a cluster of black, egglike polyps shudder and writhe. Some leak a yellowish fluid, while others leak blood. In the center of the chamber, roughly surrounded by the writhing, oozing polyps, is a scarlet-hued sword, rammed point-first into the stone floor. A few wooden crates are scattered near the quivering blade."));
DelayCommand(6.0, BlightSpawn(oPC));
DelayCommand(12.0, BlightSpawn2(oPC));
SetLocalInt(GetModule(), "bdd_blight", TRUE);
}
if (sTag == "bdd_cave_exp" && !GetLocalInt(GetModule(), "bdd_cave_exp"))
{
AssignCommand(oPC, SpeakString("The sand here is disturbed by the passage of many feet, and tracks lead both out into the basin, and further into the tunnel."));
SetLocalInt(GetModule(), "bdd_cave_exp", TRUE);
}
if (sTag == "bdd_books" && !GetLocalInt(GetModule(), "bdd_books"))
{
AssignCommand(oPC, SpeakString("A pile of books, magical apparatus, and other detritus, clearly gathered from Ammavaru's expedition up above. Despite being carried down into these caves, the thick layer of dust shows that they have not been used since they were brought beneath."));
SetLocalInt(GetModule(), "bdd_books", TRUE);
}
if (sTag == "bdd_climb")
{
if (GetIsSkillSuccessful(oPC, SKILL_CLIMB, 10))
{
JumpToLocation(GetLocation(GetWaypointByTag("bdd_climb_up")));
}
else
{
AssignCommand(oPC, SpeakString("Your attempt to clamber up from the cave has gone poorly. Sliding, losing traction, and eventually tumbling, you splash into the thick dust of basin. Moments later, hands drag you deep into the dust."));
DelayCommand(6.0, PopUpDeathGUIPanel(oPC, TRUE, FALSE, 0, "Your attempt to clamber up from the cave has gone poorly. Sliding, losing traction, and eventually tumbling, you splash into the thick dust of basin. Moments later, hands drag you deep into the dust."));
}
}
if (sTag == "bdd_sword" && !GetLocalInt(GetModule(), "bdd_sword") && !GetIsInCombat(oPC))
{
// Strength check
if ( (GetAbilityModifier(ABILITY_STRENGTH, oPC) + d20()) >= 15)
{
CreateItemOnObject("bdd_sword", oPC);
AssignCommand(oPC, SpeakString("A heave has ripped the sword free of the earth that trapped it. A cursory examination reveals that the sword is magical, and called 'Rive'. A deeper examination of the sword and the surroundings brings further knowledge."));
AddJournalQuestEntry("bdd_finish", 1, oPC);
//ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SCINTILLATING_PATTERN), oPC);
SetLocalInt(GetModule(), "bdd_sword", TRUE);
SetCutsceneMode(oPC, TRUE);
DelayCommand(8.0, AssignCommand(oPC, SpeakString("While it is true that various starmetals were seeded when the falling star struck the surface, it was not true that Ammavaru was the only one who sent an expedition to attempt to profit thereby. In fact, a nearby community of asheratis was also drawn to the event. Being suited to life below the sand, they were able to begin filtering particles of strange starmetals from the earth as soon as conditions in the crater settled down. They found some of the particles very interesting indeed. Unfortunately, the particles were also strangely toxic (and eventually mind- and body-altering) to the asherati community, though these particular effects were not immediately evident.")));
DelayCommand(20.0, AssignCommand(oPC, SpeakString("When Ammavaru turned up, she interrupted the effort of the asheratis to gather all the residual starmetal. However, Ammavaru and her team didn't immediately realize that they weren't alone (since asheratis operate mostly below the surface). Oblivious, Ammavaru constructed her base at the edge of the crater. The asheratis who still remained at the site were by now seriously infected by the toxic variety of starmetal dust they had foundered into and had become murderously deranged.")));
DelayCommand(30.0, AssignCommand(oPC, SpeakString("In the end, the asheratis rose one midnight from the surrounding dust, and then silently and efficiently murdered the miners in their sleep. The tainted asheratis (or their descendants) remain to this day, living around and under the Basin of Deadly Dust, killing any creature that seeks to explore or claim any portion of starmetal found at the location, and it was they who you fought through in order to get to this point.")));
DelayCommand(40.0, AssignCommand(oPC, SpeakString("From here on out, there is nothing more to do but leave this sad venture behind, and find a new challenge out there in the wastes.")));
DelayCommand(45.0, SetCutsceneMode(oPC, FALSE));
DelayCommand(45.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SCINTILLATING_PATTERN), oPC));
DelayCommand(48.0, BDDGrantXP(oPC));
if (GetLocalInt(oPC, "BDD_Enter")) DelayCommand(48.0, ETReturnHome(oPC));
}
else
AssignCommand(oPC, SpeakString("You struggle, but the sword is in too firmly. Perhaps another go..."));
}
}
}

View File

@@ -0,0 +1,40 @@
// Outdoor heatstroke
void Heat();
#include "prc_inc_spells"
void Heat()
{
effect eImpact = EffectVisualEffect(/*VFX_IMP_DUST_EXPLOSION*/VFX_IMP_SUNSTRIKE);
object oTarget = GetFirstObjectInArea(GetObjectByTag("bdd_basinrim"));
while (GetIsObjectValid(oTarget))
{
if (PRCGetIsAliveCreature(oTarget) && !GetHasFeat(FEAT_HEAT_ENDURANCE, oTarget) && GetIsPC(oTarget))
{
int nDC = 15 + GetLocalInt(oTarget, "HeatstrokeCount");
if (GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget)) > 0) nDC += 4;
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_NONE))
{
effect eHeat = EffectFatigue();
if (GetLocalInt(oTarget, "Fatigued")) eHeat = EffectExhausted();
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d4()), oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eHeat, oTarget, HoursToSeconds(12));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eImpact, oTarget);
SetLocalInt(oTarget, "Fatigued", TRUE);
AssignCommand(oTarget, SpeakString("The blazing sun saps energy from your limbs. Best to find shelter, and quickly."));
}
SetLocalInt(oTarget, "HeatstrokeCount", GetLocalInt(oTarget, "HeatstrokeCount")+1);
}
//Select the next target within the spell shape.
oTarget = GetNextObjectInArea(GetObjectByTag("bdd_basinrim"));
}
DelayCommand(90.0, Heat());
}
void main()
{
if (!GetLocalInt(GetModule(), "BDDHeat")) Heat();
SetLocalInt(GetModule(), "BDDHeat", TRUE);
}

View File

@@ -0,0 +1,58 @@
// Resting isn't very safe around here
void SchoonerAttack(object oPC, object oSpawn);
void SchoonerAttack(object oPC, object oSpawn)
{
if (!GetIsDead(oPC))
{
AssignCommand(oSpawn, ActionAttack(oPC));
DelayCommand(3.0, SchoonerAttack(oPC, oSpawn));
}
}
void RestSpawn(object oPC)
{
int nSwitch = d3();
if (nSwitch == 1)
{
AssignCommand(oPC, SpeakString("A dry wind touches your flesh moments before a creature charges into the light."));
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_ashen_husk", GetLocation(oPC));
SchoonerAttack(oPC, oSpawn1);
}
else if (nSwitch == 2)
{
AssignCommand(oPC, SpeakString("The rustle of sand grains is the only warning you get before tainted creatures swim from the sand towards you."));
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(oPC));
object oSpawn2 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(oPC));
object oSpawn3 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(oPC));
object oSpawn4 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(oPC));
object oSpawn5 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_asherati_tnt", GetLocation(oPC));
SchoonerAttack(oPC, oSpawn1);
SchoonerAttack(oPC, oSpawn2);
SchoonerAttack(oPC, oSpawn3);
SchoonerAttack(oPC, oSpawn4);
SchoonerAttack(oPC, oSpawn5);
}
else if (nSwitch == 3)
{
AssignCommand(oPC, SpeakString("A revolting, stooped, humanoid apparently composed of bleeding ash, has come hunting, and you are its prey."));
object oSpawn1 = CreateObject(OBJECT_TYPE_CREATURE, "bdd_dustblight", GetLocation(oPC));
SchoonerAttack(oPC, oSpawn1);
}
}
void main()
{
if (d2() == 2)
RestSpawn(GetLastPCRested()); // 50% chance of being attacked while resting
else
{
SetLocalInt(GetLastPCRested(), "Fatigued", FALSE);
DeleteLocalInt(GetLastPCRested(), "HeatstrokeCount");
}
ExecuteScript("prc_rest", OBJECT_SELF);
ExecuteScript("x2_mod_def_rest", OBJECT_SELF);
}

View File

@@ -0,0 +1,30 @@
//::///////////////////////////////////////////////
//:: Aura of Fear
//:: NW_S1_AuraFear.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Upon entering the aura of the creature the player
must make a will save or be struck with fear because
of the creatures presence.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 25, 2001
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
object oPC = OBJECT_SELF;
if(GetHasSpellEffect(SPELL_HOUND_AURAMENACE))
{
PRCRemoveEffectsFromSpell(oPC, SPELL_HOUND_AURAMENACE);
return;
}
//Set and apply AOE object
effect eAOE = ExtraordinaryEffect(EffectAreaOfEffect(AOE_MOB_FEAR,"hound_aurafeara"));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAOE, oPC);
}

View File

@@ -0,0 +1,50 @@
//::///////////////////////////////////////////////
//:: Aura of Fear On Enter
//:: NW_S1_AuraFearA.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Upon entering the aura of the creature the player
must make a will save or be struck with fear because
of the creatures presence.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 25, 2001
//:://////////////////////////////////////////////
// shaken -2 attack,weapon dmg,save.
// panicked -2 save + flee away ,50 % drop object holding
#include "prc_inc_spells"
void main()
{
//Declare major variables
object oPC = GetAreaOfEffectCreator();
object oTarget = GetEnteringObject();
// <20>2 penalty on attacks, AC, and saves
effect eShaken = EffectLinkEffects(EffectShaken(), EffectACDecrease(2));
eShaken = EffectLinkEffects(eShaken, EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE));
effect eVis = EffectVisualEffect(VFX_IMP_FEAR_S);
int nHD = GetHitDice(oPC);
// DC is charisma based
int nDC = 10 + (nHD / 2) + GetAbilityModifier(ABILITY_CHARISMA, oPC);
int nDuration = d6(2);
if(GetIsEnemy(oTarget, oPC) && GetHitDice(oTarget) <= nHD)
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(oPC, SPELLABILITY_AURA_FEAR));
if(!GetIsImmune(oTarget, IMMUNITY_TYPE_FEAR) && !GetIsImmune(oTarget, IMMUNITY_TYPE_MIND_SPELLS))
{
//Make a saving throw check
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_FEAR))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eShaken, oTarget, RoundsToSeconds(nDuration));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}
}
}

View File

@@ -0,0 +1,14 @@
/*
Minotaur does an extra 1d6 damage over the
3d6+6 of its normal attack
*/
#include "prc_inc_combmove"
void main()
{
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
DoCharge(oPC, oTarget, TRUE, TRUE, d6());
}

View File

@@ -0,0 +1,61 @@
//::///////////////////////////////////////////////
//:: Name racial appearance enforcenemt
//:: FileName race_appear
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This script make sure a character is only useing
an appearance that is allowed by their race.
Takes transformational classes into account too.
Also applies wings/tails when appropriate
Note: Rather than the simplistic Appearance column
in racialtypes.2da this takes the data from
racialappear.2da
*/
//:://////////////////////////////////////////////
//:: Created By: Primogrnitor
//:: Created On: 13/9/06
//:://////////////////////////////////////////////
#include "prc_alterations"
void main()
{
object oPC = OBJECT_SELF;
if(GetIsPolyMorphedOrShifted(oPC))
return;
int nRace = GetRacialType(oPC);
int nCurrAppear = GetAppearanceType(oPC);
int nNewAppear = nCurrAppear;
int nCurrWings = GetCreatureWingType(oPC);
int nNewWings = nCurrWings;
int nCurrTail = GetCreatureTailType(oPC);
int nNewTail = nCurrTail;
//race checks
//appearance
nNewAppear = StringToInt(Get2DACache("racialtypes", "Appearance", nRace));
//wings
//tails
//class checks
//appearance
if(GetLevelByClass(CLASS_TYPE_LICH, oPC) >= 10)
nNewAppear = APPEARANCE_TYPE_DEMI_LICH;
else if(GetLevelByClass(CLASS_TYPE_LICH, oPC) >= 4)
nNewAppear = APPEARANCE_TYPE_LICH;
//wings
//tails
//set it if it changes
if(nNewAppear != nCurrAppear)
SetCreatureAppearanceType(oPC, nNewAppear);
if(nNewTail != nCurrTail)
SetCreatureTailType(nNewTail, oPC);
if(nNewWings != nCurrWings)
SetCreatureWingType(nNewWings, oPC);
}

View File

@@ -0,0 +1,58 @@
//::///////////////////////////////////////////////
//:: [Aranea Alternate Form: Humanoid]
//:: [race_ara_human.nss]
//:: [Jaysyn / ebonfowl / PRC 20220421]
//::///////////////////////////////////////////////
/**@file Alternate Form (Su): An aranea's natural form is that of a large
monstrous spider. It can assume two other forms. The first is a Medium-size
humanoid (the exact form is fixed at birth). The second form is a Medium-size,
spider-humanoid hybrid. Changing form is a standard action.
The aranea keeps its ability scores and can cast spells, but cannot use webs or
poison in humanoid form.
In hybrid form, an aranea looks like a humanoid at first glance, but a closer
inspection will reveal its fangs & spinneretes. The aranea can use weapons &
webs in this form.
//////////////////////////////////////////////////////////////////////////////*/
#include "prc_inc_shifting"
#include "prc_inc_natweap"
void main()
{
object oPC = OBJECT_SELF;
string sCWL = GetResRef(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC));
StoreCurrentAppearanceAsTrueAppearance(oPC, TRUE);
ShiftIntoResRef(oPC, SHIFTER_TYPE_ARANEA, "prc_ara_human", FALSE);
SetLocalInt(oPC, "AraneaHumanoidForm", 1);
DeleteLocalInt(oPC, "AraneaHybridForm");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_c");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_d");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_f");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_g");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_h");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_l");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_m");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_s");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_t");
if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC)))
{
if ((sCWL == "prc_ara_bite_c")
|| (sCWL == "prc_ara_bite_d")
|| (sCWL == "prc_ara_bite_f")
|| (sCWL == "prc_ara_bite_g")
|| (sCWL == "prc_ara_bite_h")
|| (sCWL == "prc_ara_bite_l")
|| (sCWL == "prc_ara_bite_m")
|| (sCWL == "prc_ara_bite_s")
|| (sCWL == "prc_ara_bite_t"))
MyDestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC));
}
}

View File

@@ -0,0 +1,58 @@
//::///////////////////////////////////////////////
//:: [Aranea Alternate Form: Hybrid]
//:: [race_ara_hybrid.nss]
//:: [Jaysyn / ebonfowl / PRC 20220421]
//::///////////////////////////////////////////////
/**@file Alternate Form (Su): An aranea's natural form is that of a large
monstrous spider. It can assume two other forms. The first is a Medium-size
humanoid (the exact form is fixed at birth). The second form is a Medium-size,
spider-humanoid hybrid. Changing form is a standard action.
The aranea keeps its ability scores and can cast spells, but cannot use webs or
poison in humanoid form.
In hybrid form, an aranea looks like a humanoid at first glance, but a closer
inspection will reveal its fangs & spinneretes. The aranea can use weapons &
webs in this form.
//////////////////////////////////////////////////////////////////////////////*/
#include "prc_inc_shifting"
#include "prc_inc_natweap"
void main()
{
object oPC = OBJECT_SELF;
string sCWL = GetResRef(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC));
StoreCurrentAppearanceAsTrueAppearance(oPC, TRUE);
ShiftIntoResRef(oPC, SHIFTER_TYPE_ARANEA, "prc_ara_hybrid", FALSE);
SetLocalInt(oPC, "AraneaHybridForm", 1);
DeleteLocalInt(oPC, "AraneaHumanoidForm");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_c");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_d");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_f");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_g");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_h");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_l");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_m");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_s");
RemoveNaturalPrimaryWeapon(oPC, "prc_ara_bite_t");
if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC)))
{
if ((sCWL == "prc_ara_bite_c")
|| (sCWL == "prc_ara_bite_d")
|| (sCWL == "prc_ara_bite_f")
|| (sCWL == "prc_ara_bite_g")
|| (sCWL == "prc_ara_bite_h")
|| (sCWL == "prc_ara_bite_l")
|| (sCWL == "prc_ara_bite_m")
|| (sCWL == "prc_ara_bite_s")
|| (sCWL == "prc_ara_bite_t"))
MyDestroyObject(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC));
}
}

View File

@@ -0,0 +1,65 @@
//::///////////////////////////////////////////////
//:: [Aranea Web]
//:: [race_aranea_web.nss]
//:: [Jaysyn / PRC 20220420]
//::///////////////////////////////////////////////
/**@file Web (Ex): In spider or hybrid form (see below), an aranea
can throw a web up to six times per day. This is similar to an
attack with a net but has a maximum range of 50 feet, with a
range increment of 10 feet, and is effective against targets of
up to Large size. The web anchors the target in place, allowing
no movement.
/////////////////////////////////////////////////////////////////////////////*/
#include "NW_I0_SPELLS"
#include "x2_inc_switches"
#include "prc_inc_nwscript"
#include "prc_inc_combmove"
void main()
{
//:: Declare major varibles
object oCaster = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nHD = GetHitDice(oCaster);
int nCount = d6(1) + (nHD / 2);
int TargetSize = PRCGetSizeModifier(oTarget);
int nHumanoid = GetLocalInt(oCaster, "AraneaHumanoidForm");
effect eVis = EffectVisualEffect(VFX_DUR_WEB);
effect eStick = EffectEntangle();
effect eLink = ExtraordinaryEffect(EffectLinkEffects(eVis, eStick));
//:: Sanity check
if (nHumanoid)
{
SendMessageToPC(oCaster, "You can't throw webbing in humanoid form");
IncrementRemainingFeatUses(oCaster, FEAT_ARANEA_WEB);
return;
}
//:: Only affects large or smaller targets
if (TargetSize > 4)
{
FloatingTextStringOnCreature("This creature is too large to web.", oTarget);
IncrementRemainingFeatUses(oCaster, FEAT_ARANEA_WEB);
return;
}
//:: Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_ARANEA_WEB));
//:: Make a ranged touch attack
if (PRCDoRangedTouchAttack(oTarget))
{
if(GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_IS_INCORPOREAL) != TRUE )
{
//Apply the VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nCount));
}
}
}

View File

@@ -0,0 +1,28 @@
/*
27/10/21 by Stratovarius
Strength from Magic (Ex) Each time an arkamoi casts an
arcane spell, magical feedback grants it a rush of power.
For each arcane spell cast, an arkamoi increases the save
DC of subsequent arcane spells it casts by 1. Additionally,
the arkamoi gains a +2 bonus on damage rolls for
subsequent spells, and gains a +2 deflection bonus to
AC. These benefits last for 1 minute starting in the round
during which the arkamoi finishes casting its first spell of
the encounter.
Bonuses stack each time an arkamoi casts an arcane
spell within that minute, to a maximum of a +5 bonus
to save DCs, a +10 bonus on damage rolls, and a +10
deflection bonus to AC. At the end of that minute, all
these bonuses disappear. They could begin accumulating
again if the arkemoi casts more spells.
*/
#include "prc_inc_function"
void main()
{
object oCaster = PRCGetSpellTargetObject();
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectACIncrease(GetLocalInt(oCaster, "StrengthFromMagic")*2, AC_DEFLECTION_BONUS)), oCaster, 60.0);
}

View File

@@ -0,0 +1,13 @@
#include "prc_inc_spells"
void main()
{
object oPC = OBJECT_SELF;
if (3 > GetLocalInt(oPC, "StrengthFromMagic"))
{
FloatingTextStringOnCreature("Your Strength from Magic is not strong enough to be an Arcane Mastermind", oPC, FALSE);
return;
}
if(!TakeSwiftAction(oPC)) return;
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectAttackIncrease(2)), PRCGetSpellTargetObject(), 6.0);
}

View File

@@ -0,0 +1,63 @@
//::///////////////////////////////////////////////
//:: Azer Heat damage adder
//:: race_azer_flame
//::///////////////////////////////////////////////
/*
Adds 1 fire damage to all the Azer's weapons.
Moved to it's own script since adding to
natural weapons requires waiting for callback
from unarmed_caller.
*/
//:://////////////////////////////////////////////
//:: Created By: Ornedan
//:: Created On: 04.04.2005
//:://////////////////////////////////////////////
#include "prc_inc_unarmed"
void main()
{
object oPC = OBJECT_SELF;
if(!GetLocalInt(oPC, UNARMED_CALLBACK))
{
object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
if (!GetIsObjectValid(oItem))
{
// Add fire damage to gloves
oItem = GetItemInSlot(INVENTORY_SLOT_ARMS, oPC);
SetCompositeDamageBonusT(oItem, "AzerFlameDamage", 1, IP_CONST_DAMAGETYPE_FIRE);
// Request callback once the feat & fist evaluation is done, if it is done
AddEventScript(oPC, CALLBACKHOOK_UNARMED, "race_azer_flame", FALSE, FALSE);
}
else
{
// Add fire damage to mainhand
SetCompositeDamageBonusT(oItem, "AzerFlameDamage", 1, IP_CONST_DAMAGETYPE_FIRE);
// Add fire damage to offhand, if it contains a weapon
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
// check to make sure the weapon is not a shield or torch
if (GetIsObjectValid(oItem) &&
GetBaseItemType(oItem) != BASE_ITEM_SMALLSHIELD && GetBaseItemType(oItem) != BASE_ITEM_LARGESHIELD &&
GetBaseItemType(oItem) != BASE_ITEM_TOWERSHIELD && GetBaseItemType(oItem) != BASE_ITEM_TORCH)
SetCompositeDamageBonusT(oItem, "AzerFlameDamage", 1, IP_CONST_DAMAGETYPE_FIRE);
}
}
else
{
// Add damage to natural weapons in the callback
object oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC);
if(GetIsPRCCreatureWeapon(oItem))
SetCompositeDamageBonusT(oItem, "AzerFlameDamage", 1, IP_CONST_DAMAGETYPE_FIRE);
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
if(GetIsPRCCreatureWeapon(oItem))
SetCompositeDamageBonusT(oItem, "AzerFlameDamage", 1, IP_CONST_DAMAGETYPE_FIRE);
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oPC);
if(GetIsPRCCreatureWeapon(oItem))
SetCompositeDamageBonusT(oItem, "AzerFlameDamage", 1, IP_CONST_DAMAGETYPE_FIRE);
}
}

View File

@@ -0,0 +1,13 @@
/*
Bariaur Charge
*/
#include "prc_inc_combmove"
void main()
{
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
SetLocalInt(oPC, "BariaurCharge", TRUE);
DoCharge(oPC, oTarget);
}

View File

@@ -0,0 +1,35 @@
//::///////////////////////////////////////////////
//:: Blinding Beauty Toggle
//:: race_blindbeaut.nss
//::///////////////////////////////////////////////
/*
Toggles Blinding Beauty aura.
*/
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Feb 21, 2008
//:://////////////////////////////////////////////
//#include "prc_alterations"
#include "prc_inc_spells"
void main()
{
object oPC = OBJECT_SELF;
string sMes = "";
if(!GetHasSpellEffect(SPELL_NYMPH_BLINDING_BEAUTY))
{
effect eAura = ExtraordinaryEffect(EffectAreaOfEffect(AOE_PER_NYMPH_BLINDING));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAura, oPC);
sMes = "*Blinding Beauty Activated*";
}
else
{
// Removes effects
PRCRemoveSpellEffects(SPELL_NYMPH_BLINDING_BEAUTY, oPC, oPC);
sMes = "*Blinding Beauty Deactivated*";
}
FloatingTextStringOnCreature(sMes, oPC, FALSE);
}

View File

@@ -0,0 +1,45 @@
//::///////////////////////////////////////////////
//:: Blinding Beauty Enter
//:: race_blindbeauta.nss
//::///////////////////////////////////////////////
/*
Handles creatures entering the Aura AoE for
Blinding Beauty
*/
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Nov 27, 2007
//:://////////////////////////////////////////////
//#include "prc_alterations"
#include "prc_inc_spells"
void main()
{
object oTarget = GetEnteringObject();
object oNymph = GetAreaOfEffectCreator();
if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oNymph))
{
//don't blind self :P
if(oTarget == oNymph)
return;
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(oNymph, SPELL_NYMPH_BLINDING_BEAUTY));
// DC is charisma based
int nDC = 10 + (GetHitDice(oNymph) / 2) + GetAbilityModifier(ABILITY_CHARISMA, oNymph);
//Make Fort Save to negate effect
if (!/*Fort Save*/ PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_NONE))
{
effect eBlind = EffectBlindness();
effect eVis = EffectVisualEffect(VFX_IMP_BLIND_DEAF_M);
if(GetPRCSwitch(PRC_PNP_BLINDNESS_DEAFNESS))
eBlind = SupernaturalEffect(eBlind);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBlind, oTarget);
}
}
}

View File

@@ -0,0 +1,18 @@
/* Body Lamp racial ability for Ashrati
Glow like a lightbulb*/
#include "prc_alterations"
void main()
{
object oPC = OBJECT_SELF;
if (GetHasSpellEffect(SPELL_ASHRATI_BODYLAMP, oPC))
PRCRemoveSpellEffects(SPELL_ASHRATI_BODYLAMP, oPC, oPC);
else
{
effect eLink = EffectLinkEffects(EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20), EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE));
eLink = SupernaturalEffect(eLink);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oPC);
}
}

View File

@@ -0,0 +1,26 @@
/* Body Lamp Dazzle racial ability for Ashrati
Dazzle enemies*/
#include "prc_inc_spells"
void main()
{
object oPC = OBJECT_SELF;
location lTarget = GetLocation(oPC);
effect eExplode = EffectVisualEffect(VFX_FNF_FIREBALL);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eExplode, lTarget);
int nDC = 10 + GetAbilityModifier(ABILITY_CHARISMA, oPC) + GetHitDice(oPC)/2;
//Get the first target in the radius around the caster
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget);
while(GetIsObjectValid(oTarget))
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
if(oPC != oTarget && !PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_NONE))
{
effect eDazzle = SupernaturalEffect(EffectDazzle());
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDazzle, oTarget, 60.0);
}
//Get the next target in the specified area around the caster
oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget);
}
}

View File

@@ -0,0 +1,123 @@
//::///////////////////////////////////////////////
//:: Draconian Death Throes
//:: race_deaththroes.nss
//::///////////////////////////////////////////////
/*
Handles the after-death effects of Draconians
*/
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Feb 09, 2008
//:://////////////////////////////////////////////
#include "prc_inc_spells"
//function to handle the damage from a kapak's acid pool
void DoKapakAcidDamage(object oPC, location lTarget)
{
float fRadius = FeetToMeters(5.0);
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, fRadius, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
while(GetIsObjectValid(oTarget))
{
if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oPC))
{
float fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
int nDamage = d6();
effect eDam = EffectDamage(nDamage, DAMAGE_TYPE_ACID);
effect eVis = EffectVisualEffect(VFX_IMP_ACID_S);
// Apply effects to the currently selected target.
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, fRadius, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
}
void main()
{
/* int nEvent = GetRunningEvent();
if(DEBUG) DoDebug("race_deaththroes running, event: " + IntToString(nEvent));
// Init the PC.
object oPC;
// We aren't being called from any event, instead from EvalPRCFeats
if(nEvent == FALSE)
{
oPC = OBJECT_SELF;
// Hook in the events
if(DEBUG) DoDebug("race_deaththroes: Adding eventhooks");
AddEventScript(oPC, EVENT_ONPLAYERDEATH, "race_deaththroes", TRUE, FALSE);
}
else if(nEvent == EVENT_ONPLAYERDEATH)
{
oPC = GetLastPlayerDied();
object oEnemy = GetLastHostileActor();
if(DEBUG) DoDebug("race_deaththroes - OnDeath");
int nRace = GetRacialType(oPC);
if(nRace == RACIAL_TYPE_BOZAK)
{
location lTarget = GetLocation(oPC);
int nDC = 10 + GetAbilityModifier(ABILITY_CONSTITUTION, oPC);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_PULSE_FIRE), lTarget);
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
while (GetIsObjectValid(oTarget))
{
if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oPC))
{
float fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
int nDamage = d6();
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, nDC, SAVING_THROW_TYPE_NONE);
if(nDamage)
{
effect eDam = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL);
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_S);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
}
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
}
else if(nRace == RACIAL_TYPE_KAPAK)
{
int nDuration = d6();
location lTarget = GetLocation(oPC);
//use a switch to set the proper amount of "pulses" of damage
switch(nDuration)
{
case 6:
DelayCommand(RoundsToSeconds(5), DoKapakAcidDamage(oPC, lTarget));
case 5:
DelayCommand(RoundsToSeconds(4), DoKapakAcidDamage(oPC, lTarget));
case 4:
DelayCommand(RoundsToSeconds(3), DoKapakAcidDamage(oPC, lTarget));
case 3:
DelayCommand(RoundsToSeconds(2), DoKapakAcidDamage(oPC, lTarget));
case 2:
DelayCommand(RoundsToSeconds(1), DoKapakAcidDamage(oPC, lTarget));
case 1:
DoKapakAcidDamage(oPC, lTarget); break;
}
}
else if(nRace == RACIAL_TYPE_BAAZ)
{
//disarm code
if(GetIsCreatureDisarmable(oEnemy) && !GetPRCSwitch(PRC_PNP_DISARM))
{
if(DEBUG) DoDebug("race_deaththroes: Disarming Enemy");
AssignCommand(oEnemy, ActionGiveItem(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oEnemy), oPC));
}
else
if(DEBUG) DoDebug("race_deaththroes: Enemy not disarmable.");
}
}*/
}

View File

@@ -0,0 +1,52 @@
/*
----------------
Energy Ray
race_enray.nss
----------------
30/10/04 by Stratovarius
Class: Psion/Wilder
Power Level: 1
Range: Short
Target: One Creature
Duration: Instantaneous
Saving Throw: None
Power Resistance: Yes
Power Point Cost: 1
You create a ray of energy of the chosen type that shoots forth from your finger tips,
doing 1d6+1 elemental damage on a successful ranged touch attack.
Augment: For every additional power point spent, this power's damage increases by 1d6+1.
*/
const int RACE_POWER_ENERGYRAY_COLD = 1985;
const int RACE_POWER_ENERGYRAY_ELEC = 1986;
const int RACE_POWER_ENERGYRAY_FIRE = 1987;
const int RACE_POWER_ENERGYRAY_SONIC = 1988;
#include "psi_inc_psifunc"
void main()
{
int nSpellID = GetSpellId();
int nPower;
switch (nSpellID)
{
case RACE_POWER_ENERGYRAY_COLD:
nPower = POWER_ENERGYRAY_COLD;
break;
case RACE_POWER_ENERGYRAY_ELEC:
nPower = POWER_ENERGYRAY_ELEC;
break;
case RACE_POWER_ENERGYRAY_FIRE:
nPower = POWER_ENERGYRAY_FIRE;
break;
case RACE_POWER_ENERGYRAY_SONIC:
nPower = POWER_ENERGYRAY_SONIC;
break;
}
UsePower(nPower, CLASS_TYPE_INVALID, TRUE, GetHitDice(OBJECT_SELF)/2);
}

View File

@@ -0,0 +1,270 @@
/** @file
This handles subraces and race restricted items.
Drow should be able to use Elven only items for example.
*/
#include "prc_racial_const"
#include "prc_alterations"
//#include "psi_inc_manifest"
const string ARRAY_NAME = "PRC_Racial_IPs";
void AddRaceIP(object oItem, int iIP)
{
if(array_get_string(oItem, ARRAY_NAME, iIP) == "")
{
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByRace(iIP), oItem);
array_set_string(oItem, ARRAY_NAME, iIP, "1");
}
}
void AddRacialRestrictions(object oItem)
{
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_ABERRATION) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_DRIDER);
AddRaceIP(oItem, RACIAL_TYPE_ELAN);
AddRaceIP(oItem, RACIAL_TYPE_ILLITHID);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_CONSTRUCT) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_WARFORGED);
AddRaceIP(oItem, RACIAL_TYPE_WARFORGED_CHARGER);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_DRAGON) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_BAAZ);
AddRaceIP(oItem, RACIAL_TYPE_BOZAK);
AddRaceIP(oItem, RACIAL_TYPE_KAPAK);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_DWARF) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_ARC_DWARF);
AddRaceIP(oItem, RACIAL_TYPE_DS_DWARF);
AddRaceIP(oItem, RACIAL_TYPE_DARK_DWARF);
AddRaceIP(oItem, RACIAL_TYPE_DUERGAR);
AddRaceIP(oItem, RACIAL_TYPE_FIREBLOOD_DWARF);
AddRaceIP(oItem, RACIAL_TYPE_GOLD_DWARF);
AddRaceIP(oItem, RACIAL_TYPE_GULLY_DWARF);
AddRaceIP(oItem, RACIAL_TYPE_KOROBKURU);
AddRaceIP(oItem, RACIAL_TYPE_MUL);
AddRaceIP(oItem, RACIAL_TYPE_URDINNIR);
AddRaceIP(oItem, RACIAL_TYPE_WILD_DWARF);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_ELF) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_AQELF);
AddRaceIP(oItem, RACIAL_TYPE_DS_ELF);
AddRaceIP(oItem, RACIAL_TYPE_AVARIEL);
AddRaceIP(oItem, RACIAL_TYPE_DROW_FEMALE);
AddRaceIP(oItem, RACIAL_TYPE_DROW_MALE);
AddRaceIP(oItem, RACIAL_TYPE_FEYRI);
AddRaceIP(oItem, RACIAL_TYPE_FORESTLORD_ELF);
AddRaceIP(oItem, RACIAL_TYPE_KAGONESTI_ELF);
AddRaceIP(oItem, RACIAL_TYPE_SILVANESTI_ELF);
AddRaceIP(oItem, RACIAL_TYPE_SNOW_ELF);
AddRaceIP(oItem, RACIAL_TYPE_SUN_ELF);
AddRaceIP(oItem, RACIAL_TYPE_WILD_ELF);
AddRaceIP(oItem, RACIAL_TYPE_WOOD_ELF);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_FEY) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_BROWNIE);
AddRaceIP(oItem, RACIAL_TYPE_GRIG);
AddRaceIP(oItem, RACIAL_TYPE_NIXIE);
AddRaceIP(oItem, RACIAL_TYPE_NYMPH);
AddRaceIP(oItem, RACIAL_TYPE_PIXIE);
AddRaceIP(oItem, RACIAL_TYPE_SATYR);
AddRaceIP(oItem, RACIAL_TYPE_HYBSIL);
AddRaceIP(oItem, RACIAL_TYPE_GLOURA);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_GIANT) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_DS_HALFGIANT);
AddRaceIP(oItem, RACIAL_TYPE_PH_HALFGIANT);
AddRaceIP(oItem, RACIAL_TYPE_HALFOGRE);
AddRaceIP(oItem, RACIAL_TYPE_KRYNN_HOGRE);
AddRaceIP(oItem, RACIAL_TYPE_OGRE);
AddRaceIP(oItem, RACIAL_TYPE_TROLL);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_GNOME) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_FOR_GNOME);
AddRaceIP(oItem, RACIAL_TYPE_ROCK_GNOME);
AddRaceIP(oItem, RACIAL_TYPE_STONEHUNTER_GNOME);
AddRaceIP(oItem, RACIAL_TYPE_DEEP_GNOME);
AddRaceIP(oItem, RACIAL_TYPE_TINK_GNOME);
AddRaceIP(oItem, RACIAL_TYPE_WHISPER_GNOME);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HUMANOID_GOBLINOID) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_BUGBEAR);
AddRaceIP(oItem, RACIAL_TYPE_GOBLIN);
AddRaceIP(oItem, RACIAL_TYPE_HOBGOBLIN);
AddRaceIP(oItem, RACIAL_TYPE_SUNSCORCH_HOBGOBLIN);
AddRaceIP(oItem, RACIAL_TYPE_TASLOI);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HALFELF) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_DS_HALFELF);
AddRaceIP(oItem, RACIAL_TYPE_HALFDROW);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HALFLING) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_DS_HALFLING);
AddRaceIP(oItem, RACIAL_TYPE_DEEP_HALFLING);
AddRaceIP(oItem, RACIAL_TYPE_GHOSTWISE_HALFLING);
AddRaceIP(oItem, RACIAL_TYPE_GLIMMERSKIN_HALFING);
AddRaceIP(oItem, RACIAL_TYPE_KENDER);
AddRaceIP(oItem, RACIAL_TYPE_STRONGHEART_HALFLING);
AddRaceIP(oItem, RACIAL_TYPE_TALLFELLOW_HALFLING);
AddRaceIP(oItem, RACIAL_TYPE_TUNDRA_HALFLING);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HUMAN) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_AASIMAR);
AddRaceIP(oItem, RACIAL_TYPE_AIR_GEN);
AddRaceIP(oItem, RACIAL_TYPE_IMASKARI);
AddRaceIP(oItem, RACIAL_TYPE_EARTH_GEN);
AddRaceIP(oItem, RACIAL_TYPE_FIRE_GEN);
AddRaceIP(oItem, RACIAL_TYPE_GITHYANKI);
AddRaceIP(oItem, RACIAL_TYPE_GITHZERAI);
AddRaceIP(oItem, RACIAL_TYPE_KALASHTAR);
AddRaceIP(oItem, RACIAL_TYPE_MAENADS);
AddRaceIP(oItem, RACIAL_TYPE_SILVERBROW_HUMAN);
AddRaceIP(oItem, RACIAL_TYPE_KRINTH);
AddRaceIP(oItem, RACIAL_TYPE_SPIRIT_FOLK);
AddRaceIP(oItem, RACIAL_TYPE_TIEFLING);
AddRaceIP(oItem, RACIAL_TYPE_WATER_GEN);
AddRaceIP(oItem, RACIAL_TYPE_XEPH);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HUMANOID_MONSTROUS) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_CATFOLK);
AddRaceIP(oItem, RACIAL_TYPE_DROMITE);
AddRaceIP(oItem, RACIAL_TYPE_FLIND);
AddRaceIP(oItem, RACIAL_TYPE_GNOLL);
AddRaceIP(oItem, RACIAL_TYPE_KRYNN_MINOTAUR);
AddRaceIP(oItem, RACIAL_TYPE_MINOTAUR);
AddRaceIP(oItem, RACIAL_TYPE_NEZUMI);
AddRaceIP(oItem, RACIAL_TYPE_WEMIC);
AddRaceIP(oItem, RACIAL_TYPE_PURE_YUAN);
AddRaceIP(oItem, RACIAL_TYPE_ARKAMOI);
AddRaceIP(oItem, RACIAL_TYPE_LASHEMOI);
AddRaceIP(oItem, RACIAL_TYPE_TURLEMOI);
AddRaceIP(oItem, RACIAL_TYPE_HADRIMOI);
AddRaceIP(oItem, RACIAL_TYPE_REDSPAWN_ARCANISS);
AddRaceIP(oItem, RACIAL_TYPE_MARRULURK);
AddRaceIP(oItem, RACIAL_TYPE_MARRUSAULT);
AddRaceIP(oItem, RACIAL_TYPE_MARRUTACT);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HALFORC) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_FROSTBLOOD_ORC);
AddRaceIP(oItem, RACIAL_TYPE_GRAYORC);
AddRaceIP(oItem, RACIAL_TYPE_ORC);
AddRaceIP(oItem, RACIAL_TYPE_OROG);
AddRaceIP(oItem, RACIAL_TYPE_SCRO);
AddRaceIP(oItem, RACIAL_TYPE_TANARUKK);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_OUTSIDER) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_AASIMAR);
AddRaceIP(oItem, RACIAL_TYPE_AIR_GEN);
AddRaceIP(oItem, RACIAL_TYPE_AZER);
AddRaceIP(oItem, RACIAL_TYPE_BARIAUR);
AddRaceIP(oItem, RACIAL_TYPE_BLADELING);
AddRaceIP(oItem, RACIAL_TYPE_BRALANI);
AddRaceIP(oItem, RACIAL_TYPE_BUOMMANS);
AddRaceIP(oItem, RACIAL_TYPE_CHAOND);
AddRaceIP(oItem, RACIAL_TYPE_EARTH_GEN);
AddRaceIP(oItem, RACIAL_TYPE_FEYRI);
AddRaceIP(oItem, RACIAL_TYPE_FIRE_GEN);
AddRaceIP(oItem, RACIAL_TYPE_GITHYANKI);
AddRaceIP(oItem, RACIAL_TYPE_GITHZERAI);
AddRaceIP(oItem, RACIAL_TYPE_HOUND_ARCHON);
AddRaceIP(oItem, RACIAL_TYPE_KHAASTA);
AddRaceIP(oItem, RACIAL_TYPE_NATHRI);
AddRaceIP(oItem, RACIAL_TYPE_NAZTHARUNE_RAKSHASA);
AddRaceIP(oItem, RACIAL_TYPE_NERAPHIM);
AddRaceIP(oItem, RACIAL_TYPE_RAKSHASA);
AddRaceIP(oItem, RACIAL_TYPE_SHADOWSWYFT);
AddRaceIP(oItem, RACIAL_TYPE_TANARUKK);
AddRaceIP(oItem, RACIAL_TYPE_TIEFLING);
AddRaceIP(oItem, RACIAL_TYPE_TULADHARA);
AddRaceIP(oItem, RACIAL_TYPE_WATER_GEN);
AddRaceIP(oItem, RACIAL_TYPE_ZAKYA_RAKSHASA);
AddRaceIP(oItem, RACIAL_TYPE_ZENYRTHRI);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_PLANT) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_VOLODNI);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_HUMANOID_REPTILIAN) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_ASABI);
AddRaceIP(oItem, RACIAL_TYPE_DRAGONKIN);
AddRaceIP(oItem, RACIAL_TYPE_KOBOLD);
AddRaceIP(oItem, RACIAL_TYPE_LIZARDFOLK);
AddRaceIP(oItem, RACIAL_TYPE_POISON_DUSK);
AddRaceIP(oItem, RACIAL_TYPE_PTERRAN);
AddRaceIP(oItem, RACIAL_TYPE_VILETOOTH_LIZARDFOLK);
AddRaceIP(oItem, RACIAL_TYPE_MUCKDWELLER);
}
if(array_get_string(oItem, ARRAY_NAME, RACIAL_TYPE_SHAPECHANGER) != "")
{
AddRaceIP(oItem, RACIAL_TYPE_CHANGELING);
AddRaceIP(oItem, RACIAL_TYPE_IRDA);
AddRaceIP(oItem, RACIAL_TYPE_SHIFTER);
AddRaceIP(oItem, RACIAL_TYPE_ARANEA);
}
//clean up
array_delete(oItem, ARRAY_NAME);
}
void main()
{
//object oCreature = GetModuleItemAcquiredBy();
object oItem = GetModuleItemAcquired();
//int nRace = GetRacialType(oCreature);
// Only do this once per item
if(GetLocalInt(oItem, "PRC_RacialRestrictionsExpanded"))
return;
// Ignore tokens and creature items
int nBaseItem = GetBaseItemType(oItem);
string sResRef = GetStringLowerCase(GetResRef(oItem));
if(nBaseItem == BASE_ITEM_CBLUDGWEAPON
|| nBaseItem == BASE_ITEM_CPIERCWEAPON
|| nBaseItem == BASE_ITEM_CREATUREITEM
|| nBaseItem == BASE_ITEM_CSLASHWEAPON
|| nBaseItem == BASE_ITEM_CSLSHPRCWEAP
|| sResRef == "hidetoken"
|| sResRef == "prc_maniftoken")
return;
if(array_exists(oItem, ARRAY_NAME))
array_delete(oItem, ARRAY_NAME);
array_create(oItem, ARRAY_NAME);
SetLocalInt(oItem, "PRC_RacialRestrictionsExpanded", TRUE);
// Loop over all itemproperties, looking for racial restrictions
int bModifyItem = FALSE;
itemproperty ipTest = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ipTest))
{
if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_USE_LIMITATION_RACIAL_TYPE)
{
int nIPRace = GetItemPropertySubType(ipTest);
array_set_string(oItem, ARRAY_NAME, nIPRace, "1");
bModifyItem = TRUE;
}
ipTest = GetNextItemProperty(oItem);
}
if(bModifyItem)
DelayCommand(0.0f, AddRacialRestrictions(oItem));
}

View File

@@ -0,0 +1,92 @@
//::///////////////////////////////////////////////
//:: Faerie Fire
//:: sp_faerie_fire
//:://////////////////////////////////////////////
/*
Faerie Fire
Evocation [Light]
Level: Drd 1
Components: V, S, DF
Casting Time: 1 standard action
Range: Long (400 ft. + 40 ft./level)
Area: Creatures and objects within a 5-ft.-radius burst
Duration: 1 min./level (D)
Saving Throw: None
Spell Resistance: Yes
A pale glow surrounds and outlines the subjects. Outlined subjects shed light
as candles. Outlined creatures do not benefit from the concealment normally
provided by darkness (though a 2nd-level or higher magical darkness effect
functions normally), blur, displacement, invisibility, or similar effects.
The light is too dim to have any special effect on undead or dark-dwelling
creatures vulnerable to light. The faerie fire can be blue, green, or violet,
according to your choice at the time of casting. The faerie fire does not
cause any harm to the objects or creatures thus outlined.
*/
//:://////////////////////////////////////////////
//:: Created By: Primogenitor
//:: Created On: Sept 22 , 2004
//:://////////////////////////////////////////////
//:: modified by mr_bumpkin Dec 4, 2003 for PRC stuff
#include "prc_inc_spells"
//#include "x2_inc_spellhook"
void main()
{
if(!X2PreSpellCastCode()) return;
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
//Declare major variables
object oCaster = OBJECT_SELF;
location lTarget = PRCGetSpellTargetLocation();
int nCasterLvl = PRCGetCasterLevel(oCaster);
int nPenetr = nCasterLvl + SPGetPenetr();
int nMetaMagic = PRCGetMetaMagicFeat();
float fDuration = MinutesToSeconds(nCasterLvl);
effect eVis, eExplode;
if(nMetaMagic & METAMAGIC_EXTEND)
fDuration *= 2;
switch(Random(3))
{
case 0:
eVis = EffectVisualEffect(VFX_DUR_LIGHT_PURPLE_5);
eExplode = EffectVisualEffect(VFX_IMP_FAERIE_FIRE_VIOLET);
break;
case 1:
eVis = EffectVisualEffect(VFX_DUR_LIGHT_BLUE_5);
eExplode = EffectVisualEffect(VFX_IMP_FAERIE_FIRE_BLUE);
break;
case 2:
eVis = EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_5);
eExplode = EffectVisualEffect(VFX_IMP_FAERIE_FIRE_GREEN);
break;
}
//Declare the spell shape, size and the location. Capture the first target object in the shape.
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
//Cycle through the targets within the spell shape until an invalid object is captured.
while(GetIsObjectValid(oTarget))
{
SignalEvent(oTarget, EventSpellCastAt(oCaster, SPELL_FAERIE_FIRE));
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr))
{
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eExplode, oTarget);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, fDuration);
PRCRemoveSpecificEffect(EFFECT_TYPE_IMPROVEDINVISIBILITY, oTarget);
PRCRemoveSpecificEffect(EFFECT_TYPE_INVISIBILITY, oTarget);
PRCRemoveSpecificEffect(EFFECT_TYPE_DARKNESS, oTarget);
PRCRemoveSpecificEffect(EFFECT_TYPE_CONCEALMENT, oTarget);
}
//Select the next target within the spell shape.
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, lTarget, TRUE, OBJECT_TYPE_CREATURE);
}
PRCSetSchool();
}

View File

@@ -0,0 +1,47 @@
//::///////////////////////////////////////////////
//:: Name Fey'ri alter self
//:: FileName race_feyrialter
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
*/
//:://////////////////////////////////////////////
//:: Created By: Shane Hennessy
//:: Created On:
//:://////////////////////////////////////////////
// disguise for fey'ri
#include "pnp_shft_poly"
//internal function to remove wings
void RemoveWings(object oPC)
{
//if not shifted
//store current appearance to be safe
StoreAppearance(oPC);
SetPersistantLocalInt(oPC, "WingsOff", TRUE);
SetCreatureWingType(CREATURE_WING_TYPE_NONE, oPC);
}
//internal function to turn wings on
void AddWings(object oPC)
{
//grant wings
SetPersistantLocalInt(oPC, "WingsOff", FALSE);
SetCreatureWingType(CREATURE_WING_TYPE_DEMON, oPC);
}
void main()
{
object oPC = OBJECT_SELF;
if(!GetIsPolyMorphedOrShifted(oPC))
{
if(!GetPersistantLocalInt(oPC, "WingsOff"))
RemoveWings(oPC);
else
AddWings(oPC);
}
else
FloatingTextStringOnCreature("You cannot use this ability while shifted.", oPC, FALSE);
}

View File

@@ -0,0 +1,50 @@
/*
11/4/20 by Stratovarius
Frost Folk Ice Blast
Frost folk can produce a 20-foot cone of icy
mist from their left eye. This deals 2d6 points of cold damage
to all creatures within the area (Reflex save
DC 13 half). The save DC is Constitution-based. Once a frost folk uses his ice blast,
he must wait 1d4 rounds before he can
use this ability again
*/
#include "prc_inc_function"
void main()
{
object oPC = OBJECT_SELF;
if (!GetLocalInt(oPC, "FrostFolkDelay"))
{
object oTarget = PRCGetSpellTargetObject();
int nDC = 10 + GetHitDice(oPC)/2 + GetAbilityModifier(ABILITY_CONSTITUTION, oPC);
effect eVis = EffectVisualEffect(VFX_IMP_FROST_S);
//Get the first target in the radius around the caster
oTarget = MyFirstObjectInShape(SHAPE_SPELLCONE, FeetToMeters(20.0), PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{
if(oTarget != oPC)
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
int nDamage = d6(2);
//Run the damage through the various reflex save and evasion feats
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, nDC, SAVING_THROW_TYPE_COLD);
if(nDamage > 0)
{
SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_COLD), oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}
//Get the next target in the specified area around the caster
oTarget = MyNextObjectInShape(SHAPE_SPELLCONE, FeetToMeters(20.0), PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
}
SetLocalInt(oPC, "FrostFolkDelay", TRUE);
float fDelay = RoundsToSeconds(d4());
DelayCommand(fDelay, DeleteLocalInt(oPC, "FrostFolkDelay"));
DelayCommand(fDelay, FloatingTextStringOnCreature("You may use your Ice Blast again", oPC));
}
}

View File

@@ -0,0 +1,16 @@
/*
06/11/21 by Stratovarius
Unearthly Grace: A gloura gains a deflection bonus to Armor Class and all saving throws equal to its Charisma modifier
*/
#include "prc_inc_function"
void main()
{
object oCaster = PRCGetSpellTargetObject();
int nBonus = GetAbilityModifier(ABILITY_CHARISMA, oCaster);
//FloatingTextStringOnCreature("Applying Unearthly Grace "+IntToString(nBonus), oCaster, FALSE);
effect eLink = EffectLinkEffects(EffectACIncrease(nBonus, AC_DEFLECTION_BONUS), EffectSavingThrowIncrease(SAVING_THROW_ALL, nBonus, SAVING_THROW_TYPE_ALL));
if (nBonus > 0) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oCaster, 9999.0);
}

View File

@@ -0,0 +1,50 @@
/*
28/10/21 by Stratovarius
Speed from Pain (Ex) Each time a hadrimoi takes damage,
the fibrous tendrils that make up its body become
increasingly elastic and responsive. The hadrimoi gains
a +2 dodge bonus to AC, a +1 bonus on attack rolls and
Reflex saves, and a +10-foot bonus to its land speed.
These benefits last for 1 minute starting in the round
during which a hadrimoi first takes damage in the
encounter.
Bonuses stack each time a hadrimoi takes damage,
to a maximum of a +10 dodge bonus to AC, a +5
bonus on attack rolls and Reflex saves, and a +50-foot
bonus to land speed. These bonuses accrue each time
a hadrimoi takes damage during that minute, even
from multiple attacks in the same round. At the end of
that minute, all these bonuses disappear. They could
begin accumulating again if the hadremoi takes more
damage.
*/
#include "prc_inc_function"
void main()
{
object oCaster = OBJECT_SELF;
//FloatingTextStringOnCreature(GetName(GetLastDamager())+ " hit me for "+IntToString(GetTotalDamageDealt()), oCaster, FALSE);
int nStrength = GetLocalInt(oCaster, "SpeedFromPain");
// First time here
if (!nStrength)
{
SetLocalInt(oCaster, "SpeedFromPain", 1);
DelayCommand(60.0, DeleteLocalInt(oCaster, "SpeedFromPain"));
DelayCommand(60.0, FloatingTextStringOnCreature("Speed from Pain reset", oCaster, FALSE));
DelayCommand(60.0, PRCRemoveSpellEffects(SPELL_HADRIMOI_STRENGTH, oCaster, oCaster));
DelayCommand(60.0, GZPRCRemoveSpellEffects(SPELL_HADRIMOI_STRENGTH, oCaster, FALSE));
DelayCommand(60.0, ExecuteScript("prc_speed", oCaster));
}
else if (5 > nStrength) // nStrength equals something, can't go above five
SetLocalInt(oCaster, "SpeedFromPain", nStrength + 1);
PRCRemoveSpellEffects(SPELL_HADRIMOI_STRENGTH, oCaster, oCaster);
GZPRCRemoveSpellEffects(SPELL_HADRIMOI_STRENGTH, oCaster, FALSE);
ActionCastSpellOnSelf(SPELL_HADRIMOI_STRENGTH);
//FloatingTextStringOnCreature("Lesser Strength from Pain at "+IntToString(nStrength+1), oCaster, FALSE);
}

View File

@@ -0,0 +1,38 @@
/*
28/10/21 by Stratovarius
Speed from Pain (Ex) Each time a hadrimoi takes damage,
the fibrous tendrils that make up its body become
increasingly elastic and responsive. The hadrimoi gains
a +2 dodge bonus to AC, a +1 bonus on attack rolls and
Reflex saves, and a +10-foot bonus to its land speed.
These benefits last for 1 minute starting in the round
during which a hadrimoi first takes damage in the
encounter.
Bonuses stack each time a hadrimoi takes damage,
to a maximum of a +10 dodge bonus to AC, a +5
bonus on attack rolls and Reflex saves, and a +50-foot
bonus to land speed. These bonuses accrue each time
a hadrimoi takes damage during that minute, even
from multiple attacks in the same round. At the end of
that minute, all these bonuses disappear. They could
begin accumulating again if the hadremoi takes more
damage.
*/
#include "prc_inc_function"
void main()
{
object oCaster = PRCGetSpellTargetObject();
int nBonus = GetLocalInt(oCaster, "SpeedFromPain");
effect eLink = EffectLinkEffects(EffectACIncrease(nBonus*2, AC_DODGE_BONUS), EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nBonus));
eLink = EffectLinkEffects(eLink, EffectAttackIncrease(nBonus));
ExecuteScript("prc_speed", oCaster);
if (nBonus >= 3) IPSafeAddItemProperty(GetPCSkin(oCaster), ItemPropertyBonusFeat(IP_CONST_FEAT_SPRINGATTACK), 60.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
FloatingTextStringOnCreature("Applying Speed from Pain for "+IntToString(nBonus), oCaster, FALSE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oCaster, 60.0);
}

View File

@@ -0,0 +1,211 @@
/*
Script for all racial abilities / penalties that require a heartbeat check
*/
#include "prc_inc_spells"
void main()
{
object oPC = OBJECT_SELF;
object oArea = GetArea(oPC);
object oSkin = GetPCSkin(oPC);
int bHasLightSensitive = GetHasFeat(FEAT_LTSENSE, oPC);
int bHasLightBlindness = GetHasFeat(FEAT_LTBLIND, oPC);
if(bHasLightSensitive || bHasLightBlindness)
{
int bIsEffectedByLight = FALSE;
if(GetIsObjectValid(oArea)
&& !GetHasFeat(FEAT_DAYLIGHTADAPT, oPC)
&& !GetHasFeat(FEAT_NS_LIGHT_ADAPTION, oPC)
&& GetIsDay()
&& GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND
&& !GetIsAreaInterior(oArea))
bIsEffectedByLight = TRUE;
// light sensitivity
// those with lightblindess are also sensitive
if(bIsEffectedByLight)
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDazzle(), oPC, 6.5);
// light blindness
if(bHasLightBlindness && bIsEffectedByLight)
{
// on first entering bright light
// cause blindness for 1 round
if(!GetLocalInt(oPC, "EnteredDaylight"))
{
effect eBlind = EffectBlindness();
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, oPC, 5.99);
SetLocalInt(oPC, "EnteredDaylight", TRUE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDazzle(), oPC, 6.5);
}
}
if(!bIsEffectedByLight && GetLocalInt(oPC, "EnteredDaylight"))
DeleteLocalInt(oPC, "EnteredDaylight");
}
// imaskari underground hide bonus
//this is in addition to the normal bonus
if(GetHasFeat(FEAT_SA_HIDEU, oPC))
{
if(GetIsAreaAboveGround(oArea) == AREA_UNDERGROUND)
SetCompositeBonus(oSkin, "SA_Hide_Underground", 2, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "SA_Hide_Underground", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
// troglodyte underground hide bonus
//this is in addition to the normal bonus
if(GetHasFeat(FEAT_SA_HIDE_TROG, oPC))
{
if(GetIsAreaAboveGround(oArea) == AREA_UNDERGROUND)
SetCompositeBonus(oSkin, "SA_Hide_Underground", 4, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "SA_Hide_Underground", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
// forest gnomes bonus to hide in the woods
//this is in addition to the normal bonus
if(GetHasFeat(FEAT_SA_HIDEF, oPC) || GetHasFeat(FEAT_BONUS_BAMBOO, oPC))
{
if(GetIsAreaNatural(oArea) == AREA_NATURAL
&& GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
SetCompositeBonus(oSkin, "SA_Hide_Forest", 4, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "SA_Hide_Forest", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
// grig bonus to hide in the woods
if(GetHasFeat(FEAT_SA_HIDEF_5, oPC))
{
if(GetIsAreaNatural(oArea) == AREA_NATURAL &&
GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
SetCompositeBonus(oSkin, "SA_Hide_Forest", 5, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "SA_Hide_Forest", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
// ranger Camouflage
if(GetHasFeat(FEAT_CAMOUFLAGE, oPC))
{
if(GetIsAreaNatural(oArea) == AREA_NATURAL &&
GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
SetCompositeBonus(oSkin, "Cls_Camouflage", 5, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "Cls_Camouflage", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
//Chameleon Skin Hide bonus for Poison Dusk Lizardfolk
//+5 to Hide if most of skin is uncovered
if(GetHasFeat(FEAT_CHAMELEON, oPC))
{
if(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC) == OBJECT_INVALID)
SetCompositeBonus(oSkin, "Chameleon", 5, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "Chameleon", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
// Krinth Shadowstrike is done as interior areas, applies to melee only
if(GetHasFeat(FEAT_SHADOWSTRIKE, oPC) && GetIsAreaInterior(oArea) && IPGetIsMeleeWeapon(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)))
{
effect eShadow = EffectLinkEffects(EffectAttackIncrease(1), EffectDamageIncrease(DAMAGE_BONUS_1d6, DAMAGE_TYPE_BASE_WEAPON));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eShadow), oPC, 6.0);
}
// Treebrother WOL bonus to Hide/MS
if(GetIsObjectValid(GetItemPossessedBy(oPC, "WOL_Treebrother")) && GetHitDice(oPC) >= 10)
{
if(GetIsAreaNatural(oArea) == AREA_NATURAL && GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
{
SetCompositeBonus(oSkin, "TreebrotherH", 5, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
SetCompositeBonus(oSkin, "TreebrotherMS", 5, ITEM_PROPERTY_SKILL_BONUS, SKILL_MOVE_SILENTLY);
}
else
{
SetCompositeBonus(oSkin, "TreebrotherH", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
SetCompositeBonus(oSkin, "TreebrotherMS", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_MOVE_SILENTLY);
}
}
// Bhuka Sandskimming hackjob
if(GetRacialType(oPC) == RACIAL_TYPE_BHUKA && GetIsAreaNatural(oArea) == AREA_NATURAL && GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
{
effect eLook = GetFirstEffect(oPC);
while(GetIsEffectValid(eLook))
{
if(GetEffectType(eLook) == EFFECT_TYPE_MOVEMENT_SPEED_DECREASE)
{
RemoveEffect(oPC, eLook);
}
eLook = GetNextEffect(oPC);
}
}
if(GetRacialType(oPC) == RACIAL_TYPE_FROST_FOLK)
{
if(GetWeather(oArea) == WEATHER_SNOW)
SetCompositeBonus(oSkin, "FrostFolkHide", 8, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "FrostFolkHide", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
}
if(GetRacialType(oPC) == RACIAL_TYPE_ULDRA)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamageIncrease(DAMAGE_BONUS_1, DAMAGE_TYPE_COLD), oPC, 6.0);
}
if(GetRacialType(oPC) == RACIAL_TYPE_SHARAKIM)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(VersusRacialTypeEffect(EffectAttackIncrease(1), RACIAL_TYPE_HUMANOID_ORC)), oPC, 6.0);
if(GetIsNight())
{
SetCompositeBonus(oSkin, "Sharakhim_H", 2, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
SetCompositeBonus(oSkin, "Sharakhim_S", 2, ITEM_PROPERTY_SKILL_BONUS, SKILL_SPOT);
SetCompositeBonus(oSkin, "Sharakhim_M", 2, ITEM_PROPERTY_SKILL_BONUS, SKILL_MOVE_SILENTLY);
SetCompositeBonus(oSkin, "Sharakhim_R", 2, ITEM_PROPERTY_SKILL_BONUS, SKILL_SEARCH);
}
else
{
SetCompositeBonus(oSkin, "Sharakhim_H", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
SetCompositeBonus(oSkin, "Sharakhim_S", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_SPOT);
SetCompositeBonus(oSkin, "Sharakhim_M", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_MOVE_SILENTLY);
SetCompositeBonus(oSkin, "Sharakhim_R", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_SEARCH);
}
}
// Underfolk Camo
if(GetRacialType(oPC) == RACIAL_TYPE_UNDERFOLK)
{
if(GetIsAreaNatural(oArea) == AREA_NATURAL)
SetCompositeBonus(oSkin, "Underfolk_H", 10, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE);
else
SetCompositeBonus(oSkin, "Underfolk_H", 4, ITEM_PROPERTY_SKILL_BONUS, SKILL_HIDE); // Yes, they always have a +4 minimum
}
if (GetIsPC(oPC) == TRUE && GetPRCSwitch(PRC_CHICKEN_INFESTED) && GetLevelByClass(CLASS_TYPE_COMMONER, oPC))
{
MultisummonPreSummon();
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectSummonCreature("prc_chicken"), GetLocation(oPC), HoursToSeconds(GetPRCSwitch(PRC_CHICKEN_INFESTED)));
}
if (GetRacialType(oPC) == RACIAL_TYPE_SKULK && GetActionMode(oPC, ACTION_MODE_STEALTH))
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectMovementSpeedIncrease(99)), oPC, 6.0);
if (GetRacialType(oPC) == RACIAL_TYPE_HYBSIL)
{
if(GetIsAreaNatural(oArea) == AREA_NATURAL && GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND)
{
SetCompositeBonus(oSkin, "HybsilSearch", 4, ITEM_PROPERTY_SKILL_BONUS, SKILL_SEARCH);
SetCompositeBonus(oSkin, "HybsilDisable", 4, ITEM_PROPERTY_SKILL_BONUS, SKILL_DISABLE_TRAP);
}
else
{
SetCompositeBonus(oSkin, "HybsilSearch", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_SEARCH);
SetCompositeBonus(oSkin, "HybsilDisable", 0, ITEM_PROPERTY_SKILL_BONUS, SKILL_DISABLE_TRAP);
}
}
}

View File

@@ -0,0 +1,44 @@
/* Kapak Saliva ability
Male: 1d6/1d6 dex damage, DC 18
Female: 2d6 heal, every 4 hours for each creature, can't use on self*/
#include "prc_inc_fork"
#include "prc_x2_itemprop"
void main()
{
object oPC = OBJECT_SELF;
int nGender = GetGender(oPC);
if(nGender == GENDER_MALE)
{
object oItem = PRCGetSpellTargetObject();
//weapons only
if(!GetIsWeapon(oItem))
return;
itemproperty ipPoison = ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_KAPAK_POISON, GetHitDice(oPC));
effect eVis = EffectVisualEffect(VFX_IMP_HEAD_ACID);
//poison lasts for 3 rounds
IPSafeAddItemProperty(oItem, ipPoison, RoundsToSeconds(3), X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
}
else if(nGender == GENDER_FEMALE)
{
object oCreature = PRCGetSpellTargetObject();
//if HD is 0 or below, not a creature
if(GetHitDice(oCreature) < 1)
return;
effect eHeal = EffectHeal(d6(2));
//Make sure it's the first time or been over 4 hours
int nHealed = GetLocalInt(oCreature, "KapakHealLock");
if(nHealed == TRUE) return;
//apply the heal
effect eVis = EffectVisualEffect(VFX_IMP_HEALING_M);
effect eLink = EffectLinkEffects(eVis, eHeal);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oCreature);
//set the haling lock
SetLocalInt(oCreature, "KapakHealLock", TRUE);
DelayCommand(HoursToSeconds(4), DeleteLocalInt(oCreature, "KapakHealLock"));
}
}

View File

@@ -0,0 +1,57 @@
//::///////////////////////////////////////////////
//:: OnHit Firedamage
//:: x2_s3_flamgind
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
OnHit Castspell Fire Damage property for the
flaming weapon spell (x2_s0_flmeweap).
We need to use this property because we can not
add random elemental damage to a weapon in any
other way and implementation should be as close
as possible to the book.
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-07-17
//:://////////////////////////////////////////////
/// altered Dec 15, 2003 by mr_bumpkin for prc stuff.
/// altered Apr 7, 2007 by motu99
// Converted to control Kapak poison Feb 10, 2008 by Fox
#include "prc_inc_spells"
#include "prc_inc_onhit"
void main()
{
//string toSay = " Self: " + GetTag(OBJECT_SELF) + " Item: " + GetTag(GetSpellCastItem());
//SendMessageToPC(OBJECT_SELF, toSay);
// GetTag(OBJECT_SELF) was nothing, just "" and the SendMessageToPC sent the message to my player.
// It's funny because I thought player characters had tags :-? So who knows what to make of it?
object oSpellOrigin = OBJECT_SELF;
// route all onhit-cast spells through the unique power script (hardcoded to "prc_onhitcast")
// in order to fix the Bioware bug, that only executes the first onhitcast spell found on an item
// any onhitcast spell should have the check ContinueOnHitCast() at the beginning of its code
// if you want to force the execution of an onhitcast spell script, that has the check, without routing the call
// through prc_onhitcast, you must use ForceExecuteSpellScript(), to be found in prc_inc_spells
if(!ContinueOnHitCastSpell(oSpellOrigin)) return;
// find the weapon on which the Flame Weapon spell resides
object oWeapon = PRCGetSpellCastItem(oSpellOrigin);
// find the target of the spell
object oTarget = PRCGetSpellTargetObject(oSpellOrigin);
// only do anything, if we have a valid weapon, and a valid living target
if (GetIsObjectValid(oWeapon) && GetIsObjectValid(oTarget)&& !GetIsDead(oTarget))
{
effect ePoison = EffectPoison(POISON_GIANT_WASP_POISON);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoison, oTarget);
}
}

View File

@@ -0,0 +1,20 @@
// Killoren Aspect of the Ancient
#include "prc_alterations"
void main()
{
object oPC = OBJECT_SELF;
int nBonus = GetHitDice(oPC);
if (GetHasFeat(FEAT_KILLOREN_ANCIENT, oPC)) nBonus += 4;
effect eLore = SupernaturalEffect(EffectSkillIncrease(SKILL_LORE, nBonus));
SetLocalInt(oPC, "KillorenAncient", TRUE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLore, oPC, HoursToSeconds(24));
DecrementRemainingFeatUses(oPC, FEAT_KILLOREN_ASPECT_H);
DecrementRemainingFeatUses(oPC, FEAT_KILLOREN_ASPECT_D);
}

View File

@@ -0,0 +1,22 @@
/* Killoren Hunter, detect enemies in area*/
#include "prc_inc_spells"
void main()
{
object oPC = OBJECT_SELF;
if(!GetLocalInt(oPC, "KillorenHunter")) return;
location lTarget = GetLocation(oPC);
//Get the first target in the radius around the caster
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget);
while(GetIsObjectValid(oTarget))
{
FloatingTextStringOnCreature("A "+GetName(oTarget)+" approaches", oPC, FALSE);
//Get the next target in the specified area around the caster
oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget);
}
}

View File

@@ -0,0 +1,22 @@
// Killoren Aspect of the Hunter
#include "prc_alterations"
void main()
{
object oPC = OBJECT_SELF;
object oSkin = GetPCSkin(oPC);
itemproperty iKill = PRCItemPropertyBonusFeat(IP_CONST_FEAT_BLOODED);
AddItemProperty(DURATION_TYPE_TEMPORARY, iKill, oSkin, HoursToSeconds(24));
effect eLink = EffectLinkEffects(EffectSkillIncrease(SKILL_HIDE, 2), EffectSkillIncrease(SKILL_MOVE_SILENTLY, 2));
eLink = EffectLinkEffects(EffectSkillIncrease(SKILL_LISTEN, 2), eLink);
effect eLore = SupernaturalEffect(eLink);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLore, oPC, HoursToSeconds(24));
DecrementRemainingFeatUses(oPC, FEAT_KILLOREN_ASPECT_A);
DecrementRemainingFeatUses(oPC, FEAT_KILLOREN_ASPECT_D);
SetLocalInt(oPC, "KillorenHunter", TRUE);
}

View File

@@ -0,0 +1,46 @@
#include "prc_inc_smite"
void main()
{
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nRace = MyPRCGetRacialType(oTarget);
DecrementRemainingFeatUses(oPC, FEAT_KILLOREN_ASPECT_A);
DecrementRemainingFeatUses(oPC, FEAT_KILLOREN_ASPECT_H);
if(nRace == RACIAL_TYPE_DWARF
|| nRace == RACIAL_TYPE_ELF
|| nRace == RACIAL_TYPE_GNOME
|| nRace == RACIAL_TYPE_HALFLING
|| nRace == RACIAL_TYPE_HALFELF
|| nRace == RACIAL_TYPE_HALFORC
|| nRace == RACIAL_TYPE_HUMAN
|| nRace == RACIAL_TYPE_HUMANOID_GOBLINOID
|| nRace == RACIAL_TYPE_HUMANOID_MONSTROUS
|| nRace == RACIAL_TYPE_HUMANOID_ORC
|| nRace == RACIAL_TYPE_HUMANOID_REPTILIAN
|| nRace == RACIAL_TYPE_ABERRATION
|| nRace == RACIAL_TYPE_CONSTRUCT
|| nRace == RACIAL_TYPE_OOZE
|| nRace == RACIAL_TYPE_OUTSIDER
|| nRace == RACIAL_TYPE_UNDEAD)
DoSmite(oPC, oTarget, SMITE_TYPE_KILLOREN);
if (GetLocalInt(oTarget, "PRCCombat_StruckByAttack") && GetHasFeat(FEAT_KILLOREN_DESTROYER, oPC))
{
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
effect eDaze = EffectDazed();
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eLink = EffectLinkEffects(eMind, eDaze);
eLink = EffectLinkEffects(eLink, eDur);
int nDC = 10 + GetHitDice(oPC)/2 + GetAbilityModifier(ABILITY_CHARISMA, oPC);
//Make Will Save to negate effect
if (!/*Will Save*/ PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_NONE))
{
//Apply VFX Impact and daze effect
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, 6.0);
}
}
}

View File

@@ -0,0 +1,46 @@
/*
27/10/21 by Stratovarius
Lesser Strength from Pain (Ex) Whenever a lashemoi takes
damage from any source, it gains a +1 bonus on attack
rolls, a +1 bonus on damage rolls, and its natural armor
bonus to AC increases by 1. These benefits last for 1
minute starting in the round during which a lashemoi
first takes damage in the encounter.
Bonuses stack each time a lashemoi takes damage, to
a maximum of a +5 bonus on attack rolls, a +5 bonus on
damage rolls, and a +5 natural armor bonus to AC. These
bonuses accrue each time a lashemoi takes damage
during that minute, even from multiple attacks in the
same round. At the end of that minute, all these bonuses
disappear. They could begin accumulating again if the
lashemoi takes more damage
*/
#include "prc_inc_function"
void main()
{
object oCaster = OBJECT_SELF;
//FloatingTextStringOnCreature(GetName(GetLastDamager())+ " hit me for "+IntToString(GetTotalDamageDealt()), oCaster, FALSE);
int nStrength = GetLocalInt(oCaster, "LesserStrengthFromPain");
// First time here
if (!nStrength)
{
SetLocalInt(oCaster, "LesserStrengthFromPain", 1);
DelayCommand(60.0, DeleteLocalInt(oCaster, "LesserStrengthFromPain"));
DelayCommand(60.0, FloatingTextStringOnCreature("Lesser Strength from Pain reset", oCaster, FALSE));
DelayCommand(60.0, PRCRemoveSpellEffects(SPELL_LASHEMOI_STRENGTH, oCaster, oCaster));
DelayCommand(60.0, GZPRCRemoveSpellEffects(SPELL_LASHEMOI_STRENGTH, oCaster, FALSE));
}
else if (5 > nStrength) // nStrength equals something, can't go above five
SetLocalInt(oCaster, "LesserStrengthFromPain", nStrength + 1);
PRCRemoveSpellEffects(SPELL_LASHEMOI_STRENGTH, oCaster, oCaster);
GZPRCRemoveSpellEffects(SPELL_LASHEMOI_STRENGTH, oCaster, FALSE);
ActionCastSpellOnSelf(SPELL_LASHEMOI_STRENGTH);
//FloatingTextStringOnCreature("Lesser Strength from Pain at "+IntToString(nStrength+1), oCaster, FALSE);
}

View File

@@ -0,0 +1,34 @@
/*
27/10/21 by Stratovarius
Strength from Magic (Ex) Each time an arkamoi casts an
arcane spell, magical feedback grants it a rush of power.
For each arcane spell cast, an arkamoi increases the save
DC of subsequent arcane spells it casts by 1. Additionally,
the arkamoi gains a +2 bonus on damage rolls for
subsequent spells, and gains a +2 deflection bonus to
AC. These benefits last for 1 minute starting in the round
during which the arkamoi finishes casting its first spell of
the encounter.
Bonuses stack each time an arkamoi casts an arcane
spell within that minute, to a maximum of a +5 bonus
to save DCs, a +10 bonus on damage rolls, and a +10
deflection bonus to AC. At the end of that minute, all
these bonuses disappear. They could begin accumulating
again if the arkemoi casts more spells.
*/
#include "prc_inc_function"
void main()
{
object oCaster = PRCGetSpellTargetObject();
int nBonus = GetLocalInt(oCaster, "LesserStrengthFromPain");
effect eLink = EffectLinkEffects(EffectACIncrease(nBonus, AC_NATURAL_BONUS), EffectDamageIncrease(nBonus, DAMAGE_TYPE_SLASHING | DAMAGE_TYPE_BLUDGEONING | DAMAGE_TYPE_PIERCING));
eLink = EffectLinkEffects(eLink, EffectAttackIncrease(nBonus));
FloatingTextStringOnCreature("Applying Lesser Strength from Pain for "+IntToString(nBonus), oCaster, FALSE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oCaster, 60.0);
}

View File

@@ -0,0 +1,190 @@
//:://////////////////////////////////////////////
//:: Life Path conversation script
//:: race_lifepthconv
//:://////////////////////////////////////////////
/** @file
This script controls the feat selection
conversation for Tinker Gnomes
@author Primogenitor - Orinigal
@author Ornedan - Modifications
@author Fox - ripped from Psionics convo
@date Modified - 2005.03.13
@date Modified - 2005.09.23
@date Modified - 2008.01.25
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
/*#include "prc_alterations"
#include "inc_dynconv"
#include "inc_nwnx_funcs"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
/*const int STAGE_SELECT_LIFEPATH = 0;
const int STAGE_LIFEPATH_SELECTED = 1;
const int STAGE_CONFIRM_SELECTION = 2;
const int CHOICE_BACK_TO_LSELECT = -1;
const int STRREF_LEVELLIST_HEADER = 16833128; // "Select a guild to pursue your Life Quest in:"
const int STRREF_SELECTED_HEADER1 = 16824209; // "You have selected:"
const int STRREF_SELECTED_HEADER2 = 16824210; // "Is this correct?"
const int STRREF_END_HEADER = 16833129; // "Your Life Path has been selected."
const int STRREF_END_CONVO_SELECT = 16824212; // "Finish"
const int STRREF_YES = 4752; // "Yes"
const int STRREF_NO = 4753; // "No"
//////////////////////////////////////////////////
/* Function defintions */
//////////////////////////////////////////////////
/*void main()
{
object oPC = GetPCSpeaker();
object oSkin = GetPCSkin(oPC);
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
int nStage = GetStage(oPC);
int bFuncs = GetPRCSwitch(PRC_NWNX_FUNCS);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
if(DEBUG) DoDebug("race_lifepthconv: Running setup stage for stage " + IntToString(nStage));
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
if(DEBUG) DoDebug("race_lifepthconv: Stage was not set up already");
// Level selection stage
if(nStage == STAGE_SELECT_LIFEPATH)
{
if(DEBUG) DoDebug("race_lifepthconv: Building guild selection");
SetHeader(GetStringByStrRef(STRREF_LEVELLIST_HEADER));
// Set the tokens
int i = 0;
AddChoice(GetStringByStrRef(16834289), 1);// "Craft Guild"
AddChoice(GetStringByStrRef(16834291), 2);// "Tech Guild"
AddChoice(GetStringByStrRef(16834293), 3);// "Sage Guild"
// Set the next, previous and wait tokens to default values
SetDefaultTokens();
// Set the convo quit text to "Abort"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_ABORT_CONVO));
}
// Selection confirmation stage
else if(nStage == STAGE_CONFIRM_SELECTION)
{
if(DEBUG) DoDebug("race_lifepthconv: Building selection confirmation");
// Build the confirmantion query
string sToken = GetStringByStrRef(STRREF_SELECTED_HEADER1) + "\n\n"; // "You have selected:"
int nGuild = GetLocalInt(oPC, "nGuild");
if(nGuild == 1)
sToken += GetStringByStrRef(16834290);
//"Craft Guild \n\nYou are a member of one of the gnomish crafting guilds. You gain a +2 bonus to crafting skills.";
else if(nGuild == 2)
sToken += GetStringByStrRef(16834292);
//"Tech Guild \n\nYou are a member of one of the gnomish technology guilds. You gain a +1 bonus to crafting skills and Lore.";
else if(nGuild == 3)
sToken += GetStringByStrRef(16834294);
//"Sage Guild \n\nYou are a member of one of the gnomish research guilds. You gain a +2 bonus to Lore.";
sToken += GetStringByStrRef(STRREF_SELECTED_HEADER2); // "Is this correct?"
SetHeader(sToken);
AddChoice(GetStringByStrRef(STRREF_YES), TRUE, oPC); // "Yes"
AddChoice(GetStringByStrRef(STRREF_NO), FALSE, oPC); // "No"
}
// Conversation finished stage
else if(nStage == STAGE_LIFEPATH_SELECTED)
{
if(DEBUG) DoDebug("race_lifepthconv: Building finish note");
SetHeader(GetStringByStrRef(STRREF_END_HEADER));
// Set the convo quit text to "Finish"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(STRREF_END_CONVO_SELECT));
AllowExit(DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, FALSE, oPC);
}
}
// Do token setup
SetupTokens();
}
else if(nValue == DYNCONV_EXITED)
{
if(DEBUG) DoDebug("race_lifepthconv: Running exit handler");
// End of conversation cleanup
DeleteLocalInt(oPC, "nGuild");
}
else if(nValue == DYNCONV_ABORTED)
{
// This section should never be run, since aborting this conversation should
// always be forbidden and as such, any attempts to abort the conversation
// should be handled transparently by the system
if(DEBUG) DoDebug("race_lifepthconv: ERROR: Conversation abort section run");
}
// Handle PC response
else
{
int nChoice = GetChoice(oPC);
if(DEBUG) DoDebug("race_lifepthconv: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " + IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
if(nStage == STAGE_SELECT_LIFEPATH)
{
if(DEBUG) DoDebug("race_lifepthconv: Guild selected. Entering Confirmation.");
SetLocalInt(oPC, "nGuild", nChoice);
nStage = STAGE_CONFIRM_SELECTION;
}
else if(nStage == STAGE_CONFIRM_SELECTION)
{
if(DEBUG) DoDebug("race_lifepthconv: Handling guild confirmation");
if(nChoice == TRUE)
{
if(DEBUG) DoDebug("race_lifepthconv: Marking Guild");
int nGuild = GetLocalInt(oPC, "nGuild");
itemproperty ipIP;
int nFeat;
if(nGuild == 1)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_CRAFTGUILD);
nFeat = FEAT_CRAFTGUILD;
}
else if(nGuild == 2)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_TECHGUILD);
nFeat = FEAT_TECHGUILD;
}
else if(nGuild == 3)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SAGEGUILD);
nFeat = FEAT_SAGEGUILD;
}
if(bFuncs)
PRC_Funcs_AddFeat(oPC, nFeat);
else
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
nStage = STAGE_LIFEPATH_SELECTED;
}
else
nStage = STAGE_SELECT_LIFEPATH;
}
if(DEBUG) DoDebug("race_lifepthconv: New stage: " + IntToString(nStage));
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}*/
void main()
{
}

View File

@@ -0,0 +1,37 @@
/*
13/4/20 by Stratovarius
Once per day, a marrulurk can
breathe a 10-foot cone of nauseating gas as a free action. All
creatures except other marrulurks
within the area must succeed on a DC
13 Fortitude save or be nauseated 1
round. The save DC is Constitutionbased
*/
#include "prc_inc_function"
void main()
{
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nDC = 10 + GetHitDice(oPC)/2 + GetAbilityModifier(ABILITY_CONSTITUTION, oPC);
effect eVis = EffectVisualEffect(VFX_IMP_DISEASE_S);
//Get the first target in the radius around the caster
oTarget = MyFirstObjectInShape(SHAPE_SPELLCONE, FeetToMeters(10.0), PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
while(GetIsObjectValid(oTarget))
{
if((GetRacialType(oTarget) != RACIAL_TYPE_MARRULURK))
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
if (!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC))
{
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectNausea(oTarget, 6.0), oTarget, 6.0);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}
//Get the next target in the specified area around the caster
oTarget = MyNextObjectInShape(SHAPE_SPELLCONE, FeetToMeters(10.0), PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
}
}

View File

@@ -0,0 +1,32 @@
//::///////////////////////////////////////////////
//:: Name Marrusault Howl
//:: FileName race_mars_howl
//::
//:://////////////////////////////////////////////
#include "prc_inc_template"
void main()
{
location lTarget = GetLocation(OBJECT_SELF);
// Declare the spell shape, size and the location. Capture the first target object in the shape.
// Cycle through the targets within the spell shape until an invalid object is captured.
int nDC = 10 + GetHitDice(OBJECT_SELF)/2 + GetAbilityModifier(ABILITY_CHARISMA);
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
while (GetIsObjectValid(oTarget))
{
if (GetRacialType(oTarget) != RACIAL_TYPE_MARRUSAULT)
{
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC))
{
// Fatigue outside of ten feet, exhausted within
if (MetersToFeet(GetDistanceBetween(OBJECT_SELF,oTarget)) > 10.0)
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectFatigue()), oTarget, HoursToSeconds(GetHitDice(OBJECT_SELF)));
else
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectExhausted()), oTarget, HoursToSeconds(GetHitDice(OBJECT_SELF)));
}
}
oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
}
}

View File

@@ -0,0 +1,30 @@
//::///////////////////////////////////////////////
//:: Name Marrutact Howl
//:: FileName race_mart_howl
//::
//:://////////////////////////////////////////////
#include "prc_inc_template"
void main()
{
location lTarget = GetLocation(OBJECT_SELF);
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
while (GetIsObjectValid(oTarget))
{
if (GetRacialType(oTarget) == RACIAL_TYPE_MARRUSAULT || GetRacialType(oTarget) == RACIAL_TYPE_MARRULURK || GetRacialType(oTarget) == RACIAL_TYPE_MARRUTACT)
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectHeal(d8(3)+5)), oTarget);
oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(30.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
}
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(10.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
while (GetIsObjectValid(oTarget))
{
if (GetRacialType(oTarget) == RACIAL_TYPE_MARRUSAULT || GetRacialType(oTarget) == RACIAL_TYPE_MARRULURK || GetRacialType(oTarget) == RACIAL_TYPE_MARRUTACT)
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectHeal(d8()+1)), oTarget);
oTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(10.0), lTarget, FALSE, OBJECT_TYPE_CREATURE);
}
}

View File

@@ -0,0 +1,93 @@
//::///////////////////////////////////////////////
//:: [Mephling Breath Weapon]
//:: [prc_mephbreath.nss]
//:: [Jaysyn / PRC 20220428]
//::///////////////////////////////////////////////
/**@file Each mephling has a breath weapon, the effect of which varies by the
mephling's heritage. An air mephling's breath weapon is a cone of dust and grit
(piercing damage), an earth mephling's breath weapon is a cone of rock shards
and pebbles (bludgeoning damage), a fire mephling's breath weapon is a cone of
flame (fire damage), and a water mephling's breath weapon is a cone of caustic
liquid (acid damage). Regardless of the effect, a mephling's breath weapon fills
a 15-foot cone, deals 1d8 points of damage to each target, and allows a Reflex
save (10 + 1/2 mephling's Hit Dice + mephling's Con modifier) for half damage.
A 1st level mephling can use his breath weapon once per day; a higher-level
mephling gains one additional use per day for every four levels he has attained.
If a mephling can use his breath weapon more than once per day, 1d4 rounds
must pass between consecutive uses of the breath weapon.
//////////////////////////////////////////////////////////////////////////////*/
#include "prc_inc_spells"
#include "prc_inc_breath"
#include "prc_inc_combat"
//:: Returns range in feet for breath struct. Conversion to meters is
//:: handled internally in the include
float GetRangeFromSize(int nSize)
{
float fRange = 15.0;
switch(nSize)
{
case CREATURE_SIZE_FINE:
case CREATURE_SIZE_DIMINUTIVE:
case CREATURE_SIZE_TINY: fRange = 10.0; break;
case CREATURE_SIZE_SMALL: fRange = 15.0; break;
case CREATURE_SIZE_MEDIUM: fRange = 20.0; break;
case CREATURE_SIZE_LARGE: fRange = 30.0; break;
case CREATURE_SIZE_HUGE: fRange = 40.0; break;
case CREATURE_SIZE_GARGANTUAN: fRange = 50.0; break;
case CREATURE_SIZE_COLOSSAL: fRange = 60.0; break;
}
return fRange;
}
void main()
{
//:: Declare major variables.
object oPC = OBJECT_SELF;
int nHD = GetHitDice(oPC);
int nSaveDCBonus = (nHD/2);
int nVis;
location lTarget = PRCGetSpellTargetLocation();
struct breath MephBreath;
//:: Range calculation
float fRange = GetRangeFromSize(PRCGetCreatureSize(oPC));
//:: Flat 1d8 damage breath weapon
int nDice = 1;
//:: Sanity check, mephlings only.
int nMephType = GetHasFeat(FEAT_AIR_MEPHLING, oPC) ? DAMAGE_TYPE_PIERCING :
GetHasFeat(FEAT_EARTH_MEPHLING, oPC) ? DAMAGE_TYPE_BLUDGEONING :
GetHasFeat(FEAT_FIRE_MEPHLING, oPC) ? DAMAGE_TYPE_FIRE :
GetHasFeat(FEAT_WATER_MEPHLING, oPC) ? DAMAGE_TYPE_ACID :
-1;
//:: Assemble breath weapon struct.
MephBreath = CreateBreath(oPC, 0, fRange, nMephType, 10, nDice, ABILITY_CONSTITUTION, nSaveDCBonus);
//:: Set breath weapon VFX.
switch(nMephType)
{
case DAMAGE_TYPE_FIRE: nVis = VFX_FNF_DRAGBREATHGROUND; break;
case DAMAGE_TYPE_ACID: nVis = VFX_FNF_DRAGBREATHACID; break;
case DAMAGE_TYPE_PIERCING: nVis = VFX_FNF_DRAGBREATHSONIC; break;
case DAMAGE_TYPE_BLUDGEONING: nVis = VFX_FNF_DRAGBREATHODD; break;
default: nVis = VFX_FNF_DRAGBREATHODD; break;
}
//:: Actual breath effect
ApplyBreath(MephBreath, lTarget);
//:: Breath weapon VFX
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(nVis), lTarget);
}

View File

@@ -0,0 +1,44 @@
//::///////////////////////////////////////////////
//:: [Squirt]
//:: [race_muck_squirt.nss]
//:: [Jaysyn / PRC 20220419]
//::///////////////////////////////////////////////
/**@file Squirt (Ex): A muckdweller can
squirt a jet of water into the eyes of
a target up to 25 feet away. Anyone
hit by this attack must make a DC 13
Reflex save or be blinded for 1 round. The
save DC is Dexterity-based.
/////////////////////////////////////////////////////////////////////////////*/
#include "prc_inc_spells"
#include "prc_add_spell_dc"
void main()
{
//:: Declare major varibles
object oCaster = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nDC = 10 + (GetAbilityModifier(1, oCaster));
float fDuration = RoundsToSeconds(1);
effect eVis = EffectVisualEffect(VFX_IMP_BLIND_DEAF_M);
effect eBlind = EffectBlindness();
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eLink = ExtraordinaryEffect(EffectLinkEffects(eBlind, eDur));
//:: Fire cast spell at event
SignalEvent(oTarget, EventSpellCastAt(oCaster, SPELL_MUCK_SQUIRT));
//:: Make Reflex save to negate
if (!PRCMySavingThrow(SAVING_THROW_REFLEX, oTarget, nDC))
{
//:: Apply visual and effects
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}

View File

@@ -0,0 +1,20 @@
/* Outburst racial ability for Maenads
-2 Int and Wis and +2 Str for 4 rounds.*/
//#include "prc_alterations"
void main()
{
object oPC = OBJECT_SELF;
effect eAbilDec = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
effect eAbilDec2 = EffectAbilityDecrease(ABILITY_WISDOM, 2);
effect eAbilInc = EffectAbilityIncrease(ABILITY_STRENGTH, 2);
effect eVis = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
effect eLink = EffectLinkEffects(eAbilDec, eAbilDec2);
eLink = EffectLinkEffects(eLink, eAbilInc);
eLink = EffectLinkEffects(eLink, eVis);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HOLY_AID), oPC);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oPC, RoundsToSeconds(4));
}

View File

@@ -0,0 +1,171 @@
//::///////////////////////////////////////////////
//:: Wild Shape
//:: NW_S2_WildShape
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 22, 2002
//:: Edited by Wyz_sub10, Oct 2004 for Pixie SA
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "prc_inc_spells"
//#include "x2_inc_spellhook"
#include "pnp_shft_poly"
void main()
{
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_TRANSMUTATION);
/*
Spellcast Hook Code
Added 2003-06-23 by GeorgZ
If you want to make changes to all spells,
check x2_inc_spellhook.nss to find out more
*/
if (!X2PreSpellCastCode())
{
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
return;
}
// End of Spell Cast Hook
//Declare major variables
int nSpell = GetSpellId();
object oTarget = PRCGetSpellTargetObject();
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
effect ePoly;
int nPoly;
int nMetaMagic = PRCGetMetaMagicFeat();
int nDuration = 8;
//Enter Metamagic conditions
if (nMetaMagic & METAMAGIC_EXTEND)
{
nDuration = nDuration *2; //Duration is +100%
}
//Determine Polymorph subradial type
if(nSpell == 1979)
{
nPoly = POLYMORPH_TYPE_BROWN_BEAR;
if (nDuration >= 12)
{
nPoly = POLYMORPH_TYPE_DIRE_BROWN_BEAR;
}
}
else if (nSpell == 1980)
{
nPoly = POLYMORPH_TYPE_PANTHER;
if (nDuration >= 12)
{
nPoly = POLYMORPH_TYPE_DIRE_PANTHER;
}
}
else if (nSpell == 1981)
{
nPoly = POLYMORPH_TYPE_WOLF;
if (nDuration >= 12)
{
nPoly = POLYMORPH_TYPE_DIRE_WOLF;
}
}
else if (nSpell == 1982)
{
nPoly = POLYMORPH_TYPE_BOAR;
if (nDuration >= 12)
{
nPoly = POLYMORPH_TYPE_DIRE_BOAR;
}
}
else if (nSpell == 1983)
{
nPoly = POLYMORPH_TYPE_BADGER;
if (nDuration >= 12)
{
nPoly = POLYMORPH_TYPE_DIRE_BADGER;
}
}
ePoly = EffectPolymorph(nPoly);
ePoly = ExtraordinaryEffect(ePoly);
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_WILD_SHAPE, FALSE));
int bWeapon = StringToInt(Get2DACache("polymorph","MergeW",nPoly)) == 1;
int bArmor = StringToInt(Get2DACache("polymorph","MergeA",nPoly)) == 1;
int bItems = StringToInt(Get2DACache("polymorph","MergeI",nPoly)) == 1;
object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF);
object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,OBJECT_SELF);
object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,OBJECT_SELF);
object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,OBJECT_SELF);
object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,OBJECT_SELF);
object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,OBJECT_SELF);
object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,OBJECT_SELF);
object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,OBJECT_SELF);
object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,OBJECT_SELF);
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,OBJECT_SELF);
if (GetIsObjectValid(oShield))
{
if (GetBaseItemType(oShield) !=BASE_ITEM_LARGESHIELD &&
GetBaseItemType(oShield) !=BASE_ITEM_SMALLSHIELD &&
GetBaseItemType(oShield) !=BASE_ITEM_SMALLSHIELD)
{
oShield = OBJECT_INVALID;
}
}
// abort if mounted
if (!GetLocalInt(GetModule(),"X3_NO_SHAPESHIFT_SPELL_CHECK"))
{ // check to see if abort due to being mounted
if (PRCHorseGetIsMounted(oTarget))
{ // abort
if (GetIsPC(oTarget)) FloatingTextStrRefOnCreature(111982,oTarget,FALSE);
return;
} // abort
} // check to see if abort due to being mounted
//this command will make shore that polymorph plays nice with the shifter
ShifterCheck(oTarget);
AssignCommand(oTarget, ClearAllActions()); // prevents an exploit
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePoly, oTarget, HoursToSeconds(nDuration),TRUE,-1,8);
DelayCommand(1.5,ActionCastSpellOnSelf(SPELL_SHAPE_INCREASE_DAMAGE));
//Apply the VFX impact and effects
//ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
//ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePoly, OBJECT_SELF, HoursToSeconds(nDuration));
object oWeaponNew = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF);
object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,OBJECT_SELF);
if (bWeapon)
{
IPWildShapeCopyItemProperties(oWeaponOld,oWeaponNew, TRUE);
}
if (bArmor)
{
IPWildShapeCopyItemProperties(oShield,oArmorNew);
IPWildShapeCopyItemProperties(oHelmetOld,oArmorNew);
IPWildShapeCopyItemProperties(oArmorOld,oArmorNew);
}
if (bItems)
{
IPWildShapeCopyItemProperties(oRing1Old,oArmorNew);
IPWildShapeCopyItemProperties(oRing2Old,oArmorNew);
IPWildShapeCopyItemProperties(oAmuletOld,oArmorNew);
IPWildShapeCopyItemProperties(oCloakOld,oArmorNew);
IPWildShapeCopyItemProperties(oBootsOld,oArmorNew);
IPWildShapeCopyItemProperties(oBeltOld,oArmorNew);
}
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
// Getting rid of the integer used to hold the spells spell school
}

View File

@@ -0,0 +1,8 @@
/*
*/
#include "psi_inc_psifunc"
void main()
{
UsePower(POWER_STOMP, CLASS_TYPE_INVALID, TRUE, GetHitDice(OBJECT_SELF)/2);
}

View File

@@ -0,0 +1,58 @@
//::///////////////////////////////////////////////
//:: Razor Storm
//:: race_razorstorm.nss
//:://////////////////////////////////////////////
/*
// 2d6 slashing in a 15' cone, Reflex save(10+Con) for half
*/
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Feb 8, 2008
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
//Declare major variables
float fDist;
int nDamage;
int nDC = 10 + GetAbilityModifier(ABILITY_CONSTITUTION);
effect eRazor;
effect eArmorPenalty = EffectACDecrease(2);
//Declare and assign personal impact visual effect.
effect eVis = EffectVisualEffect(VFX_IMP_SPIKE_TRAP);
int RzrDmg = ChangedElementalDamage(OBJECT_SELF, DAMAGE_TYPE_SLASHING);
//Declare the spell shape, size and the location. Capture the first target object in the shape.
object oTarget = MyFirstObjectInShape(SHAPE_SPELLCONE, FeetToMeters(15.0), GetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
//Cycle through the targets within the spell shape until an invalid object is captured.
while(GetIsObjectValid(oTarget))
{
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, OBJECT_SELF))
{
//Signal spell cast at event to fire.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_BLADELING_RAZOR_STORM));
//Calculate the delay time on the application of effects based on the distance
//between the caster and the target
fDist = GetDistanceBetween(OBJECT_SELF, oTarget)/20;
//Make saving throw.
nDamage = d6(2);
//Run the damage through the various reflex save and evasion feats
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, nDC, SAVING_THROW_TYPE_NONE);
eRazor = PRCEffectDamage(oTarget, nDamage, RzrDmg);
if(nDamage > 0)
{
// Apply effects to the currently selected target.
DelayCommand(fDist, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRazor, oTarget));
DelayCommand(fDist, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
}
}
//Select the next target within the spell shape.
oTarget = MyNextObjectInShape(SHAPE_SPELLCONE, FeetToMeters(15.0), GetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
}
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eArmorPenalty, OBJECT_SELF, HoursToSeconds(24));
}

View File

@@ -0,0 +1,20 @@
/* Resiliance racial ability for Elans
Piggybacks on the Psionic system as a "fake manifestation" similar to Diamond Dragons
To simulate damage prevention adds Temp HP for 1 round.*/
#include "psi_inc_psifunc"
#include "prc_sp_func"
void main()
{
object oManifester = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
struct manifestation manif =
EvaluateManifestation(oManifester, oTarget, PowerAugmentationProfile(PRC_NO_GENERIC_AUGMENTS, 1, PRC_UNLIMITED_AUGMENTATION), METAPSIONIC_NONE);
effect eHP = EffectTemporaryHitpoints(manif.nTimesAugOptUsed_1 * 2);
//Apply the VFX impact and effects
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eHP), oTarget, 6.0, TRUE, -1, 0);
}

View File

@@ -0,0 +1,25 @@
/* Resistance racial ability for Elans
Grants a save bonus for 1 round.*/
#include "psi_inc_psifunc"
#include "prc_sp_func"
void main()
{
object oTarget = PRCGetSpellTargetObject();
if(GetCurrentPowerPoints(OBJECT_SELF) > 0)
{
effect eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, 4);
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
//Apply the VFX impact and effects
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSave, oTarget, 6.0, TRUE, -1, 0);
//pay the PP cost
LosePowerPoints(OBJECT_SELF, 1);
}
}

View File

@@ -0,0 +1,43 @@
//::///////////////////////////////////////////////
//:: Name Rak disguise
//:: FileName race_rkdisguise
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
*/
//:://////////////////////////////////////////////
//:: Created By: Shane Hennessy
//:: Created On:
//:://////////////////////////////////////////////
// disguise for rak
#include "prc_alterations"
#include "pnp_shft_poly"
void main()
{
StoreAppearance(OBJECT_SELF);
int nCurForm = GetAppearanceType(OBJECT_SELF);
int nPCForm = GetTrueForm(OBJECT_SELF);
// Switch to lich
if (nPCForm == nCurForm)
{
effect eFx = EffectVisualEffect(VFX_IMP_MAGICAL_VISION);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eFx,OBJECT_SELF);
//SetCreatureAppearanceType(OBJECT_SELF, APPEARANCE_TYPE_HUMAN_NPC_FEMALE_12);
//any of the normal races will do
DoDisguise(Random(7));
}
else // Switch to PC
{
effect eFx = EffectVisualEffect(VFX_IMP_MAGICAL_VISION);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eFx,OBJECT_SELF);
//re-use unshifter code from shifter instead
//this will also remove complexities with lich/shifter characters
SetShiftTrueForm(OBJECT_SELF);
//SetCreatureAppearanceType(OBJECT_SELF,nPCForm);
}
}

View File

@@ -0,0 +1,259 @@
//:://////////////////////////////////////////////
//:: Shifter Trait conversation script
//:: race_shfttrt_con
//:://////////////////////////////////////////////
/** @file
This script controls the feat selection
conversation for Shifters
@author Primogenitor - Orinigal
@author Ornedan - Modifications
@author Fox - ripped from Psionics convo
@date Modified - 2005.03.13
@date Modified - 2005.09.23
@date Modified - 2008.01.25
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "inc_dynconv"
#include "inc_nwnx_funcs"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_SELECT_TRAIT = 0;
const int STAGE_TRAIT_SELECTED = 1;
const int STAGE_CONFIRM_SELECTION = 2;
const int CHOICE_BACK_TO_LSELECT = -1;
const int STRREF_LEVELLIST_HEADER = 16828148; // "Select a shifter trait to represent your lycanthrope heritage:"
const int STRREF_SELECTED_HEADER1 = 16824209; // "You have selected:"
const int STRREF_SELECTED_HEADER2 = 16824210; // "Is this correct?"
const int STRREF_END_HEADER = 16828149; // "Your trait has been selected."
const int STRREF_END_CONVO_SELECT = 16824212; // "Finish"
const int STRREF_YES = 4752; // "Yes"
const int STRREF_NO = 4753; // "No"
const int BEASTHIDE = 1;
const int DREAMSIGHT = 2;
const int GOREBRUTE = 3;
const int LONGSTRIDE = 4;
const int LONGTOOTH = 5;
const int RAZORCLAW = 6;
const int WILDHUNT = 7;
const int WINTERHIDE = 8;
//////////////////////////////////////////////////
/* Function defintions */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
object oSkin = GetPCSkin(oPC);
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
int nStage = GetStage(oPC);
int bFuncs = GetPRCSwitch(PRC_NWNX_FUNCS);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
if(DEBUG) DoDebug("race_shfttrt_con: Running setup stage for stage " + IntToString(nStage));
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
if(DEBUG) DoDebug("race_shfttrt_con: Stage was not set up already");
// Level selection stage
if(nStage == STAGE_SELECT_TRAIT)
{
if(DEBUG) DoDebug("race_shfttrt_con: Building guild selection");
SetHeader(GetStringByStrRef(STRREF_LEVELLIST_HEADER));
// Set the tokens
int i = 0;
if(!GetHasFeat(FEAT_SHIFTER_BEASTHIDE))
AddChoice(GetStringByStrRef(16828134), BEASTHIDE);// "Beasthide"
if(!GetHasFeat(FEAT_SHIFTER_DREAMSIGHT))
AddChoice(GetStringByStrRef(16828136), DREAMSIGHT);//"Dreamsight"
if(!GetHasFeat(FEAT_SHIFTER_GOREBRUTE))
AddChoice(GetStringByStrRef(16828138), GOREBRUTE);//"Gorebrute"
if(!GetHasFeat(FEAT_SHIFTER_LONGSTRIDE))
AddChoice(GetStringByStrRef(16828140), LONGSTRIDE);//"Longstride"
if(!GetHasFeat(FEAT_SHIFTER_LONGTOOTH))
AddChoice(GetStringByStrRef(16828142), LONGTOOTH);// "Longtooth"
if(!GetHasFeat(FEAT_SHIFTER_RAZORCLAW))
AddChoice(GetStringByStrRef(16828144), RAZORCLAW);// "Razorclaw"
if(!GetHasFeat(FEAT_SHIFTER_WILDHUNT))
AddChoice(GetStringByStrRef(16828146), WILDHUNT);// "Wildhunt"
if(!GetHasFeat(FEAT_SHIFTER_WINTERHIDE))
AddChoice(GetStringByStrRef(16835618), WINTERHIDE);// "Wildhunt"
// Set the next, previous and wait tokens to default values
SetDefaultTokens();
// Set the convo quit text to "Abort"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_ABORT_CONVO));
}
// Selection confirmation stage
else if(nStage == STAGE_CONFIRM_SELECTION)
{
if(DEBUG) DoDebug("race_shfttrt_con: Building selection confirmation");
// Build the confirmantion query
string sToken = GetStringByStrRef(STRREF_SELECTED_HEADER1) + "\n\n"; // "You have selected:"
int nTrait = GetLocalInt(oPC, "nTrait");
if(nTrait == BEASTHIDE)
sToken += GetStringByStrRef(16828134) + "\n\n" + GetStringByStrRef(16828135) + "\n";
else if(nTrait == DREAMSIGHT)
sToken += GetStringByStrRef(16828136) + "\n\n" + GetStringByStrRef(16828137) + "\n";
else if(nTrait == GOREBRUTE)
sToken += GetStringByStrRef(16828138) + "\n\n" + GetStringByStrRef(16828139) + "\n";
else if(nTrait == LONGSTRIDE)
sToken += GetStringByStrRef(16828140) + "\n\n" + GetStringByStrRef(16828141) + "\n";
else if(nTrait == LONGTOOTH)
sToken += GetStringByStrRef(16828142) + "\n\n" + GetStringByStrRef(16828143) + "\n";
else if(nTrait == RAZORCLAW)
sToken += GetStringByStrRef(16828144) + "\n\n" + GetStringByStrRef(16828145) + "\n";
else if(nTrait == WILDHUNT)
sToken += GetStringByStrRef(16828146) + "\n\n" + GetStringByStrRef(16828147) + "\n";
else if(nTrait == WINTERHIDE)
sToken += GetStringByStrRef(16835618) + "\n\n" + GetStringByStrRef(16835619) + "\n";
sToken += GetStringByStrRef(STRREF_SELECTED_HEADER2); // "Is this correct?"
SetHeader(sToken);
AddChoice(GetStringByStrRef(STRREF_YES), TRUE, oPC); // "Yes"
AddChoice(GetStringByStrRef(STRREF_NO), FALSE, oPC); // "No"
}
// Conversation finished stage
else if(nStage == STAGE_TRAIT_SELECTED)
{
if(DEBUG) DoDebug("race_shfttrt_con: Building finish note");
SetHeader(GetStringByStrRef(STRREF_END_HEADER));
// Set the convo quit text to "Finish"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(STRREF_END_CONVO_SELECT));
AllowExit(DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, FALSE, oPC);
}
}
// Do token setup
SetupTokens();
}
else if(nValue == DYNCONV_EXITED)
{
if(DEBUG) DoDebug("race_shfttrt_con: Running exit handler");
// End of conversation cleanup
if(GetPersistantLocalInt(oPC, "FirstShifterTrait") < 100)
{
int nTrait = GetLocalInt(oPC, "nTrait");
if(nTrait == BEASTHIDE)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_BEASTHIDE);
else if(nTrait == DREAMSIGHT)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_DREAMSIGHT);
else if(nTrait == GOREBRUTE)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_GOREBRUTE);
else if(nTrait == LONGSTRIDE)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_LONGSTRIDE);
else if(nTrait == LONGTOOTH)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_LONGTOOTH);
else if(nTrait == RAZORCLAW)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_RAZORCLAW);
else if(nTrait == WILDHUNT)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_WILDHUNT);
else if(nTrait == WINTERHIDE)
SetPersistantLocalInt(oPC, "FirstShifterTrait", FEAT_SHIFTER_WINTERHIDE);
}
DeleteLocalInt(oPC, "nTrait");
}
else if(nValue == DYNCONV_ABORTED)
{
// This section should never be run, since aborting this conversation should
// always be forbidden and as such, any attempts to abort the conversation
// should be handled transparently by the system
if(DEBUG) DoDebug("race_shfttrt_con: ERROR: Conversation abort section run");
}
// Handle PC response
else
{
int nChoice = GetChoice(oPC);
if(DEBUG) DoDebug("race_shfttrt_con: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " + IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
if(nStage == STAGE_SELECT_TRAIT)
{
if(DEBUG) DoDebug("race_shfttrt_con: Trait selected. Entering Confirmation.");
SetLocalInt(oPC, "nTrait", nChoice);
nStage = STAGE_CONFIRM_SELECTION;
}
else if(nStage == STAGE_CONFIRM_SELECTION)
{
if(DEBUG) DoDebug("race_shfttrt_con: Handling trait confirmation");
if(nChoice == TRUE)
{
if(DEBUG) DoDebug("race_shfttrt_con: Marking Trait");
int nTrait = GetLocalInt(oPC, "nTrait");
itemproperty ipIP;
int nFeat;
if(nTrait == BEASTHIDE)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_BEASTHIDE);
nFeat = FEAT_SHIFTER_BEASTHIDE;
}
else if(nTrait == DREAMSIGHT)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_DREAMSIGHT);
nFeat = FEAT_SHIFTER_DREAMSIGHT;
}
else if(nTrait == GOREBRUTE)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_GOREBRUTE);
nFeat = FEAT_SHIFTER_GOREBRUTE;
}
else if(nTrait == LONGSTRIDE)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_LONGSTRIDE);
nFeat = FEAT_SHIFTER_LONGSTRIDE;
}
else if(nTrait == LONGTOOTH)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_LONGTOOTH);
nFeat = FEAT_SHIFTER_LONGTOOTH;
}
else if(nTrait == RAZORCLAW)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_RAZORCLAW);
nFeat = FEAT_SHIFTER_RAZORCLAW;
}
else if(nTrait == WILDHUNT)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_WILDHUNT);
nFeat = FEAT_SHIFTER_WILDHUNT;
}
else if(nTrait == WILDHUNT)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SHIFTER_WINTERHIDE);
nFeat = FEAT_SHIFTER_WINTERHIDE;
}
if(bFuncs)
PRC_Funcs_AddFeat(oPC, nFeat);
else
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
nStage = STAGE_TRAIT_SELECTED;
}
else
nStage = STAGE_SELECT_TRAIT;
}
if(DEBUG) DoDebug("race_shfttrt_con: New stage: " + IntToString(nStage));
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}

View File

@@ -0,0 +1,189 @@
//::///////////////////////////////////////////////
//:: Shifter Traits
//:: race_shifter.nss
//::///////////////////////////////////////////////
/*
Handles Eberron Shifters' shifting ability
*/
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Feb 19, 2008
//:://////////////////////////////////////////////
#include "prc_inc_function"
#include "prc_inc_natweap"
void ApplyPrimaryTrait(object oPC, int nAbility, int nDuration)
{
effect eTrait = EffectAbilityIncrease(nAbility, 2);
effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
eTrait = SupernaturalEffect(eTrait);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eTrait, oPC, RoundsToSeconds(nDuration));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
DelayCommand(RoundsToSeconds(nDuration), ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC));
}
void main()
{
object oPC = OBJECT_SELF;
int nDuration = 3 + GetAbilityModifier(ABILITY_CONSTITUTION, oPC) + GetShiftingFeats(oPC);
int nPrimaryTrait = GetPersistantLocalInt(oPC, "FirstShifterTrait");
if(GetIsPolyMorphedOrShifted(oPC))
{
SendMessageToPC(oPC, "You can only shift in your natural form.");
return;
}
if(GetHasFeat(FEAT_SHIFTER_WILDHUNT, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_WILDHUNT)
ApplyPrimaryTrait(oPC, ABILITY_CONSTITUTION, nDuration);
//scent bonuses
effect eTrait = EffectSkillIncrease(SKILL_SPOT, 4);
eTrait = EffectLinkEffects(eTrait, EffectSkillIncrease(SKILL_SEARCH, 4));
eTrait = EffectLinkEffects(eTrait, EffectSkillIncrease(SKILL_LISTEN, 4));
if(GetHasFeat(FEAT_WILDHUNT_ELITE))
eTrait = EffectLinkEffects(eTrait, EffectUltravision());
eTrait = SupernaturalEffect(eTrait);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eTrait, oPC, RoundsToSeconds(nDuration));
}
if(GetHasFeat(FEAT_SHIFTER_RAZORCLAW, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_RAZORCLAW)
ApplyPrimaryTrait(oPC, ABILITY_STRENGTH, nDuration);
//primary weapon
string sResRef = "prc_claw_1d6l_";
int nSize = PRCGetCreatureSize(oPC);
if(GetHasFeat(FEAT_SHIFTER_SAVAGERY) && GetHasFeatEffect(FEAT_FRENZY, oPC))
nSize += 2;
if(nSize > CREATURE_SIZE_COLOSSAL)
nSize = CREATURE_SIZE_COLOSSAL;
sResRef += GetAffixForSize(nSize);
AddNaturalPrimaryWeapon(oPC, sResRef, 2);
DelayCommand(RoundsToSeconds(nDuration), RemoveNaturalPrimaryWeapon(oPC, sResRef));
}
if(GetHasFeat(FEAT_SHIFTER_LONGTOOTH, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_LONGTOOTH)
ApplyPrimaryTrait(oPC, ABILITY_STRENGTH, nDuration);
string sResRef = "prc_raks_bite_";
if(GetHasFeat(FEAT_LONGTOOTH_ELITE))
sResRef = "prc_lngth_elt_";
int nSize = PRCGetCreatureSize(oPC);
if(GetHasFeat(FEAT_SHIFTER_SAVAGERY) && GetHasFeatEffect(FEAT_FRENZY, oPC))
nSize += 2;
if(nSize > CREATURE_SIZE_COLOSSAL)
nSize = CREATURE_SIZE_COLOSSAL;
sResRef += GetAffixForSize(nSize);
AddNaturalSecondaryWeapon(oPC, sResRef);
DelayCommand(RoundsToSeconds(nDuration), RemoveNaturalSecondaryWeapons(oPC, sResRef));
}
if(GetHasFeat(FEAT_SHIFTER_LONGSTRIDE, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_LONGSTRIDE)
ApplyPrimaryTrait(oPC, ABILITY_DEXTERITY, nDuration);
effect eTrait = EffectMovementSpeedIncrease(33);
if(GetHasFeat(FEAT_LONGSTRIDE_ELITE))
eTrait = EffectMovementSpeedIncrease(67);
if(GetHasFeat(FEAT_SHIFTER_AGILITY))
{
eTrait = EffectLinkEffects(eTrait, EffectACIncrease(1));
eTrait = EffectLinkEffects(eTrait, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 1));
}
eTrait = SupernaturalEffect(eTrait);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eTrait, oPC, RoundsToSeconds(nDuration));
}
if(GetHasFeat(FEAT_SHIFTER_BEASTHIDE, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_BEASTHIDE)
ApplyPrimaryTrait(oPC, ABILITY_CONSTITUTION, nDuration);
effect eTrait = EffectACIncrease(2);
if(GetHasFeat(FEAT_BEASTHIDE_ELITE))
eTrait = EffectACIncrease(4);
eTrait = SupernaturalEffect(eTrait);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eTrait, oPC, RoundsToSeconds(nDuration));
}
if(GetHasFeat(FEAT_SHIFTER_DREAMSIGHT, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_DREAMSIGHT)
ApplyPrimaryTrait(oPC, ABILITY_WISDOM, nDuration);
effect eTrait = EffectSkillIncrease(SKILL_ANIMAL_EMPATHY, 2);
if(GetHasFeat(FEAT_DREAMSIGHT_ELITE))
{
eTrait = EffectLinkEffects(eTrait, EffectSeeInvisible());
eTrait = EffectLinkEffects(eTrait, EffectSkillIncrease(SKILL_SPOT, 5));
}
eTrait = SupernaturalEffect(eTrait);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eTrait, oPC, RoundsToSeconds(nDuration));
}
if(GetHasFeat(FEAT_SHIFTER_GOREBRUTE, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_GOREBRUTE)
ApplyPrimaryTrait(oPC, ABILITY_STRENGTH, nDuration);
SetLocalInt(oPC, "ShifterGore", TRUE);
DelayCommand(RoundsToSeconds(nDuration), DeleteLocalInt(oPC, "ShifterGore"));
}
if(GetHasFeat(FEAT_SHIFTER_WINTERHIDE, oPC))
{
if(nPrimaryTrait == FEAT_SHIFTER_WINTERHIDE)
ApplyPrimaryTrait(oPC, ABILITY_CONSTITUTION, nDuration);
effect eTrait = EffectACIncrease(1, AC_NATURAL_BONUS);
eTrait = EffectLinkEffects(eTrait, EffectDamageResistance(DAMAGE_TYPE_COLD, 5));
eTrait = SupernaturalEffect(eTrait);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eTrait, oPC, RoundsToSeconds(nDuration));
}
if(GetHasFeat(FEAT_HEALING_FACTOR))
{
effect eHeal = EffectHeal(GetHitDice(oPC));
eHeal = EffectLinkEffects(eHeal, EffectVisualEffect(VFX_IMP_HEALING_L));
DelayCommand(RoundsToSeconds(nDuration), ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC));
}
if(GetHasFeat(FEAT_SHIFTER_DEFENSE))
{
effect eDR = EffectDamageReduction(2, DAMAGE_POWER_PLUS_TWO);
eDR = SupernaturalEffect(eDR);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDR, oPC, RoundsToSeconds(nDuration));
}
else if(GetHasFeat(FEAT_GREATER_SHIFTER_DEFENSE))
{
effect eDR = EffectDamageReduction(4, DAMAGE_POWER_PLUS_TWO);
eDR = SupernaturalEffect(eDR);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDR, oPC, RoundsToSeconds(nDuration));
}
if(GetHasFeat(FEAT_SHIFTER_SAVAGERY) && GetHasFeatEffect(FEAT_FRENZY, oPC))
{
itemproperty ipSavage = ItemPropertyBonusFeat(IP_CONST_FEAT_ImpCritCreature);
IPSafeAddItemProperty(GetPCSkin(oPC), ipSavage, RoundsToSeconds(nDuration),
X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
if(GetHasFeat(FEAT_SHIFTER_FEROCITY))
{
itemproperty ipSavage = ItemPropertyBonusFeat(IP_CONST_FEAT_REMAIN_CONCIOUS);
IPSafeAddItemProperty(GetPCSkin(oPC), ipSavage, RoundsToSeconds(nDuration),
X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
}

View File

@@ -0,0 +1,91 @@
/* Skarn Spines, which are equivalent to a shortsword*/
#include "moi_inc_moifunc"
void CleanSpines(object oMeldshaper);
void CleanSpines(object oMeldshaper)
{
object oItem = GetItemPossessedBy(oMeldshaper, "skarn_spine");
if (GetIsObjectValid(oItem))
{
DestroyObject(oItem);
DelayCommand(0.1, CleanSpines(oMeldshaper));
}
}
void main()
{
object oMeldshaper = OBJECT_SELF;
object oItem = GetItemPossessedBy(oMeldshaper, "skarn_spine");
int nClass = GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper);
if (GetIsObjectValid(oItem))
{
CleanSpines(oMeldshaper);
}
else if (nClass)
{
// Right Hand
oItem = CreateItemOnObject("nw_wswss001", oMeldshaper, 1, "skarn_spine");
SetPlotFlag(oItem, TRUE);
SetDroppableFlag(oItem, FALSE);
AssignCommand(oMeldshaper, ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTHAND));
if (nClass >= 5) // Spine Rend
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
if (nClass >= 9)
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(5), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(5), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
else if (GetIsChakraBound(oMeldshaper, CHAKRA_ARMS))
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(3), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(3), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
// Left Hand
oItem = CreateItemOnObject("nw_wswss001", oMeldshaper, 1, "skarn_spine");
SetPlotFlag(oItem, TRUE);
SetDroppableFlag(oItem, FALSE);
AssignCommand(oMeldshaper, ActionEquipItem(oItem, INVENTORY_SLOT_LEFTHAND));
if (nClass >= 5) // Spine Rend
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
if (nClass >= 9)
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(5), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(5), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
else if (GetIsChakraBound(oMeldshaper, CHAKRA_ARMS))
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(3), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(3), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
}
else
{
oItem = CreateItemOnObject("nw_wswss001", oMeldshaper, 1, "skarn_spine");
// No dropping and no selling the item
SetPlotFlag(oItem, TRUE);
SetDroppableFlag(oItem, FALSE);
object oRight = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oMeldshaper);
object oLeft = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oMeldshaper);
if (!GetIsObjectValid(oRight))
AssignCommand(oMeldshaper, ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTHAND));
else if (!GetIsObjectValid(oLeft))
AssignCommand(oMeldshaper, ActionEquipItem(oItem, INVENTORY_SLOT_LEFTHAND));
else
{
DestroyObject(oItem);
FloatingTextStringOnCreature("You have no free hands to use your Skarn Spine with", oMeldshaper, FALSE);
}
if (GetIsObjectValid(oItem) && GetIsChakraBound(oMeldshaper, CHAKRA_ARMS))
{
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(3), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
IPSafeAddItemProperty(oItem, ItemPropertyAttackPenalty(3), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,342 @@
/**
* @file
* Spellscript for a range of racial SLAs.
*
* Racial SLAs that use DoRacialSLA() are all grouped in this file.
*/
#include "inc_newspellbook"
#include "prc_inc_core"
void ClearLocals()
{
DeleteLocalInt(OBJECT_SELF, PRC_CASTERLEVEL_OVERRIDE);
DeleteLocalInt(OBJECT_SELF, PRC_DC_TOTAL_OVERRIDE);
}
void main()
{
int nRace = GetRacialType(OBJECT_SELF);
int nHD = GetHitDice(OBJECT_SELF);
int nCasterLvl = nHD, nDC, nSpell;
switch(GetSpellId()){
case SPELL_URDINNIR_STONESKIN:
{
nCasterLvl = 4;
nSpell = SPELL_STONESKIN;
break;
}
case SPELL_RACE_DARKNESS:
{
nCasterLvl = nRace == RACIAL_TYPE_OMAGE ? 9 : 3;
nSpell = SPELL_DARKNESS;
break;
}
case SPELL_RACE_DAZE:
{
nCasterLvl = 3;
nSpell = SPELL_DAZE;
break;
}
case SPELL_RACE_LIGHT:
{
nSpell = SPELL_LIGHT;
break;
}
case SPELL_SVIRF_BLINDDEAF:
{
// 10 + Spell level (2) + Racial bonus (4) + Cha Mod
nDC = 16 + GetAbilityModifier(ABILITY_CHARISMA);
nSpell = SPELL_BLINDNESS_AND_DEAFNESS;
break;
}
case SPELL_ILLITHID_CHARM_MONSTER:
{
nCasterLvl = 8;
nSpell = SPELL_CHARM_MONSTER;
break;
}
case SPELL_RACE_CHARM_PERSON:
{
if (nRace == RACIAL_TYPE_PURE_YUAN) { nCasterLvl = 3; }
else if (nRace == RACIAL_TYPE_NIXIE) { nCasterLvl = 4; }
else if (nRace == RACIAL_TYPE_BRALANI) { nCasterLvl = 6; }
else if (nRace == RACIAL_TYPE_OMAGE) { nCasterLvl = 9; }
nSpell = SPELL_CHARM_PERSON;
break;
}
case SPELL_FEYRI_ENERVATION:
{
nSpell = SPELL_ENERVATION;
break;
}
case SPELL_RACE_ENTANGLE:
{
nCasterLvl = 3;
if(nRace == RACIAL_TYPE_PIXIE)
nCasterLvl = 8;
else if(nRace == RACIAL_TYPE_GRIG)
nCasterLvl = 9;
nSpell = SPELL_ENTANGLE;
break;
}
case SPELL_RACE_FEAR:
{
nCasterLvl = 3;
nSpell = SPELL_FEAR;
break;
}
case SPELL_RACE_CLAIR:
{
nSpell = SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE;
break;
}
case SPELL_RACE_NEUTRALIZE_POISON:
{
nSpell = SPELL_NEUTRALIZE_POISON;
break;
}
case SPELL_PIXIE_CONFUSION:
{
nCasterLvl = 8;
nSpell = SPELL_CONFUSION;
break;
}
case SPELL_PIXIE_IMPINVIS:
case SPELL_DUERGAR_INVIS:
{
nCasterLvl = 8;
if(nRace == RACIAL_TYPE_GRIG)
nCasterLvl = 9;
else if(nRace == RACIAL_TYPE_DUERGAR)
nCasterLvl = (nHD * 2);
nSpell = SPELL_INVISIBILITY;
break;
}
case SPELL_PIXIE_DISPEL:
{
nCasterLvl = 8;
nSpell = SPELL_DISPEL_MAGIC;
break;
}
case SPELL_RACE_CHILLTOUCH:
{
if(nRace == RACIAL_TYPE_MORTIF)
nCasterLvl = (nHD)+2;
else if(nRace == RACIAL_TYPE_ZAKYA_RAKSHASA)
nCasterLvl = 7;
nSpell = SPELL_CHILL_TOUCH;
break;
}
case SPELL_RACE_SILENCE:
{
nSpell = SPELL_SILENCE;
break;
}
case SPELL_RACE_MAGE_HAND:
{
nSpell = SPELL_MAGE_HAND;
break;
}
case SPELL_ZAKYA_VAMPIRIC_TOUCH:
{
nCasterLvl = 7;
nSpell = SPELL_VAMPIRIC_TOUCH;
break;
}
case SPELL_GRIG_PYROTECHNICS_FIREWORKS:
{
nCasterLvl = 9;
nSpell = SPELL_PYROTECHNICS_FIREWORKS;
break;
}
case SPELL_GRIG_PYROTECHNICS_SMOKE:
{
nCasterLvl = 9;
nSpell = SPELL_PYROTECHNICS_SMOKE;
break;
}
case SPELL_BRALANI_LIGHTNING_BOLT:
{
nCasterLvl = 6;
nSpell = SPELL_LIGHTNING_BOLT;
break;
}
case SPELL_BRALANI_CURE_SERIOUS_WOUNDS:
{
nCasterLvl = 6;
nSpell = SPELL_CURE_SERIOUS_WOUNDS;
break;
}
case SPELL_BRALANI_GUST_OF_WIND:
{
nCasterLvl = 6;
nSpell = SPELL_GUST_OF_WIND;
break;
}
case SPELL_BRALANI_MIRROR_IMAGE:
{
nCasterLvl = 6;
nSpell = SPELL_MIRROR_IMAGE;
break;
}
case SPELL_IRDA_FLARE:
{
nSpell = SPELL_FLARE;
break;
}
case SPELL_HOUND_DETECTEVIL:
{
nSpell = SPELL_DETECT_EVIL;
break;
}
case SPELL_HOUND_AID:
{
nCasterLvl = 6;
nSpell = SPELL_AID;
break;
}
case SPELL_HOUND_CONTFLAME:
{
nCasterLvl = 6;
nSpell = SPELL_CONTINUAL_FLAME;
break;
}
case SPELL_HOUND_TELEPORT:
{
nCasterLvl = 6;
nSpell = SPELL_GREATER_TELEPORT_SELF;
DelayCommand(1.0f, ClearLocals());
break;
}
case SPELL_ZENYTH_TRUE_STRIKE:
{
nSpell = SPELL_TRUE_STRIKE;
break;
}
case SPELL_RACIAL_CIRCLE_VS_GOOD:
{
nSpell = SPELL_MAGIC_CIRCLE_AGAINST_GOOD;
break;
}
case SPELL_RACIAL_CIRCLE_VS_EVIL:
{
nSpell = SPELL_MAGIC_CIRCLE_AGAINST_EVIL;
break;
}
case SPELL_RACIAL_CIRCLE_VS_LAW:
{
nSpell = SPELL_MAGIC_CIRCLE_AGAINST_LAW;
break;
}
case SPELL_RACIAL_CIRCLE_VS_CHAOS:
{
nSpell = SPELL_MAGIC_CIRCLE_AGAINST_CHAOS;
break;
}
case SPELL_NATHRI_EXPEDITIOUS_RETREAT:
{
nSpell = SPELL_EXPEDITIOUS_RETREAT;
break;
}
case SPELL_NYMPH_DIMDOOR_SELF:
{
nCasterLvl = 7;
nSpell = SPELL_DIMENSION_DOOR_SELF;
DelayCommand(1.0f, ClearLocals());
break;
}
case SPELL_NYMPH_DIMDOOR_PARTY:
{
nCasterLvl = 7;
nSpell = SPELL_DIMENSION_DOOR_PARTY;
DelayCommand(1.0f, ClearLocals());
break;
}
case SPELL_NYMPH_DIMDOOR_DIST_SELF:
{
nCasterLvl = 7;
nSpell = SPELL_DIMENSION_DOOR_DIRDIST_SELF;
DelayCommand(1.0f, ClearLocals());
break;
}
case SPELL_NYMPH_DIMDOOR_DIST_PARTY:
{
nCasterLvl = 7;
nSpell = SPELL_DIMENSION_DOOR_DIRDIST_PARTY;
DelayCommand(1.0f, ClearLocals());
break;
}
case SPELL_DRIDER_DETECTGOOD:
{
nSpell = SPELL_DETECT_GOOD;
break;
}
case SPELL_DRIDER_DETECTLAW:
{
nSpell = SPELL_DETECT_LAW;
break;
}
case SPELL_RACE_BLUR:
{
if(nRace == RACIAL_TYPE_GITHYANKI)
nCasterLvl = 3;
else if(nRace == RACIAL_TYPE_BRALANI)
nCasterLvl = 6;
nSpell = SPELL_BLUR;
break;
}
case SPELL_HYBSIL_MIRROR_IMAGE:
{
nCasterLvl = 1;
nSpell = SPELL_MIRROR_IMAGE;
break;
}
case SPELL_HYBSIL_DANCLIGHTS:
{
nCasterLvl = 1;
nSpell = SPELL_DANCING_LIGHTS;
break;
}
case SPELL_HYBSIL_JUMP:
{
nCasterLvl = 1;
nSpell = SPELL_SPELL_JUMP;
break;
}
case 1965://Faerie fire
{
nSpell = SPELL_FAERIE_FIRE;
break;
}
case 3494: // Magic Stone for Stonechild
{
nCasterLvl = 3;
nSpell = SPELL_MAGIC_STONE;
break;
}
case 3804: // Uldra Ray of Frost
{
nDC = 10 + GetAbilityModifier(ABILITY_WISDOM);
nCasterLvl = GetHitDice(OBJECT_SELF);
nSpell = SPELL_RAY_OF_FROST;
break;
}
case 3805: // Uldra Touch of Fatigue
{
nDC = 10 + GetAbilityModifier(ABILITY_WISDOM);
nCasterLvl = GetHitDice(OBJECT_SELF);
nSpell = SPELL_TOUCH_FATIGUE;
break;
}
case 3826: // Extaminaar Charm Animal
{
nCasterLvl = GetHitDice(OBJECT_SELF);
nSpell = SPELL_CHARM_PERSON_OR_ANIMAL;
break;
}
}
DoRacialSLA(nSpell, nCasterLvl, nDC);
}

View File

@@ -0,0 +1,196 @@
//:://////////////////////////////////////////////
//:: Spirit Folk conversation script
//:: race_spiritfkcon
//:://////////////////////////////////////////////
/** @file
This script controls the feat selection
conversation for Spirit Folk
@author Primogenitor - Original
@author Ornedan - Modifications
@author Fox - ripped from Psionics convo
@date Modified - 2005.03.13
@date Modified - 2005.09.23
@date Modified - 2008.01.25
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "inc_dynconv"
#include "inc_nwnx_funcs"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_SELECT_SPIRIT = 0;
const int STAGE_SPIRIT_SELECTED = 1;
const int STAGE_CONFIRM_SELECTION = 2;
const int CHOICE_BACK_TO_LSELECT = -1;
const int STRREF_LEVELLIST_HEADER = 16828040; // "Select a spirit heritage:"
const int STRREF_SELECTED_HEADER1 = 16824209; // "You have selected:"
const int STRREF_SELECTED_HEADER2 = 16824210; // "Is this correct?"
const int STRREF_END_HEADER = 16828041; // "Your spirit heritage has been selected."
const int STRREF_END_CONVO_SELECT = 16824212; // "Finish"
const int STRREF_YES = 4752; // "Yes"
const int STRREF_NO = 4753; // "No"
//////////////////////////////////////////////////
/* Function defintions */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
object oSkin = GetPCSkin(oPC);
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
int nStage = GetStage(oPC);
int bFuncs = GetPRCSwitch(PRC_NWNX_FUNCS);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
if(DEBUG) DoDebug("race_spiritfkcon: Running setup stage for stage " + IntToString(nStage));
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
if(DEBUG) DoDebug("race_spiritfkcon: Stage was not set up already");
// Level selection stage
if(nStage == STAGE_SELECT_SPIRIT)
{
if(DEBUG) DoDebug("race_spiritfkcon: Building Spirit selection");
SetHeader(GetStringByStrRef(STRREF_LEVELLIST_HEADER));
// Set the tokens
int i = 0;
AddChoice(GetStringByStrRef(16834283), 1);// "Bamboo Folk"
AddChoice(GetStringByStrRef(16834285), 2);// "River Folk"
AddChoice(GetStringByStrRef(16834287), 3);// "Sea Folk"
AddChoice(GetStringByStrRef(16833105), 4);// "Mountain Folk"
// Set the next, previous and wait tokens to default values
SetDefaultTokens();
// Set the convo quit text to "Abort"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_ABORT_CONVO));
}
// Selection confirmation stage
else if(nStage == STAGE_CONFIRM_SELECTION)
{
if(DEBUG) DoDebug("race_spiritfkcon: Building selection confirmation");
// Build the confirmantion query
string sToken = GetStringByStrRef(STRREF_SELECTED_HEADER1) + "\n\n"; // "You have selected:"
int nSpirit = GetLocalInt(oPC, "nSpirit");
if(nSpirit == 1)
sToken += GetStringByStrRef(16834284);
// "Bamboo Spirit \n\nYou are one of the Bamboo tribe of Spirit Folk. You gain a +2 bonus to lore and saves against acid spells, due ot your earthen nature. You also gain Trackless Step and +4 to hide in wilderness settings.";
else if(nSpirit == 2)
sToken += GetStringByStrRef(16834286);
// "River Spirit \n\nYou are one of the River tribe of Spirit Folk. You are immune to drowning, and gain a +2 to save vs cold spells and effects, due to your water nature.";
else if(nSpirit == 3)
sToken += GetStringByStrRef(16834288);
//"Sea Spirit \n\nYou are one of the Sea tribe of Spirit Folk. You are immune to drowning, and gain a +2 to save vs fire spells and effects.";
else if(nSpirit == 4)
sToken += GetStringByStrRef(16833110);
//"You are one of the Mountain tribe of Spirit Folk. You gain a +8 bonus to Climb, and a +2 bonus to Balance, Jump, and Tumble.";
sToken += GetStringByStrRef(STRREF_SELECTED_HEADER2); // "Is this correct?"
SetHeader(sToken);
AddChoice(GetStringByStrRef(STRREF_YES), TRUE, oPC); // "Yes"
AddChoice(GetStringByStrRef(STRREF_NO), FALSE, oPC); // "No"
}
// Conversation finished stage
else if(nStage == STAGE_SPIRIT_SELECTED)
{
if(DEBUG) DoDebug("race_spiritfkcon: Building finish note");
SetHeader(GetStringByStrRef(STRREF_END_HEADER));
// Set the convo quit text to "Finish"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(STRREF_END_CONVO_SELECT));
AllowExit(DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, FALSE, oPC);
}
}
// Do token setup
SetupTokens();
}
else if(nValue == DYNCONV_EXITED)
{
if(DEBUG) DoDebug("race_spiritfkcon: Running exit handler");
// End of conversation cleanup
DeleteLocalInt(oPC, "nSpirit");
}
else if(nValue == DYNCONV_ABORTED)
{
// This section should never be run, since aborting this conversation should
// always be forbidden and as such, any attempts to abort the conversation
// should be handled transparently by the system
if(DEBUG) DoDebug("race_spiritfkcon: ERROR: Conversation abort section run");
}
// Handle PC response
else
{
int nChoice = GetChoice(oPC);
if(DEBUG) DoDebug("race_spiritfkcon: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " + IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
if(nStage == STAGE_SELECT_SPIRIT)
{
if(DEBUG) DoDebug("race_spiritfkcon: Spirit selected. Entering Confirmation.");
SetLocalInt(oPC, "nSpirit", nChoice);
nStage = STAGE_CONFIRM_SELECTION;
}
else if(nStage == STAGE_CONFIRM_SELECTION)
{
if(DEBUG) DoDebug("race_spiritfkcon: Handling Spirit confirmation");
if(nChoice == TRUE)
{
if(DEBUG) DoDebug("race_spiritfkcon: Marking Spirit");
int nSpirit = GetLocalInt(oPC, "nSpirit");
itemproperty ipIP;
int nFeat;
if(nSpirit == 1)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_BAMBOO_FOLK);
nFeat = FEAT_BONUS_BAMBOO;
}
else if(nSpirit == 2)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_RIVER_FOLK);
nFeat = FEAT_BONUS_RIVER;
}
else if(nSpirit == 3)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_SEA_FOLK);
nFeat = FEAT_BONUS_SEA;
}
else if(nSpirit == 4)
{
ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_MOUNTAIN_FOLK);
nFeat = FEAT_BONUS_MOUNTAIN;
}
if(bFuncs)
PRC_Funcs_AddFeat(oPC, nFeat);
else
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
nStage = STAGE_SPIRIT_SELECTED;
}
else
nStage = STAGE_SELECT_SPIRIT;
}
if(DEBUG) DoDebug("race_spiritfkcon: New stage: " + IntToString(nStage));
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}

View File

@@ -0,0 +1,29 @@
//::///////////////////////////////////////////////
//:: Troglodyte Stench
//:: race_stench.nss
//:://////////////////////////////////////////////
/*
Objects entering the aura must make a fortitude saving
throw or or be sickened for 10 rounds
*/
//:://////////////////////////////////////////////
//:: Created By: xwarren
//:: Created On: 2011-05-05
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
object oCaster = OBJECT_SELF;
if(GetHasSpellEffect(SPELL_TROGLODYTE_STENCH))
{
PRCRemoveEffectsFromSpell(oCaster, SPELL_TROGLODYTE_STENCH);
return;
}
effect eStench = EffectAreaOfEffect(AOE_MOB_TROGLODYTE_STENCH, "prc_TrogStenchA", "", "");
eStench = ExtraordinaryEffect(eStench);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStench, oCaster);
}

View File

@@ -0,0 +1,64 @@
//::///////////////////////////////////////////////
//:: Troglodyte Stench On Enter
//:: race_stencha.nss
//:://////////////////////////////////////////////
/*
Objects entering the aura must make a fortitude saving
throw or or be sickened for 10 rounds
*/
//:://////////////////////////////////////////////
//:: Created By: xwarren
//:: Created On: 2011-05-05
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
// Declare major variables
object oTarget = GetEnteringObject();
object oSource = GetAreaOfEffectCreator();
// Troglodytes are immune
if(GetRacialType(oTarget) == RACIAL_TYPE_TROGLODYTE
|| GetIsImmune(oTarget, IMMUNITY_TYPE_POISON))
return;
effect eSick;
if(!GetHasSpellEffect(SPELL_TROGLODYTE_STENCH, oTarget))
{
// Is the target a valid creature
if(PRCGetIsAliveCreature(oTarget)
&& !GetIsReactionTypeFriendly(oTarget, oSource))
{
// Notify the target that they are being attacked
SignalEvent(oTarget, EventSpellCastAt(oSource, SPELL_TROGLODYTE_STENCH));
// Prepare the visual effect for the casting and saving throw
effect eVis1 = EffectVisualEffect(VFX_IMP_POISON_S);
effect eVis2 = EffectVisualEffect(VFX_IMP_FORTITUDE_SAVING_THROW_USE);
effect eImmune = EffectVisualEffect(VFX_DUR_CESSATE_NEUTRAL);
eImmune = ExtraordinaryEffect(eImmune);
// Create the sickened effect
// and make it supernatural so it can be dispelled
eSick = SupernaturalEffect(EffectSickened());
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget);
// DC is constitution based
int nDC = 10 + (GetHitDice(oSource) / 2) + GetAbilityModifier(ABILITY_CONSTITUTION, oSource);
// Make a Fortitude saving throw and apply the effect if it fails
if(!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_POISON, oSource))
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis1, oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSick, oTarget, RoundsToSeconds(10));
}
else
// if save was sucessful - immune to stench for 24h.
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmune, oTarget, HoursToSeconds(24));
}
}
}

View File

@@ -0,0 +1,44 @@
//::///////////////////////////////////////////////
//:: Stunning Glance
//:: race_stunglance
//:://////////////////////////////////////////////
//:: Fort save or the target is stunned for 2d4 round
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Feb 21, 2008
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
//Declare major variables
object oNymph = OBJECT_SELF;
object oTarget = GetSpellTargetObject(); //not using prc version here
if(!GetIsReactionTypeFriendly(oTarget))
{
if(GetDistanceBetween(oNymph, oTarget) > FeetToMeters(30.0))
return;
effect eVis = EffectVisualEffect(VFX_IMP_STUN);
effect eLink = EffectLinkEffects(EffectStunned(), EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE));
int nDuration = d4(2);
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(oNymph, SPELL_NYMPH_STUNNING_GLANCE));
// DC is charisma based
int nDC = 10 + (GetHitDice(oNymph) / 2) + GetAbilityModifier(ABILITY_CHARISMA, oNymph);
//Make Fort Save to negate effect
if (!/*Fort Save*/ PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS))
{
//Apply VFX Impact and stun effect
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}
}

View File

@@ -0,0 +1,16 @@
/* Glimmerskin Halfling's "Touch of Luck"
+2 to the saving throw of an ally within 30'*/
#include "prc_sp_func"
void main()
{
object oTarget = PRCGetSpellTargetObject();
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
//Apply the VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSavingThrowIncrease(SAVING_THROW_ALL, 2), oTarget, 6.0);
}

View File

@@ -0,0 +1,56 @@
//::///////////////////////////////////////////////
//:: Spell: Dimension Door
//:: sp_dimens_door
//::///////////////////////////////////////////////
/** @ file
Dimension Door
Conjuration (Teleportation)
Level: Brd 4, Sor/Wiz 4, Travel 4
Components: V
Casting Time: 1 standard action
Range: Long (400 ft. + 40 ft./level)
Target: You and other touched willing creatures (ie. party members within 10ft of you)
Duration: Instantaneous
Saving Throw: None
Spell Resistance: No
You instantly transfer yourself from your current location to any other spot within range.
You always arrive at exactly the spot desired<65>whether by simply visualizing the area or by
stating direction**. You may also bring one additional willing Medium or smaller creature
or its equivalent per three caster levels. A Large creature counts as two Medium creatures,
a Huge creature counts as two Large creatures, and so forth. All creatures to be
transported must be in contact with you. *
Notes:
* Implemented as within 10ft of you due to the lovely quality of NWN location tracking code.
** The direction is the same as the direction of where you target the spell relative to you.
A listener will be created so you can say the distance.
@author Ornedan
@date Created - 2005.07.04
@date Modified - 2005.10.12
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "spinc_dimdoor"
void main()
{
/* Main spellscript */
object oCaster = OBJECT_SELF;
int nCasterLvl = GetHitDice(oCaster);
int nSpellID = PRCGetSpellId();
int bUseDirDist = nSpellID == SPELL_FORESTLORD_TREEWALK_DIRDIST;
SetLocalInt(oCaster, "Treewalk", TRUE);
DimensionDoor(oCaster, nCasterLvl, nSpellID, "", DIMENSIONDOOR_SELF, bUseDirDist);
DelayCommand(10.1, DeleteLocalInt(oCaster, "Treewalk"));
}

View File

@@ -0,0 +1,46 @@
/*
28/10/21 by Stratovarius
Strength from Pain (Ex) Whenever a turlemoi takes damage
from any source, it gains a +1 bonus on attack rolls, a +2
bonus on damage rolls, and its natural armor bonus
to AC increases by 2. These benefits last for 1 minute
starting in the round during which a turlemoi first takes
damage in the encounter.
Bonuses stack each time a turlemoi takes damage,
to a maximum of a +5 bonus on attack rolls, a +10 bonus
on damage rolls, and a +10 natural armor bonus to AC.
These bonuses accrue each time a turlemoi takes damage
during that minute, even from multiple attacks in the
same round. At the end of that minute, all these bonuses
disappear. They could begin accumulating again if the
turlemoi takes more damage
*/
#include "prc_inc_function"
void main()
{
object oCaster = OBJECT_SELF;
//FloatingTextStringOnCreature(GetName(GetLastDamager())+ " hit me for "+IntToString(GetTotalDamageDealt()), oCaster, FALSE);
int nStrength = GetLocalInt(oCaster, "StrengthFromPain");
// First time here
if (!nStrength)
{
SetLocalInt(oCaster, "StrengthFromPain", 1);
DelayCommand(60.0, DeleteLocalInt(oCaster, "StrengthFromPain"));
DelayCommand(60.0, FloatingTextStringOnCreature("Strength from Pain reset", oCaster, FALSE));
DelayCommand(60.0, PRCRemoveSpellEffects(SPELL_TURLEMOI_STRENGTH, oCaster, oCaster));
DelayCommand(60.0, GZPRCRemoveSpellEffects(SPELL_TURLEMOI_STRENGTH, oCaster, FALSE));
}
else if (5 > nStrength) // nStrength equals something, can't go above five
SetLocalInt(oCaster, "StrengthFromPain", nStrength + 1);
PRCRemoveSpellEffects(SPELL_TURLEMOI_STRENGTH, oCaster, oCaster);
GZPRCRemoveSpellEffects(SPELL_TURLEMOI_STRENGTH, oCaster, FALSE);
ActionCastSpellOnSelf(SPELL_TURLEMOI_STRENGTH);
//FloatingTextStringOnCreature("Lesser Strength from Pain at "+IntToString(nStrength+1), oCaster, FALSE);
}

View File

@@ -0,0 +1,34 @@
/*
28/10/21 by Stratovarius
Strength from Pain (Ex) Whenever a turlemoi takes damage
from any source, it gains a +1 bonus on attack rolls, a +2
bonus on damage rolls, and its natural armor bonus
to AC increases by 2. These benefits last for 1 minute
starting in the round during which a turlemoi first takes
damage in the encounter.
Bonuses stack each time a turlemoi takes damage,
to a maximum of a +5 bonus on attack rolls, a +10 bonus
on damage rolls, and a +10 natural armor bonus to AC.
These bonuses accrue each time a turlemoi takes damage
during that minute, even from multiple attacks in the
same round. At the end of that minute, all these bonuses
disappear. They could begin accumulating again if the
turlemoi takes more damage
*/
#include "prc_inc_function"
void main()
{
object oCaster = PRCGetSpellTargetObject();
int nBonus = GetLocalInt(oCaster, "StrengthFromPain");
effect eLink = EffectLinkEffects(EffectACIncrease(nBonus*2, AC_NATURAL_BONUS), EffectDamageIncrease(nBonus*2, DAMAGE_TYPE_SLASHING | DAMAGE_TYPE_BLUDGEONING | DAMAGE_TYPE_PIERCING));
eLink = EffectLinkEffects(eLink, EffectAttackIncrease(nBonus));
if (nBonus >= 3) eLink = EffectLinkEffects(eLink, EffectImmunity(IMMUNITY_TYPE_MIND_SPELLS));
FloatingTextStringOnCreature("Applying Strength from Pain for "+IntToString(nBonus), oCaster, FALSE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(eLink), oCaster, 60.0);
}

View File

@@ -0,0 +1,169 @@
//::///////////////////////////////////////////////
//:: Warforged Armor Restrictions
//:: race_warforged.nss
//::///////////////////////////////////////////////
/*
Handles restrictions on warforged armor-equipping
*/
//:://////////////////////////////////////////////
//:: Created By: Fox
//:: Created On: Feb 12, 2008
//:://////////////////////////////////////////////
#include "prc_alterations"
void CreateWarforgedArmor(object oPC)
{
object oArmor;
object oHelm;
//object oFeatHide = CreateItemOnObject("prc_wf_feats", oPC);
if(GetHasFeat(FEAT_IRONWOOD_PLATING, oPC))
{
oArmor = CreateItemOnObject("prc_wf_woodbody", oPC);
oHelm = CreateItemOnObject("prc_wf_helmwood", oPC);
}
else if(GetHasFeat(FEAT_MITHRIL_PLATING, oPC))
{
oArmor = CreateItemOnObject("prc_wf_mithbody", oPC);
oHelm = CreateItemOnObject("prc_wf_helmmith", oPC);
}
else if(GetHasFeat(FEAT_ADAMANTINE_PLATING, oPC))
{
oArmor = CreateItemOnObject("prc_wf_admtbody", oPC);
oHelm = CreateItemOnObject("prc_wf_helmadmt", oPC);
}
else if(GetHasFeat(FEAT_UNARMORED_BODY, oPC))
{
oArmor = CreateItemOnObject("prc_wf_unacbody", oPC);
oHelm = CreateItemOnObject("prc_wf_helmhead", oPC);
}
else if(GetHasFeat(FEAT_COMPOSITE_PLATING, oPC))
{
oArmor = CreateItemOnObject("prc_wf_compbody", oPC);
oHelm = CreateItemOnObject("prc_wf_helmhead", oPC);
}
SetDroppableFlag(oArmor, FALSE);
SetItemCursedFlag(oArmor, TRUE);
SetDroppableFlag(oHelm, FALSE);
SetItemCursedFlag(oHelm, TRUE);
// Force equip
DelayCommand(1.0, AssignCommand(oPC, ActionEquipItem(oArmor, INVENTORY_SLOT_CHEST)));
DelayCommand(1.0, AssignCommand(oPC, ActionEquipItem(oHelm, INVENTORY_SLOT_HEAD)));
}
void DoWarforgedCheck(object oPC)
{
if(!GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)))
AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC, "prc_wf_helmhead"), INVENTORY_SLOT_HEAD));
if(!GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)))
AssignCommand(oPC, ActionEquipItem(GetItemPossessedBy(oPC, "prc_wf_unacbody"), INVENTORY_SLOT_CHEST));
}
void main()
{
int nEvent = GetRunningEvent();
if(DEBUG) DoDebug("race_warforged running, event: " + IntToString(nEvent));
// Init the PC.
object oPC = OBJECT_SELF;
object oItem;
object oArmor;
object oSkin;
// We aren't being called from any event, instead from EvalPRCFeats
if(nEvent == FALSE)
{
oPC = OBJECT_SELF;
int nArmorExists = GetIsObjectValid(GetItemPossessedBy(oPC, "prc_wf_unacbody"))
|| GetIsObjectValid(GetItemPossessedBy(oPC, "prc_wf_woodbody"))
|| GetIsObjectValid(GetItemPossessedBy(oPC, "prc_wf_mithbody"))
|| GetIsObjectValid(GetItemPossessedBy(oPC, "prc_wf_admtbody"))
|| GetIsObjectValid(GetItemPossessedBy(oPC, "prc_wf_compbody"));
// Hook in the events
if(DEBUG) DoDebug("race_warforged: Adding eventhooks");
AddEventScript(oPC, EVENT_ONHEARTBEAT, "race_warforged", TRUE, FALSE);
//may not be needed, put in just in case(ala HotU start)
AddEventScript(oPC, EVENT_ONUNAQUIREITEM, "race_warforged", TRUE, FALSE);
if(!nArmorExists)
{
CreateWarforgedArmor(oPC);
}
}
else if(nEvent == EVENT_ONHEARTBEAT)
{
oSkin = GetPCSkin(oPC);
if(DEBUG) DoDebug("race_warforged - OnHeartbeat");
if(GetHasFeat(FEAT_IRONWOOD_PLATING, oPC))
{
if (!GetHasFeat(FEAT_ARMOR_PROFICIENCY_LIGHT, oPC))
{
//Add proficiency
itemproperty ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_ARMOR_PROF_LIGHT);
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
if(DEBUG) DoDebug("race_warforged - ironwood - adding item property "+ItemPropertyToString(ipIP));
}
// Force equip
oItem = GetItemPossessedBy(oPC, "prc_wf_woodbody");
if (oItem != GetItemInSlot(INVENTORY_SLOT_CHEST, oPC))
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
}
else if(GetHasFeat(FEAT_MITHRIL_PLATING, oPC))
{
if (!GetHasFeat(FEAT_ARMOR_PROFICIENCY_LIGHT, oPC))
{
//Add proficiency
itemproperty ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_ARMOR_PROF_LIGHT);
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
if(DEBUG) DoDebug("race_warforged - mithril - adding item property "+ItemPropertyToString(ipIP));
}
// Force equip
oItem = GetItemPossessedBy(oPC, "prc_wf_mithbody");
if (oItem != GetItemInSlot(INVENTORY_SLOT_CHEST, oPC))
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
}
else if(GetHasFeat(FEAT_ADAMANTINE_PLATING, oPC))
{
if (!GetHasFeat(FEAT_ARMOR_PROFICIENCY_HEAVY, oPC))
{
//Add proficiency
itemproperty ipIP = ItemPropertyBonusFeat(IP_CONST_FEAT_ARMOR_PROF_HEAVY);
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
if(DEBUG) DoDebug("race_warforged - adamantine - adding item property "+ItemPropertyToString(ipIP));
}
// Force equip
oItem = GetItemPossessedBy(oPC, "prc_wf_admtbody");
if (oItem != GetItemInSlot(INVENTORY_SLOT_CHEST, oPC))
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
}
else if(GetHasFeat(FEAT_COMPOSITE_PLATING, oPC))
{
// Force equip
oItem = GetItemPossessedBy(oPC, "prc_wf_compbody");
if (oItem != GetItemInSlot(INVENTORY_SLOT_CHEST, oPC))
AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
}
// Delay a bit to make sure they are appropriately dressed
DelayCommand(0.5f, DoWarforgedCheck(oPC));
}
else if(nEvent == EVENT_ONUNAQUIREITEM)
{
if(DEBUG) DoDebug("race_warforged: OnUnAcquire");
object oItem = GetModuleItemLost();
if(GetStringLeft(GetTag(oItem), 7) == "prc_wf_")
{
if(DEBUG) DoDebug("Destroying lost warforged stuff");
MyDestroyObject(oItem);
}
//recreates armor after 1 second to avoid triggering any infinite loops from HotU-type scripts
DelayCommand(1.0, CreateWarforgedArmor(oPC));
}
}

View File

@@ -0,0 +1,58 @@
/*
Nixie waterbreathing
*/
#include "prc_sp_func"
//Implements the spell impact, put code here
// if called in many places, return TRUE if
// stored charges should be decreased
// eg. touch attack hits
//
// Variables passed may be changed if necessary
int DoSpell(object oCaster, object oTarget, int nCasterLevel, int nEvent)
{
effect eWater = EffectSpellImmunity(SPELL_DROWN);
effect eWater2 = EffectSpellImmunity(SPELL_MASS_DROWN);
effect eVis = EffectVisualEffect(VFX_IMP_DEATH_WARD);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
effect eLink = EffectLinkEffects(eWater, eWater2);
eLink = EffectLinkEffects(eLink, eDur);
int CasterLvl = nCasterLevel;
int nDuration = CasterLvl;
//Apply VFX impact and death immunity effect
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, HoursToSeconds(nDuration),TRUE,-1,CasterLvl);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
return TRUE; //return TRUE if spell charges should be decremented
}
void main()
{
object oCaster = OBJECT_SELF;
int nCasterLevel = 12;
PRCSetSchool(GetSpellSchool(PRCGetSpellId()));
if (!X2PreSpellCastCode()) return;
object oTarget = PRCGetSpellTargetObject();
int nEvent = GetLocalInt(oCaster, PRC_SPELL_EVENT); //use bitwise & to extract flags
if(!nEvent) //normal cast
{
if(GetLocalInt(oCaster, PRC_SPELL_HOLD) && oCaster == oTarget)
{ //holding the charge, casting spell on self
SetLocalSpellVariables(oCaster, 1); //change 1 to number of charges
return;
}
DoSpell(oCaster, oTarget, nCasterLevel, nEvent);
}
else
{
if(nEvent & PRC_SPELL_EVENT_ATTACK)
{
if(DoSpell(oCaster, oTarget, nCasterLevel, nEvent))
DecrementSpellCharges(oCaster);
}
}
PRCSetSchool();
}

View File

@@ -0,0 +1,23 @@
/*Once per day, a wildren who has taken at least 1 point of damage can choose to enter a brief state of rage-like fury at the beginning of her next turn.
In this state, a wildren gains +4 to Strength and <20>2 to Armor Class. The fury lasts for 1 round, and a wildren cannot end her fury voluntarily. The
effect of this ability stacks with similar effects (such as the barbarian<61>s rage class feature).*/
#include "inc_vfx_const"
void main()
{
object oPC = OBJECT_SELF;
// Need to be wounded
if (GetCurrentHitPoints(oPC) == GetMaxHitPoints(oPC))
IncrementRemainingFeatUses(oPC, 5386);
else
{
effect eLink = EffectLinkEffects(EffectAbilityIncrease(ABILITY_STRENGTH, 4), EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE));
eLink = EffectLinkEffects(EffectACDecrease(2), eLink);
eLink = ExtraordinaryEffect(eLink);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_BONUS_STRENGTH), oPC);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oPC, 6.0);
}
}

View File

@@ -0,0 +1,32 @@
//::///////////////////////////////////////////////
//:: Turns player into a wolf
//:: prc_wwformwolf
//:: Copyright (c) 2004 Shepherd Soft
//:://////////////////////////////////////////////
/*
*/
//:://////////////////////////////////////////////
//:: Created By: Russell S. Ahlstrom
//:: Created On: May 11, 2004
//:://////////////////////////////////////////////
//Modified for use with Hound Archon
#include "pnp_shft_poly"
void main()
{
object oPC = OBJECT_SELF;
if(!GetLocalInt(oPC, "WWWolf"))
{
LycanthropePoly(oPC, POLYMORPH_TYPE_WOLF_2);
SetLocalInt(oPC, "WWWolf", TRUE);
}
else
{
ExecuteScript("prc_wwunpoly", oPC);
SetLocalInt(oPC, "WWWolf", FALSE);
}
}

View File

@@ -0,0 +1,27 @@
/* Burst racial ability for Xephs
Speed Increase for 3 rounds.*/
void main()
{
int nSpdIncrease;
switch(GetHitDice(OBJECT_SELF))
{
case 1:
case 2:
case 3:
case 4: nSpdIncrease = 33; break;
case 5:
case 6:
case 7:
case 8: nSpdIncrease = 67; break;
default: nSpdIncrease = 99; break;
}
effect eLink = EffectLinkEffects(EffectMovementSpeedIncrease(nSpdIncrease),
EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, RoundsToSeconds(3));
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HOLY_AID), OBJECT_SELF);
}

View File

@@ -0,0 +1,116 @@
//::///////////////////////////////////////////////
//:: Mindflayer Extract Brain
//:: x2_s1_suckbrain
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
The Mindflayer's Extract Brain ability
Since we can not simulate the When All 4 tentacles
hit condition reliably, we use this approach for
extract brain
It is only triggered through the specialized
mindflayer AI if the player is helpless.
(see x2_ai_mflayer for details)
If the player is helpless, the mindflayer will
walk up and cast this spell, which has the Suck Brain
special creature animation tied to it through spells.2da
The spell first performs a melee touch attack. If that succeeds
in <Hardcore difficulty, the player is awarded a Fortitude Save
against DC 10+(HD/2).
If the save fails, or the player is on a hardcore+ difficulty
setting, the mindflayer will do d3()+2 points of permanent
intelligence damage. Once a character's intelligence drops
below 5, his enough of her brain has been extracted to kill her.
As a little special condition, if the player is either diseased
or poisoned, the mindflayer will also become disases or poisoned
if by sucking the brain.
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-09-01
//:://////////////////////////////////////////////
void DoSuckBrain(object oTarget,int nDamage)
{
effect eDrain = EffectAbilityDecrease(ABILITY_INTELLIGENCE, nDamage);
eDrain = ExtraordinaryEffect(eDrain);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDrain, oTarget);
}
#include "prc_inc_spells"
void main()
{
object oTarget = PRCGetSpellTargetObject();
effect eBlood = EffectVisualEffect(493);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eBlood, oTarget);
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
// Do a melee touch attack.
int bHit = (TouchAttackMelee(oTarget,TRUE)>0) ;
if (!bHit)
{
return;
}
if (GetObjectType(oTarget) != OBJECT_TYPE_CREATURE) return;
int nRacial = MyPRCGetRacialType(oTarget);
// These types dont have brains to eat
if (nRacial == RACIAL_TYPE_CONSTRUCT || nRacial == RACIAL_TYPE_ELEMENTAL || nRacial == RACIAL_TYPE_UNDEAD || nRacial == RACIAL_TYPE_OOZE) return;
int bSave;
int nDifficulty = GetGameDifficulty();
// if we are on hardcore difficulty, we get no save
if (nDifficulty >= GAME_DIFFICULTY_NORMAL)
{
bSave = FALSE;
}
else
{
bSave = (PRCMySavingThrow(SAVING_THROW_FORT,oTarget,10+(GetHitDice(OBJECT_SELF)/2)) != 0);
}
// if we failed the save (or never got one)
if (!bSave)
{
// int below 5? We are braindead
FloatingTextStrRefOnCreature(85566,oTarget);
if (GetAbilityScore(oTarget,ABILITY_INTELLIGENCE) <5)
{
effect eDeath = EffectDamage(GetCurrentHitPoints(oTarget)+1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eBlood,oTarget);
DelayCommand(1.5f, ApplyEffectToObject(DURATION_TYPE_INSTANT,eDeath,oTarget));
}
else
{
int nDamage = d3()+2;
// Ok, since the engine prevents ability score damage from the same spell to stack,
// we are using another "quirk" in the engine to make it stack:
// by DelayCommanding the spell the effect looses its SpellID information and stacks...
DelayCommand(0.01f,DoSuckBrain(oTarget, nDamage));
// if our target was poisoned or diseased, we inherit that
if (PRCGetHasEffect( EFFECT_TYPE_POISON,oTarget))
{
effect ePoison = EffectPoison(POISON_PHASE_SPIDER_VENOM);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,ePoison,OBJECT_SELF);
}
if (PRCGetHasEffect( EFFECT_TYPE_DISEASE,oTarget))
{
effect eDisease = EffectDisease(DISEASE_SOLDIER_SHAKES);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eDisease,OBJECT_SELF);
}
}
}
}