Further file organization
Further file organization
This commit is contained in:
70
nwn/nwnprc/trunk/racescripts/avar_dive.nss
Normal file
70
nwn/nwnprc/trunk/racescripts/avar_dive.nss
Normal 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);
|
||||
}
|
||||
}
|
106
nwn/nwnprc/trunk/racescripts/bdd_cave_conv.nss
Normal file
106
nwn/nwnprc/trunk/racescripts/bdd_cave_conv.nss
Normal 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);
|
||||
}
|
||||
}
|
16
nwn/nwnprc/trunk/racescripts/bdd_cave_ent.nss
Normal file
16
nwn/nwnprc/trunk/racescripts/bdd_cave_ent.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
535
nwn/nwnprc/trunk/racescripts/bdd_flavor.nss
Normal file
535
nwn/nwnprc/trunk/racescripts/bdd_flavor.nss
Normal 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..."));
|
||||
}
|
||||
}
|
||||
}
|
40
nwn/nwnprc/trunk/racescripts/bdd_heat.nss
Normal file
40
nwn/nwnprc/trunk/racescripts/bdd_heat.nss
Normal 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);
|
||||
}
|
58
nwn/nwnprc/trunk/racescripts/bdd_onplayerrest.nss
Normal file
58
nwn/nwnprc/trunk/racescripts/bdd_onplayerrest.nss
Normal 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);
|
||||
}
|
30
nwn/nwnprc/trunk/racescripts/hound_aurafear.nss
Normal file
30
nwn/nwnprc/trunk/racescripts/hound_aurafear.nss
Normal 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);
|
||||
}
|
50
nwn/nwnprc/trunk/racescripts/hound_aurafeara.nss
Normal file
50
nwn/nwnprc/trunk/racescripts/hound_aurafeara.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
nwn/nwnprc/trunk/racescripts/minot_charge.nss
Normal file
14
nwn/nwnprc/trunk/racescripts/minot_charge.nss
Normal 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());
|
||||
}
|
61
nwn/nwnprc/trunk/racescripts/race_appear.nss
Normal file
61
nwn/nwnprc/trunk/racescripts/race_appear.nss
Normal 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);
|
||||
}
|
58
nwn/nwnprc/trunk/racescripts/race_ara_human.nss
Normal file
58
nwn/nwnprc/trunk/racescripts/race_ara_human.nss
Normal 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));
|
||||
}
|
||||
}
|
58
nwn/nwnprc/trunk/racescripts/race_ara_hybrid.nss
Normal file
58
nwn/nwnprc/trunk/racescripts/race_ara_hybrid.nss
Normal 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));
|
||||
}
|
||||
}
|
65
nwn/nwnprc/trunk/racescripts/race_aranea_web.nss
Normal file
65
nwn/nwnprc/trunk/racescripts/race_aranea_web.nss
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
28
nwn/nwnprc/trunk/racescripts/race_arkamoi.nss
Normal file
28
nwn/nwnprc/trunk/racescripts/race_arkamoi.nss
Normal 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);
|
||||
}
|
13
nwn/nwnprc/trunk/racescripts/race_arkamoi_mmd.nss
Normal file
13
nwn/nwnprc/trunk/racescripts/race_arkamoi_mmd.nss
Normal 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);
|
||||
}
|
63
nwn/nwnprc/trunk/racescripts/race_azer_flame.nss
Normal file
63
nwn/nwnprc/trunk/racescripts/race_azer_flame.nss
Normal 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);
|
||||
}
|
||||
}
|
13
nwn/nwnprc/trunk/racescripts/race_bar_charge.nss
Normal file
13
nwn/nwnprc/trunk/racescripts/race_bar_charge.nss
Normal 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);
|
||||
}
|
35
nwn/nwnprc/trunk/racescripts/race_blindbeaut.nss
Normal file
35
nwn/nwnprc/trunk/racescripts/race_blindbeaut.nss
Normal 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);
|
||||
}
|
45
nwn/nwnprc/trunk/racescripts/race_blindbeauta.nss
Normal file
45
nwn/nwnprc/trunk/racescripts/race_blindbeauta.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
18
nwn/nwnprc/trunk/racescripts/race_bodylamp.nss
Normal file
18
nwn/nwnprc/trunk/racescripts/race_bodylamp.nss
Normal 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);
|
||||
}
|
||||
}
|
26
nwn/nwnprc/trunk/racescripts/race_bodylampdaz.nss
Normal file
26
nwn/nwnprc/trunk/racescripts/race_bodylampdaz.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
|
123
nwn/nwnprc/trunk/racescripts/race_deaththroes.nss
Normal file
123
nwn/nwnprc/trunk/racescripts/race_deaththroes.nss
Normal 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.");
|
||||
}
|
||||
}*/
|
||||
}
|
52
nwn/nwnprc/trunk/racescripts/race_enray.nss
Normal file
52
nwn/nwnprc/trunk/racescripts/race_enray.nss
Normal 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);
|
||||
}
|
270
nwn/nwnprc/trunk/racescripts/race_ev_aquire.nss
Normal file
270
nwn/nwnprc/trunk/racescripts/race_ev_aquire.nss
Normal 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));
|
||||
}
|
92
nwn/nwnprc/trunk/racescripts/race_faerief.nss
Normal file
92
nwn/nwnprc/trunk/racescripts/race_faerief.nss
Normal 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();
|
||||
}
|
47
nwn/nwnprc/trunk/racescripts/race_feyrialter.nss
Normal file
47
nwn/nwnprc/trunk/racescripts/race_feyrialter.nss
Normal 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);
|
||||
}
|
50
nwn/nwnprc/trunk/racescripts/race_ff_iceblast.nss
Normal file
50
nwn/nwnprc/trunk/racescripts/race_ff_iceblast.nss
Normal 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));
|
||||
}
|
||||
}
|
16
nwn/nwnprc/trunk/racescripts/race_gloura.nss
Normal file
16
nwn/nwnprc/trunk/racescripts/race_gloura.nss
Normal 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);
|
||||
}
|
50
nwn/nwnprc/trunk/racescripts/race_hadrimoi.nss
Normal file
50
nwn/nwnprc/trunk/racescripts/race_hadrimoi.nss
Normal 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);
|
||||
}
|
38
nwn/nwnprc/trunk/racescripts/race_hadrimoi_bf.nss
Normal file
38
nwn/nwnprc/trunk/racescripts/race_hadrimoi_bf.nss
Normal 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);
|
||||
}
|
211
nwn/nwnprc/trunk/racescripts/race_hb.nss
Normal file
211
nwn/nwnprc/trunk/racescripts/race_hb.nss
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
44
nwn/nwnprc/trunk/racescripts/race_kapak_apply.nss
Normal file
44
nwn/nwnprc/trunk/racescripts/race_kapak_apply.nss
Normal 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"));
|
||||
}
|
||||
}
|
57
nwn/nwnprc/trunk/racescripts/race_kapak_onhit.nss
Normal file
57
nwn/nwnprc/trunk/racescripts/race_kapak_onhit.nss
Normal 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);
|
||||
}
|
||||
}
|
20
nwn/nwnprc/trunk/racescripts/race_kil_ancient.nss
Normal file
20
nwn/nwnprc/trunk/racescripts/race_kil_ancient.nss
Normal 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);
|
||||
}
|
22
nwn/nwnprc/trunk/racescripts/race_kil_ft_hunt.nss
Normal file
22
nwn/nwnprc/trunk/racescripts/race_kil_ft_hunt.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
|
22
nwn/nwnprc/trunk/racescripts/race_kil_hunter.nss
Normal file
22
nwn/nwnprc/trunk/racescripts/race_kil_hunter.nss
Normal 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);
|
||||
}
|
46
nwn/nwnprc/trunk/racescripts/race_kil_smite.nss
Normal file
46
nwn/nwnprc/trunk/racescripts/race_kil_smite.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
46
nwn/nwnprc/trunk/racescripts/race_lashemoi.nss
Normal file
46
nwn/nwnprc/trunk/racescripts/race_lashemoi.nss
Normal 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);
|
||||
}
|
34
nwn/nwnprc/trunk/racescripts/race_lashemoi_bf.nss
Normal file
34
nwn/nwnprc/trunk/racescripts/race_lashemoi_bf.nss
Normal 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);
|
||||
}
|
190
nwn/nwnprc/trunk/racescripts/race_lifepthconv.nss
Normal file
190
nwn/nwnprc/trunk/racescripts/race_lifepthconv.nss
Normal 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()
|
||||
{
|
||||
}
|
37
nwn/nwnprc/trunk/racescripts/race_marrubreath.nss
Normal file
37
nwn/nwnprc/trunk/racescripts/race_marrubreath.nss
Normal 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);
|
||||
}
|
||||
}
|
32
nwn/nwnprc/trunk/racescripts/race_mars_howl.nss
Normal file
32
nwn/nwnprc/trunk/racescripts/race_mars_howl.nss
Normal 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);
|
||||
}
|
||||
}
|
30
nwn/nwnprc/trunk/racescripts/race_mart_howl.nss
Normal file
30
nwn/nwnprc/trunk/racescripts/race_mart_howl.nss
Normal 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);
|
||||
}
|
||||
}
|
93
nwn/nwnprc/trunk/racescripts/race_mephbreath.nss
Normal file
93
nwn/nwnprc/trunk/racescripts/race_mephbreath.nss
Normal 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);
|
||||
|
||||
}
|
44
nwn/nwnprc/trunk/racescripts/race_muck_squirt.nss
Normal file
44
nwn/nwnprc/trunk/racescripts/race_muck_squirt.nss
Normal 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);
|
||||
}
|
||||
}
|
20
nwn/nwnprc/trunk/racescripts/race_outburst.nss
Normal file
20
nwn/nwnprc/trunk/racescripts/race_outburst.nss
Normal 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));
|
||||
}
|
171
nwn/nwnprc/trunk/racescripts/race_pixpoly.nss
Normal file
171
nwn/nwnprc/trunk/racescripts/race_pixpoly.nss
Normal 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
|
||||
}
|
8
nwn/nwnprc/trunk/racescripts/race_psi_stomp.nss
Normal file
8
nwn/nwnprc/trunk/racescripts/race_psi_stomp.nss
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
*/
|
||||
#include "psi_inc_psifunc"
|
||||
|
||||
void main()
|
||||
{
|
||||
UsePower(POWER_STOMP, CLASS_TYPE_INVALID, TRUE, GetHitDice(OBJECT_SELF)/2);
|
||||
}
|
58
nwn/nwnprc/trunk/racescripts/race_razorstorm.nss
Normal file
58
nwn/nwnprc/trunk/racescripts/race_razorstorm.nss
Normal 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));
|
||||
}
|
20
nwn/nwnprc/trunk/racescripts/race_resiliance.nss
Normal file
20
nwn/nwnprc/trunk/racescripts/race_resiliance.nss
Normal 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);
|
||||
}
|
25
nwn/nwnprc/trunk/racescripts/race_resistance.nss
Normal file
25
nwn/nwnprc/trunk/racescripts/race_resistance.nss
Normal 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);
|
||||
}
|
||||
}
|
43
nwn/nwnprc/trunk/racescripts/race_rkdisguise.nss
Normal file
43
nwn/nwnprc/trunk/racescripts/race_rkdisguise.nss
Normal 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);
|
||||
|
||||
}
|
||||
}
|
259
nwn/nwnprc/trunk/racescripts/race_shfttrt_con.nss
Normal file
259
nwn/nwnprc/trunk/racescripts/race_shfttrt_con.nss
Normal 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);
|
||||
}
|
||||
}
|
189
nwn/nwnprc/trunk/racescripts/race_shifter.nss
Normal file
189
nwn/nwnprc/trunk/racescripts/race_shifter.nss
Normal 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);
|
||||
}
|
||||
|
||||
}
|
91
nwn/nwnprc/trunk/racescripts/race_skarn_spine.nss
Normal file
91
nwn/nwnprc/trunk/racescripts/race_skarn_spine.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
1268
nwn/nwnprc/trunk/racescripts/race_skin.nss
Normal file
1268
nwn/nwnprc/trunk/racescripts/race_skin.nss
Normal file
File diff suppressed because it is too large
Load Diff
342
nwn/nwnprc/trunk/racescripts/race_sla.nss
Normal file
342
nwn/nwnprc/trunk/racescripts/race_sla.nss
Normal 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);
|
||||
}
|
196
nwn/nwnprc/trunk/racescripts/race_spiritfkcon.nss
Normal file
196
nwn/nwnprc/trunk/racescripts/race_spiritfkcon.nss
Normal 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);
|
||||
}
|
||||
}
|
29
nwn/nwnprc/trunk/racescripts/race_stench.nss
Normal file
29
nwn/nwnprc/trunk/racescripts/race_stench.nss
Normal 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);
|
||||
}
|
64
nwn/nwnprc/trunk/racescripts/race_stencha.nss
Normal file
64
nwn/nwnprc/trunk/racescripts/race_stencha.nss
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
44
nwn/nwnprc/trunk/racescripts/race_stunglance.nss
Normal file
44
nwn/nwnprc/trunk/racescripts/race_stunglance.nss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
16
nwn/nwnprc/trunk/racescripts/race_touchluck.nss
Normal file
16
nwn/nwnprc/trunk/racescripts/race_touchluck.nss
Normal 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);
|
||||
}
|
56
nwn/nwnprc/trunk/racescripts/race_treewalk.nss
Normal file
56
nwn/nwnprc/trunk/racescripts/race_treewalk.nss
Normal 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"));
|
||||
|
||||
}
|
||||
|
||||
|
46
nwn/nwnprc/trunk/racescripts/race_turlemoi.nss
Normal file
46
nwn/nwnprc/trunk/racescripts/race_turlemoi.nss
Normal 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);
|
||||
}
|
34
nwn/nwnprc/trunk/racescripts/race_turlemoi_bf.nss
Normal file
34
nwn/nwnprc/trunk/racescripts/race_turlemoi_bf.nss
Normal 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);
|
||||
}
|
169
nwn/nwnprc/trunk/racescripts/race_warforged.nss
Normal file
169
nwn/nwnprc/trunk/racescripts/race_warforged.nss
Normal 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));
|
||||
}
|
||||
}
|
58
nwn/nwnprc/trunk/racescripts/race_waterbreath.nss
Normal file
58
nwn/nwnprc/trunk/racescripts/race_waterbreath.nss
Normal 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();
|
||||
}
|
23
nwn/nwnprc/trunk/racescripts/race_wld_fury.nss
Normal file
23
nwn/nwnprc/trunk/racescripts/race_wld_fury.nss
Normal 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);
|
||||
}
|
||||
}
|
32
nwn/nwnprc/trunk/racescripts/race_wolfform.nss
Normal file
32
nwn/nwnprc/trunk/racescripts/race_wolfform.nss
Normal 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);
|
||||
}
|
||||
}
|
27
nwn/nwnprc/trunk/racescripts/race_xeph_burst.nss
Normal file
27
nwn/nwnprc/trunk/racescripts/race_xeph_burst.nss
Normal 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);
|
||||
}
|
116
nwn/nwnprc/trunk/racescripts/x2_s1_suckbrain.nss
Normal file
116
nwn/nwnprc/trunk/racescripts/x2_s1_suckbrain.nss
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user