Area Cleanup. Added CEP3 Skyboxes
Area Cleanup. Added CEP3 Skyboxes. Beholder AI fix. NPC & Mook pass. Added QN OnHit script. Add XP for Traps system.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Port PC
|
||||
// Port PC to 10a NW Caves
|
||||
///////////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
|
||||
60
_module/nss/ema_xp4trap_dis.nss
Normal file
60
_module/nss/ema_xp4trap_dis.nss
Normal file
@@ -0,0 +1,60 @@
|
||||
/*----------------------------------------------------------------------
|
||||
|
||||
New Name: ema_xp4trap_dis
|
||||
Date: 19-OCT-2003 - created
|
||||
Date: 20-oct-2003 - reworked comments
|
||||
Re-creator: Drakkenkin
|
||||
|
||||
Notes:
|
||||
This Script was made from the scripts Telzar08Trap_XP_award and
|
||||
Velar03trap_disarm_xp. The Scripts were made by Telzar and Velar
|
||||
respectively.
|
||||
|
||||
I re-worked this script because I like most of one of the script but
|
||||
I like the detection if the PC is in or out of combat of the
|
||||
other script. So I combined the two.
|
||||
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
// Variables
|
||||
object oPC=GetLastDisarmed();
|
||||
int iXPaward = 0;
|
||||
int iXPawarddc = 0;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (GetIsInCombat(oPC))
|
||||
{
|
||||
iXPawarddc = (GetTrapDisarmDC(OBJECT_SELF) *10);
|
||||
// Multiplies the Trap Disarm DC by 10
|
||||
|
||||
iXPaward = (iXPawarddc -((GetHitDice(oPC)-1)*10));
|
||||
// Subtracts 10xp for every (level - 1) of pc form award.
|
||||
//(this way 1st level Pcs get full xp).
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
iXPawarddc = (GetTrapDisarmDC(OBJECT_SELF) *5);
|
||||
// Multiplies the Trap Disarm DC by 5
|
||||
|
||||
iXPaward = (iXPawarddc -((GetHitDice(oPC)-1)*5));
|
||||
// Subtracts 5xp for every (level - 1) of pc form award.
|
||||
}
|
||||
SendMessageToPC( (oPC ),"Trap disarmed");
|
||||
// Sends message to the PC stating - trap was disarmed.
|
||||
|
||||
if (iXPaward >= 1)
|
||||
// checks to make sure that the xp award is at least 1.
|
||||
{
|
||||
GiveXPToCreature(oPC, iXPaward);
|
||||
// If the XP reward is at least 1 then give the PC a reward.
|
||||
}
|
||||
else
|
||||
// If the XP award is less then 1.
|
||||
{
|
||||
GiveXPToCreature(oPC, 1);
|
||||
// give 1 xp.
|
||||
}
|
||||
}
|
||||
@@ -13839,7 +13839,7 @@ int AI_AttemptHostileSkills()
|
||||
GlobalIntelligence >= 3) ||
|
||||
GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PICKPOCKETING, AI_OTHER_COMBAT_MASTER))
|
||||
{
|
||||
// SpeakString("Seting for NO: " + IntToString(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PICKPOCKETING, AI_OTHER_COMBAT_MASTER)) + " YES: " + IntToString(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PICKPOCKETING, AI_OTHER_COMBAT_MASTER)));
|
||||
//SpeakString("Seting for NO: " + IntToString(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PICKPOCKETING, AI_OTHER_COMBAT_MASTER)) + " YES: " + IntToString(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PICKPOCKETING, AI_OTHER_COMBAT_MASTER)));
|
||||
// Need appropriate level of skill, checked On Spawn, or overriden...
|
||||
AI_ActionUseSkillOnMeleeTarget(SKILL_PICK_POCKET);
|
||||
return TRUE;
|
||||
|
||||
56
_module/nss/nw_ai_cmbtrndend.nss
Normal file
56
_module/nss/nw_ai_cmbtrndend.nss
Normal file
@@ -0,0 +1,56 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On End of Combat Round
|
||||
//:: nw_ai_cmbtrndend
|
||||
//:: Copyright (c) 2008 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Calls the end of combat script every round
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Oct 16, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Modified By: Deva Winblood
|
||||
//:: Modified On: Feb 16th, 2008
|
||||
//:: Added Support for Mounted Combat Feat Support
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "NW_I0_GENERIC"
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT"))
|
||||
{ // set variables on target for mounted combat
|
||||
DeleteLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL");
|
||||
DeleteLocalInt(OBJECT_SELF,"nX3_HP_BEFORE");
|
||||
DeleteLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT");
|
||||
if (GetHasFeat(FEAT_MOUNTED_COMBAT,OBJECT_SELF))
|
||||
{ // check for AC increase
|
||||
int nRoll=d20()+GetSkillRank(SKILL_RIDE);
|
||||
nRoll=nRoll-10;
|
||||
if (nRoll>4)
|
||||
{ // ac increase
|
||||
nRoll=nRoll/5;
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectACIncrease(nRoll),OBJECT_SELF,8.5);
|
||||
} // ac increase
|
||||
} // check for AC increase
|
||||
} // set variables on target for mounted combat
|
||||
|
||||
if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
|
||||
{
|
||||
DetermineSpecialBehavior();
|
||||
}
|
||||
else if(!GetSpawnInCondition(NW_FLAG_SET_WARNINGS))
|
||||
{
|
||||
DetermineCombatRound();
|
||||
}
|
||||
if(GetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(1003));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
106
_module/nss/nw_ai_heartbeat.nss
Normal file
106
_module/nss/nw_ai_heartbeat.nss
Normal file
@@ -0,0 +1,106 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Heartbeat
|
||||
//:: nw_ai_heartbeat
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnHeartbeat script for NPCs.
|
||||
|
||||
This script causes NPCs to perform default animations
|
||||
while not otherwise engaged.
|
||||
|
||||
This script duplicates the behavior of the default
|
||||
script and just cleans up the code and removes
|
||||
redundant conditional checks.
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/22/2002
|
||||
//:://////////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
|
||||
void main()
|
||||
{
|
||||
// * if not runnning normal or better Ai then exit for performance reasons
|
||||
if (GetAILevel() == AI_LEVEL_VERY_LOW) return;
|
||||
|
||||
// Buff ourselves up right away if we should
|
||||
if(GetSpawnInCondition(NW_FLAG_FAST_BUFF_ENEMY))
|
||||
{
|
||||
// This will return TRUE if an enemy was within 40.0 m
|
||||
// and we buffed ourselves up instantly to respond --
|
||||
// simulates a spellcaster with protections enabled
|
||||
// already.
|
||||
if(TalentAdvancedBuff(40.0))
|
||||
{
|
||||
// This is a one-shot deal
|
||||
SetSpawnInCondition(NW_FLAG_FAST_BUFF_ENEMY, FALSE);
|
||||
|
||||
// This return means we skip sending the user-defined
|
||||
// heartbeat signal in this one case.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(GetHasEffect(EFFECT_TYPE_SLEEP))
|
||||
{
|
||||
// If we're asleep and this is the result of sleeping
|
||||
// at night, apply the floating 'z's visual effect
|
||||
// every so often
|
||||
|
||||
if(GetSpawnInCondition(NW_FLAG_SLEEPING_AT_NIGHT))
|
||||
{
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_SLEEP);
|
||||
if(d10() > 6)
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have the 'constant' waypoints flag set, walk to the next
|
||||
// waypoint.
|
||||
else if ( GetWalkCondition(NW_WALK_FLAG_CONSTANT) )
|
||||
{
|
||||
WalkWayPoints();
|
||||
}
|
||||
|
||||
// Check to see if we should be playing default animations
|
||||
// - make sure we don't have any current targets
|
||||
else if ( !GetIsObjectValid(GetAttemptedAttackTarget())
|
||||
&& !GetIsObjectValid(GetAttemptedSpellTarget())
|
||||
// && !GetIsPostOrWalking())
|
||||
&& !GetIsObjectValid(GetNearestSeenEnemy()))
|
||||
{
|
||||
if (GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL) || GetBehaviorState(NW_FLAG_BEHAVIOR_OMNIVORE) ||
|
||||
GetBehaviorState(NW_FLAG_BEHAVIOR_HERBIVORE))
|
||||
{
|
||||
// This handles special attacking/fleeing behavior
|
||||
// for omnivores & herbivores.
|
||||
DetermineSpecialBehavior();
|
||||
}
|
||||
else if (!IsInConversation(OBJECT_SELF))
|
||||
{
|
||||
if (GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS)
|
||||
|| GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN)
|
||||
|| GetIsEncounterCreature())
|
||||
{
|
||||
PlayMobileAmbientAnimations();
|
||||
}
|
||||
else if (GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS))
|
||||
{
|
||||
PlayImmobileAmbientAnimations();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send the user-defined event signal if specified
|
||||
if(GetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_HEARTBEAT));
|
||||
}
|
||||
}
|
||||
69
_module/nss/nw_ai_onattacked.nss
Normal file
69
_module/nss/nw_ai_onattacked.nss
Normal file
@@ -0,0 +1,69 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Attacked
|
||||
//:: nw_ai_onattacked
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
If already fighting then ignore, else determine
|
||||
combat round
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Oct 16, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Modified By: Deva Winblood
|
||||
//:: Modified On: Jan 4th, 2008
|
||||
//:: Added Support for Mounted Combat Feat Support
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
|
||||
void main()
|
||||
{
|
||||
if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT"))
|
||||
{ // set variables on target for mounted combat
|
||||
SetLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL",TRUE);
|
||||
SetLocalInt(OBJECT_SELF,"nX3_HP_BEFORE",GetCurrentHitPoints(OBJECT_SELF));
|
||||
} // set variables on target for mounted combat
|
||||
|
||||
if(GetFleeToExit()) {
|
||||
// Run away!
|
||||
ActivateFleeToExit();
|
||||
} else if (GetSpawnInCondition(NW_FLAG_SET_WARNINGS)) {
|
||||
// We give an attacker one warning before we attack
|
||||
// This is not fully implemented yet
|
||||
SetSpawnInCondition(NW_FLAG_SET_WARNINGS, FALSE);
|
||||
|
||||
//Put a check in to see if this attacker was the last attacker
|
||||
//Possibly change the GetNPCWarning function to make the check
|
||||
} else {
|
||||
object oAttacker = GetLastAttacker();
|
||||
if (!GetIsObjectValid(oAttacker)) {
|
||||
// Don't do anything, invalid attacker
|
||||
|
||||
} else if (!GetIsFighting(OBJECT_SELF)) {
|
||||
// We're not fighting anyone else, so
|
||||
// start fighting the attacker
|
||||
if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) {
|
||||
SetSummonHelpIfAttacked();
|
||||
DetermineSpecialBehavior(oAttacker);
|
||||
} else if (GetArea(oAttacker) == GetArea(OBJECT_SELF)) {
|
||||
SetSummonHelpIfAttacked();
|
||||
DetermineCombatRound(oAttacker);
|
||||
}
|
||||
|
||||
//Shout Attack my target, only works with the On Spawn In setup
|
||||
SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
|
||||
|
||||
//Shout that I was attacked
|
||||
SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(GetSpawnInCondition(NW_FLAG_ATTACK_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_ATTACKED));
|
||||
}
|
||||
}
|
||||
49
_module/nss/nw_ai_onblocked.nss
Normal file
49
_module/nss/nw_ai_onblocked.nss
Normal file
@@ -0,0 +1,49 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Blocked
|
||||
//:: nw_ai_onblocked
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This will cause blocked creatures to open
|
||||
or smash down doors depending on int and
|
||||
str.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Nov 23, 2001
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
object oDoor = GetBlockingDoor();
|
||||
if (GetObjectType(oDoor) == OBJECT_TYPE_CREATURE)
|
||||
{
|
||||
// * Increment number of times blocked
|
||||
/*SetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED", GetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED") + 1);
|
||||
if (GetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED") > 3)
|
||||
{
|
||||
SpeakString("Blocked by creature");
|
||||
SetLocalInt(OBJECT_SELF, "X2_NUMTIMES_BLOCKED",0);
|
||||
ClearAllActions();
|
||||
object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||
if (GetIsObjectValid(oEnemy) == TRUE)
|
||||
{
|
||||
ActionEquipMostDamagingRanged(oEnemy);
|
||||
ActionAttack(oEnemy);
|
||||
}
|
||||
return;
|
||||
} */
|
||||
return;
|
||||
}
|
||||
if(GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 5)
|
||||
{
|
||||
if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_OPEN) && GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 7 )
|
||||
{
|
||||
DoDoorAction(oDoor, DOOR_ACTION_OPEN);
|
||||
}
|
||||
else if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_BASH))
|
||||
{
|
||||
DoDoorAction(oDoor, DOOR_ACTION_BASH);
|
||||
}
|
||||
}
|
||||
}
|
||||
93
_module/nss/nw_ai_onconvers.nss
Normal file
93
_module/nss/nw_ai_onconvers.nss
Normal file
@@ -0,0 +1,93 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Conversation
|
||||
//:: nw_ai_onconvers
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnConversation event handler for NPCs.
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/22/2002
|
||||
//:://////////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
|
||||
void main()
|
||||
{
|
||||
// * if petrified, jump out
|
||||
if (GetHasEffect(EFFECT_TYPE_PETRIFY, OBJECT_SELF) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// * If dead, exit directly.
|
||||
if (GetIsDead(OBJECT_SELF) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// See if what we just 'heard' matches any of our
|
||||
// predefined patterns
|
||||
int nMatch = GetListenPatternNumber();
|
||||
object oShouter = GetLastSpeaker();
|
||||
|
||||
if (nMatch == -1)
|
||||
{
|
||||
// Not a match -- start an ordinary conversation
|
||||
if (GetCommandable(OBJECT_SELF))
|
||||
{
|
||||
ClearActions(CLEAR_NW_C2_DEFAULT4_29);
|
||||
BeginConversation();
|
||||
}
|
||||
else
|
||||
// * July 31 2004
|
||||
// * If only charmed then allow conversation
|
||||
// * so you can have a better chance of convincing
|
||||
// * people of lowering prices
|
||||
if (GetHasEffect(EFFECT_TYPE_CHARMED) == TRUE)
|
||||
{
|
||||
ClearActions(CLEAR_NW_C2_DEFAULT4_29);
|
||||
BeginConversation();
|
||||
}
|
||||
}
|
||||
// Respond to shouts from friendly non-PCs only
|
||||
else if (GetIsObjectValid(oShouter)
|
||||
&& !GetIsPC(oShouter)
|
||||
&& GetIsFriend(oShouter))
|
||||
{
|
||||
object oIntruder = OBJECT_INVALID;
|
||||
// Determine the intruder if any
|
||||
if(nMatch == 4)
|
||||
{
|
||||
oIntruder = GetLocalObject(oShouter, "NW_BLOCKER_INTRUDER");
|
||||
}
|
||||
else if (nMatch == 5)
|
||||
{
|
||||
oIntruder = GetLastHostileActor(oShouter);
|
||||
if(!GetIsObjectValid(oIntruder))
|
||||
{
|
||||
oIntruder = GetAttemptedAttackTarget();
|
||||
if(!GetIsObjectValid(oIntruder))
|
||||
{
|
||||
oIntruder = GetAttemptedSpellTarget();
|
||||
if(!GetIsObjectValid(oIntruder))
|
||||
{
|
||||
oIntruder = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Actually respond to the shout
|
||||
RespondToShout(oShouter, nMatch, oIntruder);
|
||||
}
|
||||
|
||||
// Send the user-defined event if appropriate
|
||||
if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DIALOGUE));
|
||||
}
|
||||
}
|
||||
110
_module/nss/nw_ai_ondamaged.nss
Normal file
110
_module/nss/nw_ai_ondamaged.nss
Normal file
@@ -0,0 +1,110 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Damaged
|
||||
//:: nw_ai_ondamaged
|
||||
//:: Copyright (c) 2002 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Default OnDamaged handler
|
||||
/*
|
||||
If already fighting then ignore, else determine
|
||||
combat round
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/22/2002
|
||||
//:://////////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Modified By: Deva Winblood
|
||||
//:: Modified On: Jan 17th, 2008
|
||||
//:: Added Support for Mounted Combat Feat Support
|
||||
//:://////////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
#include "x3_inc_horse"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oDamager = GetLastDamager();
|
||||
object oMe=OBJECT_SELF;
|
||||
int nHPBefore;
|
||||
if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT"))
|
||||
if (GetHasFeat(FEAT_MOUNTED_COMBAT)&&HorseGetIsMounted(OBJECT_SELF))
|
||||
{ // see if can negate some damage
|
||||
if (GetLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL"))
|
||||
{ // last attack was physical
|
||||
nHPBefore=GetLocalInt(OBJECT_SELF,"nX3_HP_BEFORE");
|
||||
if (!GetLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT"))
|
||||
{ // haven't already had a chance to use this for the round
|
||||
SetLocalInt(OBJECT_SELF,"bX3_ALREADY_MOUNTED_COMBAT",TRUE);
|
||||
int nAttackRoll=GetBaseAttackBonus(oDamager)+d20();
|
||||
int nRideCheck=GetSkillRank(SKILL_RIDE,OBJECT_SELF)+d20();
|
||||
if (nRideCheck>=nAttackRoll&&!GetIsDead(OBJECT_SELF))
|
||||
{ // averted attack
|
||||
if (GetIsPC(oDamager)) SendMessageToPC(oDamager,GetName(OBJECT_SELF)+GetStringByStrRef(111991));
|
||||
//if (GetIsPC(OBJECT_SELF)) SendMessageToPCByStrRef(OBJECT_SELF,111992");
|
||||
if (GetCurrentHitPoints(OBJECT_SELF)<nHPBefore)
|
||||
{ // heal
|
||||
effect eHeal=EffectHeal(nHPBefore-GetCurrentHitPoints(OBJECT_SELF));
|
||||
AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_INSTANT,eHeal,oMe));
|
||||
} // heal
|
||||
} // averted attack
|
||||
} // haven't already had a chance to use this for the round
|
||||
} // last attack was physical
|
||||
} // see if can negate some damage
|
||||
if(GetFleeToExit()) {
|
||||
// We're supposed to run away, do nothing
|
||||
} else if (GetSpawnInCondition(NW_FLAG_SET_WARNINGS)) {
|
||||
// don't do anything?
|
||||
} else {
|
||||
if (!GetIsObjectValid(oDamager)) {
|
||||
// don't do anything, we don't have a valid damager
|
||||
} else if (!GetIsFighting(OBJECT_SELF)) {
|
||||
// If we're not fighting, determine combat round
|
||||
if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) {
|
||||
DetermineSpecialBehavior(oDamager);
|
||||
} else {
|
||||
if(!GetObjectSeen(oDamager)
|
||||
&& GetArea(OBJECT_SELF) == GetArea(oDamager)) {
|
||||
// We don't see our attacker, go find them
|
||||
ActionMoveToLocation(GetLocation(oDamager), TRUE);
|
||||
ActionDoCommand(DetermineCombatRound());
|
||||
} else {
|
||||
DetermineCombatRound();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We are fighting already -- consider switching if we've been
|
||||
// attacked by a more powerful enemy
|
||||
object oTarget = GetAttackTarget();
|
||||
if (!GetIsObjectValid(oTarget))
|
||||
oTarget = GetAttemptedAttackTarget();
|
||||
if (!GetIsObjectValid(oTarget))
|
||||
oTarget = GetAttemptedSpellTarget();
|
||||
|
||||
// If our target isn't valid
|
||||
// or our damager has just dealt us 25% or more
|
||||
// of our hp in damager
|
||||
// or our damager is more than 2HD more powerful than our target
|
||||
// switch to attack the damager.
|
||||
if (!GetIsObjectValid(oTarget)
|
||||
|| (
|
||||
oTarget != oDamager
|
||||
&& (
|
||||
GetTotalDamageDealt() > (GetMaxHitPoints(OBJECT_SELF) / 4)
|
||||
|| (GetHitDice(oDamager) - 2) > GetHitDice(oTarget)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
// Switch targets
|
||||
DetermineCombatRound(oDamager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send the user-defined event signal
|
||||
if(GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DAMAGED));
|
||||
}
|
||||
}
|
||||
56
_module/nss/nw_ai_ondeath.nss
Normal file
56
_module/nss/nw_ai_ondeath.nss
Normal file
@@ -0,0 +1,56 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Death
|
||||
//:: nw_ai_ondeath
|
||||
//:: Copyright (c) 2002 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnDeath event handler for NPCs.
|
||||
|
||||
Adjusts killer's alignment if appropriate and
|
||||
alerts allies to our death.
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/22/2002
|
||||
//:://////////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Modified By: Deva Winblood
|
||||
//:: Modified On: April 1st, 2008
|
||||
//:: Added Support for Dying Wile Mounted
|
||||
//:://///////////////////////////////////////////////
|
||||
|
||||
#include "x2_inc_compon"
|
||||
#include "x0_i0_spawncond"
|
||||
#include "x3_inc_horse"
|
||||
|
||||
void main()
|
||||
{
|
||||
int nClass = GetLevelByClass(CLASS_TYPE_COMMONER);
|
||||
int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);
|
||||
object oKiller = GetLastKiller();
|
||||
|
||||
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsObjectValid(GetMaster(OBJECT_SELF))) SetLocalInt(GetMaster(OBJECT_SELF),"bX3_STORE_MOUNT_INFO",TRUE);
|
||||
|
||||
|
||||
// If we're a good/neutral commoner,
|
||||
// adjust the killer's alignment evil
|
||||
if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
|
||||
{
|
||||
AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
|
||||
}
|
||||
|
||||
// Call to allies to let them know we're dead
|
||||
SpeakString("NW_I_AM_DEAD", TALKVOLUME_SILENT_TALK);
|
||||
|
||||
//Shout Attack my target, only works with the On Spawn In setup
|
||||
SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
|
||||
|
||||
// NOTE: the OnDeath user-defined event does not
|
||||
// trigger reliably and should probably be removed
|
||||
if(GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(1007));
|
||||
}
|
||||
craft_drop_items(oKiller);
|
||||
}
|
||||
31
_module/nss/nw_ai_ondisturb.nss
Normal file
31
_module/nss/nw_ai_ondisturb.nss
Normal file
@@ -0,0 +1,31 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Disturbed
|
||||
//:: nw_ai_ondisturb
|
||||
//:: Copyright (c) 2002 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnDisturbed event handler for NPCs.
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/22/2002
|
||||
//:://////////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oTarget = GetLastDisturbed();
|
||||
|
||||
// If we've been disturbed and are not already fighting,
|
||||
// attack our disturber.
|
||||
if (GetIsObjectValid(oTarget) && !GetIsFighting(OBJECT_SELF)) {
|
||||
DetermineCombatRound(oTarget);
|
||||
}
|
||||
|
||||
// Send the disturbed flag if appropriate.
|
||||
if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT)) {
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DISTURBED));
|
||||
}
|
||||
}
|
||||
166
_module/nss/nw_ai_onpercept.nss
Normal file
166
_module/nss/nw_ai_onpercept.nss
Normal file
@@ -0,0 +1,166 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Perception
|
||||
//:: nw_ai_onpercept
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnPerception event handler for NPCs.
|
||||
|
||||
Handles behavior when perceiving a creature for the
|
||||
first time.
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
|
||||
void main()
|
||||
{
|
||||
// * if not runnning normal or better Ai then exit for performance reasons
|
||||
// * if not runnning normal or better Ai then exit for performance reasons
|
||||
if (GetAILevel() == AI_LEVEL_VERY_LOW) return;
|
||||
|
||||
object oPercep = GetLastPerceived();
|
||||
int bSeen = GetLastPerceptionSeen();
|
||||
int bHeard = GetLastPerceptionHeard();
|
||||
if (bHeard == FALSE)
|
||||
{
|
||||
// Has someone vanished in front of me?
|
||||
bHeard = GetLastPerceptionVanished();
|
||||
}
|
||||
|
||||
// This will cause the NPC to speak their one-liner
|
||||
// conversation on perception even if they are already
|
||||
// in combat.
|
||||
if(GetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION)
|
||||
&& GetIsPC(oPercep)
|
||||
&& bSeen)
|
||||
{
|
||||
SpeakOneLinerConversation();
|
||||
}
|
||||
|
||||
// March 5 2003 Brent
|
||||
// Had to add this section back in, since modifications were not taking this specific
|
||||
// example into account -- it made invisibility basically useless.
|
||||
//If the last perception event was hearing based or if someone vanished then go to search mode
|
||||
if ((GetLastPerceptionVanished()) && GetIsEnemy(GetLastPerceived()))
|
||||
{
|
||||
object oGone = GetLastPerceived();
|
||||
if((GetAttemptedAttackTarget() == GetLastPerceived() ||
|
||||
GetAttemptedSpellTarget() == GetLastPerceived() ||
|
||||
GetAttackTarget() == GetLastPerceived()) && GetArea(GetLastPerceived()) != GetArea(OBJECT_SELF))
|
||||
{
|
||||
ClearAllActions();
|
||||
DetermineCombatRound();
|
||||
}
|
||||
}
|
||||
|
||||
// This section has been heavily revised while keeping the
|
||||
// pre-existing behavior:
|
||||
// - If we're in combat, keep fighting.
|
||||
// - If not and we've perceived an enemy, start to fight.
|
||||
// Even if the perception event was a 'vanish', that's
|
||||
// still what we do anyway, since that will keep us
|
||||
// fighting any visible targets.
|
||||
// - If we're not in combat and haven't perceived an enemy,
|
||||
// see if the perception target is a PC and if we should
|
||||
// speak our attention-getting one-liner.
|
||||
if (GetIsInCombat(OBJECT_SELF))
|
||||
{
|
||||
// don't do anything else, we're busy
|
||||
//MyPrintString("GetIsFighting: TRUE");
|
||||
|
||||
}
|
||||
// * BK FEB 2003 Only fight if you can see them. DO NOT RELY ON HEARING FOR ENEMY DETECTION
|
||||
else if (GetIsEnemy(oPercep) && bSeen)
|
||||
{ // SpawnScriptDebugger();
|
||||
//MyPrintString("GetIsEnemy: TRUE");
|
||||
// We spotted an enemy and we're not already fighting
|
||||
if(!GetHasEffect(EFFECT_TYPE_SLEEP)) {
|
||||
if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
|
||||
{
|
||||
//MyPrintString("DetermineSpecialBehavior");
|
||||
DetermineSpecialBehavior();
|
||||
} else
|
||||
{
|
||||
//MyPrintString("DetermineCombatRound");
|
||||
SetFacingPoint(GetPosition(oPercep));
|
||||
SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);
|
||||
DetermineCombatRound();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bSeen)
|
||||
{
|
||||
//MyPrintString("GetLastPerceptionSeen: TRUE");
|
||||
if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL)) {
|
||||
DetermineSpecialBehavior();
|
||||
} else if (GetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION)
|
||||
&& GetIsPC(oPercep))
|
||||
{
|
||||
// The NPC will speak their one-liner conversation
|
||||
// This should probably be:
|
||||
// SpeakOneLinerConversation(oPercep);
|
||||
// instead, but leaving it as is for now.
|
||||
ActionStartConversation(OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
else
|
||||
// * July 14 2003: Some minor reactions based on invisible creatures being nearby
|
||||
if (bHeard && GetIsEnemy(oPercep))
|
||||
{
|
||||
// SpeakString("vanished");
|
||||
// * don't want creatures wandering too far after noises
|
||||
if (GetDistanceToObject(oPercep) <= 7.0)
|
||||
{
|
||||
// if (GetHasSpell(SPELL_TRUE_SEEING) == TRUE)
|
||||
if (GetHasSpell(SPELL_TRUE_SEEING))
|
||||
{
|
||||
ActionCastSpellAtObject(SPELL_TRUE_SEEING, OBJECT_SELF);
|
||||
}
|
||||
else
|
||||
// if (GetHasSpell(SPELL_SEE_INVISIBILITY) == TRUE)
|
||||
if (GetHasSpell(SPELL_SEE_INVISIBILITY))
|
||||
{
|
||||
ActionCastSpellAtObject(SPELL_SEE_INVISIBILITY, OBJECT_SELF);
|
||||
}
|
||||
else
|
||||
// if (GetHasSpell(SPELL_INVISIBILITY_PURGE) == TRUE)
|
||||
if (GetHasSpell(SPELL_INVISIBILITY_PURGE))
|
||||
{
|
||||
ActionCastSpellAtObject(SPELL_INVISIBILITY_PURGE, OBJECT_SELF);
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.5);
|
||||
ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.5);
|
||||
ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// activate ambient animations or walk waypoints if appropriate
|
||||
if (!IsInConversation(OBJECT_SELF)) {
|
||||
if (GetIsPostOrWalking()) {
|
||||
WalkWayPoints();
|
||||
} else if (GetIsPC(oPercep) &&
|
||||
(GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS)
|
||||
|| GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN)
|
||||
|| GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS)
|
||||
|| GetIsEncounterCreature()))
|
||||
{
|
||||
SetAnimationCondition(NW_ANIM_FLAG_IS_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send the user-defined event if appropriate
|
||||
if(GetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT) && GetLastPerceptionSeen())
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_PERCEIVE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
20
_module/nss/nw_ai_onrested.nss
Normal file
20
_module/nss/nw_ai_onrested.nss
Normal file
@@ -0,0 +1,20 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Rested
|
||||
//:: nw_ai_onrested
|
||||
//:: Copyright (c) 2002 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Determines the course of action to be taken
|
||||
after having just rested.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Don Moar
|
||||
//:: Created On: April 28, 2002
|
||||
//:://////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
// enter desired behaviour here
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
331
_module/nss/nw_ai_onspawn.nss
Normal file
331
_module/nss/nw_ai_onspawn.nss
Normal file
@@ -0,0 +1,331 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Spawn
|
||||
//:: nw_ai_onspawn
|
||||
//:: Copyright (c) 2002 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
* Default OnSpawn handler with XP1 revisions.
|
||||
* This corresponds to and produces the same results
|
||||
* as the default OnSpawn handler in the OC.
|
||||
*
|
||||
* This can be used to customize creature behavior in three main ways:
|
||||
*
|
||||
* - Uncomment the existing lines of code to activate certain
|
||||
* common desired behaviors from the moment when the creature
|
||||
* spawns in.
|
||||
*
|
||||
* - Uncomment the user-defined event signals to cause the
|
||||
* creature to fire events that you can then handle with
|
||||
* a custom OnUserDefined event handler script.
|
||||
*
|
||||
* - Add new code _at the end_ to alter the initial
|
||||
* behavior in a more customized way.
|
||||
*/
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/11/2002
|
||||
//:://////////////////////////////////////////////////
|
||||
//:: Updated 2003-08-20 Georg Zoeller: Added check for variables to active spawn in conditions without changing the spawnscript
|
||||
|
||||
#include "ms_name_inc"
|
||||
#include "x0_i0_anims"
|
||||
// #include "x0_i0_walkway" - in x0_i0_anims
|
||||
#include "x0_i0_treasure"
|
||||
|
||||
#include "x2_inc_switches"
|
||||
|
||||
void main()
|
||||
{
|
||||
// ***** Spawn-In Conditions ***** //
|
||||
|
||||
// * REMOVE COMMENTS (// ) before the "Set..." functions to activate
|
||||
// * them. Do NOT touch lines commented out with // *, those are
|
||||
// * real comments for information.
|
||||
|
||||
// * This causes the creature to say a one-line greeting in their
|
||||
// * conversation file upon perceiving the player. Put [NW_D2_GenCheck]
|
||||
// * in the "Text Seen When" field of the greeting in the conversation
|
||||
// * file. Don't attach any player responses.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
|
||||
|
||||
// * Same as above, but for hostile creatures to make them say
|
||||
// * a line before attacking.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
|
||||
|
||||
// * This NPC will attack when its allies call for help
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
|
||||
|
||||
// * If the NPC has the Hide skill they will go into stealth mode
|
||||
// * while doing WalkWayPoints().
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_STEALTH);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Enable stealth mode by setting a variable on the creature
|
||||
// Great for ambushes
|
||||
// See x2_inc_switches for more information about this
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_STEALTH) == TRUE)
|
||||
{
|
||||
SetSpawnInCondition(NW_FLAG_STEALTH);
|
||||
}
|
||||
// * Same, but for Search mode
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_SEARCH);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Make creature enter search mode after spawning by setting a variable
|
||||
// Great for guards, etc
|
||||
// See x2_inc_switches for more information about this
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_SEARCH) == TRUE)
|
||||
{
|
||||
SetSpawnInCondition(NW_FLAG_SEARCH);
|
||||
}
|
||||
// * This will set the NPC to give a warning to non-enemies
|
||||
// * before attacking.
|
||||
// * NN -- no clue what this really does yet
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
|
||||
|
||||
// * Separate the NPC's waypoints into day & night.
|
||||
// * See comment on WalkWayPoints() for use.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
|
||||
|
||||
// * If this is set, the NPC will appear using the "EffectAppear"
|
||||
// * animation instead of fading in, *IF* SetListeningPatterns()
|
||||
// * is called below.
|
||||
// *
|
||||
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
|
||||
|
||||
// * This will cause an NPC to use common animations it possesses,
|
||||
// * and use social ones to any other nearby friendly NPCs.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Enable immobile ambient animations by setting a variable
|
||||
// See x2_inc_switches for more information about this
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT_IMMOBILE) == TRUE)
|
||||
{
|
||||
SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
|
||||
}
|
||||
// * Same as above, except NPC will wander randomly around the
|
||||
// * area.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Enable mobile ambient animations by setting a variable
|
||||
// See x2_inc_switches for more information about this
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_USE_SPAWN_AMBIENT) == TRUE)
|
||||
{
|
||||
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
|
||||
}
|
||||
// **** Animation Conditions **** //
|
||||
// * These are extra conditions you can put on creatures with ambient
|
||||
// * animations.
|
||||
|
||||
// * Civilized creatures interact with placeables in
|
||||
// * their area that have the tag "NW_INTERACTIVE"
|
||||
// * and "talk" to each other.
|
||||
// *
|
||||
// * Humanoid races are civilized by default, so only
|
||||
// * set this flag for monster races that you want to
|
||||
// * behave the same way.
|
||||
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
|
||||
|
||||
// * If this flag is set, this creature will constantly
|
||||
// * be acting. Otherwise, creatures will only start
|
||||
// * performing their ambient animations when they
|
||||
// * first perceive a player, and they will stop when
|
||||
// * the player moves away.
|
||||
// SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
|
||||
|
||||
// * Civilized creatures with this flag set will
|
||||
// * randomly use a few voicechats. It's a good
|
||||
// * idea to avoid putting this on multiple
|
||||
// * creatures using the same voiceset.
|
||||
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
|
||||
|
||||
// * Creatures with _immobile_ ambient animations
|
||||
// * can have this flag set to make them mobile in a
|
||||
// * close range. They will never leave their immediate
|
||||
// * area, but will move around in it, frequently
|
||||
// * returning to their starting point.
|
||||
// *
|
||||
// * Note that creatures spawned inside interior areas
|
||||
// * that contain a waypoint with one of the tags
|
||||
// * "NW_HOME", "NW_TAVERN", "NW_SHOP" will automatically
|
||||
// * have this condition set.
|
||||
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
|
||||
|
||||
|
||||
// **** Special Combat Tactics *****//
|
||||
// * These are special flags that can be set on creatures to
|
||||
// * make them follow certain specialized combat tactics.
|
||||
// * NOTE: ONLY ONE OF THESE SHOULD BE SET ON A SINGLE CREATURE.
|
||||
|
||||
// * Ranged attacker
|
||||
// * Will attempt to stay at ranged distance from their
|
||||
// * target.
|
||||
// SetCombatCondition(X0_COMBAT_FLAG_RANGED);
|
||||
|
||||
// * Defensive attacker
|
||||
// * Will use defensive combat feats and parry
|
||||
// SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE);
|
||||
|
||||
// * Ambusher
|
||||
// * Will go stealthy/invisible and attack, then
|
||||
// * run away and try to go stealthy again before
|
||||
// * attacking anew.
|
||||
// SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER);
|
||||
|
||||
// * Cowardly
|
||||
// * Cowardly creatures will attempt to flee
|
||||
// * attackers.
|
||||
// SetCombatCondition(X0_COMBAT_FLAG_COWARDLY);
|
||||
|
||||
|
||||
// **** Escape Commands ***** //
|
||||
// * NOTE: ONLY ONE OF THE FOLLOWING SHOULD EVER BE SET AT ONE TIME.
|
||||
// * NOTE2: Not clear that these actually work. -- NN
|
||||
|
||||
// * Flee to a way point and return a short time later.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN);
|
||||
|
||||
// * Flee to a way point and do not return.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE);
|
||||
|
||||
// * Teleport to safety and do not return.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE);
|
||||
|
||||
// * Teleport to safety and return a short time later.
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN);
|
||||
|
||||
|
||||
|
||||
// ***** CUSTOM USER DEFINED EVENTS ***** /
|
||||
|
||||
|
||||
/*
|
||||
If you uncomment any of these conditions, the creature will fire
|
||||
a specific user-defined event number on each event. That will then
|
||||
allow you to write custom code in the "OnUserDefinedEvent" handler
|
||||
script to go on top of the default NPC behaviors for that event.
|
||||
|
||||
Example: I want to add some custom behavior to my NPC when they
|
||||
are damaged. I uncomment the "NW_FLAG_DAMAGED_EVENT", then create
|
||||
a new user-defined script that has something like this in it:
|
||||
|
||||
if (GetUserDefinedEventNumber() == 1006) {
|
||||
// Custom code for my NPC to execute when it's damaged
|
||||
}
|
||||
|
||||
These user-defined events are in the range 1001-1007.
|
||||
*/
|
||||
|
||||
// * Fire User Defined Event 1001 in the OnHeartbeat
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT);
|
||||
|
||||
// * Fire User Defined Event 1002
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT);
|
||||
|
||||
// * Fire User Defined Event 1005
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_ATTACK_EVENT);
|
||||
|
||||
// * Fire User Defined Event 1006
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT);
|
||||
|
||||
// * Fire User Defined Event 1008
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT);
|
||||
|
||||
// * Fire User Defined Event 1003
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT);
|
||||
|
||||
// * Fire User Defined Event 1004
|
||||
// *
|
||||
// SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT);
|
||||
|
||||
|
||||
|
||||
// ***** DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) ***** //
|
||||
|
||||
// * Goes through and sets up which shouts the NPC will listen to.
|
||||
// *
|
||||
SetListeningPatterns();
|
||||
|
||||
// * Walk among a set of waypoints.
|
||||
// * 1. Find waypoints with the tag "WP_" + NPC TAG + "_##" and walk
|
||||
// * among them in order.
|
||||
// * 2. If the tag of the Way Point is "POST_" + NPC TAG, stay there
|
||||
// * and return to it after combat.
|
||||
//
|
||||
// * Optional Parameters:
|
||||
// * void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
|
||||
//
|
||||
// * If "NW_FLAG_DAY_NIGHT_POSTING" is set above, you can also
|
||||
// * create waypoints with the tags "WN_" + NPC Tag + "_##"
|
||||
// * and those will be walked at night. (The standard waypoints
|
||||
// * will be walked during the day.)
|
||||
// * The night "posting" waypoint tag is simply "NIGHT_" + NPC tag.
|
||||
WalkWayPoints();
|
||||
|
||||
//* Create a small amount of treasure on the creature
|
||||
if ((GetLocalInt(GetModule(), "X2_L_NOTREASURE") == FALSE) &&
|
||||
(GetLocalInt(OBJECT_SELF, "X2_L_NOTREASURE") == FALSE) )
|
||||
{
|
||||
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF);
|
||||
}
|
||||
|
||||
|
||||
// ***** ADD ANY SPECIAL ON-SPAWN CODE HERE ***** //
|
||||
|
||||
// * If Incorporeal, apply changes
|
||||
if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_IS_INCORPOREAL) == TRUE)
|
||||
{
|
||||
effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL);
|
||||
eConceal = ExtraordinaryEffect(eConceal);
|
||||
effect eGhost = EffectCutsceneGhost();
|
||||
eGhost = ExtraordinaryEffect(eGhost);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF);
|
||||
|
||||
}
|
||||
|
||||
// * Give the create a random name.
|
||||
// * If you create a script named x3_name_gen in your module, you can
|
||||
// * set the value of the variable X3_S_RANDOM_NAME on OBJECT_SELF inside
|
||||
// * the script to override the creature's default name.
|
||||
if (GetCreatureFlag(OBJECT_SELF, CREATURE_VAR_RANDOMIZE_NAME) == TRUE)
|
||||
{
|
||||
ExecuteScript("x3_name_gen",OBJECT_SELF);
|
||||
string sName = GetLocalString(OBJECT_SELF,"X3_S_RANDOM_NAME");
|
||||
if ( sName == "" )
|
||||
{
|
||||
sName = RandomName();
|
||||
}
|
||||
SetName(OBJECT_SELF,sName);
|
||||
}
|
||||
|
||||
//Calls the Markshire Random Name Generator
|
||||
ms_Nomenclature(OBJECT_SELF);
|
||||
}
|
||||
157
_module/nss/nw_ai_onspellcst.nss
Normal file
157
_module/nss/nw_ai_onspellcst.nss
Normal file
@@ -0,0 +1,157 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On Spell Cast At
|
||||
//:: nw_ai_onspellcst
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
This determines if the spell just cast at the
|
||||
target is harmful or not.
|
||||
|
||||
GZ 2003-Oct-02 : - New AoE Behavior AI. Will use
|
||||
Dispel Magic against AOES
|
||||
- Flying Creatures will ignore
|
||||
Grease
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Preston Watamaniuk
|
||||
//:: Created On: Dec 6, 2001
|
||||
//:: Last Modified On: 2003-Oct-13
|
||||
//:://////////////////////////////////////////////
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Modified By: Deva Winblood
|
||||
//:: Modified On: Jan 4th, 2008
|
||||
//:: Added Support for Mounted Combat Feat Support
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "nw_i0_generic"
|
||||
#include "x2_i0_spells"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oCaster = GetLastSpellCaster();
|
||||
|
||||
|
||||
if(GetLastSpellHarmful())
|
||||
{
|
||||
SetCommandable(TRUE);
|
||||
|
||||
if (!GetLocalInt(GetModule(),"X3_NO_MOUNTED_COMBAT_FEAT"))
|
||||
{ // set variables on target for mounted combat
|
||||
DeleteLocalInt(OBJECT_SELF,"bX3_LAST_ATTACK_PHYSICAL");
|
||||
} // set variables on target for mounted combat
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// If I was hurt by someone in my own faction
|
||||
// Then clear any hostile feelings I have against them
|
||||
// After all, we're all just trying to do our job here
|
||||
// if we singe some eyebrow hair, oh well.
|
||||
// ------------------------------------------------------------------
|
||||
if (GetFactionEqual(oCaster, OBJECT_SELF) == TRUE)
|
||||
{
|
||||
ClearPersonalReputation(oCaster, OBJECT_SELF);
|
||||
ClearAllActions(TRUE);
|
||||
DelayCommand(1.2, ActionDoCommand(DetermineCombatRound(OBJECT_INVALID)));
|
||||
// Send the user-defined event as appropriate
|
||||
if(GetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_SPELL_CAST_AT));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int bAttack = TRUE;
|
||||
// ------------------------------------------------------------------
|
||||
// GZ, 2003-Oct-02
|
||||
// Try to do something smart if we are subject to an AoE Spell.
|
||||
// ------------------------------------------------------------------
|
||||
if (MatchAreaOfEffectSpell(GetLastSpell()) == TRUE)
|
||||
{
|
||||
int nAI = (GetBestAOEBehavior(GetLastSpell())); // from x2_i0_spells
|
||||
switch (nAI)
|
||||
{
|
||||
case X2_SPELL_AOEBEHAVIOR_DISPEL_L:
|
||||
case X2_SPELL_AOEBEHAVIOR_DISPEL_N:
|
||||
case X2_SPELL_AOEBEHAVIOR_DISPEL_M:
|
||||
case X2_SPELL_AOEBEHAVIOR_DISPEL_G:
|
||||
case X2_SPELL_AOEBEHAVIOR_DISPEL_C:
|
||||
bAttack = FALSE;
|
||||
ActionCastSpellAtLocation(nAI, GetLocation(OBJECT_SELF));
|
||||
ActionDoCommand(SetCommandable(TRUE));
|
||||
SetCommandable(FALSE);
|
||||
break;
|
||||
|
||||
case X2_SPELL_AOEBEHAVIOR_FLEE:
|
||||
ClearActions(CLEAR_NW_C2_DEFAULTB_GUSTWIND);
|
||||
oCaster = GetLastSpellCaster();
|
||||
ActionForceMoveToObject(oCaster, TRUE, 2.0);
|
||||
DelayCommand(1.2, ActionDoCommand(DetermineCombatRound(oCaster)));
|
||||
bAttack = FALSE;
|
||||
break;
|
||||
|
||||
case X2_SPELL_AOEBEHAVIOR_IGNORE:
|
||||
// well ... nothing
|
||||
break;
|
||||
|
||||
case X2_SPELL_AOEBEHAVIOR_GUST:
|
||||
ActionCastSpellAtLocation(SPELL_GUST_OF_WIND, GetLocation(OBJECT_SELF));
|
||||
ActionDoCommand(SetCommandable(TRUE));
|
||||
SetCommandable(FALSE);
|
||||
bAttack = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
// Not an area of effect spell, but another hostile spell.
|
||||
// If we're not already fighting someone else,
|
||||
// attack the caster.
|
||||
// ---------------------------------------------------------------------
|
||||
if( !GetIsFighting(OBJECT_SELF) && bAttack)
|
||||
{
|
||||
if(GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
|
||||
{
|
||||
DetermineSpecialBehavior(oCaster);
|
||||
}
|
||||
else
|
||||
{
|
||||
DetermineCombatRound(oCaster);
|
||||
}
|
||||
}
|
||||
|
||||
// We were attacked, so yell for help
|
||||
SetCommandable(TRUE);
|
||||
//Shout Attack my target, only works with the On Spawn In setup
|
||||
SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
|
||||
|
||||
//Shout that I was attacked
|
||||
SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ---------------------------------------------------------------------
|
||||
// July 14, 2003 BK
|
||||
// If there is a valid enemy nearby and a NON HARMFUL spell has been
|
||||
// cast on me I should call DetermineCombatRound
|
||||
// I may be invisible and casting spells on myself to buff myself up
|
||||
// ---------------------------------------------------------------------
|
||||
// Fix: JE - let's only do this if I'm currently in combat. If I'm not
|
||||
// in combat, and something casts a spell on me, it'll make me search
|
||||
// out the nearest enemy, no matter where they are on the level, which
|
||||
// is kinda dumb.
|
||||
object oEnemy =GetNearestEnemy();
|
||||
if ((GetIsObjectValid(oEnemy) == TRUE) && (GetIsInCombat() == TRUE))
|
||||
{
|
||||
// SpeakString("keep me in combat");
|
||||
DetermineCombatRound(oEnemy);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the user-defined event as appropriate
|
||||
if(GetSpawnInCondition(NW_FLAG_SPELL_CAST_AT_EVENT))
|
||||
{
|
||||
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_SPELL_CAST_AT));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
20
_module/nss/nw_ai_onuserdef.nss
Normal file
20
_module/nss/nw_ai_onuserdef.nss
Normal file
@@ -0,0 +1,20 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Vanilla NWN On User Defined
|
||||
//:: nw_ai_onuserdef
|
||||
//:: Copyright (c) 2002 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Determines the course of action to be taken
|
||||
on a user defined event.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Don Moar
|
||||
//:: Created On: April 28, 2002
|
||||
//:://////////////////////////////////////////////
|
||||
void main()
|
||||
{
|
||||
// enter desired behaviour here
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
@@ -149,9 +149,6 @@ void main()
|
||||
}
|
||||
// Signal the death event.
|
||||
FireUserEvent(AI_FLAG_UDE_DEATH_EVENT, EVENT_DEATH_EVENT);
|
||||
|
||||
ExecuteScript("prc_npc_death", OBJECT_SELF);
|
||||
ExecuteScript("prc_pwondeath", OBJECT_SELF);
|
||||
}
|
||||
|
||||
// We need a wrapper. If the amount of deaths, got in this, is not equal to iDeaths,
|
||||
|
||||
643
_module/nss/qn_onhit.nss
Normal file
643
_module/nss/qn_onhit.nss
Normal file
@@ -0,0 +1,643 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: qn_onhit
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Touch Attacks (Creature Slam) Workaround:
|
||||
-5 Damage
|
||||
+20 Attack
|
||||
OnHit Cast Spell: Unique Power (Level 1)
|
||||
|
||||
TAG must be named the same as the script "qn_onhit" !!!
|
||||
|
||||
To use create a claw/slam/bite give it whatever damage
|
||||
you would like then change the TAG to the name of the
|
||||
script.
|
||||
|
||||
Give it the OnHit Cast Spell: Unique Power (OnHit Level 1).
|
||||
|
||||
Assign the appropriate variable below. Example: Wraith
|
||||
would be SPECIAL_ATTACK int 16.
|
||||
|
||||
I didn't use NWNs touch attack script... its too flawed. Higher
|
||||
level undead can Touch you more than once a round, so I made
|
||||
a workaround claw/slam noted at the very begning to make it
|
||||
more D&D based. +20 to attack may seem like alot but you have
|
||||
to figure that Incorporeal Undead are touching you which might
|
||||
I add in 90% of the cases is very easy.
|
||||
|
||||
Of course you don't have to use this method - its optional.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Q-Necron
|
||||
//:://////////////////////////////////////////////
|
||||
#include "x2_inc_switches"
|
||||
#include "x2_inc_spellhook"
|
||||
|
||||
//Belker
|
||||
void SmokeClaw(object oTarget, int nDC, int nRounds);
|
||||
|
||||
//Burn
|
||||
void Burn(object oTarget, int nDamage);
|
||||
|
||||
//Spawn Undead
|
||||
void SpawnUndead(object oTarget, string sRESREF, location lDeadPC);
|
||||
|
||||
//Drain Ability:
|
||||
void NegativeAbility(object oTarget, int nAbility, int nDrain);
|
||||
|
||||
//Drain Ability or Death:
|
||||
void NegativeOrDeath(object oTarget, int nAbility, int nDrain, string sRESREF, int bSpawn);
|
||||
|
||||
//Living Check
|
||||
int GetIsLiving(object oTarget);
|
||||
|
||||
void main()
|
||||
{
|
||||
//Make sure it fires correctly.
|
||||
if(GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ONHITCAST &&
|
||||
GetLocalInt(OBJECT_SELF, "SPECIAL_ATTACK") != 0)
|
||||
{
|
||||
object oTarget = GetAttemptedAttackTarget();
|
||||
int nAbility;
|
||||
int nAppearance = GetAppearanceType(OBJECT_SELF);
|
||||
int nCharisma = GetAbilityModifier(ABILITY_CHARISMA, OBJECT_SELF);
|
||||
int nConstitution = GetAbilityModifier(ABILITY_CONSTITUTION, OBJECT_SELF);
|
||||
int nDamage;
|
||||
int nDC;
|
||||
int nDrain;
|
||||
int nHD = GetHitDice(OBJECT_SELF);
|
||||
int nPower;
|
||||
int nTempHP;
|
||||
int nType;
|
||||
int nSpecial = GetLocalInt(OBJECT_SELF, "SPECIAL_ATTACK");
|
||||
int bSave = TRUE;
|
||||
int bSpawn = FALSE;
|
||||
int bSpectre = FALSE;
|
||||
int bStirge = FALSE;
|
||||
int nStrength = GetAbilityModifier(ABILITY_STRENGTH, OBJECT_SELF);
|
||||
int bTempHP = FALSE;
|
||||
int bWight = FALSE;
|
||||
effect eDamage;
|
||||
effect eTempHP;
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_REDUCE_ABILITY_SCORE);
|
||||
string sRESREF;
|
||||
|
||||
//Determine special attack.
|
||||
switch(nSpecial)
|
||||
{
|
||||
//Allip
|
||||
case 1:
|
||||
nAbility = ABILITY_WISDOM;
|
||||
nDrain = d4(1);
|
||||
bSave = FALSE;
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Cockatrice
|
||||
case 2:
|
||||
nDC = 10 + (nHD / 2) + nConstitution;
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0)
|
||||
{
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectPetrify(), oTarget, RoundsToSeconds(nHD * 2));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Succubus
|
||||
case 3:
|
||||
if(GetIsLiving(oTarget) == FALSE){return;}
|
||||
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNegativeLevel(1), oTarget));
|
||||
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectConfused(), oTarget, RoundsToSeconds(12)));
|
||||
return;
|
||||
break;
|
||||
|
||||
//Rake
|
||||
case 4:
|
||||
if(GetHasFeatEffect(FEAT_KNOCKDOWN, oTarget) == TRUE ||
|
||||
GetHasFeatEffect(FEAT_IMPROVED_KNOCKDOWN, oTarget) == TRUE)
|
||||
{
|
||||
//Determine creature appearance.
|
||||
switch(nAppearance)
|
||||
{
|
||||
//Dire Tiger
|
||||
case APPEARANCE_TYPE_CAT_CAT_DIRE:
|
||||
nDamage = d4(2) + 4;
|
||||
nType = DAMAGE_TYPE_SLASHING;
|
||||
nPower = DAMAGE_POWER_NORMAL;
|
||||
break;
|
||||
|
||||
//Androsphinx
|
||||
case APPEARANCE_TYPE_SPHINX:
|
||||
nDamage = d4(2) + 3;
|
||||
nType = DAMAGE_TYPE_SLASHING;
|
||||
nPower = DAMAGE_POWER_NORMAL;
|
||||
break;
|
||||
|
||||
//Mountain Lion
|
||||
case APPEARANCE_TYPE_CAT_COUGAR:
|
||||
nDamage = d3(1) + 1;
|
||||
nType = DAMAGE_TYPE_SLASHING;
|
||||
nPower = DAMAGE_POWER_NORMAL;
|
||||
break;
|
||||
|
||||
//Lion
|
||||
case APPEARANCE_TYPE_CAT_LION:
|
||||
nDamage = d4(1) + 2;
|
||||
nType = DAMAGE_TYPE_SLASHING;
|
||||
nPower = DAMAGE_POWER_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
//Set damage.
|
||||
eDamage = EffectDamage(nDamage, nType, nPower);
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Fire Elemental
|
||||
case 5:
|
||||
nDC = 10 + (nHD / 2) + nConstitution;
|
||||
if(nHD <= 7){nDamage = d6(1);}//------------------ Medium
|
||||
else if(nHD >= 8 && nHD <= 15){nDamage = d6(2);}// Large
|
||||
else{nDamage = d8(2);}//-------------------------- Huge
|
||||
//Reflex Save
|
||||
if(ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_FIRE, OBJECT_SELF) == 0)
|
||||
{
|
||||
//Apply burn.
|
||||
DelayCommand(3.0f, Burn(oTarget, nDamage));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Water Elemental
|
||||
case 6:
|
||||
if(GetHasSpellEffect(SPELL_DARKFIRE, oTarget) == TRUE ||
|
||||
GetHasSpellEffect(SPELL_ELEMENTAL_SHIELD, oTarget) == TRUE ||
|
||||
GetHasSpellEffect(SPELL_FLAME_WEAPON, oTarget) == TRUE &&
|
||||
d20(1) + nHD > 11 + GetHitDice(oTarget))//Dispel Check
|
||||
{
|
||||
object oLeft = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
|
||||
object oRight = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_DISPEL);
|
||||
itemproperty ipDamage = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE, IP_CONST_DAMAGEBONUS_1d6);
|
||||
itemproperty ipVis = ItemPropertyVisualEffect(ITEM_VISUAL_FIRE);
|
||||
|
||||
//Elemental Shield
|
||||
effect eEffect = GetFirstEffect(oTarget);
|
||||
while(GetIsEffectValid(eEffect))
|
||||
{
|
||||
if(GetHasSpellEffect(SPELL_ELEMENTAL_SHIELD, oTarget) == TRUE)
|
||||
{
|
||||
RemoveEffect(oTarget, eEffect);
|
||||
}
|
||||
eEffect = GetNextEffect(oTarget);
|
||||
}
|
||||
|
||||
//Prevents stacking
|
||||
IPRemoveMatchingItemProperties(oLeft, GetItemPropertyType(ipDamage), DURATION_TYPE_TEMPORARY);
|
||||
IPRemoveMatchingItemProperties(oLeft, GetItemPropertyType(ipVis), DURATION_TYPE_TEMPORARY);
|
||||
IPRemoveMatchingItemProperties(oRight, GetItemPropertyType(ipDamage), DURATION_TYPE_TEMPORARY);
|
||||
IPRemoveMatchingItemProperties(oRight, GetItemPropertyType(ipVis), DURATION_TYPE_TEMPORARY);
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Ghoul, Ghast & Mohrg Paralysis
|
||||
case 7:
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0)
|
||||
{
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectParalyze(), oTarget, RoundsToSeconds(nHD * 2));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZE_HOLD), oTarget, RoundsToSeconds(nHD * 2));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZED), oTarget, RoundsToSeconds(nHD * 2));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Trample
|
||||
case 8:
|
||||
nDC = 10 + (nHD / 2) + nStrength;
|
||||
// if(!MySavingThrow(SAVING_THROW_REFLEX, oTarget, nDC))
|
||||
if(ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0)
|
||||
{
|
||||
//Determine creature appearance.
|
||||
switch(nAppearance)
|
||||
{
|
||||
case APPEARANCE_TYPE_GORGON:
|
||||
nDamage = d8(1) + 7;
|
||||
break;
|
||||
|
||||
case APPEARANCE_TYPE_BEETLE_STAG:
|
||||
nDamage = d8(2) + 3;
|
||||
break;
|
||||
}
|
||||
|
||||
//Set damage.
|
||||
eDamage = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING, DAMAGE_POWER_NORMAL);
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
|
||||
//Set Local Int
|
||||
SetLocalInt(OBJECT_SELF, "SPECIAL_ATTACK", 0);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Rend
|
||||
case 9:
|
||||
if(d2(1) == 1)
|
||||
{
|
||||
//Determine creature appearance.
|
||||
switch(nAppearance)
|
||||
{
|
||||
case APPEARANCE_TYPE_GREY_RENDER:
|
||||
case APPEARANCE_TYPE_TROLL:
|
||||
case APPEARANCE_TYPE_TROLL_CHIEFTAIN:
|
||||
case APPEARANCE_TYPE_TROLL_SHAMAN:
|
||||
nDamage = d6(2) + 9;
|
||||
nType = DAMAGE_TYPE_SLASHING;
|
||||
nPower = DAMAGE_POWER_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
//Set damage.
|
||||
eDamage = EffectDamage(nDamage, nType, nPower);
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Gelatinous Cube
|
||||
case 10:
|
||||
nDC = 10 + (nHD / 2) + nConstitution;
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0)
|
||||
{
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectParalyze(), oTarget, RoundsToSeconds(nHD * 2));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZE_HOLD), oTarget, RoundsToSeconds(nHD * 2));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_GLOW_GREEN), oTarget, RoundsToSeconds(nHD * 2));
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
//Belker Claw
|
||||
case 11:
|
||||
nDC = 10 + (nHD / 2) + nConstitution;
|
||||
//Smoke Claw
|
||||
SmokeClaw(oTarget, nDC, d3(2));
|
||||
return;
|
||||
break;
|
||||
|
||||
//Shadow & Greater Shadow
|
||||
case 12:
|
||||
nAbility = ABILITY_STRENGTH;
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
bSave = FALSE;
|
||||
bSpawn = TRUE;
|
||||
sRESREF = "shadow01";
|
||||
//Determine creature appearance.
|
||||
switch(nAppearance)
|
||||
{
|
||||
//1d6 Strength Drain
|
||||
case APPEARANCE_TYPE_SHADOW:
|
||||
nDrain = d6(1);
|
||||
break;
|
||||
|
||||
//1d8 Strength Drain
|
||||
case APPEARANCE_TYPE_SHADOW_FIEND:
|
||||
nDrain = d8(1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
//Spectre
|
||||
case 13:
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
bSpectre = TRUE;
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Stirge
|
||||
case 14:
|
||||
nAbility = ABILITY_CONSTITUTION;
|
||||
nDrain = 1;
|
||||
bStirge = TRUE;
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 1;
|
||||
eVis = EffectVisualEffect(VFX_IMP_HEAD_EVIL);
|
||||
break;
|
||||
|
||||
//Wight
|
||||
case 15:
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
bWight = TRUE;
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Wraith
|
||||
case 16:
|
||||
nAbility = ABILITY_CONSTITUTION;
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
nDrain = d6(1);
|
||||
bSpawn = TRUE;
|
||||
sRESREF = "wraith01";
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Dread Wraith
|
||||
case 17:
|
||||
nAbility = ABILITY_CONSTITUTION;
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
nDrain = d8(1);
|
||||
bSpawn = TRUE;
|
||||
sRESREF = "wraith01";
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Icegaunt
|
||||
case 18:
|
||||
nAbility = ABILITY_CONSTITUTION;
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
nDrain = d4(1);
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Cinderspawn
|
||||
case 19:
|
||||
nAbility = ABILITY_CHARISMA;
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
nDrain = d6(1);
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
|
||||
//Sword Wraith
|
||||
case 20:
|
||||
nAbility = ABILITY_STRENGTH;
|
||||
nDrain = 1;
|
||||
bSave = FALSE;
|
||||
break;
|
||||
|
||||
//Voidwraith
|
||||
case 21:
|
||||
nAbility = ABILITY_CONSTITUTION;
|
||||
nDC = 10 + (nHD / 2) + nCharisma;
|
||||
nDrain = d2(1);
|
||||
bTempHP = TRUE;
|
||||
nTempHP = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
//Constructs & Undead
|
||||
if(GetIsLiving(oTarget) == FALSE){return;}
|
||||
|
||||
//Bone Ring
|
||||
if(GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oTarget)) == "r_bone" ||
|
||||
GetTag(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oTarget)) == "r_bone")
|
||||
{
|
||||
//Priceless...
|
||||
bSave = TRUE;
|
||||
}
|
||||
|
||||
//Spectre
|
||||
if(bSpectre == TRUE)
|
||||
{
|
||||
nDrain = 2;
|
||||
//Fotitude Save!
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_NEGATIVE) == 1){nDrain = 1;}
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNegativeLevel(nDrain), oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
|
||||
//Does the touch grant temporary HP?
|
||||
if(bTempHP == TRUE)
|
||||
{
|
||||
eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP));
|
||||
//Temporary HitPoints
|
||||
if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Stirge
|
||||
if(bStirge == TRUE)
|
||||
{
|
||||
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget, RoundsToSeconds(nHD)));
|
||||
|
||||
//Does the touch grant temporary HP?
|
||||
if(bTempHP == TRUE)
|
||||
{
|
||||
eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP));
|
||||
//Temporary HitPoints.
|
||||
if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Wight
|
||||
if(bWight == TRUE)
|
||||
{
|
||||
//Fotitude Save!
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_NEGATIVE) == 0)
|
||||
{
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNegativeLevel(1), oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
|
||||
//Does the touch grant temporary HP?
|
||||
if(bTempHP == TRUE)
|
||||
{
|
||||
eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP));
|
||||
//Temporary HitPoints
|
||||
if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Aw no save...
|
||||
if(bSave == FALSE)
|
||||
{
|
||||
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||
DelayCommand(0.1, NegativeOrDeath(oTarget, nAbility, nDrain, sRESREF, bSpawn));
|
||||
|
||||
//Does the touch grant temporary HP?
|
||||
if(bTempHP == TRUE)
|
||||
{
|
||||
eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP));
|
||||
//Temporary HitPoints.
|
||||
if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Save.
|
||||
else
|
||||
{
|
||||
//Fotitude Save!
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_NEGATIVE) == 0)
|
||||
{
|
||||
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||
DelayCommand(0.1, NegativeOrDeath(oTarget, nAbility, nDrain, sRESREF, bSpawn));
|
||||
|
||||
//Does the touch grant temporary HP?
|
||||
if(bTempHP == TRUE)
|
||||
{
|
||||
eTempHP = SupernaturalEffect(EffectTemporaryHitpoints(nTempHP));
|
||||
//Temporary HitPoints
|
||||
if(GetCurrentHitPoints(OBJECT_SELF) < (GetMaxHitPoints(OBJECT_SELF) * 2))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTempHP, OBJECT_SELF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Burn
|
||||
//------------------------------------------------------------------------------
|
||||
void Burn(object oTarget, int nDamage)
|
||||
{
|
||||
effect eBurn = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eBurn, oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Spawn Undead
|
||||
//------------------------------------------------------------------------------
|
||||
void SpawnUndead(object oTarget, string sRESREF, location lDeadPC)
|
||||
{
|
||||
//Is the PC still dead?
|
||||
if(GetIsDead(oTarget) == TRUE)
|
||||
{
|
||||
//Create undead.
|
||||
CreateObject(OBJECT_TYPE_CREATURE, sRESREF, lDeadPC);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Set Local Int
|
||||
SetLocalInt(OBJECT_SELF, "DO_ONCE", 0);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Drain Ability:
|
||||
//------------------------------------------------------------------------------
|
||||
void NegativeAbility(object oTarget, int nAbility, int nDrain)
|
||||
{
|
||||
//Ablity Drain.
|
||||
effect eDrain = EffectAbilityDecrease(nAbility, nDrain);
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDrain, oTarget);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Drain Ability or Death:
|
||||
//------------------------------------------------------------------------------
|
||||
void NegativeOrDeath(object oTarget, int nAbility, int nDrain, string sRESREF, int bSpawn)
|
||||
{
|
||||
//Get PC's ability.
|
||||
int nAbilityScore = GetAbilityScore(oTarget, nAbility);
|
||||
|
||||
//Current ability vs drain.
|
||||
if(nAbilityScore - nDrain <= 0 && GetIsPC(oTarget) == TRUE)
|
||||
{
|
||||
effect eDeath = EffectDeath();
|
||||
location lDeadPC = GetLocation(oTarget);
|
||||
|
||||
//Apply effects
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDeath, oTarget);
|
||||
|
||||
//Get the killers RESREF and spawn another of its type.
|
||||
if(bSpawn == TRUE && GetLocalInt(OBJECT_SELF, "DO_ONCE") != 1)
|
||||
{
|
||||
DelayCommand(RoundsToSeconds(d3(2)), SpawnUndead(oTarget, sRESREF, lDeadPC));
|
||||
|
||||
//Set Local Int
|
||||
SetLocalInt(OBJECT_SELF, "DO_ONCE", 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Ability Drain.
|
||||
DelayCommand(0.1, NegativeAbility(oTarget, nAbility, nDrain));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Living Check
|
||||
//------------------------------------------------------------------------------
|
||||
int GetIsLiving(object oTarget)
|
||||
{
|
||||
int bAlive;
|
||||
|
||||
//Constructs & Undead
|
||||
if(GetRacialType(oTarget) == RACIAL_TYPE_CONSTRUCT ||
|
||||
GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD)
|
||||
{
|
||||
return bAlive = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return bAlive = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Smoke Claw
|
||||
//------------------------------------------------------------------------------
|
||||
void SmokeClaw(object oTarget, int nDC, int nRounds)
|
||||
{
|
||||
//Fortitude Save
|
||||
if(FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_ALL, OBJECT_SELF) == 0)
|
||||
{
|
||||
nRounds--;
|
||||
effect eDamage = EffectDamage(d4(3));
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_SILENCE);
|
||||
|
||||
//Apply effects.
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
|
||||
//Smoke Claw
|
||||
if(nRounds != 0)
|
||||
{
|
||||
SmokeClaw(oTarget, nDC, nRounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
_module/nss/ra_hidden_loot.nss
Normal file
36
_module/nss/ra_hidden_loot.nss
Normal file
@@ -0,0 +1,36 @@
|
||||
//:: ra_hidden_loot
|
||||
|
||||
//Put this script OnEnter
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
object oPC = GetEnteringObject();
|
||||
object oTarget = GetObjectByTag("RA_PLC_RUBBLE01");
|
||||
object oSpawn;
|
||||
location lTarget;
|
||||
|
||||
if (!GetIsPC(oPC)) return;
|
||||
|
||||
int DoOnce = GetLocalInt(oPC, GetTag(OBJECT_SELF));
|
||||
|
||||
if (DoOnce==TRUE) return;
|
||||
|
||||
SetLocalInt(oPC, GetTag(OBJECT_SELF), TRUE);
|
||||
|
||||
|
||||
if (GetIsSkillSuccessful(oPC, SKILL_SEARCH, 15))
|
||||
{
|
||||
if (!GetIsObjectValid(oTarget)) return;
|
||||
DelayCommand(0.1f, DestroyObject(oTarget, 0.0));
|
||||
|
||||
oTarget = GetWaypointByTag("RA_PLC_RUBBLE01");
|
||||
lTarget = GetLocation(oTarget);
|
||||
oSpawn = CreateObject(OBJECT_TYPE_PLACEABLE, "VILLIX_STOR_NOOK", lTarget);
|
||||
SendMessageToPC(oPC, "You have discovered a hidden cache.");
|
||||
DestroyObject(oSpawn, 180.0f);
|
||||
}
|
||||
|
||||
SetLocalInt(oPC, GetTag(OBJECT_SELF), TRUE);
|
||||
|
||||
}
|
||||
53
_module/nss/ra_trp_sec_door1.nss
Normal file
53
_module/nss/ra_trp_sec_door1.nss
Normal file
@@ -0,0 +1,53 @@
|
||||
//:://////////////////////////////////////////////////
|
||||
//::
|
||||
//:: ra_trp_sec_door1
|
||||
//::
|
||||
//:: This is an OnEntered script for a generic trigger.
|
||||
//:: When a PC enters the trigger area, it will perform
|
||||
//:: a check to determine if the secret item is revealed,
|
||||
//:: then make it appear if so.
|
||||
//::
|
||||
//:: Secret item to be revealed: Secret Stone Door
|
||||
//:: Checking for: SKILL_SEARCH
|
||||
//::
|
||||
//:: Pulls door rezref from trigger variables
|
||||
//:: for use with trapped secret doors
|
||||
//::
|
||||
//::
|
||||
//::
|
||||
//::
|
||||
//:: Copyright (c) 2002 Floodgate Entertainment
|
||||
//:: Created By: Naomi Novik
|
||||
//:: Created On: 12/08/2002
|
||||
//::
|
||||
//::
|
||||
//::
|
||||
//::
|
||||
//:://////////////////////////////////////////////////
|
||||
|
||||
#include "x0_i0_secret"
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
object oEntered = GetEnteringObject();
|
||||
string oDoorName = GetLocalString(OBJECT_SELF, "DOOR_REZREF");
|
||||
|
||||
if (GetIsSecretItemRevealed()) {return;}
|
||||
|
||||
if ( DetectSecretItem(oEntered)) {
|
||||
if (!GetIsPC(oEntered)) {
|
||||
// If a henchman, alert the PC if we make the detect check
|
||||
object oMaster = GetMaster(oEntered);
|
||||
if (GetIsObjectValid(oMaster)
|
||||
&& oEntered == GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oMaster))
|
||||
{
|
||||
AssignCommand(oEntered, PlayVoiceChat(VOICE_CHAT_SEARCH));
|
||||
}
|
||||
} else {
|
||||
// It's a PC, reveal the item
|
||||
AssignCommand(oEntered, PlayVoiceChat(VOICE_CHAT_LOOKHERE));
|
||||
RevealSecretItem(oDoorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
_module/nss/ra_trp_sec_reset.nss
Normal file
12
_module/nss/ra_trp_sec_reset.nss
Normal file
@@ -0,0 +1,12 @@
|
||||
/* User-defined event script to reset a secret item after a delay of
|
||||
* 30 minutes.
|
||||
*/
|
||||
|
||||
#include "x0_i0_secret"
|
||||
|
||||
void main()
|
||||
{
|
||||
if (GetUserDefinedEventNumber() == EVENT_SECRET_REVEALED) {
|
||||
DelayCommand(1800.0, ResetSecretItem());
|
||||
}
|
||||
}
|
||||
@@ -41,14 +41,25 @@ int SpawnEffect(object oSpawn, int nSpawnEffect, int nDespawnEffect)
|
||||
return nEffect;
|
||||
}
|
||||
//
|
||||
|
||||
// Effect 32
|
||||
// Gate Summon Effect
|
||||
if (nEffectNumber == 32)
|
||||
{
|
||||
nEffect = VFX_FNF_SUMMON_GATE;
|
||||
}
|
||||
//
|
||||
// Rotting Corpse Spawn/Despawn
|
||||
if (nEffectNumber == 51)
|
||||
{
|
||||
nEffect = VFX_IMP_DISEASE_S;
|
||||
}
|
||||
//
|
||||
|
||||
// Smoke Puff
|
||||
if (nEffectNumber == 263)
|
||||
{
|
||||
nEffect = VFX_FNF_SMOKE_PUFF;
|
||||
}
|
||||
//
|
||||
|
||||
// -------------------------------------------
|
||||
// Only Make Modifications Between These Lines
|
||||
|
||||
12
_module/nss/x0_o2_sec_reset.nss
Normal file
12
_module/nss/x0_o2_sec_reset.nss
Normal file
@@ -0,0 +1,12 @@
|
||||
/* User-defined event script to reset a secret item after a delay of
|
||||
* 1 minute.
|
||||
*/
|
||||
|
||||
#include "x0_i0_secret"
|
||||
|
||||
void main()
|
||||
{
|
||||
if (GetUserDefinedEventNumber() == EVENT_SECRET_REVEALED) {
|
||||
DelayCommand(60.0, ResetSecretItem());
|
||||
}
|
||||
}
|
||||
33
_module/nss/x2_def_attacked.nss
Normal file
33
_module/nss/x2_def_attacked.nss
Normal file
@@ -0,0 +1,33 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_attacked
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default On Physically attacked script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
// GZ: 2003-10-16
|
||||
// Make Plot Creatures Ignore Attacks
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetPlotFlag(OBJECT_SELF))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Execute old NWN default AI code
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
ExecuteScript("nw_c2_default5", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnAttacked script
|
||||
ExecuteScript("prc_npc_physatt", OBJECT_SELF);
|
||||
|
||||
}
|
||||
21
_module/nss/x2_def_endcombat.nss
Normal file
21
_module/nss/x2_def_endcombat.nss
Normal file
@@ -0,0 +1,21 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_endcombat
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default Combat Round End script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//:: Execute the default NPC OnCombatRoundEnd script
|
||||
ExecuteScript("nw_c2_default3", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnCombatRoundEnd script
|
||||
ExecuteScript("prc_npc_combat", OBJECT_SELF);
|
||||
}
|
||||
@@ -15,5 +15,9 @@ void main()
|
||||
if ((!GetIsInCombat(OBJECT_SELF) && (GetItemInSlot(INVENTORY_SLOT_CHEST) == OBJECT_INVALID)))
|
||||
DelayCommand(0.5f, ActionEquipMostEffectiveArmor());
|
||||
|
||||
//:: Execute the default NPC OnHeartbeat script
|
||||
ExecuteScript("nw_c2_default1", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnHeartbeat script
|
||||
ExecuteScript("prc_npc_hb", OBJECT_SELF);
|
||||
}
|
||||
|
||||
21
_module/nss/x2_def_onblocked.nss
Normal file
21
_module/nss/x2_def_onblocked.nss
Normal file
@@ -0,0 +1,21 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_onblocked
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnBlocked script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//:: Execute the default NPC OnBlocked script
|
||||
ExecuteScript("nw_c2_defaulte", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnBlocked script
|
||||
ExecuteScript("prc_npc_blocked", OBJECT_SELF);
|
||||
}
|
||||
22
_module/nss/x2_def_onconv.nss
Normal file
22
_module/nss/x2_def_onconv.nss
Normal file
@@ -0,0 +1,22 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_onconv
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default On Conversation script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//:: Execute the default NPC OnConversation script
|
||||
ExecuteScript("nw_c2_default4", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnConversation script
|
||||
ExecuteScript("prc_npc_conv", OBJECT_SELF);
|
||||
|
||||
}
|
||||
31
_module/nss/x2_def_ondamage.nss
Normal file
31
_module/nss/x2_def_ondamage.nss
Normal file
@@ -0,0 +1,31 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_ondamage
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnDamaged script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
// GZ: 2003-10-16
|
||||
// Make Plot Creatures Ignore Attacks
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetPlotFlag(OBJECT_SELF))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Execute old NWN default AI code
|
||||
//--------------------------------------------------------------------------
|
||||
ExecuteScript("nw_c2_default6", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnDamaged script
|
||||
ExecuteScript("prc_npc_damaged", OBJECT_SELF);
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
//:: Name x2_def_ondeath
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/* ra_brigand002
|
||||
/*
|
||||
Default OnDeath script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
@@ -221,6 +221,10 @@ int nVFX = GetLocalInt(OBJECT_SELF,"SpawnVFX");
|
||||
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
|
||||
}
|
||||
|
||||
|
||||
//:: Execute Default NPC OnDeath script
|
||||
ExecuteScript("nw_c2_default7", OBJECT_SELF);
|
||||
|
||||
|
||||
//:: Execute PRC NPC OnDeath script
|
||||
ExecuteScript("prc_npc_death", OBJECT_SELF);
|
||||
}
|
||||
|
||||
22
_module/nss/x2_def_ondisturb.nss
Normal file
22
_module/nss/x2_def_ondisturb.nss
Normal file
@@ -0,0 +1,22 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_ondisturb
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default OnDisturbed script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//:: Execute the default NPC OnDisturbed script
|
||||
ExecuteScript("nw_c2_default8", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnDisturbed script
|
||||
ExecuteScript("prc_npc_blocked", OBJECT_SELF);
|
||||
|
||||
}
|
||||
21
_module/nss/x2_def_percept.nss
Normal file
21
_module/nss/x2_def_percept.nss
Normal file
@@ -0,0 +1,21 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_percept
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default On Perception script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//:: Execute the default NPC OnPerception script
|
||||
ExecuteScript("nw_c2_default2", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnPerception script
|
||||
ExecuteScript("prc_npc_percep", OBJECT_SELF);
|
||||
}
|
||||
21
_module/nss/x2_def_rested.nss
Normal file
21
_module/nss/x2_def_rested.nss
Normal file
@@ -0,0 +1,21 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_rested
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default On Rested script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//:: Execute the default NPC OnRested script
|
||||
ExecuteScript("nw_c2_defaulta", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnRested script
|
||||
ExecuteScript("prc_npc_rested", OBJECT_SELF);
|
||||
}
|
||||
@@ -473,6 +473,9 @@ void main()
|
||||
// Execute default OnSpawn script.
|
||||
ExecuteScript("nw_c2_default9", OBJECT_SELF);
|
||||
|
||||
// Execute PRC OnSpawn script.
|
||||
ExecuteScript("prc_npc_spawn", OBJECT_SELF);
|
||||
|
||||
|
||||
//Post Spawn event requeste
|
||||
if (nSpecEvent == 2 || nSpecEvent == 3)
|
||||
|
||||
32
_module/nss/x2_def_spellcast.nss
Normal file
32
_module/nss/x2_def_spellcast.nss
Normal file
@@ -0,0 +1,32 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_spellcast
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default On Spell Cast At script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// GZ: 2003-10-16
|
||||
// Make Plot Creatures Ignore Attacks
|
||||
//--------------------------------------------------------------------------
|
||||
if (GetPlotFlag(OBJECT_SELF))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Execute old NWN default AI code
|
||||
//--------------------------------------------------------------------------
|
||||
ExecuteScript("nw_c2_defaultb", OBJECT_SELF);
|
||||
|
||||
//:: Execute the PRC NPC OnSpellCastAt script
|
||||
ExecuteScript("prc_npc_spellat", OBJECT_SELF);
|
||||
}
|
||||
65
_module/nss/x2_def_userdef.nss
Normal file
65
_module/nss/x2_def_userdef.nss
Normal file
@@ -0,0 +1,65 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name x2_def_userdef
|
||||
//:: Copyright (c) 2001 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Default On User Defined Event script
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Keith Warner
|
||||
//:: Created On: June 11/03
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
const int EVENT_USER_DEFINED_PRESPAWN = 1510;
|
||||
const int EVENT_USER_DEFINED_POSTSPAWN = 1511;
|
||||
void main()
|
||||
{
|
||||
int nUser = GetUserDefinedEventNumber();
|
||||
|
||||
if(nUser == EVENT_HEARTBEAT ) //HEARTBEAT
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == EVENT_PERCEIVE) // PERCEIVE
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == EVENT_END_COMBAT_ROUND) // END OF COMBAT
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == EVENT_DIALOGUE) // ON DIALOGUE
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == EVENT_ATTACKED) // ATTACKED
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == EVENT_DAMAGED) // DAMAGED
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == 1007) // DEATH - do not use for critical code, does not fire reliably all the time
|
||||
{
|
||||
|
||||
}
|
||||
else if(nUser == EVENT_DISTURBED) // DISTURBED
|
||||
{
|
||||
|
||||
}
|
||||
else if (nUser == EVENT_USER_DEFINED_PRESPAWN)
|
||||
{
|
||||
|
||||
}
|
||||
else if (nUser == EVENT_USER_DEFINED_POSTSPAWN)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//:: Execute the PRC NPC OnUserDef script
|
||||
ExecuteScript("prc_npc_userdef", OBJECT_SELF);
|
||||
|
||||
}
|
||||
|
||||
|
||||
316
_module/nss/x2_inc_beholder.nss
Normal file
316
_module/nss/x2_inc_beholder.nss
Normal file
@@ -0,0 +1,316 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Beholder AI and Attack Include
|
||||
//:: x2_inc_beholder
|
||||
//:: Copyright (c) 2003 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
|
||||
Include file for several beholder functions
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Georg Zoeller
|
||||
//:: Created On: August, 2003
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "x0_i0_spells"
|
||||
|
||||
const int BEHOLDER_RAY_DEATH = 1;
|
||||
const int BEHOLDER_RAY_TK = 2;
|
||||
const int BEHOLDER_RAY_PETRI= 3;
|
||||
const int BEHOLDER_RAY_CHARM = 4;
|
||||
const int BEHOLDER_RAY_SLOW = 5;
|
||||
const int BEHOLDER_RAY_WOUND = 6;
|
||||
const int BEHOLDER_RAY_FEAR = 7;
|
||||
|
||||
const int BEHOLDER_RAY_DIS = 8;
|
||||
const int BEHOLDER_RAY_CHARMP = 9;
|
||||
const int BEHOLDER_RAY_SLEEP = 10;
|
||||
|
||||
struct beholder_target_struct
|
||||
{
|
||||
object oTarget1;
|
||||
int nRating1;
|
||||
object oTarget2;
|
||||
int nRating2;
|
||||
object oTarget3;
|
||||
int nRating3;
|
||||
int nCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int GetAntiMagicRayMakesSense ( object oTarget );
|
||||
void OpenAntiMagicEye ( object oTarget );
|
||||
void CloseAntiMagicEye ( object oTarget );
|
||||
int BehGetTargetThreatRating ( object oTarget );
|
||||
int BehDetermineHasEffect ( int nRay, object oCreature );
|
||||
void BehDoFireBeam ( int nRay, object oTarget );
|
||||
|
||||
struct beholder_target_struct GetRayTargets ( object oTarget );
|
||||
|
||||
int GetAntiMagicRayMakesSense(object oTarget)
|
||||
{
|
||||
int bRet = TRUE;
|
||||
int nType;
|
||||
|
||||
effect eTest = GetFirstEffect(oTarget);
|
||||
|
||||
if (!GetIsEffectValid(eTest))
|
||||
{
|
||||
int nMag = GetLevelByClass(CLASS_TYPE_WIZARD,oTarget) + GetLevelByClass(CLASS_TYPE_SORCERER,oTarget) + GetLevelByClass(CLASS_TYPE_BARD,oTarget) + GetLevelByClass(CLASS_TYPE_RANGER,oTarget) + GetLevelByClass(CLASS_TYPE_PALADIN,oTarget);
|
||||
// at least 3 levels of magic user classes... we better use anti magic anyway
|
||||
if (nMag < 4)
|
||||
{
|
||||
bRet = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (GetIsEffectValid(eTest) && bRet == TRUE )
|
||||
{
|
||||
nType = GetEffectType(eTest);
|
||||
if (nType == EFFECT_TYPE_STUNNED || nType == EFFECT_TYPE_PARALYZE ||
|
||||
nType == EFFECT_TYPE_SLEEP || nType == EFFECT_TYPE_PETRIFY ||
|
||||
nType == EFFECT_TYPE_CHARMED || nType == EFFECT_TYPE_CONFUSED ||
|
||||
nType == EFFECT_TYPE_FRIGHTENED || nType == EFFECT_TYPE_SLOW )
|
||||
{
|
||||
bRet = FALSE;
|
||||
}
|
||||
|
||||
eTest = GetNextEffect(oTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetHasSpellEffect(727,oTarget)) // already antimagic
|
||||
{
|
||||
bRet = FALSE;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
void OpenAntiMagicEye (object oTarget)
|
||||
{
|
||||
if (GetAntiMagicRayMakesSense(oTarget))
|
||||
{
|
||||
ActionCastSpellAtObject(727 , GetSpellTargetObject(),METAMAGIC_ANY,TRUE,0, PROJECTILE_PATH_TYPE_DEFAULT,TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// being a badass beholder, we close our antimagic eye only to attack with our eye rays
|
||||
// and then reopen it...
|
||||
void CloseAntiMagicEye(object oTarget)
|
||||
{
|
||||
RemoveSpellEffects (727,OBJECT_SELF,oTarget);
|
||||
}
|
||||
|
||||
|
||||
// stacking protection
|
||||
int BehDetermineHasEffect(int nRay, object oCreature)
|
||||
{
|
||||
switch (nRay)
|
||||
{
|
||||
case BEHOLDER_RAY_FEAR : if (GetHasEffect(EFFECT_TYPE_FRIGHTENED,oCreature))
|
||||
return TRUE;
|
||||
|
||||
case BEHOLDER_RAY_DEATH : if (GetIsDead(oCreature))
|
||||
return TRUE;
|
||||
|
||||
case BEHOLDER_RAY_CHARM: if (GetHasEffect(EFFECT_TYPE_CHARMED,oCreature))
|
||||
return TRUE;
|
||||
|
||||
case BEHOLDER_RAY_SLOW: if (GetHasEffect(EFFECT_TYPE_SLOW,oCreature))
|
||||
return TRUE;
|
||||
|
||||
case BEHOLDER_RAY_SLEEP: if (GetHasEffect(EFFECT_TYPE_SLEEP,oCreature))
|
||||
return TRUE;
|
||||
|
||||
case BEHOLDER_RAY_PETRI: if (GetHasEffect(EFFECT_TYPE_PETRIFY,oCreature))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int BehGetTargetThreatRating(object oTarget)
|
||||
{
|
||||
if (oTarget == OBJECT_INVALID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nRet = 20;
|
||||
|
||||
if (GetDistanceBetween(oTarget,OBJECT_SELF) <5.0f)
|
||||
{
|
||||
nRet += 3;
|
||||
}
|
||||
|
||||
nRet += (GetHitDice(oTarget)-GetHitDice(OBJECT_SELF) /2);
|
||||
|
||||
if (GetPlotFlag(oTarget)) //
|
||||
{
|
||||
nRet -= 6 ;
|
||||
}
|
||||
|
||||
if (GetMaster(oTarget)!= OBJECT_INVALID)
|
||||
{
|
||||
nRet -= 4;
|
||||
}
|
||||
|
||||
if (GetHasEffect(EFFECT_TYPE_PETRIFY,oTarget))
|
||||
{
|
||||
nRet -=10;
|
||||
}
|
||||
|
||||
if (GetIsDead(oTarget))
|
||||
{
|
||||
nRet = 0;
|
||||
}
|
||||
|
||||
return nRet;
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct beholder_target_struct GetRayTargets(object oTarget)
|
||||
{
|
||||
|
||||
struct beholder_target_struct stRet;
|
||||
object oMaster = oTarget;
|
||||
object oSumm;
|
||||
object oHench1;
|
||||
int nMaster;
|
||||
int nSumm;
|
||||
int nHench1;
|
||||
int nCount = 0;
|
||||
if (!GetIsPC(oTarget))
|
||||
{
|
||||
if (GetMaster(oTarget) != OBJECT_INVALID)
|
||||
{
|
||||
oMaster = GetMaster(oTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (oMaster != OBJECT_INVALID)
|
||||
{
|
||||
nCount ++;
|
||||
nMaster = BehGetTargetThreatRating(oMaster);
|
||||
|
||||
oSumm = GetAssociate(ASSOCIATE_TYPE_SUMMONED,oMaster);
|
||||
if (oSumm != OBJECT_INVALID)
|
||||
{
|
||||
nSumm = BehGetTargetThreatRating(oSumm);
|
||||
nCount ++;
|
||||
}
|
||||
|
||||
object oHench1 = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oMaster,1);
|
||||
if (oHench1 != OBJECT_INVALID)
|
||||
{
|
||||
nHench1 = BehGetTargetThreatRating(oHench1);
|
||||
nCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stRet.oTarget1 = oMaster;
|
||||
stRet.nRating1 = nMaster;
|
||||
if (oSumm != OBJECT_INVALID)
|
||||
{
|
||||
stRet.oTarget2 = oSumm;
|
||||
stRet.nRating2 = nSumm;
|
||||
}
|
||||
else
|
||||
{
|
||||
stRet.oTarget2 = oMaster;
|
||||
stRet.nRating2 = nMaster;
|
||||
nCount =2;
|
||||
}
|
||||
|
||||
if (nCount ==3)
|
||||
{
|
||||
stRet.oTarget3 = oHench1;
|
||||
stRet.nRating3 = nHench1;
|
||||
}
|
||||
stRet.nCount = nCount;
|
||||
|
||||
|
||||
return stRet;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BehDoFireBeam(int nRay, object oTarget)
|
||||
{
|
||||
|
||||
// don't use a ray if the target already has that effect
|
||||
if (BehDetermineHasEffect(nRay,oTarget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int bHit = TouchAttackRanged(oTarget,FALSE)>0;
|
||||
int nProj;
|
||||
switch (nRay)
|
||||
{
|
||||
case BEHOLDER_RAY_DEATH: nProj = 776;
|
||||
break;
|
||||
case BEHOLDER_RAY_TK: nProj = 777;
|
||||
break;
|
||||
case BEHOLDER_RAY_PETRI: nProj = 778;
|
||||
break;
|
||||
case BEHOLDER_RAY_CHARM: nProj = 779;
|
||||
break;
|
||||
case BEHOLDER_RAY_SLOW: nProj = 780;
|
||||
break;
|
||||
case BEHOLDER_RAY_WOUND: nProj = 783;
|
||||
break;
|
||||
case BEHOLDER_RAY_FEAR: nProj = 783;
|
||||
break;
|
||||
|
||||
case BEHOLDER_RAY_DIS: nProj = 785;
|
||||
break;
|
||||
case BEHOLDER_RAY_CHARMP: nProj = 786;
|
||||
break;
|
||||
case BEHOLDER_RAY_SLEEP: nProj = 787;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (bHit)
|
||||
{
|
||||
ActionCastSpellAtObject(nProj,oTarget,METAMAGIC_ANY,TRUE,0,PROJECTILE_PATH_TYPE_DEFAULT,TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
location lFail = GetLocation(oTarget);
|
||||
vector vFail = GetPositionFromLocation(lFail);
|
||||
|
||||
if (GetDistanceBetween(OBJECT_SELF,oTarget) > 6.0f)
|
||||
{
|
||||
|
||||
vFail.x += IntToFloat(Random(3)) - 1.5;
|
||||
vFail.y += IntToFloat(Random(3)) - 1.5;
|
||||
vFail.z += IntToFloat(Random(2));
|
||||
lFail = Location(GetArea(oTarget),vFail,0.0f);
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------
|
||||
// if we are fairly near, calculating a location could cause us to
|
||||
// spin, so we use the same location all the time
|
||||
//----------------------------------------------------------------------
|
||||
else
|
||||
{
|
||||
vFail.z += 0.8;
|
||||
vFail.y += 0.2;
|
||||
vFail.x -= 0.2;
|
||||
}
|
||||
|
||||
ActionCastFakeSpellAtLocation(nProj,lFail);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
157
_module/nss/x2_s1_beholdatt.nss
Normal file
157
_module/nss/x2_s1_beholdatt.nss
Normal file
@@ -0,0 +1,157 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: x2_s1_beholdatt
|
||||
//:: Beholder Attack Spell Logic
|
||||
//:: Copyright (c) 2003 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
|
||||
This spellscript is the core of the beholder's
|
||||
attack logic.
|
||||
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Georg Zoeller
|
||||
//:: Created On: 2003-08-28
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "x2_inc_beholder"
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
int nApp = GetAppearanceType(OBJECT_SELF);
|
||||
object oTarget = GetSpellTargetObject();
|
||||
// Only if we are beholders and not beholder mages
|
||||
/*
|
||||
//* GZ: cut whole immunity thing because it was causing too much trouble
|
||||
if (nApp == 472 ||nApp == 401 || nApp == 403)
|
||||
{
|
||||
CloseAntiMagicEye(oTarget);
|
||||
}
|
||||
*/
|
||||
|
||||
// need that to make them not drop out of combat
|
||||
SignalEvent(oTarget,EventSpellCastAt(OBJECT_SELF,GetSpellId()));
|
||||
|
||||
struct beholder_target_struct stTargets = GetRayTargets(oTarget);
|
||||
int nRay;
|
||||
int nOdd=d2()==1;
|
||||
if (stTargets.nCount ==0)
|
||||
{
|
||||
//emergency fallback
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget1);
|
||||
}
|
||||
else if (stTargets.nCount ==1) // AI for only one target
|
||||
{
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget1);
|
||||
}
|
||||
else if (stTargets.nCount ==2)
|
||||
{
|
||||
if (nOdd)
|
||||
{
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget1);
|
||||
}
|
||||
}
|
||||
else if (stTargets.nCount ==3)
|
||||
{
|
||||
switch (d3())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget3);
|
||||
}
|
||||
break; case 2:
|
||||
{
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget1);
|
||||
}
|
||||
break; case 3:
|
||||
{
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget3);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_SLEEP,stTargets.oTarget1);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_DIS,stTargets.oTarget2);
|
||||
if (d2()==1) BehDoFireBeam(BEHOLDER_RAY_CHARMP,stTargets.oTarget2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only if we are beholders and not beholder mages
|
||||
if (nApp == 472 ||nApp == 401 || nApp == 403)
|
||||
{
|
||||
OpenAntiMagicEye(oTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
*/
|
||||
254
_module/nss/x2_s1_beholdray.nss
Normal file
254
_module/nss/x2_s1_beholdray.nss
Normal file
@@ -0,0 +1,254 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Beholder Ray Attacks
|
||||
//:: x2_s2_beholdray
|
||||
//:: Copyright (c) 2003 Bioware Corp.
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Implementation for the new version of the
|
||||
beholder rays, using projectiles instead of
|
||||
rays
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Georg Zoeller
|
||||
//:: Created On: 2003-09-16
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "x0_i0_spells"
|
||||
|
||||
|
||||
void DoBeholderPetrify(int nDuration,object oSource, object oTarget, int nSpellID);
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
int nSpell = GetSpellId();
|
||||
object oTarget = GetSpellTargetObject();
|
||||
int nSave, bSave;
|
||||
int nSaveDC = 15;
|
||||
float fDelay;
|
||||
effect e1, eLink, eVis, eDur;
|
||||
|
||||
|
||||
switch (nSpell)
|
||||
{
|
||||
case 776 :
|
||||
nSave = SAVING_THROW_FORT; // BEHOLDER_RAY_DEATH
|
||||
break;
|
||||
|
||||
case 777:
|
||||
nSave = SAVING_THROW_WILL; // BEHOLDER_RAY_TK
|
||||
break;
|
||||
|
||||
case 778 : // BEHOLDER_RAY_PETRI
|
||||
nSave = SAVING_THROW_FORT;
|
||||
break;
|
||||
|
||||
case 779: // BEHOLDER_RAY_CHARM
|
||||
|
||||
case 786:
|
||||
nSave = SAVING_THROW_WILL;
|
||||
break;
|
||||
|
||||
case 780: // BEHOLDER_RAY_SLOW
|
||||
nSave = SAVING_THROW_WILL;
|
||||
break;
|
||||
|
||||
case 783:
|
||||
nSave = SAVING_THROW_FORT; // BEHOLDER_RAY_WOUND
|
||||
break;
|
||||
|
||||
case 784: // BEHOLDER_RAY_FEAR
|
||||
nSave = SAVING_THROW_WILL;
|
||||
break;
|
||||
|
||||
case 785: // BEHOLDER_RAY_DISINTEGRATE
|
||||
nSave = SAVING_THROW_FORT;
|
||||
break;
|
||||
|
||||
case 787: // BEHOLDER_RAY_SLEEP
|
||||
nSave = SAVING_THROW_WILL;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
SignalEvent(oTarget,EventSpellCastAt(OBJECT_SELF,GetSpellId(),TRUE));
|
||||
fDelay = 0.0f; //old -- GetSpellEffectDelay(GetLocation(oTarget),OBJECT_SELF);
|
||||
|
||||
int iTargetRace = GetRacialType(oTarget);
|
||||
|
||||
if ((nSpell == 786) && (
|
||||
((!GetIsPlayableRacialType(oTarget))
|
||||
|
||||
&&(iTargetRace!=RACIAL_TYPE_HUMANOID_GOBLINOID)
|
||||
&&(iTargetRace!=RACIAL_TYPE_HUMANOID_MONSTROUS)
|
||||
&&(iTargetRace!=RACIAL_TYPE_HUMANOID_ORC)
|
||||
&&(iTargetRace!=RACIAL_TYPE_HUMANOID_REPTILIAN))
|
||||
|
||||
&&(iTargetRace==RACIAL_TYPE_ELF))) bSave = TRUE;
|
||||
|
||||
if (nSave == SAVING_THROW_WILL)
|
||||
{
|
||||
bSave = MySavingThrow(SAVING_THROW_WILL,oTarget, nSaveDC,SAVING_THROW_TYPE_ALL,OBJECT_SELF,fDelay) >0;
|
||||
}
|
||||
else if (nSave == SAVING_THROW_FORT)
|
||||
{
|
||||
bSave = MySavingThrow(SAVING_THROW_FORT,oTarget, nSaveDC,SAVING_THROW_TYPE_ALL,OBJECT_SELF,fDelay) >0;
|
||||
}
|
||||
|
||||
if (!bSave)
|
||||
{
|
||||
|
||||
switch (nSpell)
|
||||
{
|
||||
case 776: e1 = EffectDeath(TRUE);
|
||||
eVis = EffectVisualEffect(VFX_IMP_DEATH);
|
||||
eLink = EffectLinkEffects(e1,eVis);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
|
||||
break;
|
||||
|
||||
case 777: e1 = ExtraordinaryEffect(EffectKnockdown());
|
||||
eVis = EffectVisualEffect(VFX_IMP_STUN);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,6.0f);
|
||||
break;
|
||||
|
||||
// Petrify for one round per SaveDC
|
||||
case 778: eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
DoBeholderPetrify(nSaveDC,OBJECT_SELF,oTarget,GetSpellId());
|
||||
break;
|
||||
|
||||
case 786:
|
||||
case 779: e1 = EffectCharmed();
|
||||
eVis = EffectVisualEffect(VFX_IMP_CHARM);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,24.0f);
|
||||
break;
|
||||
|
||||
|
||||
case 780: e1 = EffectSlow();
|
||||
eVis = EffectVisualEffect(VFX_IMP_SLOW);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,RoundsToSeconds(6));
|
||||
break;
|
||||
|
||||
case 783: e1 = EffectDamage(d8(2)+10);
|
||||
eVis = EffectVisualEffect(VFX_COM_BLOOD_REG_RED);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,e1,oTarget);
|
||||
break;
|
||||
|
||||
|
||||
case 784:
|
||||
e1 = EffectFrightened();
|
||||
eVis = EffectVisualEffect(VFX_IMP_FEAR_S);
|
||||
eDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR);
|
||||
e1 = EffectLinkEffects(eDur,e1);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,RoundsToSeconds(1+d4()));
|
||||
break;
|
||||
|
||||
case 785: e1 = EffectDamage(d6(GetHitDice(OBJECT_SELF)));
|
||||
eVis = EffectVisualEffect(VFX_IMP_DUST_EXPLOSION);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,e1,oTarget);
|
||||
break;
|
||||
|
||||
case 787: e1 = EffectSleep();
|
||||
eVis = EffectVisualEffect(VFX_IMP_SLEEP);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,RoundsToSeconds(3+GetHitDice(OBJECT_SELF)));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (nSpell)
|
||||
{
|
||||
case 776: e1 = EffectDamage(d6(3)+13);
|
||||
eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);
|
||||
eLink = EffectLinkEffects(e1,eVis);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
|
||||
|
||||
case 785: e1 = EffectDamage(d6(5));
|
||||
eVis = EffectVisualEffect(VFX_IMP_DUST_EXPLOSION);
|
||||
eLink = EffectLinkEffects(e1,eVis);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DoBeholderPetrify(int nDuration,object oSource, object oTarget, int nSpellID)
|
||||
{
|
||||
|
||||
if(!GetIsReactionTypeFriendly(oTarget) && !GetIsDead(oTarget))
|
||||
{
|
||||
// * exit if creature is immune to petrification
|
||||
if (spellsIsImmuneToPetrification(oTarget) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
float fDifficulty = 0.0;
|
||||
int bIsPC = GetIsPC(oTarget);
|
||||
int bShowPopup = FALSE;
|
||||
|
||||
// * calculate Duration based on difficulty settings
|
||||
int nGameDiff = GetGameDifficulty();
|
||||
switch (nGameDiff)
|
||||
{
|
||||
case GAME_DIFFICULTY_VERY_EASY:
|
||||
case GAME_DIFFICULTY_EASY:
|
||||
case GAME_DIFFICULTY_NORMAL:
|
||||
fDifficulty = RoundsToSeconds(nDuration); // One Round per hit-die or caster level
|
||||
break;
|
||||
case GAME_DIFFICULTY_CORE_RULES:
|
||||
case GAME_DIFFICULTY_DIFFICULT:
|
||||
if (!GetPlotFlag(oTarget))
|
||||
{
|
||||
bShowPopup = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
effect ePetrify = EffectPetrify();
|
||||
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||
effect eLink = EffectLinkEffects(eDur, ePetrify);
|
||||
|
||||
|
||||
/// * The duration is permanent against NPCs but only temporary against PCs
|
||||
if (bIsPC == TRUE)
|
||||
{
|
||||
if (bShowPopup == TRUE)
|
||||
{
|
||||
// * under hardcore rules or higher, this is an instant death
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
|
||||
DelayCommand(2.75, PopUpDeathGUIPanel(oTarget, FALSE , TRUE, 40579));
|
||||
// if in hardcore, treat the player as an NPC
|
||||
bIsPC = FALSE;
|
||||
}
|
||||
else
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDifficulty);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
|
||||
// * Feb 11 2003 BK I don't think this is necessary anymore
|
||||
//if the target was an NPC - make him uncommandable until Stone to Flesh is cast
|
||||
//SetCommandable(FALSE, oTarget);
|
||||
|
||||
// Feb 5 2004 - Jon
|
||||
// Added kick-henchman-out-of-party code from generic petrify script
|
||||
if (GetAssociateType(oTarget) == ASSOCIATE_TYPE_HENCHMAN)
|
||||
{
|
||||
FireHenchman(GetMaster(oTarget),oTarget);
|
||||
}
|
||||
}
|
||||
// April 2003: Clearing actions to kick them out of conversation when petrified
|
||||
AssignCommand(oTarget, ClearAllActions());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user