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:
Jaysyn904
2021-12-31 01:45:43 -05:00
parent 8c0a2224cb
commit 64c913bf07
282 changed files with 10734 additions and 10497 deletions

View File

@@ -1,4 +1,4 @@
// Port PC
// Port PC to 10a NW Caves
///////////////////////////////////////////////////
void main()
{

View 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.
}
}

View File

@@ -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;

View 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));
}
}

View 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));
}
}

View 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));
}
}

View 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);
}
}
}

View 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));
}
}

View 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));
}
}

View 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);
}

View 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));
}
}

View 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));
}
}

View 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;
}

View 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);
}

View 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));
}
}

View 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;
}

View File

@@ -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
View 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);
}
}
}

View 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);
}

View 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);
}
}
}

View 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());
}
}

View File

@@ -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

View 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());
}
}

View 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);
}

View 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);
}

View File

@@ -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);
}

View 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);
}

View 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);
}

View 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);
}

View File

@@ -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);
}

View 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);
}

View 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);
}

View 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);
}

View File

@@ -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)

View 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);
}

View 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);
}

View 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);
}
}

View 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);
}
}
/*
*/

View 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());
}
}