Further file organization

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

View File

@@ -0,0 +1,41 @@
include ../config.mk
ZIP = ../prc_consortium.tgz
ERF = ../prc_consortium.erf
HAK = ../prc_consortium.hak
2DAS = ~~~2das~~~
GFXS = ~~~gfxs~~~
OTHERS = ~~~others~~~
SCRIPTS = ~~~scripts~~~
OBJS = $(SCRIPTS:.nss=.ncs)
all: scripts pack
scripts: $(OBJS)
pack: scripts
@echo -n 'Packing erf file..'
@$(ERFCOMPILER) -c $(ERF) $(SCRIPTS) $(OBJS)
@echo '.done'
@echo -n 'Packing hak file..'
@$(ERFCOMPILER) -c $(HAK) $(2DAS) $(OTHERS) $(GFXS)
@echo '.done'
clean:
@rm -f $(OBJS) $(ZIP) $(ERF) $(HAK) *.ndb
# NOTE: It really should be $(OBJS) instead of *.ncs but this causes problems with include files
install: scripts
@echo 'Copying 2das, gfx, scripts and others to override and tlk to tlk directory...'
@cp -f *.ncs $(NWN_OVERRIDE)
@cp -f $(2DAS) $(NWN_OVERRIDE)
@cp -f $(GFXS) $(NWN_OVERRIDE)
@cp -f $(OTHERS) $(NWN_OVERRIDE)
@cp -f $(2DAS) $(NWN_OVERRIDE)
@cp -f ../tlk/prc_consortium.tlk $(NWN_TLK)
@echo 'Done.'
%.ncs: %.nss
$(NSSCOMPILER) $*.nss

View File

@@ -0,0 +1,624 @@
//:://////////////////////////////////////////////
//:: PRC New Spellbooks use conversation
//:: prc_s_spellb
//:://////////////////////////////////////////////
/** @file
@todo Primo: Could you write a blurb on what
this does and TLKify it?
@author Primogenitor
@date Created - yyyy.mm.dd
last changed by motu99, April 29, 2008:
Conversation script for setting up spells to be memorized by prepared casters
This conversation script sets up a persistent array of the spells to be memorized
(at the end of the next rest) for any newspellbook prepared caster class.
It uses the persistent array name prefix "Spellbook", then appends the spell level
(converted to a string) to the prefix and lastly appends the class-nr (converted to a string)
The thus appended prefix is a persistent array name, in which the nSpellbookIDs of the
spells to be memorized at the end of the next rest are stored
the conversation is called by activating the prc_spellbook feat (#1999 in feats.2da)
which fires the spellscript prc_spellbook (#1792 in spells.2da), which then calls this
conversation script
*/
//:://////////////////////////////////////////////
//:: Updated for .35 by Jaysyn 2023/03/11
//:://////////////////////////////////////////////
// persistant storage format on hide
/**
MEMORIZED SPELLS FOR PREP CASTERS:
All spell levels are all stored in one single array (motu99: very unfortunate, should be changed):
sArrayName = "NewSpellbookMem_"+IntToString(nClass)
The array is indexed by the spellbookID; the value is the number of spells with that spellbookID still in memory:
nNrOfSpellsStillInMemory = sArrayName[nSpellbookID]
SPELLS TO BE MEMORIZED BY PREP CASTERS
They are stored in up to ten arrays, one array for each spell level (or rather spell slot level)
sArrayName = "Spellbook"+IntToString(nSpellLevel)+"_"+IntToString(nClass)
The array is indexed by the slot number, starting at #0; the value contains the nSpelllbookID of the spell to be memorized
nSpellbookID = sArrayName[nSlotNr]
SPELLS MEMORIZED BY PREP CASTERS - INDEX
Array created from "spells to be memorized" in OnRest event. Only unique spellids are stored.
sArrayName = "SpellbookIDX"+IntToString(nSpellLevel)+"_"+IntToString(nClass)
Serves as "NewSpellbookMem_" index for fast search and delete - allows looping only through memorized SpellbookIDs
(archivist - max 56 + bonus slots from high WIS) instead of all SpellbookIDs (archivist - 2400+)
Should help reduce instruction count sagnificantly.
SPELLS KNOWN BY PREP CASTERS:
so far prep NSB casters know all spells in their class spellbook; they need not learn spells
motu99: This might change, if for instance wizards use the NSB system to gain higher spell slot levels (10+)
//for archivist:
They are stored in up to ten arrays, one array for each spell level (or rather spell slot level)
sArrayName = "Spellbook_Known_"+IntToString(nClass)+"_"+IntToString(nSpellLevel)
SPELLS KNOWN BY SPONT CASTERS:
The spells known are stored in one single array (the array contains only the non-metamagic versions and only master spells)
sArrayName = "Spellbook" + IntToString(nClass);
The array is indexed by a counter (the i-th spell learned); the value contains the nSpellbookID of the (non-metamagic master) spell known
nSpellbookID = sArrayName[i]
AVAILABLE SPELL SLOTS FOR SPONT CASTERS:
The nr of still available spell slots for a prep caster are all stored in one single array
sArrayName = "NewSpellbookMem_" + IntToString(nClass)
The array is indexed by the spell (slot) level, the value contains the nr of still available slots at that spell (slot) level
nNrOfSpellSlotsAvailable = sArrayName[nSpellSlotLevel]
*/
// spells in the class spellbook of nClass (a spont caster generally will not know all of these spells)
/**
SPELLS IN THE CLASS SPELLBOOK OF PREP OR SPONT CASTERS:
The spells that are potentially learnable by nClass are stored on the prc cache object in up to 10 different tokens.
The class spell book ONLY stores the masterspells and ONLY the non-metamagicked version!
There is one storage token for every spell level (and class); it has the tag name:
sTag = "SpellLvl_"+IntToString(nClass)+"_Level_"+IntToString(nSpellLevel);
The spells are stored on the token object oToken (defined by the unique sTag) in an array with name sArrayName
oToken = GetObjectByTag(sTag)
sArrayName = "Lkup"
The array is indexed by a counter (the i-th spell of a given level in the class spellbook); the value is the spellbookID
nSpellbookID = sArrayName[i]
*/
#include "x2_inc_spellhook"
#include "inc_dynconv"
#include "inc_sp_gain_mem"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_SELECT_CLASS = 0;
const int STAGE_SELECT_SPELL_LEVEL = 1;
const int STAGE_SELECT_SPELL_SLOT = 2;
const int STAGE_SELECT_METAMAGIC = 3;
const int STAGE_SELECT_SPELL = 4;
const int CHOICE_RETURN_TO_PREVIOUS = 0xEFFFFFFF;
const string CONV_SPELLB_CLASS = "SpellClass";
const string CONV_SPELLB_LEVEL = "SpellLevel";
const string CONV_SPELLB_META = "MetaMagic";
const string CONV_SPELLB_SLOT = "SpellSlot";
const int DYNCONV_NEXT_STAGE = -4;
//////////////////////////////////////////////////
/* Aid functions */
//////////////////////////////////////////////////
const string SPELLS_MEMORIZED_CACHE = "SMCCCache";
void DeleteSpellsMemorizedCache(object oPC)
{
int i;
for (i=1; i <= MAX_CLASSES; i++)
{
int nClass = GetClassByPosition(i, oPC);
if (nClass == CLASS_TYPE_INVALID) break;
if(GetLocalInt(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass)))
{
DeleteLocalInt(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass));
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "0");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "1");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "2");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "3");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "4");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "5");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "6");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "7");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "8");
DeleteLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + "9");
}
}
}
// now build the cache
void GenerateSpellsMemorizedCache(int nClass, object oPC)
{
// get the object on the hide of oPC where the persistant data are stored
//object oToken = GetHideToken(oPC);
string sSpellsMemorized = GetSpellsMemorized_Array(nClass);
// if the persistant array with the remaining memorized spells does not exist, abort
if(!persistant_array_exists(oPC, sSpellsMemorized))
{
if(DEBUG) DoDebug("Error: " +sSpellsMemorized+ " array does not exist");
}
else
{
string sFile = GetNSBDefinitionFileName(nClass);
string sArrayIDX, sSpellbookID, sMessage, sMess, sClass = IntToString(nClass);
// remember the class (because this might change during the conversation)
SetLocalInt(oPC, SPELLS_MEMORIZED_CACHE + sClass, TRUE);
int nSpellLevel, nSlot, nSlots, nSpellbookID;
for(nSpellLevel = 0; nSpellLevel <= 9; nSpellLevel++)
{
sArrayIDX = "SpellbookIDX" + IntToString(nSpellLevel) + "_" + sClass;
sMessage = "";
nSlots = persistant_array_get_size(oPC, sArrayIDX);
for(nSlot = 0; nSlot < nSlots; nSlot++)
{
nSpellbookID = persistant_array_get_int(oPC, sArrayIDX, nSlot);
int nCount = nSpellbookID ? persistant_array_get_int(oPC, sSpellsMemorized, nSpellbookID) : 0;
if(nCount)
{
// determine spell name from spellID by reference
int nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", nSpellbookID));
sMess = PRC_TEXT_WHITE + GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
// add the metamagic [ext emp]
int nMetaMagicFeat = StringToInt(Get2DACache(sFile, "ReqFeat", nSpellbookID));
if(nMetaMagicFeat)
{
int nMetaMagic = GetMetaMagicFromFeat(nMetaMagicFeat);
sMess += " - " +GetMetaMagicString(nMetaMagic);
}
// add the nr of spells in memory
sMess += PRC_TEXT_BLUE + " [" +IntToString(nCount)+ "]\n";
sMessage += sMess;
}
}
// now store the values for later retrieval
if (sMessage != "") SetLocalString(oPC, SPELLS_MEMORIZED_CACHE + sClass + "_" + IntToString(nSpellLevel), sMessage);
}
}
// we delete the cached values on exit from the conversation, so no need to do it now
// DelayCommand(6.0, DeleteSpellsMemorizedCache(oPC));
}
// creates a string with a list of memorized spells of the given nClass and nSpellSlotLevel
// each spell has an extra line, which denotes the spell's name
string ListMemorizedSpells(int nClass, int nSpellSlotLevel, object oPC)
{
// try to get the list from cache; but only if cache is for the correct nClass
//if (GetLocalInt(oPC, SPELLS_MEMORIZED_CACHE) == nClass)
//{
return GetLocalString(oPC, SPELLS_MEMORIZED_CACHE + IntToString(nClass) + "_" + IntToString(nSpellSlotLevel));
//}
}
//////////////////////////////////////////////////
/* Main function */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
/* Get the value of the local variable set by the conversation script calling
* this script. Values:
* DYNCONV_ABORTED Conversation aborted
* DYNCONV_EXITED Conversation exited via the exit node
* DYNCONV_SETUP_STAGE System's reply turn
* 0 Error - something else called the script
* Other The user made a choice
*/
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
// The stage is used to determine the active conversation node.
// 0 is the entry node.
int nStage = GetStage(oPC);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
if(nStage == STAGE_SELECT_CLASS)
{
//select spell class
SetHeader("Select a spell book:");
int i;
for (i=1; i <= MAX_CLASSES; i++)
{
int nClass = GetClassByPosition(i, oPC);
if (nClass == CLASS_TYPE_INVALID) break;
if(GetIsNSBClass(nClass) && // must be a new spellbook class
GetSpellbookTypeForClass(nClass) == SPELLBOOK_TYPE_PREPARED) // must be a prepared caster
{
// must have levels in the prepared class and at least level 1 spell slots
int nAbilityScore = GetAbilityScoreForClass(nClass, oPC);
int nClassLevel = GetLevelByPosition(i, oPC);
if(nClassLevel
&& (GetSlotCount(nClassLevel, 0, nAbilityScore, nClass)
|| GetSlotCount(nClassLevel, 1, nAbilityScore, nClass)))
{
string sClassName = GetStringByStrRef(StringToInt(Get2DACache("classes", "Name", nClass)));
GenerateSpellsMemorizedCache(nClass, oPC);
AddChoice(sClassName, nClass, oPC);
}
}
}
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
MarkStageSetUp(nStage, oPC);
}
else if(nStage == STAGE_SELECT_SPELL_LEVEL)
{
int nClass = GetLocalInt(oPC, CONV_SPELLB_CLASS);
int nCasterLevel = GetCasterLevelByClass(nClass, oPC);
int nMaxSpellSlotLevel = GetMaxSpellLevelForCasterLevel(nClass, nCasterLevel);
int nMinSpellSlotLevel = GetMinSpellLevelForCasterLevel(nClass, nCasterLevel);
int nChoiceAdded = FALSE;
if(nMaxSpellSlotLevel >= nMinSpellSlotLevel)
{
string sChoiceSpellLevel = "Spell slot level ";
int nAbilityScore = GetAbilityScoreForClass(nClass, oPC);
// List all spell slot levels available to the caster for this class
int nSpellSlotLevel;
for(nSpellSlotLevel = nMinSpellSlotLevel; nSpellSlotLevel <= nMaxSpellSlotLevel; nSpellSlotLevel++)
{
// for every spell level, determine the slot count, and if it is non-zero add a choice
// we do not break out of the loop on an empty slot count, because of bonus slot counts from items there might be gaps
if(GetSlotCount(nCasterLevel, nSpellSlotLevel, nAbilityScore, nClass))
{
AddChoice(sChoiceSpellLevel +IntToString(nSpellSlotLevel), nSpellSlotLevel, oPC);
nChoiceAdded = TRUE;
}
}
}
if (nChoiceAdded)
SetHeader("Select a spell slot level:");
else
SetHeader("You cannot memorize any spells at the moment - check your ability score");
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
MarkStageSetUp(nStage, oPC);
}
else if(nStage == STAGE_SELECT_SPELL_SLOT)
{
int nClass = GetLocalInt(oPC, CONV_SPELLB_CLASS);
int nSpellSlotLevel = GetLocalInt(oPC, CONV_SPELLB_LEVEL);
int nCasterLevel = GetCasterLevelByClass(nClass, oPC);
int nAbilityScore = GetAbilityScoreForClass(nClass, oPC);
// get the object on the hide of oPC where the persistant data are stored
//object oToken = GetHideToken(oPC);
// determine the name of the persistant array that holds the spells to be memorized for the given nClass and nSpellLevel
// (the index to the array is the nr of the slot of the given nClass and nSpellLevel)
string sSpellsToBeMemorized = GetSpellsToBeMemorized_Array(nClass, nSpellSlotLevel);
// unfortunatly, the spellsMemorized list has a different format (all spell levels in one huge sparse array, indexed by nSpellbookID)
string sSpellsMemorized = GetSpellsMemorized_Array(nClass);
// now check if the arrays "spells to be memorized" and "spells memorized" exist at the given spell slot level and create them, if not
if (persistant_array_get_size(oPC, sSpellsToBeMemorized) < 0) persistant_array_create(oPC, sSpellsToBeMemorized);
if (persistant_array_get_size(oPC, sSpellsMemorized) < 0) persistant_array_create(oPC, sSpellsMemorized);
string sHeader = "You have remaining:\n";
sHeader += ListMemorizedSpells(nClass, nSpellSlotLevel, oPC) + "\n";
// get the nr of spell slots for the given nClass and nSpellLevel
// (should be non-zero, because we only allow the PC to select spell slot levels with non-zero slot count)
int nSlots = GetSlotCount(nCasterLevel, nSpellSlotLevel, nAbilityScore, nClass, oPC);
if (nSlots > 0)
{
sHeader += "Select a spell slot:\n"+ PRC_TEXT_WHITE + "spell to be memorized " + PRC_TEXT_BLUE + "[# still in memory]";
// set the array size of "spells to be memorized" and "spells memorized" to the nr of slots
array_set_size(oPC, sSpellsToBeMemorized, nSlots);
string sFile = GetNSBDefinitionFileName(nClass);
string sChoice;
string sNameToBeMemorized;
// add a choice for every slot; show what is currently in the slot (if nothing, show "empty")
int nSlotNr;
for(nSlotNr = 0; nSlotNr < nSlots; nSlotNr++)
{
// get the spell associated with the i-th slot
int nSpellbookID = persistant_array_get_int(oPC, sSpellsToBeMemorized, nSlotNr);
int nMetaMagic = 0;
// nothing "to be memorized" for this slot?
if (nSpellbookID == 0)
{
sNameToBeMemorized = "Empty";
}
else
{
// get the spell name "to be memorized", including metamagic
// int nIPFeatID = StringToInt(Get2DACache(sFile, "IPFeatID", nSpellbookID));
// sNameToBeMemorized = GetStringByStrRef(StringToInt(Get2DACache("iprp_feats", "Name", nIPFeatID)));
int nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", nSpellbookID));
sNameToBeMemorized = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
nMetaMagic = GetMetaMagicFromFeat(StringToInt(Get2DACache(sFile, "ReqFeat", nSpellbookID)));
if (nMetaMagic) sNameToBeMemorized += " - " + GetMetaMagicString(nMetaMagic);
}
//first we show what spell will "be memorized" at next rest from the given slot (this is in white)
sChoice = PRC_TEXT_WHITE + sNameToBeMemorized;
// now check if there are spells still in memory that are equal to the spell "to be memorized" at the given slot
if (nSpellbookID)
{
int nNrOfSpells_Mem = persistant_array_get_int(oPC, sSpellsMemorized, nSpellbookID);
// show in blue and in brackets
sChoice += PRC_TEXT_BLUE + " [" +IntToString(nNrOfSpells_Mem)+ "]";
}
// add the slot nr as choice
AddChoice(sChoice, nSlotNr, oPC);
}
}
else
{
sHeader += PRC_TEXT_WHITE + "there aren't any slots available at the chosen level - check your ability score";
}
SetHeader(sHeader);
AddChoice("Back", CHOICE_RETURN_TO_PREVIOUS);
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
MarkStageSetUp(nStage, oPC);
}
else if (nStage == STAGE_SELECT_METAMAGIC)
{
// get the metamagic feats oPC possesses
int nMetaMagicCaster = GetMetaMagicOfCaster(oPC);
int bChoiceAdded;
// only need to do this, if the caster has at least one metamagic feat
if (nMetaMagicCaster)
{
// get the currently selected spell slot level
int nSpellSlotLevel = GetLocalInt(oPC, CONV_SPELLB_LEVEL);
int nClass = GetLocalInt(oPC, CONV_SPELLB_CLASS);
int nCasterLevel = GetCasterLevelByClass(nClass, oPC);
int nMinSpellSlotLevel = GetMinSpellLevelForCasterLevel(nClass, nCasterLevel);
// metamagics only for slot levels higher than the lowest slot level
if (nSpellSlotLevel > nMinSpellSlotLevel)
{
// calculate the maximum metamagic adjustment that is possible at the given spell slot level
// note that the metamagic adjustment will generally result in spells to choose from, that are
// lower in level than the spell slot level. But we cannot reduce the level below the minimum spell level of the class
int nMaxMetaMagicAdj = nSpellSlotLevel - nMinSpellSlotLevel;
// go through all possible metamagics by shifting 1 to the left
// this will result in checking for some metamagics that are not implemented
// but the check against the metamagic feats possessed be oPC will get rid of all non-implemented
int nMetaMagic;
for (nMetaMagic = 1; nMetaMagic < 0x40; nMetaMagic <<= 1)
{
if ((nMetaMagicCaster & nMetaMagic) // caster must have the metamagic feat
// and the combined levels of the already chosen metamagic with the metamagic to choose must be
// less or equal than the max metamagic adjustment allowed for nClass at the given nSpellSlotLevel
&& GetMetaMagicSpellLevelAdjustment(nMetaMagic) <= nMaxMetaMagicAdj)
{
AddChoice(GetMetaMagicString(nMetaMagic), nMetaMagic, oPC);
bChoiceAdded = TRUE;
}
}
if (bChoiceAdded)
{
SetHeader("Select a metamagic adjustment:");
AddChoice("No metamagic", 0, oPC);
AddChoice("Back", CHOICE_RETURN_TO_PREVIOUS);
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
}
}
}
// no metamagics available at the spell slot level?
if (!bChoiceAdded)
{
// then advance to next stage and clear metamagic
SetStage(++nStage, oPC);
DeleteLocalInt(oPC, CONV_SPELLB_META);
}
MarkStageSetUp(STAGE_SELECT_METAMAGIC, oPC);
}
// if-clause is intentional; DONT change to else-if
if(nStage == STAGE_SELECT_SPELL)
{
int nClass = GetLocalInt(oPC, CONV_SPELLB_CLASS);
int nMetaMagic = GetLocalInt(oPC, CONV_SPELLB_META);
int nSpellSlotLevel = GetLocalInt(oPC, CONV_SPELLB_LEVEL);
int nSpellLevel = nSpellSlotLevel - GetMetaMagicSpellLevelAdjustment(nMetaMagic);
// determine from where to get the spells known (for nClass at the given level)
// so far this is the class spellbook, eg. all spells are available (divine casters)
string sFile = GetNSBDefinitionFileName(nClass);
object oToken;
string sSpellBook;
if(bKnowsAllClassSpells(nClass))
{
oToken = GetSpellsOfClass_Token(nClass, nSpellLevel);
sSpellBook = GetSpellsOfClass_Array();
}
else
{
oToken = oPC;
sSpellBook = GetSpellsKnown_Array(nClass, nSpellLevel);
}
// go through all spells that oPC has in his spellbook at the given nSpellLevel ( for divine casters this might be all)
// motu99: This array does NOT include the metamagicked versions of the spells or subradial versions!
int nSpellsKnown = persistant_array_get_size(oToken, sSpellBook);
int bSpellSelected = FALSE;
int i;
for(i = 0; i < nSpellsKnown; i++)
{
// this is the cls_spell_* row nr for the UNMETAMAGICKED version of the spell
int nSpellbookID = persistant_array_get_int(oToken, sSpellBook, i);
// get the real spellID
int nSpellID = StringToInt(Get2DACache(sFile, "RealSpellID", nSpellbookID));
// if we choose a metamagic, find the nSpellbookID for the metamagic version of the spell
// all metamagic versions of the master spell lie in a consecutive block after the non-metamagic version
if (nMetaMagic)
{
// get the next row in cls_spell_* and test if it belongs to the same real spellID
while (StringToInt(Get2DACache(sFile, "RealSpellID", ++nSpellbookID)) == nSpellID)
{
// do the metamagics match?
if (nMetaMagic == GetMetaMagicFromFeat(StringToInt(Get2DACache(sFile, "ReqFeat", nSpellbookID))))
{
// indicate success by negative nr
nSpellbookID = -nSpellbookID;
break;
}
}
// success? then redo the negation
if (nSpellbookID < 0)
nSpellbookID = -nSpellbookID;
// otherwise indicate failure by setting nSpellbookID to zero
else
nSpellbookID = 0;
}
// did we find an appropriate spellbook ID for the given spell slot evel and metamagic?
// then add it to the list
if (nSpellbookID)
{
// int nIPFeatID = StringToInt(Get2DACache(sFile, "IPFeatID", nSpellbookID));
// string sName = GetStringByStrRef(StringToInt(Get2DACache("iprp_feats", "Name", nIPFeatID)));
string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
if (nMetaMagic) sName + " - " +GetMetaMagicString(nMetaMagic);
AddChoice(sName, nSpellbookID, oPC);
bSpellSelected = TRUE;
}
}
if (bSpellSelected)
SetHeader("Select a spell:");
else
SetHeader("No spells to select at spell level " + IntToString (nSpellLevel));
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
MarkStageSetUp(nStage, oPC);
}
}
// Do token setup
SetupTokens();
}
else if(nValue == DYNCONV_EXITED ||
nValue == DYNCONV_ABORTED )
{
//end of conversation cleanup
DeleteLocalInt(oPC, CONV_SPELLB_CLASS);
DeleteLocalInt(oPC, CONV_SPELLB_LEVEL);
DeleteLocalInt(oPC, CONV_SPELLB_SLOT);
DeleteLocalInt(oPC, CONV_SPELLB_META);
DeleteSpellsMemorizedCache(oPC);
}
else
{
int nChoice = GetChoice(oPC);
if(nStage == STAGE_SELECT_CLASS)
{
//store nClass and proceed to slot level selection
SetLocalInt(oPC, CONV_SPELLB_CLASS, nChoice);
nStage = STAGE_SELECT_SPELL_LEVEL;
MarkStageNotSetUp(nStage, oPC);
}
else if(nStage == STAGE_SELECT_SPELL_LEVEL)
{
//store slot level and proceed to spell slot selection
SetLocalInt(oPC, CONV_SPELLB_LEVEL, nChoice);
nStage = STAGE_SELECT_SPELL_SLOT;
MarkStageNotSetUp(nStage, oPC);
}
else if(nStage == STAGE_SELECT_SPELL_SLOT)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
nStage = STAGE_SELECT_SPELL_LEVEL;
else
{
// store the spell slot nr and go to metamagic selection phase
SetLocalInt(oPC, CONV_SPELLB_SLOT, nChoice);
nStage = STAGE_SELECT_METAMAGIC;
}
MarkStageNotSetUp(nStage, oPC);
}
else if(nStage == STAGE_SELECT_METAMAGIC)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
nStage = STAGE_SELECT_SPELL_SLOT;
else
{
// store the metamagic and proceed to spell selection phase
SetLocalInt(oPC, CONV_SPELLB_META, nChoice);
nStage = STAGE_SELECT_SPELL;
}
MarkStageNotSetUp(nStage, oPC);
}
else if(nStage == STAGE_SELECT_SPELL)
{
// our choice is the nSpellbookID
// get the other vital information
int nSpellSlot = GetLocalInt(oPC, CONV_SPELLB_SLOT);
int nSpellSlotLevel = GetLocalInt(oPC, CONV_SPELLB_LEVEL);
int nClass = GetLocalInt(oPC, CONV_SPELLB_CLASS);
int nMetaMagic = GetLocalInt(oPC, CONV_SPELLB_META);
// get the object on the hide of oPC where the persistant data are stored
//object oToken = GetHideToken(oPC);
// determine the name of the persistant array that holds the spells to be memorized for the given nClass and nSpellLevel
// (the index to the array is the nr of the slot of the given nClass and nSpellLevel)
string sSpellsToBeMemorized = GetSpellsToBeMemorized_Array(nClass, nSpellSlotLevel);
// store the chosen nSpellbookID (row nr in the newspellbook file cls_spells_*) in the spells to be memorized array
persistant_array_set_int(oPC, sSpellsToBeMemorized, nSpellSlot, nChoice);
// let oPC select a new spell (starting with the spell level)
nStage = STAGE_SELECT_SPELL_LEVEL;
MarkStageNotSetUp(nStage, oPC);
}
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}

View File

@@ -0,0 +1,20 @@
//:://////////////////////////////////////////////
//:: New Spellbooks conversation starter
//:: prc_spellbook
//:://////////////////////////////////////////////
/** @file
This script starts the new spellbook spell
slots management conversation
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
StartDynamicConversation("prc_s_spellb", OBJECT_SELF, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, FALSE, OBJECT_SELF);
}

View File

@@ -0,0 +1,90 @@
#include "prc_x2_itemprop"
#include "inc_acp"
#include "prc_ipfeat_const"
void main()
{
object oPC = OBJECT_SELF;
if(!GetHasFeat(FEAT_ACP_FEAT)
&& GetPRCSwitch(PRC_ACP_MANUAL))
{
IPSafeAddItemProperty(GetPCSkin(OBJECT_SELF), PRCItemPropertyBonusFeat(IP_CONST_ACP_FEAT), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
return;
}
else if(((GetPRCSwitch(PRC_ACP_AUTOMATIC) && GetIsPC(OBJECT_SELF))
||(GetPRCSwitch(PRC_ACP_NPC_AUTOMATIC) && !GetIsPC(OBJECT_SELF))
||(GetLocalInt(OBJECT_SELF, PRC_ACP_NPC_AUTOMATIC) && !GetIsPC(OBJECT_SELF)))
&& !GetLocalInt(OBJECT_SELF, sLock))
{
int nKensaiScore,
nAssassinScore,
nBarbarianScore,
nFencingScore;
object oOffhand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND);
object oOnhand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
if(GetBaseItemType(oOffhand) != BASE_ITEM_TOWERSHIELD
&& GetBaseItemType(oOffhand) != BASE_ITEM_LARGESHIELD)
{
nKensaiScore += GetLevelByClass(CLASS_TYPE_SAMURAI);
nKensaiScore += GetLevelByClass(CLASS_TYPE_CW_SAMURAI);
nKensaiScore += GetLevelByClass(CLASS_TYPE_MONK);
nKensaiScore += GetLevelByClass(CLASS_TYPE_IAIJUTSU_MASTER);
nKensaiScore += GetLevelByClass(CLASS_TYPE_SHOU);
nAssassinScore += GetLevelByClass(CLASS_TYPE_ASSASSIN);
nAssassinScore += GetLevelByClass(CLASS_TYPE_SHADOWDANCER);
nAssassinScore += GetLevelByClass(CLASS_TYPE_NINJA_SPY);
nAssassinScore += GetLevelByClass(CLASS_TYPE_NIGHTSHADE);
nAssassinScore += GetLevelByClass(CLASS_TYPE_BFZ);
nAssassinScore += GetLevelByClass(CLASS_TYPE_SHADOWLORD);
nFencingScore += GetLevelByClass(CLASS_TYPE_BARD);
nFencingScore += GetLevelByClass(CLASS_TYPE_ARCANE_DUELIST);
nFencingScore += GetLevelByClass(CLASS_TYPE_BLADESINGER);
nFencingScore += GetLevelByClass(CLASS_TYPE_TEMPEST);
if(GetAbilityScore(OBJECT_SELF, ABILITY_DEXTERITY)>20)
nFencingScore += (GetAbilityScore(OBJECT_SELF, ABILITY_DEXTERITY)-10)/2;
}
nBarbarianScore += GetLevelByClass(CLASS_TYPE_BARBARIAN);
nBarbarianScore += GetLevelByClass(CLASS_TYPE_PRC_EYE_OF_GRUUMSH);
nBarbarianScore += GetLevelByClass(CLASS_TYPE_ORC_WARLORD);
nBarbarianScore += GetLevelByClass(CLASS_TYPE_FRE_BERSERKER);
nBarbarianScore += GetLevelByClass(CLASS_TYPE_BATTLERAGER);
nBarbarianScore += GetLevelByClass(CLASS_TYPE_RUNESCARRED);
if(GetAbilityScore(OBJECT_SELF, ABILITY_STRENGTH) > 20)
nBarbarianScore += (GetAbilityScore(OBJECT_SELF, ABILITY_STRENGTH)-10)/2;
int nAutoPhenotype = PHENOTYPE_NORMAL;
int nBestScore;
if(nKensaiScore > nBestScore)
{
nAutoPhenotype = PHENOTYPE_KENSAI;
nBestScore = nKensaiScore;
}
if(nAssassinScore > nBestScore)
{
nAutoPhenotype = PHENOTYPE_ASSASSIN;
nBestScore = nAssassinScore;
}
if(nBarbarianScore > nBestScore)
{
nAutoPhenotype = PHENOTYPE_BARBARIAN;
nBestScore = nBarbarianScore;
}
if(nFencingScore > nBestScore)
{
nAutoPhenotype = PHENOTYPE_FENCING;
nBestScore = nFencingScore;
}
if(GetPhenoType(OBJECT_SELF) != nAutoPhenotype)
{
SetPhenoType(nAutoPhenotype);
LockThisFeat();
}
}
}

View File

@@ -0,0 +1,33 @@
/////////////////////////////////////////////////
// ACP_S3_diffstyle
// Author: Ariel Kaiser
// Creation Date: 13 May 2005
////////////////////////////////////////////////
/*
In combination with the right feat.2da and spells.2da entries, this script
allows a player (or possessed NPC with the right feat, I guess) to change
their fighting style and trade it for different animations. Part of the ACP pack.
*/
#include "inc_acp"
void main()
{
if (GetLocalInt(OBJECT_SELF, sLock)) //Feat is still locked? Bad user!
{
SendMessageToPC(OBJECT_SELF, "You need to wait at least 90 seconds before using this feat again.");
return;
}
int nSpellID = GetSpellId();
if(nSpellID == 2282) // Normal/Reset
ResetFightingStyle();
else if(nSpellID == 2278) // Kensai
SetCustomFightingStyle(PHENOTYPE_KENSAI);
else if(nSpellID == 2279) // Assassin
SetCustomFightingStyle(PHENOTYPE_ASSASSIN);
else if(nSpellID == 2280) // Heavy
SetCustomFightingStyle(PHENOTYPE_BARBARIAN);
else if(nSpellID == 2281) // Fencing
SetCustomFightingStyle(PHENOTYPE_FENCING);
}

View File

@@ -0,0 +1,86 @@
//::///////////////////////////////////////////////
//:: Summon Creature Series
//:: alien_extrasummon.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Carries out the summoning of the appropriate
creature for the Summon Monster Series of spells
1 to 9
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 8, 2002
//:://////////////////////////////////////////////
//:: modified by mr_bumpkin Dec 4, 2003
#include "prc_inc_spells"
int GetMaxSpellLevel(object oCaster)
{
int i = 9;
for(i; i > 0; i--)
{
if(!GetLocalInt(oCaster, "PRC_ArcSpell"+IntToString(i)))
return i;
}
return 1;
}
void main()
{
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
if(!X2PreSpellCastCode()) return;
//Declare major variables
object oCaster = OBJECT_SELF;
int nSwitch = GetPRCSwitch(PRC_SUMMON_ROUND_PER_LEVEL);
float fDuration = nSwitch == 0 ? HoursToSeconds(24) :
RoundsToSeconds(GetLevelByTypeArcaneFeats(oCaster) * nSwitch);
int nMaxSpellLvl = GetMaxSpellLevel(oCaster);
if(GetHasFeat(FEAT_ANIMAL_DOMAIN_POWER, oCaster) && nMaxSpellLvl < 9)
nMaxSpellLvl++;
int nFNF_Effect;
string sSummon;
if(nMaxSpellLvl > 6)
{
string sElem;
switch(GetSpellId())
{
case 2048: sElem = "air"; break;
case 2049: sElem = "earth"; break;
case 2050: sElem = "fire"; break;
case 2051: sElem = "water"; break;
}
switch(nMaxSpellLvl)
{
case 9: sSummon = "pseudo"+sElem+"elder"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3; break;
case 8: sSummon = "pseudo"+sElem+"great"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3; break;
case 7: sSummon = "pseudo"+sElem+"huge"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3; break;
}
}
else
{
switch(nMaxSpellLvl)
{
case 6: sSummon = "pseudodiretiger"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2; break;
case 5: sSummon = "pseudobeardire"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2; break;
case 4: sSummon = "pseudospiddire"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2; break;
case 3: sSummon = "pseudodirewolf"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1; break;
case 2: sSummon = "pseudoboardire"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1; break;
case 1: sSummon = "pseudodirebadg"; nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1; break;
}
}
effect eSummon = EffectSummonCreature(sSummon, nFNF_Effect);
//Apply the VFX impact and summon effect
MultisummonPreSummon();
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, PRCGetSpellTargetLocation(), fDuration);
DelayCommand(0.5, AugmentSummonedCreature(sSummon));
PRCSetSchool();
}

View File

@@ -0,0 +1,108 @@
//:://////////////////////////////////////////////////
//:: X0_CH_HEN_CONV
/*
OnDialogue event handler for henchmen/associates.
*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 01/05/2003
//:://////////////////////////////////////////////////
#include "inc_utility"
#include "x0_inc_henai"
#include "x0_i0_henchman"
//* GeorgZ - Put in a fix for henchmen talking even if they are petrified
int AbleToTalk(object oSelf)
{
if (PRCGetHasEffect(EFFECT_TYPE_CONFUSED, oSelf) || PRCGetHasEffect(EFFECT_TYPE_DOMINATED, oSelf) ||
PRCGetHasEffect(EFFECT_TYPE_PETRIFY, oSelf) || PRCGetHasEffect(EFFECT_TYPE_PARALYZE, oSelf) ||
PRCGetHasEffect(EFFECT_TYPE_STUNNED, oSelf) || PRCGetHasEffect(EFFECT_TYPE_FRIGHTENED, oSelf)
)
{
return FALSE;
}
return TRUE;
}
void main()
{
if (GetIsHenchmanDying() == TRUE)
{
return;
}
object oShouter = GetLastSpeaker();
object oMaster = GetMaster();
object oIntruder;
int nMatch = GetListenPatternNumber();
if (nMatch == -1)
{
// * September 2 2003
// * Added the GetIsCommandable check back in so that
// * Henchman cannot be interrupted when they are walking away
if (GetCommandable(OBJECT_SELF) == TRUE && AbleToTalk(OBJECT_SELF)
&& (GetCurrentAction() != ACTION_OPENLOCK))
{ //SetCommandable(TRUE);
ClearActions(CLEAR_X0_CH_HEN_CONV_26);
string sDialogFileToUse = GetDialogFileToUse(GetLastSpeaker());
BeginConversation(sDialogFileToUse);
}
}
else
{
// listening pattern matched
if (GetIsObjectValid(oMaster))
{
// we have a master, only listen to them
// * Nov 2003 - Added an AbleToTalk, so that henchmen
// * do not respond to orders when 'frozen'
if (GetIsObjectValid(oShouter) && oMaster == oShouter && AbleToTalk(OBJECT_SELF)) {
SetCommandable(TRUE);
bkRespondToHenchmenShout(oShouter, nMatch, oIntruder);
}
}
// we don't have a master, behave in default way
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();
}
}
}
// Actually respond to the shout
RespondToShout(oShouter, nMatch, oIntruder);
}
}
// Signal user-defined event
if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT)) {
SignalEvent(OBJECT_SELF, EventUserDefined(EVENT_DIALOGUE));
}
}

View File

@@ -0,0 +1,25 @@
#include "x0_i0_henchman"
void main()
{
object oAnimate = OBJECT_SELF;
object oItem = GetItemInSlot(INVENTORY_SLOT_CHEST);
if (GetIsObjectValid(oItem))
{
CopyObject(oItem, GetLocation(oAnimate));
AssignCommand(GetModule(),DestroyObject(oItem,0.9));
AssignCommand(GetModule(),DestroyObject(oAnimate,1.0));
// ActionUnequipItem(oItem);
// ActionPutDownItem(oItem);
}
else
{
oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
if (GetIsObjectValid(oItem))
{
CopyObject(oItem, GetLocation(oAnimate));
AssignCommand(GetModule(),DestroyObject(oItem,0.9));
AssignCommand(GetModule(),DestroyObject(oAnimate,1.0));
}
}
}

View File

@@ -0,0 +1,25 @@
//:://////////////////////////////////////////////////
//:: animobj_hb.nss
/*
OnHeartbeat event handler for animated objects.
*/
//:://////////////////////////////////////////////////
#include "X0_INC_HENAI"
void main()
{
object oSelf = OBJECT_SELF;
//animated objects stop animating after casterlvl rounds
int iRoundsToGo = GetLocalInt(oSelf, "Rounds");
if(iRoundsToGo <= 0 || !GetIsObjectValid(GetMaster()))
{
ExecuteScript("animobj_killself", oSelf);
return;
}
SetLocalInt(oSelf, "Rounds", iRoundsToGo - 1);
// Schedule next HeartBeat
DelayCommand(6.0f, ExecuteScript("animobj_hb", oSelf));
}

View File

@@ -0,0 +1,5 @@
void main()
{
effect eKill = EffectDamage(9999, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_TWENTY);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eKill, OBJECT_SELF);
}

View File

@@ -0,0 +1,64 @@
//:://////////////////////////////////////////////////
//:: X0_CH_HEN_SPAWN
//:: Copyright (c) 2002 Floodgate Entertainment
//:://////////////////////////////////////////////////
/*
Henchman-specific OnSpawn handler for XP1. Based on NW_CH_AC9 by Bioware.
*/
//:://////////////////////////////////////////////////
//:: Created By: Naomi Novik
//:: Created On: 10/09/2002
//:://////////////////////////////////////////////////
#include "x0_inc_henai"
#include "x2_inc_banter"
#include "x2_inc_globals"
void main()
{
string sAreaTag = GetTag(GetArea(OBJECT_SELF));
string sModuleTag = GetTag(GetModule());
string sMyTag = GetTag(OBJECT_SELF);
//Sets up the special henchmen listening patterns
SetAssociateListenPatterns();
// Set additional henchman listening patterns
bkSetListeningPatterns();
// Default behavior for henchmen at start
SetAssociateState(NW_ASC_POWER_CASTING);
SetAssociateState(NW_ASC_HEAL_AT_50);
SetAssociateState(NW_ASC_RETRY_OPEN_LOCKS);
SetAssociateState(NW_ASC_DISARM_TRAPS);
// * July 2003. Set this to true so henchmen
// * will hopefully run off a little less often
// * by default
// * September 2003. Bad decision. Reverted back
// * to original. This mode too often looks like a bug
// * because they hang back and don't help each other out.
//SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, TRUE);
SetAssociateState(NW_ASC_DISTANCE_2_METERS);
//Use melee weapons by default
SetAssociateState(NW_ASC_USE_RANGED_WEAPON, FALSE);
// Set starting location
SetAssociateStartLocation();
// Set respawn location
SetRespawnLocation();
// For some general behavior while we don't have a master,
// let's do some immobile animations
SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
// * not allowed to have inventory fiddled with
SetLocalInt(OBJECT_SELF, "X2_JUST_A_DISABLEEQUIP", 1);
}

View File

@@ -0,0 +1,76 @@
#include "x2_inc_spellhook"
#include "prc_inc_sp_tch"
/*
* This is the spellhook code, called when the Arcane Fire feat is activated
* Turns the spell into an arcane fire
*/
void main()
{
//Declare major variables ( fDist / (3.0f * log( fDist ) + 2.0f) )
object oTarget = GetLocalObject(OBJECT_SELF, "arcane_fire_target");
int nCasterLvl = GetLevelByClass(CLASS_TYPE_ARCHMAGE, OBJECT_SELF);
int nDamage = 0;
int nMetaMagic = PRCGetMetaMagicFeat();
int nCnt;
effect eMissile = EffectVisualEffect(VFX_IMP_MIRV);
effect eVis = EffectVisualEffect(VFX_IMP_MAGBLUE);
float fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
float fDelay = fDist/(3.0 * log(fDist) + 2.0);
float fDelay2, fTime;
string nSpellLevel = lookup_spell_level(PRCGetSpellId());
/* Whatever happens next we must restore the hook */
PRCSetUserSpecificSpellScript(GetLocalString(OBJECT_SELF, "archmage_save_overridespellscript"));
/* Tell to not execute the original spell */
PRCSetUserSpecificSpellScriptFinished();
/* Allow to use it once again */
SetLocalInt(OBJECT_SELF, "arcane_fire_active", 0);
/* Paranoia -- should never happen */
if (!GetHasFeat(FEAT_ARCANE_FIRE, OBJECT_SELF)) return;
/* Only wizard/sorc spells */
if (nSpellLevel == "")
{
FloatingTextStringOnCreature("Arcane Fire can only consume arcane spells.", OBJECT_SELF, FALSE);
return;
}
/* No item casting */
if (GetIsObjectValid(GetSpellCastItem()))
{
FloatingTextStringOnCreature("Arcane Fire may not be used with scrolls.", OBJECT_SELF, FALSE);
return;
}
if(!GetIsReactionTypeFriendly(oTarget))
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_MAGIC_MISSILE));
//Make ranged touch attack check
if (PRCDoRangedTouchAttack(oTarget))
{
//Roll damage
int nDam = d6(nCasterLvl + StringToInt(nSpellLevel));
fTime = fDelay;
fDelay2 += 0.1;
fTime += fDelay2;
//Set damage effect
effect eDam = EffectDamage(nDam, DAMAGE_TYPE_MAGICAL);
//Apply the MIRV and damage effect
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oTarget));
DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget));
}
else
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, eMissile, oTarget);
}
}
}

View File

@@ -0,0 +1,46 @@
#include "prc_alterations"
#include "x2_inc_spellhook"
/*
* This is the spellhook code, called when the Spell-Like feat is activated
*/
void main()
{
object focus = GetItemPossessedBy(OBJECT_SELF, "ArchmagesFocusofPower");
int nMetaMagic = PRCGetMetaMagicFeat();
string nSpellLevel = Get2DACache("spells", "Wiz_Sorc", PRCGetSpellId());
string nEpicSpell = Get2DACache("spells", "Innate", PRCGetSpellId());
/* Whatever happens next we must restore the hook */
PRCSetUserSpecificSpellScript(GetLocalString(OBJECT_SELF, "spelllike_save_overridespellscript"));
/* Tell to not execute the original spell */
PRCSetUserSpecificSpellScriptFinished();
/* Paranoia -- should never happen */
if (!GetHasFeat(FEAT_SPELL_LIKE, OBJECT_SELF)) return;
/* Only wizard/sorc spells */
if ((nSpellLevel == "") && (nEpicSpell != "10" ))
{
FloatingTextStringOnCreature("Spell-Like can only use arcane spells.", OBJECT_SELF, FALSE);
return;
}
/* No item casting */
if (GetIsObjectValid(GetSpellCastItem()))
{
FloatingTextStringOnCreature("Spell-Like may not be used with scrolls.", OBJECT_SELF, FALSE);
return;
}
/* Setup is done */
SetLocalInt(focus, "spell_like_setup", 0);
/* Store all the info needed */
SetLocalInt(focus, "spell_like_spell", PRCGetSpellId());
SetLocalInt(focus, "spell_like_meta", nMetaMagic);
SetLocalInt(focus, "spell_like_present", TRUE);
FloatingTextStringOnCreature("Spell-Like ability ready.", OBJECT_SELF, FALSE);
}

View File

@@ -0,0 +1,32 @@
#include "prc_alterations"
void main()
{
object oTarget = OBJECT_SELF;
if(GetHasFeatEffect(FEAT_SONG_OF_FURY, oTarget))
{
PRCRemoveSpellEffects(SPELL_SONG_OF_FURY, oTarget, oTarget);
return;
}
// Light armor only?
//if(GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget)) > 3)
// return;
// nothing in left hand
if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget)))
return;
// only rapier or longsword in right hand
int nWeapType = GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget));
if(nWeapType != BASE_ITEM_RAPIER
&& nWeapType != BASE_ITEM_LONGSWORD
&& nWeapType != BASE_ITEM_ELVEN_THINBLADE)
return;
effect eLink = EffectLinkEffects(EffectAttackDecrease(2), EffectModifyAttacks(1));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_BARD_SONG));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(eLink), oTarget);
}

View File

@@ -0,0 +1,65 @@
//::///////////////////////////////////////////////
//:: Fire Shield
//:: NW_S0_FireShld.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Fire Shield for the Disciple of Mephistopheles
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 7, 2002
//:://////////////////////////////////////////////
//:: Created On: Aug 28, 2003, GZ: Fixed stacking issue
//Fixed several compile time errors.
//Aaon Graywolf - Jan 8, 2004
#include "prc_class_const"
#include "x2_inc_spellhook"
#include "prc_alterations"
void main()
{
/*
Spellcast Hook Code
Added 2003-06-23 by GeorgZ
If you want to make changes to all spells,
check x2_inc_spellhook.nss to find out more
*/
if (!X2PreSpellCastCode())
{
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
return;
}
// End of Spell Cast Hook
//Declare major variables
int nDuration = 600;
int nMetaMagic = PRCGetMetaMagicFeat();
object oTarget = OBJECT_SELF;
object oArmour = GetItemInSlot(INVENTORY_SLOT_CHEST, OBJECT_SELF);
effect eVis = EffectVisualEffect(VFX_DUR_INFERNO_CHEST);
effect eDur = EffectVisualEffect(VFX_DUR_INFERNO_CHEST);
effect eDR = EffectDamageResistance(10, DAMAGE_POWER_PLUS_ONE, 0);
effect eFire = EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, 100);
itemproperty eShield = ItemPropertyOnHitCastSpell( IP_CONST_ONHIT_CASTSPELL_COMBUST, 15);
//Link effects
effect eLink = EffectLinkEffects(eDR, eFire);
eLink = EffectLinkEffects(eLink, eDur);
eLink = EffectLinkEffects(eLink, eVis);
//Enter Metamagic conditions
if (nMetaMagic == METAMAGIC_EXTEND)
{
nDuration = nDuration *2; //Duration is +100%
}
//Apply the VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration));
AddItemProperty(DURATION_TYPE_TEMPORARY, eShield, oArmour, RoundsToSeconds(nDuration));
}

View File

@@ -0,0 +1,301 @@
//::///////////////////////////////////////////////
//:: Summon Familiar
//:: NW_S2_Familiar
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This spell summons an Arcane casters familiar
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 27, 2001
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "inc_npc"
#include "prc_feat_const"
#include "prc_ipfeat_const"
#include "prc_class_const"
const int PACKAGE_ELEMENTAL_STR = PACKAGE_ELEMENTAL ;
const int PACKAGE_ELEMENTAL_DEX = PACKAGE_FEY ;
void ElementalFamiliar()
{
// add
location loc = GetLocation(OBJECT_SELF);
vector vloc = GetPositionFromLocation( loc );
vector vLoc;
location locSummon;
vLoc = Vector( vloc.x + (Random(6) - 2.5f),
vloc.y + (Random(6) - 2.5f),
vloc.z );
locSummon = Location( GetArea(OBJECT_SELF), vLoc, IntToFloat(Random(361) - 180) );
//
object oPC = OBJECT_SELF;
string iType = GetHasFeat(FEAT_BONDED_AIR, OBJECT_SELF) ? "AIR" : "" ;
iType = GetHasFeat(FEAT_BONDED_EARTH, OBJECT_SELF) ? "EARTH" : iType ;
iType = GetHasFeat(FEAT_BONDED_FIRE, OBJECT_SELF) ? "FIRE" : iType ;
iType = GetHasFeat(FEAT_BONDED_WATER, OBJECT_SELF) ? "WATER" : iType ;
string iSize = GetHasFeat(FEAT_ELE_COMPANION_MED, OBJECT_SELF) ? "MED" : "" ;
iSize = GetHasFeat(FEAT_ELE_COMPANION_LAR, OBJECT_SELF) ? "LAR" : iSize ;
iSize = GetHasFeat(FEAT_ELE_COMPANION_HUG, OBJECT_SELF) ? "HUG" : iSize ;
iSize = GetHasFeat(FEAT_ELE_COMPANION_GRE, OBJECT_SELF) ? "GRE" : iSize ;
iSize = GetHasFeat(FEAT_ELE_COMPANION_ELD, OBJECT_SELF) ? "ELD" : iSize ;
string sRef = "HEN_"+iType+"_"+iSize+"2";
object oEle = CreateLocalNPC(OBJECT_SELF,ASSOCIATE_TYPE_FAMILIAR,sRef,locSummon,1);
effect eDomi = SupernaturalEffect(EffectCutsceneDominated());
DelayCommand(0.1f, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDomi, oEle));
SetLocalObject(OBJECT_SELF, "BONDED",oEle);
object oCreB=GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oEle);
object oCreL=GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oEle);
object oCreR=GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oEle);
object oHide=GetItemInSlot(INVENTORY_SLOT_CARMOUR,oEle);
int iPack ,iSave ;
int iHD = GetHitDice(OBJECT_SELF);
int iBonus = (iHD/5)+1;
if (iType=="FIRE")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageImmunity(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEIMMUNITY_100_PERCENT),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageVulnerability(IP_CONST_DAMAGETYPE_COLD,IP_CONST_DAMAGEVULNERABILITY_50_PERCENT),oHide);
iPack = PACKAGE_ELEMENTAL_DEX ;
iSave = IP_CONST_SAVEBASETYPE_REFLEX ;
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_DEX,iBonus),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_STR,iBonus*2/3),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_CON,iBonus*2/3),oHide);
if (iSize=="MED")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_1d6),oCreB);
}
else if (iSize=="LAR")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d6),oCreL);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d6),oCreR);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="HUG")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d8),oCreL);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d8),oCreR);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="GRE")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d8),oCreL);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d8),oCreR);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
else if (iSize=="ELD")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,2),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d8),oCreL);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_2d8),oCreR);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
}
else if (iType=="WATER")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_STR,iBonus*2/3+1),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_DEX,iBonus*2/3),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_CON,iBonus*2/3),oHide);
iPack = PACKAGE_ELEMENTAL_STR ;
iSave = IP_CONST_SAVEBASETYPE_FORTITUDE ;
if (iSize=="MED")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
}
else if (iSize=="LAR")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="HUG")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="GRE")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
else if (iSize=="ELD")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
}
else if (iType=="AIR")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_DEX,iBonus),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_STR,iBonus*2/3),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_CON,iBonus*2/3),oHide);
iPack = PACKAGE_ELEMENTAL_DEX ;
iSave = IP_CONST_SAVEBASETYPE_REFLEX ;
if (iSize=="MED")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
}
else if (iSize=="LAR")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="HUG")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,5),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="GRE")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
else if (iSize=="ELD")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
}
else if (iType=="EARTH")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_STR,iBonus),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_CON,iBonus*2/3),oHide);
iPack = PACKAGE_ELEMENTAL_STR ;
iSave = IP_CONST_SAVEBASETYPE_FORTITUDE ;
if (iSize=="MED")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
}
else if (iSize=="LAR")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="HUG")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_5_HP),oHide);
}
else if (iSize=="GRE")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,3),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
else if (iSize=="ELD")
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyReducedSavingThrow(IP_CONST_SAVEBASETYPE_WILL,4),oHide);
// AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,IP_CONST_DAMAGESOAK_10_HP),oHide);
}
}
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oHide);
int Arcanlvl = GetPrCAdjustedCasterLevelByType(TYPE_ARCANE) + GetLevelByClass(CLASS_TYPE_BONDED_SUMMONNER)/2;
if (Arcanlvl>26)
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_WeapEpicSpecCreature),oHide);
if (Arcanlvl>21)
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_WeapEpicFocCreature),oHide);
if (Arcanlvl>11)
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_WeapSpecCreature),oHide);
ApplyEffectToObject(DURATION_TYPE_INSTANT,SupernaturalEffect(EffectSpellResistanceIncrease(Arcanlvl+5)),oEle);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_BarbEndurance),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_ImpCritCreature),oHide);
}
else if (Arcanlvl>8)
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusFeat(IP_CONST_FEAT_ImpCritCreature),oHide);
ApplyEffectToObject(DURATION_TYPE_INSTANT,SupernaturalEffect(EffectSpellResistanceIncrease(Arcanlvl+5)),oEle);
}
int i;
for (i = 1; i < iHD; i++)
LevelUpHenchman( oEle,CLASS_TYPE_ELEMENTAL,TRUE,iPack);
object oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oEle);
if (!GetIsObjectValid(oCweap))
oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oEle);
if (!GetIsObjectValid(oCweap))
oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oEle);
int iSoak =-1;
if (iSize=="LAR" || iSize=="HUG")
iSoak = IP_CONST_DAMAGESOAK_5_HP;
else if (iSize=="GRE" || iSize=="ELD")
iSoak = IP_CONST_DAMAGESOAK_10_HP;
if (iHD>24) iSoak++;
if (iHD>30) iSoak++;
if (iSoak>=0)
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamageReduction(IP_CONST_DAMAGEREDUCTION_20,iSoak),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyACBonus(iBonus),GetItemInSlot(INVENTORY_SLOT_NECK,oEle));
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyACBonus(iBonus),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_WIS,iBonus),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(IP_CONST_ABILITY_WIS,iBonus),oHide);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyBonusSavingThrow(iSave,iBonus),oHide);
// AddHenchman(OBJECT_SELF,oEle);
}
void main()
{
if (GetLevelByClass(CLASS_TYPE_BONDED_SUMMONNER))
{
object oDes = GetLocalObject(OBJECT_SELF, "BONDED");
AssignCommand(oDes, SetIsDestroyable(TRUE));
DestroyObject(oDes);
DelayCommand(0.4,ElementalFamiliar());
return;
}
}

View File

@@ -0,0 +1,29 @@
#include "pnp_shft_poly"
void main()
{
object oPC = OBJECT_SELF;
int iPoly = GetHasFeat(FEAT_BONDED_AIR) ? POLYMORPH_TYPE_ELDER_AIR_ELEMENTAL:
GetHasFeat(FEAT_BONDED_EARTH) ? POLYMORPH_TYPE_ELDER_EARTH_ELEMENTAL:
GetHasFeat(FEAT_BONDED_FIRE) ? POLYMORPH_TYPE_ELDER_FIRE_ELEMENTAL:
POLYMORPH_TYPE_ELDER_WATER_ELEMENTAL;//if(GetHasFeat(FEAT_BONDED_WATER))
// abort if mounted
if(!GetLocalInt(GetModule(), "X3_NO_SHAPESHIFT_SPELL_CHECK"))
{ // check to see if abort due to being mounted
if(PRCHorseGetIsMounted(oPC))
{ // abort
if(GetIsPC(oPC))
FloatingTextStrRefOnCreature(111982, oPC, FALSE);
return;
}
}
//this command will make shore that polymorph plays nice with the shifter
ShifterCheck(oPC);
ClearAllActions(); // prevents an exploit
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectPolymorph(iPoly), oPC, HoursToSeconds(10));
DelayCommand(1.5, ActionCastSpellOnSelf(SPELL_SHAPE_INCREASE_DAMAGE));
}

View File

@@ -0,0 +1,19 @@
#!/bin/sh
twodas=`ls ../2das/*.2da | grep -v CVS | tr '\n' ' '`
gfxs=`ls -d ../gfx/* | grep -v CVS | tr '\n' ' '`
others=`ls -d ../others/* | grep -v CVS | tr '\n' ' '`
scripts=`ls *.nss | tr '\n' ' '`
# Take out the include files
#scripts=""
#for i in $tmp_scripts ; do
# tst=`grep -w main "$i"`
# if test "$tst" ; then
# scripts="$scripts$i "
# fi
#done
sed "s#~~~scripts~~~#$scripts#g" Makefile | sed "s#~~~2das~~~#$twodas#g" | sed "s#~~~others~~~#$others#g" | sed "s#~~~gfxs~~~#$gfxs#g" > Makefile.temp
make -f Makefile.temp $*
rm -f Makefile.temp

View File

@@ -0,0 +1,83 @@
//::///////////////////////////////////////////////
//:: Thousand Faces
//:: no_sw_thouface
//:://////////////////////////////////////////////
/*
Allows the Ninjamastah to appear as various
NPCs of PC playable races.
*/
//:://////////////////////////////////////////////
//:: Created By: Tim Czvetics (NamelessOne)
//:: Created On: Dec 17, 2003
//:://////////////////////////////////////////////
//taken from
//::///////////////////////////////////////////////
//:: Name Rak disguise
//:: FileName race_rkdisguise
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Shane Hennessy
//:: Created On:
//:://////////////////////////////////////////////
#include "pnp_shft_poly"
void main()
{
int iSpell = GetSpellId();
StoreAppearance(OBJECT_SELF);
int nCurForm = GetAppearanceType(OBJECT_SELF);
int nPCForm = GetTrueForm(OBJECT_SELF);
effect eFx = EffectVisualEffect(VFX_IMP_MAGICAL_VISION);
// Switch to lich
if (nPCForm == nCurForm)
{
//Determine subradial selection
if(iSpell == SPELLABILITY_NS_DWARF) //DWARF
{
DoDisguise(RACIAL_TYPE_DWARF);
}
else if (iSpell == SPELLABILITY_NS_ELF) //ELF
{
DoDisguise(RACIAL_TYPE_ELF);
}
else if (iSpell == SPELLABILITY_NS_HALF_ELF) //HALF_ELF
{
DoDisguise(RACIAL_TYPE_HALFELF);
}
else if (iSpell == SPELLABILITY_NS_HALF_ORC) //HALF_ORC
{
DoDisguise(RACIAL_TYPE_HALFORC);
}
else if (iSpell == SPELLABILITY_NS_HUMAN) //HUMAN
{
DoDisguise(RACIAL_TYPE_HUMAN);
}
else if (iSpell == SPELLABILITY_NS_GNOME) //GNOME
{
DoDisguise(RACIAL_TYPE_GNOME);
}
else if (iSpell == SPELLABILITY_NS_HALFLING) //HALFLING
{
DoDisguise(RACIAL_TYPE_HALFLING);
}
else if (iSpell == SPELLABILITY_NS_OFF) //RETURN TO ORIGINAL APPEARANCE
{
//re-use unshifter code from shifter instead
//this will also remove complexities with lich/shifter characters
SetShiftTrueForm(OBJECT_SELF);
//SetCreatureAppearanceType(OBJECT_SELF,nPCForm);
}
}
else // Switch to PC
{
//re-use unshifter code from shifter instead
//this will also remove complexities with lich/shifter characters
SetShiftTrueForm(OBJECT_SELF);
//SetCreatureAppearanceType(OBJECT_SELF,nPCForm);
}
//Apply the vfx
ApplyEffectToObject(DURATION_TYPE_INSTANT,eFx,OBJECT_SELF);
}

View File

@@ -0,0 +1,15 @@
//::///////////////////////////////////////////////
//:: Warpriest
//:: MassHaste
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_WARPRIEST);
int nDC = GetLevelByClass(CLASS_TYPE_WARPRIEST) + GetAbilityModifier(ABILITY_CHARISMA) + 10;
DoRacialSLA(SPELL_MASS_HASTE, nLevel, nDC);
}

View File

@@ -0,0 +1,15 @@
//::///////////////////////////////////////////////
//:: Warpriest
//:: MassHeal
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_inc_spells"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_WARPRIEST);
int nDC = GetLevelByClass(CLASS_TYPE_WARPRIEST) + GetAbilityModifier(ABILITY_CHARISMA) + 10;
DoRacialSLA(SPELL_MASS_HEAL, nLevel, nDC);
}

View File

@@ -0,0 +1,35 @@
#include "prc_alterations"
void main()
{
object oItem = GetInventoryDisturbItem();
object oPC = GetLastDisturbed();
if(GetPlotFlag(oItem))
{
FloatingTextStringOnCreature("You cannot sacrifice plot items.", oPC, FALSE);
ActionGiveItem(oItem, oPC);
return;
}
if(!GetIdentified(oItem) && !GetPRCSwitch(PRC_SAMURAI_ALLOW_UNIDENTIFIED_SACRIFICE))
{
FloatingTextStringOnCreature("You cannot sacrifice unidentified items.", oPC, FALSE);
ActionGiveItem(oItem, oPC);
return;
}
if(GetStolenFlag(oItem) && !GetPRCSwitch(PRC_SAMURAI_ALLOW_STOLEN_SACRIFICE))
{
FloatingTextStringOnCreature("You cannot sacrifice stolen items.", oPC, FALSE);
ActionGiveItem(oItem, oPC);
return;
}
SetIdentified(oItem, TRUE);
int iValue = GetGoldPieceValue(oItem);
if(GetPRCSwitch(PRC_SAMURAI_SACRIFICE_SCALAR_x100))
iValue *= FloatToInt(IntToFloat(iValue)*(IntToFloat(GetPRCSwitch(PRC_SAMURAI_SACRIFICE_SCALAR_x100))/100.0));
DestroyObject(oItem);
if (iValue > 0)
{
int iCurrentValue = GetPersistantLocalInt(oPC, "CODI_SAMURAI");
SetPersistantLocalInt(oPC, "CODI_SAMURAI", iCurrentValue + iValue);
FloatingTextStringOnCreature("Your sacrifice is accepted. You now have " + IntToString(iCurrentValue + iValue) + " gold in sacrifices.", oPC);
}
}

View File

@@ -0,0 +1,10 @@
void main()
{
object oExit = GetExitingObject();
if(GetLocalObject(oExit, "CODI_LAST_ALTAR") != OBJECT_INVALID)
{
DestroyObject(GetLocalObject(oExit, "LAST_ALTAR"));
DeleteLocalObject(oExit,"CODI_LAST_ALTAR");
}
}

View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: codi_pre_chmon
//:://////////////////////////////////////////////
/*
Ocular Adept: Charm Monster
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_CHARM_MONSTER, nLevel, nDC);
}

View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: codi_pre_chper
//:://////////////////////////////////////////////
/*
Ocular Adept - Charm Person
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-29
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_CHARM_PERSON, nLevel, nDC);
}

View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: codi_pre_death
//:://////////////////////////////////////////////
/*
Ocular Adept: Finger of Death
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_FINGER_OF_DEATH, nLevel, nDC);
}

View File

@@ -0,0 +1,23 @@
//::///////////////////////////////////////////////
//:: codi_pre_dis
//:://////////////////////////////////////////////
/*
Ocular Adept: Disintegrate
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:: Modified By: Ornedan
//:: Modified On: 30.03.2005
//:: Modfication: Changed to work as the spell Disintegrate
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_DISINTEGRATE, nLevel, nDC);
}

View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: codi_pre_fear
//:://////////////////////////////////////////////
/*
Ocular Adept: Fear
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_FEAR, nLevel, nDC);
}

View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: codi_pre_flst
//:://////////////////////////////////////////////
/*
Ocular Adept: Flesh to Stone
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_FLESH_TO_STONE, nLevel, nDC);
}

View File

@@ -0,0 +1,22 @@
//::///////////////////////////////////////////////
//:: codi_pre_infw
//:://////////////////////////////////////////////
/*
Ocular Adept - Inflict Moderate Wounds
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_INFLICT_MODERATE_WOUNDS, nLevel, nDC);
}

View File

@@ -0,0 +1,23 @@
//::///////////////////////////////////////////////
//:: codi_pre_sleep
//:://////////////////////////////////////////////
/*
Ocular Adept - Sleep
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_SLEEP, nLevel, nDC);
}

View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: codi_pre_slow
//:://////////////////////////////////////////////
/*
Ocular Adept - Slow
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_OCULAR);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept class level is: " + IntToString(nLevel), OBJECT_SELF);
int nDC = 10 + (nLevel/2) + GetAbilityModifier(ABILITY_CHARISMA);
if (DEBUG) FloatingTextStringOnCreature("Your Ocular Adept DC is: " + IntToString(nDC), OBJECT_SELF);
DoSpellRay(SPELL_SLOW, nLevel, nDC);
}

View File

@@ -0,0 +1,200 @@
//::///////////////////////////////////////////////
//:: codi_pre_tele
//:://////////////////////////////////////////////
/*
Ocular Adept: Telekinesis
*/
//:://////////////////////////////////////////////
//:: Created By: James Stoneburner
//:: Created On: 2003-11-30
//:://////////////////////////////////////////////
#include "prc_inc_sp_tch"
void MoveTarget(object oTarget, vector vAwayFrom, float fDistance);
void main()
{
//SendMessageToPC(OBJECT_SELF, "Telekinesis script online");
int nOcLvl = GetLevelByClass(CLASS_TYPE_OCULAR, OBJECT_SELF);
int nChaMod = GetAbilityModifier(ABILITY_CHARISMA, OBJECT_SELF);
int nOcSv = 10 + (nOcLvl/2) + nChaMod;
object oCaster = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
if(oCaster == oTarget)
{
// Cast on Self
location lSelf = GetLocation(OBJECT_SELF);
float fDist;
effect eKnockdown = EffectKnockdown();
int iWillsave;
vector vPosition = GetPosition(OBJECT_SELF);
object oTarget2 = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, lSelf, FALSE);
while(oTarget2 != OBJECT_INVALID)
{
if(oTarget2 != OBJECT_SELF && GetIsEnemy(oTarget, OBJECT_SELF))
{
fDist = 6.0 - IntToFloat(GetCreatureSize(oTarget2));
iWillsave = WillSave(oTarget, nOcSv);
if(iWillsave == 0)
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnockdown, oTarget2, 6.0);
}
DelayCommand(0.1, MoveTarget(oTarget2, vPosition, fDist));
}
oTarget2 = GetNextObjectInShape(SHAPE_SPHERE, 5.0, lSelf, FALSE);
}
}
else if (oTarget == OBJECT_INVALID)
{
// Cast on Ground
}
else if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
int bHit = PRCDoRangedTouchAttack(oTarget);;
if(bHit) {
location lSelf = GetLocation(OBJECT_SELF);
float fDist;
float fDelay = 0.2;
effect eKnockdown = EffectKnockdown();
int iFortsave;
vector vPosition = GetPosition(OBJECT_SELF);
fDist = 9.0 - (IntToFloat(GetCreatureSize(oTarget)) * 1.5);
AssignCommand(oTarget, ClearAllActions());
if(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget) != OBJECT_INVALID)
{
iFortsave = WillSave(oTarget, nOcSv);
if(iFortsave == 0)
{
object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
if (GetDroppableFlag(oItem) && !GetPlotFlag(oItem))
{
object oNew = CopyObject(oItem, GetLocation(oTarget));
DestroyObject(oItem);
}
//DelayCommand(fDelay, AssignCommand(oTarget, ActionPutDownItem(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget))));
//fDelay = fDelay + 0.3;
}
}
if(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget) != OBJECT_INVALID)
{
iFortsave = WillSave(oTarget, nOcSv);
if(iFortsave == 0)
{
object oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
if (GetDroppableFlag(oItem) && !GetPlotFlag(oItem))
{
object oNew = CopyObject(oItem, GetLocation(oTarget));
DestroyObject(oItem);
}
//DelayCommand(fDelay, AssignCommand(oTarget, ActionPutDownItem(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget))));
//fDelay = fDelay + 0.3;
}
}
DelayCommand(fDelay, MoveTarget(oTarget, vPosition, fDist));
fDelay = fDelay + fDist/2.0;
iFortsave = WillSave(oTarget, nOcSv);
if(iFortsave == 0)
{
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnockdown, oTarget, 6.0));
}
} else {
if(GetIsPC(OBJECT_SELF)) {
SendMessageToPC(OBJECT_SELF, "The ray missed.");
}
}
}
else if (GetObjectType(oTarget) == OBJECT_TYPE_DOOR)
{
if (GetLocked(oTarget) && !GetLockKeyRequired(oTarget))
{
int iDC = GetLockUnlockDC(oTarget);
if(d20(1) + GetClassByPosition(CLASS_TYPE_OCULAR) >= iDC)
{
SetLocked(oTarget, FALSE);
AssignCommand(oTarget, SpeakString("**Click**"));
}
else
{
SendMessageToPC(oCaster, "You fail to effect that object.");
}
}
else if (GetLocked(oTarget) && GetLockKeyRequired(oTarget))
{
AssignCommand(oCaster, SpeakString("This lock is beyond my ability to open, I'll need the key.",TALKVOLUME_WHISPER));
}
else if (!GetLocked(oTarget))
{
AssignCommand(oTarget, ActionOpenDoor(oTarget));
}
}
else if(GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
{
if (GetLocked(oTarget) && GetLockKeyRequired(oTarget))
{
int iDC = GetLockUnlockDC(oTarget);
if(d20(1) + GetClassByPosition(CLASS_TYPE_OCULAR) >= iDC)
{
SetLocked(oTarget, FALSE);
AssignCommand(oTarget, SpeakString("**Click**"));
}
else
{
SendMessageToPC(oCaster, "You fail to effect that object.");
}
}
else if (GetLocked(oTarget) && GetLockKeyRequired(oTarget))
{
AssignCommand(oCaster, SpeakString("This lock is beyond my ability to open, I'll need the key.",TALKVOLUME_WHISPER));
}
else if (!GetLocked(oTarget))
{
//location lLoc = GetLocation(oTarget);
//CreateObject(OBJECT_TYPE_CREATURE, "anunseenforce", lLoc, FALSE, "FORCE");
AssignCommand(oTarget, PlayAnimation(ANIMATION_PLACEABLE_OPEN));
}
}
else if (GetObjectType(oTarget) == OBJECT_TYPE_ITEM)
{
// Cast on Item
}
}
void MoveTarget(object oTarget, vector vAwayFrom, float fDistance)
{
vector vStart = GetPosition(oTarget);
int X = (vStart.x > vAwayFrom.x);
int Y = (vStart.y > vAwayFrom.y);
int i = 0;
vector vNew;
location lNew;
float fDelay = 0.1;
for(i=1;i<=FloatToInt(fDistance);i++)
{
if (X && Y)
{
vNew = Vector(vStart.x + IntToFloat(i), vStart.y + IntToFloat(i), 0.0);
}
else if (X && !Y)
{
vNew = Vector(vStart.x + IntToFloat(i), vStart.y - IntToFloat(i), 0.0);
}
else if (!X && Y)
{
vNew = Vector(vStart.x - IntToFloat(i), vStart.y + IntToFloat(i), 0.0);
}
else if (!X && !Y)
{
vNew = Vector(vStart.x - IntToFloat(i), vStart.y - IntToFloat(i), 0.0);
}
lNew = Location(GetArea(oTarget), vNew, GetFacing(oTarget));
DelayCommand(fDelay, AssignCommand(oTarget, JumpToLocation(lNew)));
fDelay = fDelay + 0.5;
}
}

View File

@@ -0,0 +1,15 @@
//::///////////////////////////////////////////////
//:: Warpriest
//:: HealingCircle
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_newspellbook"
void main()
{
int nLevel = GetLevelByClass(CLASS_TYPE_WARPRIEST);
int nDC = GetLevelByClass(CLASS_TYPE_WARPRIEST) + GetAbilityModifier(ABILITY_CHARISMA) + 10;
DoRacialSLA(SPELL_HEALING_CIRCLE, nLevel, nDC);
}

View File

@@ -0,0 +1,19 @@
/*
Implicable Foe - On Enter
*/
void main()
{
object oCreator = GetAreaOfEffectCreator(OBJECT_SELF);
object oEnter = GetEnteringObject();
if(GetIsFriend(oEnter, oCreator))
{
if(oEnter != oCreator)
{
if(!GetImmortal(oEnter))
{
SetImmortal(oEnter, TRUE);
SetLocalInt(oEnter, "IMPLICABLE_FOE_ON", TRUE);
}
}
}
}

View File

@@ -0,0 +1,83 @@
/*
Implicable Foe - Heartbeat
*/
#include "prc_alterations"
int GetIsDisabled(object oCreature);
void main()
{
object oCreator = GetAreaOfEffectCreator();
switch(GetCurrentAction(oCreator))
{
case ACTION_ANIMALEMPATHY:
case ACTION_ATTACKOBJECT:
case ACTION_CASTSPELL:
case ACTION_CLOSEDOOR:
case ACTION_COUNTERSPELL:
case ACTION_DIALOGOBJECT:
case ACTION_DISABLETRAP:
case ACTION_DROPITEM:
case ACTION_EXAMINETRAP:
case ACTION_FLAGTRAP:
case ACTION_FOLLOW:
case ACTION_HEAL:
case ACTION_ITEMCASTSPELL:
case ACTION_KIDAMAGE:
case ACTION_LOCK:
case ACTION_MOVETOPOINT:
case ACTION_OPENDOOR:
case ACTION_OPENLOCK:
case ACTION_PICKPOCKET:
case ACTION_PICKUPITEM:
case ACTION_RANDOMWALK:
case ACTION_RECOVERTRAP:
case ACTION_REST:
case ACTION_SETTRAP:
case ACTION_SIT:
case ACTION_SMITEGOOD:
case ACTION_TAUNT:
case ACTION_USEOBJECT:
FloatingTextStringOnCreature("Your concentration is broken.", oCreator, FALSE);
DestroyObject(OBJECT_SELF);
break;
}
if(GetIsDisabled(oCreator))
{
FloatingTextStringOnCreature("Your concentration is broken.", oCreator, FALSE);
DestroyObject(OBJECT_SELF);
}
}
int GetIsDisabled(object oCreature)
{
int bReturn = FALSE;
effect e = GetFirstEffect(oCreature);
while(GetIsEffectValid(e))
{
switch(GetEffectType(e))
{
case EFFECT_TYPE_CHARMED:
case EFFECT_TYPE_CONFUSED:
case EFFECT_TYPE_CUTSCENE_PARALYZE:
case EFFECT_TYPE_CUTSCENEIMMOBILIZE:
case EFFECT_TYPE_DAZED:
case EFFECT_TYPE_DOMINATED:
case EFFECT_TYPE_ENTANGLE:
case EFFECT_TYPE_FRIGHTENED:
case EFFECT_TYPE_PARALYZE:
case EFFECT_TYPE_PETRIFY:
case EFFECT_TYPE_SLEEP:
case EFFECT_TYPE_STUNNED:
bReturn = TRUE;
break;
}
e = GetNextEffect(oCreature);
}
if(GetIsDead(oCreature))
{
bReturn = TRUE;
}
return bReturn;
}

View File

@@ -0,0 +1,13 @@
void main()
{
object oExit = GetExitingObject();
if(GetImmortal(oExit))
{
if(GetLocalInt(oExit,"IMPLICABLE_FOE_ON"))
{
SetImmortal(oExit, FALSE);
DeleteLocalInt(oExit, "IMPLICABLE_FOE_ON");
}
}
}

View File

@@ -0,0 +1,11 @@
/*
Implacable Foe - Warpriest Spell
*/
#include "prc_alterations"
void main()
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectAreaOfEffect(AOE_MOB_CIRCGOOD,"codi_s0_implcfo1","codi_s0_implcfo2","codi_s0_implcfo3"), OBJECT_SELF);
FloatingTextStringOnCreature("You begin to concentrate.", OBJECT_SELF,FALSE);
ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, 9999999.99);
}

View File

@@ -0,0 +1,79 @@
/*
Inflame - Warpriest spell
*/
#include "prc_alterations"
#include "prc_feat_const"
#include "prc_class_const"
#include "prc_spell_const"
void ApplyEffect();
void main()
{
object oCaster = OBJECT_SELF;
if(GetIsInCombat(oCaster))
{
return;
}
ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 5.0);
ActionDoCommand(ApplyEffect());
string sDeity = GetDeity(oCaster);
int iAlign = GetAlignmentGoodEvil(oCaster);
int iGender = GetGender(oCaster);
string sSpeech;
if(sDeity != "")
{
switch(iAlign)
{
case ALIGNMENT_GOOD:
sSpeech = GetStringByStrRef(0x0100302D, iGender);
break;
case ALIGNMENT_EVIL:
sSpeech = GetStringByStrRef(0x0100302E, iGender);
break;
default:
sSpeech = GetStringByStrRef(0x0100302F, iGender);
break;
}
}
else
{
switch(iAlign)
{
case ALIGNMENT_GOOD:
sSpeech = GetStringByStrRef(0x01003030, iGender);
break;
case ALIGNMENT_EVIL:
sSpeech = GetStringByStrRef(0x01003031, iGender);
break;
default:
sSpeech = GetStringByStrRef(0x01003032, iGender);
break;
}
}
SpeakString(sSpeech, TALKVOLUME_TALK);
}
void ApplyEffect()
{
effect eVis = EffectVisualEffect(VFX_FNF_LOS_HOLY_10);
location lCenter = GetLocation(OBJECT_SELF);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lCenter);
int iBonus = GetLevelByClass(CLASS_TYPE_WARPRIEST, OBJECT_SELF);
effect eBuff = EffectSavingThrowIncrease(SAVING_THROW_ALL, iBonus, SAVING_THROW_TYPE_MIND_SPELLS);
float fDuration = IntToFloat(5 + iBonus);
fDuration = fDuration*60.0;
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE,10.0,lCenter,FALSE);
while(oTarget != OBJECT_INVALID)
{
if(GetObjectHeard(OBJECT_SELF,oTarget))
{
if(GetIsFriend(oTarget, OBJECT_SELF))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBuff, oTarget, fDuration);
}
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE,10.0,lCenter,FALSE);
}
}

View File

@@ -0,0 +1,40 @@
/*
Rally - Warpriest spell
*/
#include "prc_alterations"
#include "prc_feat_const"
#include "prc_class_const"
#include "prc_spell_const"
void main()
{
object oCaster = OBJECT_SELF;
location lCenter = GetLocation(oCaster);
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, lCenter);
effect eVis = EffectVisualEffect(VFX_FNF_LOS_HOLY_20);
effect eHit = EffectVisualEffect(VFX_COM_HIT_DIVINE);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lCenter);
while(oTarget != OBJECT_INVALID)
{
if(GetIsFriend(oTarget, oCaster))
{
effect e = GetFirstEffect(oTarget);
while(GetIsEffectValid(e))
{
if(GetEffectType(e) == EFFECT_TYPE_FRIGHTENED)
{
int iDC = 10 + (GetHitDice(GetEffectCreator(e))/2) - GetLevelByClass(CLASS_TYPE_WARPRIEST, oCaster);
int iWill = WillSave(oTarget, iDC, SAVING_THROW_TYPE_FEAR,GetEffectCreator(e));
if(iWill > 0)
{
RemoveEffect(oTarget, e);
}
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHit, oTarget);
SignalEvent(oTarget, EventSpellCastAt(oCaster, SPELLABILITY_WP_RALLY, FALSE));
}
e = GetNextEffect(oTarget);
}
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, 20.0, lCenter);
}
}

View File

@@ -0,0 +1,76 @@
//:://////////////////////////////////////////////
//:: Ancestral Daisho conversation starter
//:: codi_s2_ancdai
//:://////////////////////////////////////////////
/** @file
This script starts the new ancestral daisho
management conversation
@author Primogenitor
Original by CODI
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
StartDynamicConversation("codi_s2_ancdaic", OBJECT_SELF, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, TRUE, FALSE, OBJECT_SELF);
//give them the items
int bHasKatana = FALSE;
int bHasWakizashi = FALSE;
//check if they already have them
object oTest = GetFirstItemInInventory(OBJECT_SELF);
while(GetIsObjectValid(oTest))
{
if(GetTag(oTest) == "codi_katana")
bHasKatana = TRUE;
if(GetTag(oTest) == "codi_wakizashi")
bHasWakizashi = TRUE;
oTest = GetNextItemInInventory(OBJECT_SELF);
}
//may be equipped too
int i;
for(i=0;i<14;i++)
{
oTest = GetItemInSlot(i, OBJECT_SELF);
if(GetTag(oTest) == "codi_katana")
bHasKatana = TRUE;
if(GetTag(oTest) == "codi_wakizashi")
bHasWakizashi = TRUE;
}
//katana
if(!bHasKatana)
{
object oKatana = CreateItemOnObject("codi_mw_katana", OBJECT_SELF);
object oKatana2 = CopyObject(oKatana, GetLocation(OBJECT_SELF), OBJECT_SELF, "codi_katana");
DestroyObject(oKatana);
//check in inventory
if(GetItemPossessor(oKatana2) != OBJECT_SELF)
DestroyObject(oKatana2);
else
{
SetItemCursedFlag(oKatana2, TRUE);
SetStolenFlag(oKatana2, TRUE);
}
SetName(oKatana2, GetName(OBJECT_SELF)+"'s "+GetName(oKatana2));
}
//wakizashi (short sword)
if(!bHasWakizashi)
{
object oWakizashi = CreateItemOnObject("codi_mw_short", OBJECT_SELF);
object oWakizashi2 = CopyObject(oWakizashi, GetLocation(OBJECT_SELF), OBJECT_SELF, "codi_wakizashi");
DestroyObject(oWakizashi);
//check in inventory
if(GetItemPossessor(oWakizashi2) != OBJECT_SELF)
DestroyObject(oWakizashi2);
else
{
SetItemCursedFlag(oWakizashi2, TRUE);
SetStolenFlag(oWakizashi2, TRUE);
}
SetName(oWakizashi2, GetName(OBJECT_SELF)+"'s Wakizashi");
}
}

View File

@@ -0,0 +1,703 @@
//:://////////////////////////////////////////////
//:: Samurai Ancestral Daisho conversation
//:: codi_s2_ancdaic
//:://////////////////////////////////////////////
/** @file
@author Primogenitor
@date Created - 2006.01.24
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "inc_dynconv"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_ENTRY = 0;
const int STAGE_IMPROVE = 1;
const int STAGE_IMPROVE_TYPE = 2;
const int STAGE_IMPROVE_SUB_TYPE = 3;
const int STAGE_IMPROVE_PARAM1 = 4;
const int STAGE_IMPROVE_VALUE = 5;
const int STAGE_IMPROVE_ADD = 6;
const int ERROR_CODE_5_FIX =1;
const int CHOICE_RETURN_TO_PREVIOUS = 0xFFFFFFFF;
//////////////////////////////////////////////////
/* Aid functions */
//////////////////////////////////////////////////
//////////////////////////////////////////////////
/* Main function */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
/* Get the value of the local variable set by the conversation script calling
* this script. Values:
* DYNCONV_ABORTED Conversation aborted
* DYNCONV_EXITED Conversation exited via the exit node
* DYNCONV_SETUP_STAGE System's reply turn
* 0 Error - something else called the script
* Other The user made a choice
*/
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
// The stage is used to determine the active conversation node.
// 0 is the entry node.
int nStage = GetStage(oPC);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
// variable named nStage determines the current conversation node
// Function SetHeader to set the text displayed to the PC
// Function AddChoice to add a response option for the PC. The responses are show in order added
if(nStage == STAGE_ENTRY)
{
SetHeader("You have invoked the power of your ancestral daisho. What would you like to do?");
AddChoice("[Sacrifice one or more items]", 1, oPC);
AddChoice("[Improve an ancestral weapon]", 2, oPC);
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
}
else if(nStage == STAGE_IMPROVE)
{
SetHeader("Which type of weapon would you like to improve?");
AddChoice("[Katana]", 1, oPC);
AddChoice("[Wakizashi (short sword)]", 2, oPC);
AddChoice("Go back.", CHOICE_RETURN_TO_PREVIOUS, oPC);
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
}
else if(nStage == STAGE_IMPROVE_TYPE)
{
SetHeader("Which type of itemproperty do you wish to add?");
AddChoice("Go back.", CHOICE_RETURN_TO_PREVIOUS, oPC);
int nRow = 0;
string sLabel = Get2DACache("itempropdef", "Label", nRow);
while(sLabel != "")
{
int bIsValid = StringToInt(Get2DACache("itemprops", "0_Melee", nRow));
if(bIsValid)
{
int nStrRef = StringToInt(Get2DACache("itemprops", "StringRef", nRow));
if(nStrRef && !GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nRow)+"_*_*_*"))
AddChoice(GetStringByStrRef(nStrRef), nRow, oPC);
}
nRow++;
sLabel = Get2DACache("itempropdef", "Label", nRow);
}
}
else if(nStage == STAGE_IMPROVE_SUB_TYPE)
{
int nType = GetLocalInt(oPC, "codi_ancdai_type");
SetHeader("Which subtype of itemproperty do you wish to add?");
AddChoice("Go back.", CHOICE_RETURN_TO_PREVIOUS, oPC);
string sSubTypeResRef = Get2DACache("itempropdef", "SubTypeResRef", nType);
int i;
for(i=0;i<200;i++)
{
int nStrRef = StringToInt(Get2DACache(sSubTypeResRef, "Name", i));
if(nStrRef != 0)
{
if(!GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nType)+"_"+IntToString(i)+"_*_*"))
AddChoice(GetStringByStrRef(nStrRef), i, oPC);
}
}
}
else if(nStage == STAGE_IMPROVE_PARAM1)
{
int nType = GetLocalInt(oPC, "codi_ancdai_type");
int nSubType = GetLocalInt(oPC, "codi_ancdai_subtype");
SetHeader("Which variation of itemproperty do you wish to add?");
AddChoice("Go back.", CHOICE_RETURN_TO_PREVIOUS, oPC);
string sParam1ResRef = Get2DACache("itempropdef", "Param1ResRef", nType);
//may depend on subtype
if(sParam1ResRef == "")
{
string sSubTypeResRef = Get2DACache("itempropdef", "SubTypeResRef", nType);
if(sSubTypeResRef != "")
{
sParam1ResRef = Get2DACache(sSubTypeResRef, "Param1ResRef", nSubType);
}
}
//lookup the number to get the real filename
sParam1ResRef = Get2DACache("iprp_paramtable", "TableResRef", StringToInt(sParam1ResRef));
//now loop over rows
int i;
for(i=0;i<200;i++)
{
int nStrRef = StringToInt(Get2DACache(sParam1ResRef, "Name", i));
if(nStrRef != 0)
{
if(!GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nType)+"_"+IntToString(nSubType)+"_"+IntToString(i)+"_*")
&& !GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nType)+"_*_"+IntToString(i)+"_*"))
AddChoice(GetStringByStrRef(nStrRef), i, oPC);
}
}
}
else if(nStage == STAGE_IMPROVE_VALUE)
{
int nType = GetLocalInt(oPC, "codi_ancdai_type");
int nSubType = GetLocalInt(oPC, "codi_ancdai_subtype");
int nParam1 = GetLocalInt(oPC, "codi_ancdai_param1");
SetHeader("Which value of itemproperty do you wish to add?");
AddChoice("Go back.", CHOICE_RETURN_TO_PREVIOUS, oPC);
string sCostResRef = Get2DACache("itempropdef", "CostTableResRef", nType);
//lookup the number to get the real filename
sCostResRef = Get2DACache("iprp_costtable", "Name", StringToInt(sCostResRef));
int i;
for(i=0;i<200;i++)
{
int nStrRef = StringToInt(Get2DACache(sCostResRef, "Name", i));
if(nStrRef != 0)
{
if(!GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nType)+"_"+IntToString(nSubType)+"_"+IntToString(nParam1)+"_"+IntToString(i))
&& !GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nType)+"_*_"+IntToString(nParam1)+"_"+IntToString(i))
&& !GetPRCSwitch(PRC_SAMURAI_BAN_+IntToString(nType)+"_*_*_"+IntToString(i)))
AddChoice(GetStringByStrRef(nStrRef), i, oPC);
}
}
}
else if(nStage == STAGE_IMPROVE_ADD)
{
int nType = GetLocalInt(oPC, "codi_ancdai_type");
int nSubType = GetLocalInt(oPC, "codi_ancdai_subtype");
int nParam1 = GetLocalInt(oPC, "codi_ancdai_param1");
int nValue = GetLocalInt(oPC, "codi_ancdai_value");
int nVar2;
int nVar3;
int nVar4;
//assign then in order
string sSubType = Get2DACache("itempropdef", "SubTypeResRef", nType);
string sParam1ResRef = Get2DACache("itempropdef", "Param1ResRef", nType);
string sValueResRef = Get2DACache("itempropdef", "CostTableResRef", nType);
if(sParam1ResRef == "")
{
//if there is a subtype, param1 may be defined there
if(sSubType != "")
sParam1ResRef = Get2DACache(sSubType, "Param1ResRef", nSubType);
}
if(sSubType != "")
{
nVar2 = nSubType;
if(sParam1ResRef != "")
{
nVar3 = nParam1;
if(sValueResRef != "")
nVar4 = nValue;
}
else if(sValueResRef != "")
nVar3 = nValue;
}
else if(sParam1ResRef != "")
{
nVar2 = nParam1;
if(sValueResRef != "")
nVar3 = nValue;
}
else if(sValueResRef != "")
nVar2 = nValue;
//fudges to turn types into vars
if(nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT)
{
// int nTemp = nVar3;
// nVar3 = nVar4;
// nVar4 = nTemp;
}
//get the itemproperty
itemproperty ipToAdd = IPGetItemPropertyByID(nType, nVar2, nVar3, nVar4);
if(!GetIsItemPropertyValid(ipToAdd))
DoDebug("Itemproperty Not Valid");
//set the header
SetHeader("You are attempting to add "+ItemPropertyToString(ipToAdd));
//work out cost
object oItem = GetLocalObject(oPC, "codi_ancdai");
object oCopy = CopyItem(oItem, GetObjectByTag("HEARTOFCHAOS"), TRUE);
if(!GetIsObjectValid(oCopy))
DoDebug("Copy not valid");
SetIdentified(oCopy, TRUE);
SetPlotFlag(oCopy, FALSE);
SetStolenFlag(oCopy, FALSE);
int nOldValue = GetGoldPieceValue(oCopy);
IPSafeAddItemProperty(oCopy, ipToAdd);
int nNewValue = GetGoldPieceValue(oCopy);
int nIPCost = nNewValue-nOldValue;
//sanity check for infinite gold
if(nIPCost < 0)
{
AddChoice("You cannot add this because it would lower the value of your weapon.", CHOICE_RETURN_TO_PREVIOUS, oPC);
}
else
{
int nSacrificed = GetPersistantLocalInt(oPC, "CODI_SAMURAI");
if(nIPCost > nSacrificed)
AddChoice("You cannot add this because it would cost more than you have sacrificed ("+
IntToString(nIPCost)+" vs "+IntToString(nSacrificed)+")", CHOICE_RETURN_TO_PREVIOUS, oPC);
else
{
int nMaxValue;
//get maxvalue based on character level & Epic Ancestral Daisho feats
int nSamuraiLevel = GetHitDice(oPC);
if(nSamuraiLevel >=4 && nSamuraiLevel < 7)
nMaxValue = 2000;
else if(nSamuraiLevel >=7 && nSamuraiLevel < 9)
nMaxValue = 8000;
else if(nSamuraiLevel >=9 && nSamuraiLevel < 11)
nMaxValue = 18000;
else if(nSamuraiLevel >=11 && nSamuraiLevel < 13)
nMaxValue = 32000;
else if(nSamuraiLevel >=13 && nSamuraiLevel < 14)
nMaxValue = 50000;
else if(nSamuraiLevel >=14 && nSamuraiLevel < 15)
nMaxValue = 72000;
else if(nSamuraiLevel >=15 && nSamuraiLevel < 16)
nMaxValue = 98000;
else if(nSamuraiLevel >=16 && nSamuraiLevel < 17)
nMaxValue = 126000;
else if(nSamuraiLevel >=17 && nSamuraiLevel < 18)
nMaxValue = 162000;
else if(nSamuraiLevel >= 18)
{
nMaxValue = 200000;
if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_10))
nMaxValue = 8000000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_9))
nMaxValue = 7220000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_8))
nMaxValue = 6480000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_7))
nMaxValue = 5780000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_6))
nMaxValue = 5120000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_5))
nMaxValue = 4500000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_4))
nMaxValue = 3920000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_3))
nMaxValue = 3380000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_2))
nMaxValue = 2880000;
else if(GetHasFeat(FEAT_EPIC_ANCESTRAL_DAISHO_1))
nMaxValue = 2420000;
}
if(GetPRCSwitch(PRC_SAMURAI_VALUE_SCALAR_x100))
nMaxValue = FloatToInt(IntToFloat(nMaxValue)*(IntToFloat(GetPRCSwitch(PRC_SAMURAI_VALUE_SCALAR_x100))/100.0));
//get the items
object oKatana;
object oWakizashi;
int i;
for(i=0;i<14;i++)
{
object oTest = GetItemInSlot(i, oPC);
if(GetTag(oTest) == "codi_katana")
oKatana = oTest;
if(GetTag(oTest) == "codi_wakizashi")
oWakizashi = oTest;
}
object oTest = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oTest)
&& (!GetIsObjectValid(oKatana)
|| !GetIsObjectValid(oWakizashi)))
{
if(GetTag(oTest) == "codi_katana")
oKatana = oTest;
if(GetTag(oTest) == "codi_wakizashi")
oWakizashi = oTest;
oTest = GetNextItemInInventory(oPC);
}
//get the value
int nCurrentValue = nNewValue;
if(oWakizashi == oItem)
{
nCurrentValue += GetGoldPieceValue(oKatana);
}
else
nCurrentValue += GetGoldPieceValue(oWakizashi);
if(nCurrentValue > nMaxValue)
{
AddChoice("You cannot add this because it would bring the total value above your limit ("+
IntToString(nCurrentValue)+" vs "+IntToString(nMaxValue)+")", CHOICE_RETURN_TO_PREVIOUS, oPC);
}
else
{
AddChoice("This will cost "+IntToString(nIPCost)+" from your sacrificed total of "+IntToString(nSacrificed), TRUE, oPC);
AddChoice("This cost is too great at the moment", CHOICE_RETURN_TO_PREVIOUS, oPC);
}
}
}
}
}
// Do token setup
SetupTokens();
}
// End of conversation cleanup
else if(nValue == DYNCONV_EXITED)
{
// Add any locals set through this conversation
DeleteLocalObject(oPC, "codi_ancdai");
DeleteLocalInt(oPC, "codi_ancdai_type");
DeleteLocalInt(oPC, "codi_ancdai_subtype");
DeleteLocalInt(oPC, "codi_ancdai_param1");
DeleteLocalInt(oPC, "codi_ancdai_value");
}
// Abort conversation cleanup.
// NOTE: This section is only run when the conversation is aborted
// while aborting is allowed. When it isn't, the dynconvo infrastructure
// handles restoring the conversation in a transparent manner
else if(nValue == DYNCONV_ABORTED)
{
// Add any locals set through this conversation
DeleteLocalObject(oPC, "codi_ancdai");
DeleteLocalInt(oPC, "codi_ancdai_type");
DeleteLocalInt(oPC, "codi_ancdai_subtype");
DeleteLocalInt(oPC, "codi_ancdai_param1");
DeleteLocalInt(oPC, "codi_ancdai_value");
}
// Handle PC responses
else
{
// variable named nChoice is the value of the player's choice as stored when building the choice list
// variable named nStage determines the current conversation node
int nChoice = GetChoice(oPC);
if(nStage == STAGE_ENTRY)
{
if(nChoice == 1) //sacrifice items
{
object oAltar = CreateObject(OBJECT_TYPE_PLACEABLE, "codi_sam_altar", GetLocation(oPC));
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, DoPlaceableObjectAction(oAltar, PLACEABLE_ACTION_USE));
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oAltar);
DestroyObject(oAltar, 360.0); //6 minutes
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
}
else if(nChoice == 2) //improve weapon
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE;
MarkStageNotSetUp(nStage, oPC);
}
}
else if(nStage == STAGE_IMPROVE)
{
if(nChoice == 1) //katana
{
object oKatana;
object oTest;
int i;
for(i=0;i<14;i++)
{
oTest = GetItemInSlot(i, OBJECT_SELF);
if(GetTag(oTest) == "codi_katana")
oKatana = oTest;
}
oTest = GetFirstItemInInventory(OBJECT_SELF);
while(GetIsObjectValid(oTest)
&& !GetIsObjectValid(oKatana))
{
if(GetTag(oTest) == "codi_katana")
oKatana = oTest;
oTest = GetNextItemInInventory(OBJECT_SELF);
}
SetLocalObject(oPC, "codi_ancdai", oKatana);
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_TYPE;
MarkStageNotSetUp(nStage, oPC);
}
else if(nChoice == 2) //wakizashi
{
object oWakizashi;
object oTest;
int i;
for(i=0;i<14;i++)
{
oTest = GetItemInSlot(i, OBJECT_SELF);
if(GetTag(oTest) == "codi_wakizashi")
oWakizashi = oTest;
}
oTest = GetFirstItemInInventory(OBJECT_SELF);
while(GetIsObjectValid(oTest)
&& !GetIsObjectValid(oWakizashi))
{
if(GetTag(oTest) == "codi_wakizashi")
oWakizashi = oTest;
oTest = GetNextItemInInventory(OBJECT_SELF);
}
SetLocalObject(oPC, "codi_ancdai", oWakizashi);
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_TYPE;
MarkStageNotSetUp(nStage, oPC);
}
else if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_ENTRY;
MarkStageNotSetUp(nStage, oPC);
}
}
else if(nStage == STAGE_IMPROVE_TYPE)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE;
MarkStageNotSetUp(nStage, oPC);
}
else
{
int nType = nChoice;
SetLocalInt(oPC, "codi_ancdai_type", nChoice);
//look for subtype
string sSubType = Get2DACache("itempropdef", "SubTypeResRef", nType);
if(sSubType != "")
nStage = STAGE_IMPROVE_SUB_TYPE;
else
{
//no subtype
//check param1
string sParam1ResRef = Get2DACache("itempropdef", "Param1ResRef", nType);
if(sParam1ResRef != "")
{
nStage = STAGE_IMPROVE_PARAM1;
}
else
{
//no param1
//check value
int nValueResRef = StringToInt(Get2DACache("itempropdef", "CostTableResRef", nType));
if(nValueResRef)
{
nStage = STAGE_IMPROVE_VALUE;
}
else
{
//no value
//proceed to add
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_ADD;
MarkStageNotSetUp(nStage, oPC);
}
}
}
}
}
else if(nStage == STAGE_IMPROVE_SUB_TYPE)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_TYPE;
MarkStageNotSetUp(nStage, oPC);
}
else
{
SetLocalInt(oPC, "codi_ancdai_subtype", nChoice);
int nType = GetLocalInt(oPC, "codi_ancdai_type");
int nSubType = nChoice;
//check param1
string sParam1ResRef = Get2DACache("itempropdef", "Param1ResRef", nType);
if(sParam1ResRef != "")
{
nStage = STAGE_IMPROVE_PARAM1;
}
else
{
//if there is a subtype, param1 may be defined there
string sSubType = Get2DACache("itempropdef", "SubTypeResRef", nType);
if(sSubType != "")
{
sParam1ResRef = Get2DACache(sSubType, "Param1ResRef", nSubType);
if(sParam1ResRef != "")
{
nStage = STAGE_IMPROVE_PARAM1;
}
else
{
//certainly no param1 now
//cheat a bit and pretend no subtype to get into the next if statement
sSubType = "";
}
}
//this is not an else statement
if(sSubType == "")
{
//no param1
//check value
int nValueResRef = StringToInt(Get2DACache("itempropdef", "CostTableResRef", nType));
if(nValueResRef)
{
nStage = STAGE_IMPROVE_VALUE;
}
else
{
//no value
//proceed to add
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_ADD;
MarkStageNotSetUp(nStage, oPC);
}
}
}
}
}
else if(nStage == STAGE_IMPROVE_PARAM1)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_TYPE;
MarkStageNotSetUp(nStage, oPC);
}
else
{
SetLocalInt(oPC, "codi_ancdai_param1", nChoice);
int nType = GetLocalInt(oPC, "codi_ancdai_type");
int nSubType = GetLocalInt(oPC, "codi_ancdai_subtype");
//check value
string sValueResRef = Get2DACache("itempropdef", "CostTableResRef", nType);
if(sValueResRef != "")
{
nStage = STAGE_IMPROVE_VALUE;
}
else
{
//no value
//proceed to add
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_ADD;
MarkStageNotSetUp(nStage, oPC);
}
}
}
else if(nStage == STAGE_IMPROVE_VALUE)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_IMPROVE_TYPE;
MarkStageNotSetUp(nStage, oPC);
}
else
{
SetLocalInt(oPC, "codi_ancdai_value", nChoice);
int nType = GetLocalInt(oPC, "codi_ancdai_type");
//proceed to add
nStage = STAGE_IMPROVE_ADD;
}
}
else if(nStage == STAGE_IMPROVE_ADD)
{
if(nChoice == CHOICE_RETURN_TO_PREVIOUS)
{
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_ENTRY;
MarkStageNotSetUp(nStage, oPC);
}
else if(nChoice == TRUE)
{
//store old cost
object oItem = GetLocalObject(oPC, "codi_ancdai");
int nOldPlot = GetPlotFlag(oItem);
int nOldValue = GetGoldPieceValue(oItem);
SetPlotFlag(oItem, nOldPlot);
SetStolenFlag(oItem, nOldPlot);
int nSacrificed = GetPersistantLocalInt(oPC, "CODI_SAMURAI");
//add the itemproperty
int nType = GetLocalInt(oPC, "codi_ancdai_type");
int nSubType = GetLocalInt(oPC, "codi_ancdai_subtype");
int nParam1 = GetLocalInt(oPC, "codi_ancdai_param1");
int nValue = GetLocalInt(oPC, "codi_ancdai_value");
int nVar2;
int nVar3;
int nVar4;
//assign then in order
string sSubType = Get2DACache("itempropdef", "SubTypeResRef", nType);
string sParam1ResRef = Get2DACache("itempropdef", "Param1ResRef", nType);
string sValueResRef = Get2DACache("itempropdef", "CostTableResRef", nType);
if(sParam1ResRef == "")
{
//if there is a subtype, param1 may be defined there
if(sSubType != "")
sParam1ResRef = Get2DACache(sSubType, "Param1ResRef", nSubType);
}
if(sSubType != "")
{
nVar2 = nSubType;
if(sParam1ResRef != "")
{
nVar3 = nParam1;
if(sValueResRef != "")
nVar4 = nValue;
}
else if(sValueResRef != "")
nVar3 = nValue;
}
else if(sParam1ResRef != "")
{
nVar2 = nParam1;
if(sValueResRef != "")
nVar3 = nValue;
}
else if(sValueResRef != "")
nVar2 = nValue;
//fudges to turn types into vars
if(nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP
|| nType == ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT)
{
int nTemp = nVar3;
nVar3 = nVar4;
nVar4 = nTemp;
}
//get the itemproperty
itemproperty ipToAdd = IPGetItemPropertyByID(nType, nVar2, nVar3, nVar4);
if(!GetIsItemPropertyValid(ipToAdd))
DoDebug("Itemproperty Not Valid");
IPSafeAddItemProperty(oItem, ipToAdd);
//remove gold cost
//only works if non-plot
int nNewPlot = GetPlotFlag(oItem);
int nNewValue = GetGoldPieceValue(oItem);
SetPlotFlag(oItem, nNewPlot);
SetStolenFlag(oItem, nNewPlot);
int nIPCost = nNewValue-nOldValue;
SetPersistantLocalInt(oPC, "CODI_SAMURAI", nSacrificed-nIPCost);
//go back to start
MarkStageNotSetUp(nStage, oPC);
nStage = STAGE_ENTRY;
MarkStageNotSetUp(nStage, oPC);
}
}
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}

View File

@@ -0,0 +1,417 @@
//::///////////////////////////////////////////////
//:: Default eventscript
//:: default
//:://////////////////////////////////////////////
/** @file
This script is executed by the engine for events
when a creature does not have a script defined
for the event in question. This includes PCs.
The purpose of this script is to determine
which particular event triggered it's execution
and to route execution to scripts dedicated to
that event.
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "prc_inc_leadersh"
const int LOCAL_DEBUG = FALSE; //DEBUG;
/**************************/
/* Declarations for Tests */
/**************************/
int IsBlocked(); // test GetBlockingDoor()
int IsCombatRoundEnd(); // Need to fake this
int IsConversation(); // test a local variable
int IsDamaged(); // test GetLastDamager()
int IsDeath(); // test GetIsDead(OBJECT_SELF)
int IsDisturbed(); // test GetLastDisturbed()
int IsHeartbeat(); // test game time
int IsPerception(); // test GetLastPerceived()
int IsPhysicalAttacked(); // test GetLastAttacker()
int IsRested(); // test GetIsResting(GetMaster())
int IsSpawn(); // run once, never again
int IsSpellCastAt(); // test GetLastSpellCaster()
int IsUserDefined(); // test GetUserDefinedEventNumber()
/*********************************/
/* Utility Function declarations */
/*********************************/
//void ForceAddHenchman(object oHenchman);
//int IsLinkboyAttached();
//void GetLinkboy();
int IsObjectChanged(object oTest, string sVarname);
int IsIntChanged(int iTest, string sVarname);
int IsStringChanged(string sTest, string sVarname);
void RunScript(int nEvent);
//void SpawnRecallLocals(object oPC);
//void StartGroupDiscussion();
/*****************************/
/* Implementation of Actions */
/*****************************/
void OnSpawn() { RunScript(EVENT_VIRTUAL_ONSPAWNED); }
void OnDeath() { RunScript(EVENT_VIRTUAL_ONDEATH); }
void OnRested() { RunScript(EVENT_VIRTUAL_ONRESTED); }
void OnHeartbeat() { RunScript(EVENT_VIRTUAL_ONHEARTBEAT); }
void OnPerception() { RunScript(EVENT_VIRTUAL_ONPERCEPTION); }
void OnBlocked() { RunScript(EVENT_VIRTUAL_ONBLOCKED); }
void OnCombatRoundEnd() { RunScript(EVENT_VIRTUAL_ONCOMBATROUNDEND); }
void OnDisturbed() { RunScript(EVENT_VIRTUAL_ONDISTURBED); }
void OnPhysicalAttacked() { RunScript(EVENT_VIRTUAL_ONPHYSICALATTACKED); }
void OnSpellCastAt() { RunScript(EVENT_VIRTUAL_ONSPELLCASTAT); }
void OnDamaged() { RunScript(EVENT_VIRTUAL_ONDAMAGED); }
void OnUserDefined() { RunScript(EVENT_VIRTUAL_ONUSERDEFINED); }
void OnConversation() { RunScript(EVENT_VIRTUAL_ONCONVERSATION); }
/******************/
/* Main Procedure */
/******************/
void main()
{
if(LOCAL_DEBUG) DoDebug("default running for " + DebugObject2Str(OBJECT_SELF));
// OnConversation is exclusive of everything else, since it is just routed through this script
if(IsConversation()) OnConversation();
else
{
if(IsBlocked()) OnBlocked();
if(IsCombatRoundEnd()) OnCombatRoundEnd();
if(IsDamaged()) OnDamaged();
if(IsDeath()) OnDeath();
if(IsDisturbed()) OnDisturbed();
if(IsHeartbeat()) OnHeartbeat();
if(IsPerception()) OnPerception();
if(IsPhysicalAttacked()) OnPhysicalAttacked();
if(IsRested()) OnRested();
if(IsSpawn()) OnSpawn();
if(IsSpellCastAt()) OnSpellCastAt();
if(IsUserDefined()) OnUserDefined();
}
}
/************************/
/* Tests for conditions */
/************************/
int IsBlocked()
{
return IsObjectChanged(GetBlockingDoor(), "BlockingDoor");
}
int IsCombatRoundEnd()
{
// Need to fake this.
// Return TRUE iff you are in combat and not doing anything useful
if(GetIsInCombat() ||
(GetIsObjectValid(GetMaster()) &&
GetIsInCombat(GetMaster())
)
)
{
int nGCA = GetCurrentAction();
if(nGCA == ACTION_ATTACKOBJECT ||
nGCA == ACTION_CASTSPELL ||
nGCA == ACTION_COUNTERSPELL ||
nGCA == ACTION_HEAL ||
nGCA == ACTION_FOLLOW ||
nGCA == ACTION_ITEMCASTSPELL ||
nGCA == ACTION_KIDAMAGE ||
nGCA == ACTION_OPENDOOR ||
nGCA == ACTION_SMITEGOOD
)
{
return FALSE;
}
else
{
return TRUE;
}
}
else
{
return FALSE;
}
}
int IsConversation()
{
object oCreature = OBJECT_SELF;
if(GetLocalInt(oCreature, "default_conversation_event"))
{
DeleteLocalInt(oCreature, "default_conversation_event");
return TRUE;
}
return FALSE;
}
int IsDamaged()
{
object oCreature = OBJECT_SELF;
object oDamager = GetLastDamager(oCreature);
// The damage source must be valid
if(GetIsObjectValid(oDamager))
{
// Get previous damage data
string sOldDamage = GetLocalString(oCreature, "PRC_Event_OnDamaged_Data");
// Create string based on current damage values
// Start with the damaging object
string sNewDamage = ObjectToString(oDamager);
// Catenate amount of damage of each damage type
int i;
for(i = DAMAGE_TYPE_BLUDGEONING; i <= DAMAGE_TYPE_BASE_WEAPON; i = i << 1)
sNewDamage += IntToString(GetDamageDealtByType(i));
// Determine if the damage dealt has changed
if(sOldDamage != sNewDamage)
{
if(LOCAL_DEBUG) DoDebug("default: Damage has changed:\n" + sNewDamage);
SetLocalString(oCreature, "PRC_Event_OnDamaged_Data", sNewDamage);
// Update damage counter
SetLocalInt(oCreature, "PRC_LastDamageTaken", GetTotalDamageDealt());
return TRUE;
}
}
return FALSE;
}
int IsDeath()
{
return GetIsDead(OBJECT_SELF);
}
int IsDisturbed()
{
object oCreature = OBJECT_SELF;
object oDisturber = GetLastDisturbed();
if(GetIsObjectValid(oDisturber)) // The creature has been disturbed at least once during the game
{
// Get previous disturb data
string sOldDisturb = GetLocalString(oCreature, "PRC_Event_OnDisturbed_Data");
// Create string based on current disturb values
string sNewDisturb = ObjectToString(oDisturber);
sNewDisturb += IntToString(GetInventoryDisturbType());
sNewDisturb += ObjectToString(GetInventoryDisturbItem());
// Determine if the data has changed
if(sOldDisturb != sNewDisturb)
{
if(LOCAL_DEBUG) DoDebug("default: Disturbed has changed:\n" + sNewDisturb);
SetLocalString(oCreature, "PRC_Event_OnDisturbed_Data", sNewDisturb);
return TRUE;
}
}
return FALSE;
}
int IsHeartbeat()
{
object oCreature = OBJECT_SELF;
// PCs use the module HB
if(!GetIsPC(oCreature))
{
// Check how long since last recorded heartbeat
int nSecsChange = (GetTimeSecond() - GetLocalInt(oCreature, "PRC_LastHeartbeatSeconds") + 60) % 60;
// See if the master clock has ticked or 9 seconds have elapsed anyway
if(nSecsChange >= 6)
{
SetLocalInt(oCreature, "PRC_LastHeartbeatSeconds", GetTimeSecond());
return TRUE;
}
}
return FALSE;
}
int IsPerception()
{
object oCreature = OBJECT_SELF;
object oPerceived = GetLastPerceived();
if(GetIsObjectValid(oPerceived)) // The creature has perceived something at least once during the game
{
// Get previous perception data
string sOldPerception = GetLocalString(oCreature, "PRC_Event_OnPerception_Data");
// Create string based on current perception values
string sNewPerception = ObjectToString(oPerceived);
sNewPerception += IntToString(GetLastPerceptionHeard());
sNewPerception += IntToString(GetLastPerceptionInaudible());
sNewPerception += IntToString(GetLastPerceptionSeen());
sNewPerception += IntToString(GetLastPerceptionVanished());;
// Determine if the data has changed
if(sOldPerception != sNewPerception)
{
if(LOCAL_DEBUG) DoDebug("default: Perception has changed:\n" + sNewPerception);
SetLocalString(oCreature, "PRC_Event_OnPerception_Data", sNewPerception);
return TRUE;
}
}
return FALSE;
}
int IsPhysicalAttacked()
{
object oCreature = OBJECT_SELF;
object oAttacker = GetLastAttacker();
// Recent enough event that the attacker is at least still valid
if(GetIsObjectValid(oAttacker))
{
// Get previous attack data
string sOldAttack = GetLocalString(oCreature, "PRC_Event_OnPhysicalAttacked_Data");
// Create string for the current attack data
string sNewAttack = ObjectToString(oAttacker);
sNewAttack += ObjectToString(GetLastWeaponUsed(oAttacker));
sNewAttack += IntToString(GetLastAttackMode(oAttacker));
sNewAttack += IntToString(GetLastAttackType(oAttacker));
// Determine if the data has changed
if(sOldAttack != sNewAttack)
{
if(LOCAL_DEBUG) DoDebug("default: Attack has changed:\n" + sNewAttack);
SetLocalString(oCreature, "PRC_Event_OnPhysicalAttacked_Data", sNewAttack);
return TRUE;
}
}
return FALSE;
}
int IsRested()
{
// PCs use the module OnRest events
if(!GetIsPC(OBJECT_SELF))
{
// Goes TRUE when Master starts resting
int bMasterIsResting = GetIsResting(GetMaster());
return IsIntChanged(bMasterIsResting,"MasterIsResting") && bMasterIsResting;
}
return FALSE;
}
int IsSpawn()
{
object oCreature = OBJECT_SELF;
if(!GetLocalInt(oCreature, "PRC_OnSpawn_Marker"))
{
SetLocalInt(oCreature, "PRC_OnSpawn_Marker", TRUE);
return TRUE;
}
return FALSE;
}
int IsSpellCastAt()
{
object oCreature = OBJECT_SELF;
if(LOCAL_DEBUG) DoDebug("default: IsSpellCastAt():\n"
+ "GetLastSpellCaster() = " + DebugObject2Str(GetLastSpellCaster()) + "\n"
+ "GetLastSpell() = " + IntToString(GetLastSpell()) + "\n"
+ "GetLastSpellHarmful() = " + IntToString(GetLastSpellHarmful()) + "\n"
);
// If the event data does not contain the fake value, a spell has been cast
if(GetLastSpell() != -1)
{
// Reset the event data to the fake value
DelayCommand(0.0f, SignalEvent(oCreature, EventSpellCastAt(oCreature, -1, FALSE)));
return TRUE;
}
return FALSE;
}
int IsUserDefined()
{
object oCreature = OBJECT_SELF;
if(LOCAL_DEBUG) DoDebug("default: IsUserDefined():\n"
+ "GetUserDefinedEventNumber() = " + IntToString(GetUserDefinedEventNumber()) + "\n"
);
if(GetUserDefinedEventNumber() != -1)
{
// Reset the event data to the fake value
DelayCommand(0.0f, SignalEvent(oCreature, EventUserDefined(-1)));
return TRUE;
}
return FALSE;
}
/*********************/
/* Utility Functions */
/*********************/
int IsObjectChanged(object oTest, string sName)
{
if(oTest != GetLocalObject(OBJECT_SELF, "PRC_Event_" + sName))
{
SetLocalObject(OBJECT_SELF, "PRC_Event_" + sName, oTest);
return TRUE;
}
else
{
return FALSE;
}
}
int IsIntChanged(int iTest, string sName)
{
if(iTest != GetLocalInt(OBJECT_SELF, "PRC_Event_" + sName))
{
SetLocalInt(OBJECT_SELF, "PRC_Event_" + sName, iTest);
return TRUE;
}
else
{
return FALSE;
}
}
int IsStringChanged(string sTest, string sName)
{
if(sTest != GetLocalString(OBJECT_SELF, "PRC_Event_" + sName))
{
SetLocalString(OBJECT_SELF, "PRC_Event_" + sName, sTest);
return TRUE;
}
else
{
return FALSE;
}
}
void RunScript(int nEvent)
{
object oSelf = OBJECT_SELF;
if(LOCAL_DEBUG) DoDebug("default, event = " + IntToString(nEvent));
if(nEvent == EVENT_VIRTUAL_ONDAMAGED)
SignalEvent(oSelf, EventUserDefined(EVENT_DAMAGED));
// Determine NPC script name and run generic eventhook
ExecuteAllScriptsHookedToEvent(oSelf, nEvent);
}

View File

@@ -0,0 +1,25 @@
//::///////////////////////////////////////////////
//:: Name PRC Respawning Door Destroyed event
//:: FileName door_destroyed
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This handles prevent the door being removed
It should be respawned by sending a userdefined
event no 500 to the door later
*/
//:://////////////////////////////////////////////
//:: Created By: Primogenitor
//:: Created On: 08/05/06
//:://////////////////////////////////////////////
void main()
{
object oDoor = OBJECT_SELF;
int nSave = GetWillSavingThrow(oDoor);
SetIsDestroyable(FALSE);
if(nSave)
DelayCommand(TurnsToSeconds(nSave), SignalEvent(oDoor, EventUserDefined(500)));
}

View File

@@ -0,0 +1,28 @@
//::///////////////////////////////////////////////
//:: Name PRC Respawning Door User Defined event
//:: FileName door_ud
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This handles re-creating the door after it has been destroyed
To trigger it, send a user defined event no 500 to the door
This will not lock or trap the door again
*/
//:://////////////////////////////////////////////
//:: Created By: Primogenitor
//:: Created On: 08/05/06
//:://////////////////////////////////////////////
void main()
{
if(GetUserDefinedEventNumber() == 500)
{
object oDoor = OBJECT_SELF;
//respawn
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oDoor)-GetCurrentHitPoints(oDoor)), oDoor);
PlayAnimation(ANIMATION_DOOR_CLOSE);
}
}

View File

@@ -0,0 +1,99 @@
#include "prc_inc_clsfunc"
void DominatedDuration(object oTarget, object oCaster)
{
int iConc = GetLocalInt(oCaster, "SpellConc");
if (!iConc)
{
PRCRemoveEffectsFromSpell(oCaster,SPELL_DSL_SONG_COMPULSION);
return ;
}
if (GetHasSpellEffect(SPELL_DSL_SONG_COMPULSION,oTarget))
{
DelayCommand(6.0f,DominatedDuration(oTarget,oCaster) );
}
}
void main()
{
if (!GetHasFeat(FEAT_DRAGONSONG_STRENGTH, OBJECT_SELF))
{
FloatingTextStringOnCreature("This ability is tied to your dragons song ability, which has no more uses for today.",OBJECT_SELF); // no more bardsong uses left
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_SILENCE,OBJECT_SELF))
{
FloatingTextStrRefOnCreature(85764,OBJECT_SELF); // not useable when silenced
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_DEAF,OBJECT_SELF) && d100(1) <= 20)
{
FloatingTextStringOnCreature("Your deafness has caused you to fail.",OBJECT_SELF);
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
return;
}
effect eFNF = EffectVisualEffect(VFX_FNF_LOS_NORMAL_30);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(OBJECT_SELF));
RemoveOldSongEffects(OBJECT_SELF, 0);
RemoveOldSongs(OBJECT_SELF);
//Declare major variables
object oTarget = PRCGetSpellTargetObject();
object oCaster = OBJECT_SELF;
effect eDom = EffectDominated();
eDom = PRCGetScaledEffect(eDom, oTarget);
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DOMINATED);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
//Link domination and persistant VFX
effect eLink = EffectLinkEffects(eMind, eDom);
effect eVis = EffectVisualEffect(VFX_IMP_DOMINATE_S);
int nLevel = GetLevelByClass(CLASS_TYPE_DRAGONSONG_LYRIST);
effect eVis2 = EffectVisualEffect(VFX_DUR_BARD_SONG);
int nRacial = MyPRCGetRacialType(oTarget);
int nFocSong;
if (GetHasFeat(FEAT_EPIC_FOCUS_DRAGONSONG)) nFocSong = 6;
else if (GetHasFeat(FEAT_GREATER_FOCUS_DRAGONSONG)) nFocSong = 4;
else if (GetHasFeat(FEAT_FOCUS_DRAGONSONG)) nFocSong = 2;
int nEpic = GetHasFeat(FEAT_EPIC_DRAGONSONG_COMPULSION) ? TRUE:FALSE;
int nDC = 12 + nFocSong + GetLevelByClass(CLASS_TYPE_DRAGONSONG_LYRIST,OBJECT_SELF)+ GetAbilityModifier(ABILITY_CHARISMA,OBJECT_SELF);
if (nRacial== RACIAL_TYPE_DRAGON ) nDC-=2;
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_DOMINATE_MONSTER, FALSE));
//Make sure the target is a monster
if(!GetIsReactionTypeFriendly(oTarget))
{
int iSave = PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS);
if ( nEpic && iSave) iSave = PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS);
//Make a Will Save
if (!iSave)
{
//Apply linked effects and VFX Impact
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(eLink), oTarget, 0.0,FALSE);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(eVis2), OBJECT_SELF,0.0,FALSE);
SetLocalInt(OBJECT_SELF, "SpellConc", 1);
DelayCommand(6.0f,DominatedDuration(oTarget,oCaster) );
StoreSongRecipient(OBJECT_SELF, OBJECT_SELF, GetSpellId(), 0);
}
}
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
}

View File

@@ -0,0 +1,55 @@
//::///////////////////////////////////////////////
//:: Bard Song
//:: NW_S2_BardSong
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This spells applies bonuses to all of the
bard's allies within 30ft for a set duration of
10 rounds.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 25, 2002
//:://////////////////////////////////////////////
//:: Last Updated By: Georg Zoeller Oct 1, 2003
#include "prc_inc_clsfunc"
void main()
{
object oPC = OBJECT_SELF;
if(!GetHasFeat(FEAT_DRAGONSONG_STRENGTH, oPC))
{
FloatingTextStringOnCreature("This ability is tied to your dragons song ability, which has no more uses for today.", oPC, FALSE); // no more bardsong uses left
return;
}
if(PRCGetHasEffect(EFFECT_TYPE_SILENCE, oPC))
{
FloatingTextStrRefOnCreature(85764, oPC, FALSE); // not useable when silenced
return;
}
if(PRCGetHasEffect(EFFECT_TYPE_DEAF, oPC) && d100(1) <= 20)
{
FloatingTextStringOnCreature("Your deafness has caused you to fail.", oPC, FALSE);
DecrementRemainingFeatUses(oPC, FEAT_DRAGONSONG_STRENGTH);
return;
}
effect eFNF = EffectVisualEffect(VFX_FNF_LOS_NORMAL_30);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(oPC));
RemoveOldSongEffects(oPC, SPELL_DSL_SONG_FEAR);
RemoveOldSongs(oPC);
//Set and apply AOE object
effect eAOE = EffectAreaOfEffect(AOE_MOB_DRAGON_FEAR, "dslyr_songfeara", "dslyr_songfearb");
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eAOE, oPC, 0.0, FALSE);
StoreSongRecipient(oPC, oPC, SPELL_DSL_SONG_FEAR);
DecrementRemainingFeatUses(oPC, FEAT_DRAGONSONG_STRENGTH);
SetLocalInt(oPC, "SpellConc", 1);
}

View File

@@ -0,0 +1,82 @@
//::///////////////////////////////////////////////
//:: Aura of Fear On Enter
//:: NW_S1_AuraFearA.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Upon entering the aura of the creature the player
must make a will save or be struck with fear because
of the creatures presence.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 25, 2001
//:://////////////////////////////////////////////
// shaken -2 attack,weapon dmg,save.
// panicked -2 save + flee away ,50 % drop object holding
#include "prc_inc_spells"
void main()
{
//Declare major variables
object oTarget = GetEnteringObject();
effect eVis = EffectVisualEffect(VFX_IMP_FEAR_S);
effect eDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR);
effect eDur2 = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eDur3 = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
effect eFear = EffectFrightened();
effect eAttackD = EffectAttackDecrease(2);
effect eDmgD = EffectDamageDecrease(2,DAMAGE_TYPE_BLUDGEONING|DAMAGE_TYPE_PIERCING|DAMAGE_TYPE_SLASHING);
effect SaveD = EffectSavingThrowDecrease(SAVING_THROW_ALL,2);
effect Skill = EffectSkillDecrease(SKILL_ALL_SKILLS,2);
effect eLink = EffectLinkEffects(eDmgD, eDur2);
eLink = EffectLinkEffects(eLink, eAttackD);
eLink = EffectLinkEffects(eLink, SaveD);
eLink = EffectLinkEffects(eLink, eFear);
eLink = EffectLinkEffects(eLink, Skill);
effect eLink2 = EffectLinkEffects(eDur3, SaveD);
eLink2 = EffectLinkEffects(eLink2, Skill);
int nHD = GetHitDice(GetAreaOfEffectCreator());
int nEpic = GetHasFeat(FEAT_EPIC_DRAGONSONG_FEAR,GetAreaOfEffectCreator()) ? 4:0;
if (GetHasFeat(FEAT_EPIC_FOCUS_DRAGONSONG,GetAreaOfEffectCreator())) nEpic += 6;
else if (GetHasFeat(FEAT_GREATER_FOCUS_DRAGONSONG,GetAreaOfEffectCreator())) nEpic += 4;
else if (GetHasFeat(FEAT_FOCUS_DRAGONSONG,GetAreaOfEffectCreator())) nEpic += 2;
int nDC = 12 + nEpic + GetLevelByClass(CLASS_TYPE_DRAGONSONG_LYRIST,GetAreaOfEffectCreator())+ GetAbilityModifier(ABILITY_CHARISMA,GetAreaOfEffectCreator());
int nDuration = d6(2);
if(GetIsEnemy(oTarget, GetAreaOfEffectCreator()))
{
if (!PRCGetHasEffect(EFFECT_TYPE_DEAF,oTarget)) // deaf targets can't hear the song.
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(GetAreaOfEffectCreator(), SPELLABILITY_AURA_FEAR));
//Make a saving throw check
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_FEAR))
{
if (nHD>GetHitDice(oTarget)/2)
//Apply the VFX impact and effects
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oTarget, RoundsToSeconds(nDuration),FALSE);
else
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink2), oTarget, RoundsToSeconds(nDuration),FALSE);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(eVis), oTarget);
}
}
}
effect eVis2 = EffectVisualEffect(VFX_DUR_BARD_SONG);
if (oTarget == GetAreaOfEffectCreator())
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis2, OBJECT_SELF,0.0,FALSE);
}

View File

@@ -0,0 +1,25 @@
#include "prc_inc_spells"
void RemoveOldSongs(object oTarget)
{
if (GetHasSpellEffect(SPELL_DSL_SONG_STRENGTH,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_STRENGTH);
if (GetHasSpellEffect(SPELL_DSL_SONG_COMPULSION,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_COMPULSION);
if (GetHasSpellEffect(SPELL_DSL_SONG_SPEED,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_SPEED);
if (GetHasSpellEffect(SPELL_DSL_SONG_FEAR,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_FEAR);
if (GetHasSpellEffect(SPELL_DSL_SONG_HEALING,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_HEALING);
}
void main()
{
int iConc = GetLocalInt(GetAreaOfEffectCreator(), "SpellConc");
if (!iConc)
{
RemoveOldSongs(GetAreaOfEffectCreator());
DestroyObject(OBJECT_SELF);
}
}

View File

@@ -0,0 +1,115 @@
//::///////////////////////////////////////////////
//:: Heal
//:: [NW_S0_Heal.nss]
//:: Copyright (c) 2000 Bioware Corp.
//:://////////////////////////////////////////////
//:: Heals the target to full unless they are undead.
//:: If undead they reduced to 1d4 HP.
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 12, 2001
//:://////////////////////////////////////////////
//:: Update Pass By: Preston W, On: Aug 1, 2001
//:: modified by mr_bumpkin Dec 4, 2003 for PRC stuff
//::Added code to maximize for Faith Healing and Blast Infidel
//::Aaon Graywolf - Jan 7, 2004
#include "prc_inc_clsfunc"
void main()
{
//Declare major variables
object oTarget = OBJECT_SELF;
effect eHeal;
int nHeal;
effect eSun = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
effect eHealVis = EffectVisualEffect(VFX_IMP_HEALING_S);
effect eRegen = EffectRegenerate(3, 6.0);
effect eVis = EffectVisualEffect(VFX_IMP_HEAD_NATURE);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
effect eLink = EffectLinkEffects(eRegen, eDur);
eLink = EffectLinkEffects(eLink, eVis);
if (!GetHasFeat(FEAT_DRAGONSONG_STRENGTH, OBJECT_SELF))
{
FloatingTextStringOnCreature("This ability is tied to your dragons song ability, which has no more uses for today.",OBJECT_SELF); // no more bardsong uses left
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_SILENCE,OBJECT_SELF))
{
FloatingTextStrRefOnCreature(85764,OBJECT_SELF); // not useable when silenced
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_DEAF,OBJECT_SELF) && d100(1) <= 20)
{
FloatingTextStringOnCreature("Your deafness has caused you to fail.",OBJECT_SELF);
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
return;
}
effect eFNF = EffectVisualEffect(VFX_FNF_LOS_NORMAL_30);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(OBJECT_SELF));
RemoveOldSongEffects(OBJECT_SELF,SPELL_DSL_SONG_HEALING);
RemoveOldSongs(OBJECT_SELF);
int nEpic = GetHasFeat(FEAT_EPIC_DRAGONSONG_HEALING) ? TRUE:FALSE;
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_HEAL, FALSE));
int nLevel = GetLevelByClass(CLASS_TYPE_DRAGONSONG_LYRIST);
//Determine spell duration as an integer for later conversion to Rounds, Turns or Hours.
int nDuration = 10*nLevel;
//Check to see if the caster has Lasting Impression and increase duration.
if(GetHasFeat(870))
{
nDuration *= 10;
}
// lingering song
if(GetHasFeat(424)) // lingering song
{
nDuration += 5;
}
//Get first target in shape
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, PRCGetSpellTargetLocation());
while (GetIsObjectValid(oTarget))
{
if(GetIsReactionTypeFriendly(oTarget)|| GetFactionEqual(oTarget))
{
//Figure out how much to heal
nHeal = (nEpic) ? (d8(4) + 2 * nLevel) : (d8(2) + 2 * nLevel); // cure moderate or cure critical (epic)
//Set the heal effect
eHeal = EffectHeal(nHeal);
//Apply the heal effect and the VFX impact
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHealVis, oTarget);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
if (nEpic)
{
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oTarget, RoundsToSeconds(nDuration),FALSE);
StoreSongRecipient(oTarget, OBJECT_SELF, GetSpellId(), nDuration);
}
// Code for FB to remove damage that would be caused at end of Frenzy
SetLocalInt(oTarget, "PC_Damage", 0);
}
//Get next target in the shape
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, PRCGetSpellTargetLocation());
}
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
}

View File

@@ -0,0 +1,85 @@
#include "prc_inc_clsfunc"
void main()
{
if (!GetHasFeat(FEAT_DRAGONSONG_STRENGTH, OBJECT_SELF))
{
FloatingTextStringOnCreature("This ability is tied to your dragons song ability, which has no more uses for today.",OBJECT_SELF); // no more bardsong uses left
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_SILENCE,OBJECT_SELF))
{
FloatingTextStrRefOnCreature(85764,OBJECT_SELF); // not useable when silenced
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_DEAF,OBJECT_SELF) && d100(1) <= 20)
{
FloatingTextStringOnCreature("Your deafness has caused you to fail.",OBJECT_SELF);
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
return;
}
effect eFNF = EffectVisualEffect(VFX_FNF_LOS_NORMAL_30);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(OBJECT_SELF));
//Declare major variables
object oTarget;
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
effect eFast = EffectMovementSpeedIncrease(50);
effect eHaste = EffectHaste();
effect eLink = EffectLinkEffects(eFast, eDur);
if (GetHasFeat(FEAT_EPIC_DRAGONSONG_SPEED))
eLink = EffectLinkEffects(eLink, eHaste);
int nLevel = GetLevelByClass(CLASS_TYPE_DRAGONSONG_LYRIST);
//Determine spell duration as an integer for later conversion to Rounds, Turns or Hours.
int nDuration = nLevel;
//Check to see if the caster has Lasting Impression and increase duration.
if(GetHasFeat(870))
{
nDuration *= 10;
}
// lingering song
if(GetHasFeat(424)) // lingering song
{
nDuration += 5;
}
location lSpell = PRCGetSpellTargetLocation();
RemoveOldSongEffects(OBJECT_SELF,SPELL_DSL_SONG_SPEED);
RemoveOldSongs(OBJECT_SELF);
effect eVis = EffectVisualEffect(VFX_DUR_BARD_SONG);
eLink = EffectLinkEffects(eLink, eVis);
// SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, OBJECT_SELF,RoundsToSeconds(nDuration),FALSE);
//Declare the spell shape, size and the location. Capture the first target object in the shape.
oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lSpell);
//Cycle through the targets within the spell shape until an invalid object is captured or the number of
//targets affected is equal to the caster level.
while(GetIsObjectValid(oTarget))
{
//Make faction check on the target
if(oTarget == OBJECT_SELF)
{
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oTarget, RoundsToSeconds(nDuration),FALSE);
StoreSongRecipient(oTarget, OBJECT_SELF, GetSpellId(), nDuration);
}
else if(GetIsFriend(oTarget))
{
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oTarget, RoundsToSeconds(nDuration),FALSE);
StoreSongRecipient(oTarget, OBJECT_SELF, GetSpellId(), nDuration);
}
//Select the next target within the spell shape.
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lSpell);
}
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
}

View File

@@ -0,0 +1,54 @@
//::///////////////////////////////////////////////
//:: Bard Song
//:: NW_S2_BardSong
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This spells applies bonuses to all of the
bard's allies within 30ft for a set duration of
10 rounds.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 25, 2002
//:://////////////////////////////////////////////
//:: Last Updated By: Georg Zoeller Oct 1, 2003
/*
bugfix by Kovi 2002.07.30
- loosing temporary hp resulted in loosing the other bonuses
*/
#include "prc_inc_clsfunc"
void main()
{
if (PRCGetHasEffect(EFFECT_TYPE_SILENCE,OBJECT_SELF))
{
FloatingTextStrRefOnCreature(85764,OBJECT_SELF); // not useable when silenced
return;
}
if (PRCGetHasEffect(EFFECT_TYPE_DEAF,OBJECT_SELF) && d100(1) <= 20)
{
FloatingTextStringOnCreature("Your deafness has caused you to fail.",OBJECT_SELF);
DecrementRemainingFeatUses(OBJECT_SELF, FEAT_DRAGONSONG_STRENGTH);
return;
}
effect eFNF = EffectVisualEffect(VFX_FNF_LOS_NORMAL_30);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(OBJECT_SELF));
RemoveOldSongEffects(OBJECT_SELF,0);
RemoveOldSongs(OBJECT_SELF);
// effect eVis = EffectVisualEffect(VFX_DUR_BARD_SONG);
// SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, OBJECT_SELF,0.0,FALSE);
//Set and apply AOE object
effect eAOE = EffectAreaOfEffect(AOE_MOB_DRAGON_FEAR,"dslyr_songstra","dslyr_songstrb","dslyr_songstrc");
SPApplyEffectToObject(DURATION_TYPE_PERMANENT,eAOE, OBJECT_SELF,0.0,FALSE);
StoreSongRecipient(OBJECT_SELF, OBJECT_SELF, GetSpellId(), 0);
//DecrementRemainingFeatUses(OBJECT_SELF, FEAT_LYRITHSONG1);
SetLocalInt(OBJECT_SELF, "SpellConc", 1);
}

View File

@@ -0,0 +1,30 @@
#include "prc_alterations"
void main()
{
//Declare major variables
object oTarget = GetEnteringObject();
effect eVis = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
int nStr = GetHasFeat(FEAT_EPIC_DRAGONSONG_STRENGTH,GetAreaOfEffectCreator()) ? 6: 4;
int nCon = GetHasFeat(FEAT_EPIC_DRAGONSONG_STRENGTH,GetAreaOfEffectCreator()) ? 4: 0;
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH,nStr);
effect eCon = EffectAbilityIncrease(ABILITY_CONSTITUTION,nCon);
effect eLink = EffectLinkEffects(eStr, eDur);
eLink = EffectLinkEffects(eLink, eCon);
effect eVis2 = EffectVisualEffect(VFX_DUR_BARD_SONG);
eLink = EffectLinkEffects(eLink, eVis2);
if(GetIsReactionTypeFriendly(oTarget,GetAreaOfEffectCreator())|| GetFactionEqual(oTarget,GetAreaOfEffectCreator()) )
{
if (!PRCGetHasEffect(EFFECT_TYPE_DEAF,oTarget)) // deaf targets can't hear the song.
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(GetAreaOfEffectCreator(), SPELL_BULLS_STRENGTH, FALSE));
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget, 0.0,FALSE);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}
}

View File

@@ -0,0 +1,24 @@
#include "prc_inc_spells"
void RemoveOldSongs(object oTarget)
{
if (GetHasSpellEffect(SPELL_DSL_SONG_STRENGTH,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_STRENGTH);
if (GetHasSpellEffect(SPELL_DSL_SONG_COMPULSION,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_COMPULSION);
if (GetHasSpellEffect(SPELL_DSL_SONG_SPEED,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_SPEED);
if (GetHasSpellEffect(SPELL_DSL_SONG_FEAR,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_FEAR);
if (GetHasSpellEffect(SPELL_DSL_SONG_HEALING,oTarget)) PRCRemoveEffectsFromSpell(oTarget, SPELL_DSL_SONG_HEALING);
}
void main()
{
int iConc = GetLocalInt(GetAreaOfEffectCreator(), "SpellConc");
if (!iConc)
{
RemoveOldSongs(GetAreaOfEffectCreator());
DestroyObject(OBJECT_SELF);
}
}

View File

@@ -0,0 +1,29 @@
#include "prc_alterations"
void main()
{
//Declare major variables
//Get the object that is exiting the AOE
object oTarget = GetExitingObject();
object oCreator = GetAreaOfEffectCreator();
effect eAOE;
//Search through the valid effects on the target.
eAOE = GetFirstEffect(oTarget);
while (GetIsEffectValid(eAOE))
{
int nID = GetEffectSpellId(eAOE);
if(nID == SPELL_DSL_SONG_STRENGTH)
{
if (GetEffectCreator(eAOE) == oCreator)
RemoveEffect(oTarget, eAOE);
}
//Get next effect on the target
eAOE = GetNextEffect(oTarget);
}
}

View File

@@ -0,0 +1,23 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Conversation aborted
//:: dynconv_abort
//:://////////////////////////////////////////////
/** @file
Run when the conversation is exited through
being aborted.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
// Run the exit handler
_DynConvInternal_ExitedConvo(oPC, TRUE);
}

View File

@@ -0,0 +1,23 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: End conversation
//:: dynconv_end
//:://////////////////////////////////////////////
/** @file
Run when the PC exits the conversation via
the exit node.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
// Run the exit handler
_DynConvInternal_ExitedConvo(oPC, FALSE);
}

View File

@@ -0,0 +1,25 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Show end node?
//:: dynconv_end_w
//:://////////////////////////////////////////////
/** @file
Determines whether the PC is allowed to see
the conversation exit node.
@author Ornedan
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalInt(oPC, "DynConv_AllowExit") == DYNCONV_EXIT_ALLOWED_SHOW_CHOICE)
return TRUE;
else
return FALSE;
}

View File

@@ -0,0 +1,28 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Show header node
//:: dynconv_main_w
//:://////////////////////////////////////////////
/** @file
Determines whether to show the "NPC" response
text or the wait node.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalInt(oPC, "DynConv_Waiting"))
return FALSE;
_DynConvInternal_RunScript(oPC, DYNCONV_SETUP_STAGE);
if(GetLocalInt(oPC, "DynConv_Waiting") ||
GetLocalInt(oPC, "DynConv_AllowExit") == DYNCONV_EXIT_FORCE_EXIT
)
return FALSE;
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Next choices
//:: dynconv_next_a
//:://////////////////////////////////////////////
/** @file
Scrolls the choice list forward by 10.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
int nOffset = GetLocalInt(oPC, DYNCONV_CHOICEOFFSET) + 10;
SetLocalInt(oPC, DYNCONV_CHOICEOFFSET, nOffset);
}

View File

@@ -0,0 +1,26 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Show next choices node?
//:: dynconv_next_w
//:://////////////////////////////////////////////
/** @file
Determines whether there are more entries to
show.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
int nOffset = GetLocalInt(oPC, DYNCONV_CHOICEOFFSET);
if(nOffset + 10 < array_get_size(oPC, "ChoiceTokens"))
return TRUE;
else
return FALSE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Previous choices
//:: dynconv_prev_a
//:://////////////////////////////////////////////
/** @file
Scrolls the choice list backward by 10.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
int nOffset = GetLocalInt(oPC, DYNCONV_CHOICEOFFSET) - 10;
SetLocalInt(oPC, DYNCONV_CHOICEOFFSET, nOffset);
}

View File

@@ -0,0 +1,25 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Show prev choices node?
//:: dynconv_prev_w
//:://////////////////////////////////////////////
/** @file
Determines whether the list can be scrolled
backwards anymore.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
int nOffset = GetLocalInt(oPC, DYNCONV_CHOICEOFFSET);
if(nOffset >= 10)
return TRUE;
else
return FALSE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep0_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 0.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 1); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep0_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 0.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_0)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep1_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 1.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 2); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep1_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 1.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_1)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep2_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 2.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 3); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep2_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 2.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_2)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep3_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 3.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 4); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep3_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 3.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_3)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep4_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 4.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 5); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep4_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 4.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_4)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep5_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 5.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 6); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep5_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 5.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_5)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep6_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 6.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 7); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep6_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 6.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_6)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep7_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 7.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 8); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep7_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 7.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_7)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep8_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 8.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 9); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,24 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep8_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 8.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_8)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,22 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Reply chosen
//:: dynconv_rep9_a
//:://////////////////////////////////////////////
/** @file
Runs the dynamic conversation script with
reply value 9.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
void main()
{
object oPC = GetPCSpeaker();
_DynConvInternal_RunScript(oPC, 10); // Number passed is 1 greater than the actual, so that 0 can be used as a special case
}

View File

@@ -0,0 +1,23 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation
//:: dynconv_rep9_w
//:://////////////////////////////////////////////
/** @file
Checks that there is a valid option for
conversation choice 9.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalString(oPC, GetTokenIDString(DYNCONV_TOKEN_REPLY_9)) == "")
return FALSE;
else
return TRUE;
}

View File

@@ -0,0 +1,108 @@
//:://////////////////////////////////////////////
//:: Short description
//:: filename
//:://////////////////////////////////////////////
/** @file
Long description
@author Joe Random
@date Created - yyyy.mm.dd
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_ENTRY = 0;
//////////////////////////////////////////////////
/* Aid functions */
//////////////////////////////////////////////////
//////////////////////////////////////////////////
/* Main function */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
/* Get the value of the local variable set by the conversation script calling
* this script. Values:
* DYNCONV_ABORTED Conversation aborted
* DYNCONV_EXITED Conversation exited via the exit node
* DYNCONV_SETUP_STAGE System's reply turn
* 0 Error - something else called the script
* Other The user made a choice
*/
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
// The stage is used to determine the active conversation node.
// 0 is the entry node.
int nStage = GetStage(oPC);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
// variable named nStage determines the current conversation node
// Function SetHeader to set the text displayed to the PC
// Function AddChoice to add a response option for the PC. The responses are show in order added
if(nStage == STAGE_ENTRY)
{
// Set the header
SetHeader("Foo.");
// Add responses for the PC
AddChoice("Bar", 1, oPC);
AddChoice("Baz!", 2, oPC);
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
}
//add more stages for more nodes with Else If clauses
}
// Do token setup
SetupTokens();
}
// End of conversation cleanup
else if(nValue == DYNCONV_EXITED)
{
// Add any locals set through this conversation
}
// Abort conversation cleanup.
// NOTE: This section is only run when the conversation is aborted
// while aborting is allowed. When it isn't, the dynconvo infrastructure
// handles restoring the conversation in a transparent manner
else if(nValue == DYNCONV_ABORTED)
{
// Add any locals set through this conversation
}
// Handle PC responses
else
{
// variable named nChoice is the value of the player's choice as stored when building the choice list
// variable named nStage determines the current conversation node
int nChoice = GetChoice(oPC);
if(nStage == STAGE_ENTRY)
{
// Move to another stage based on response, for example
//nStage = STAGE_QUUX;
}
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}

View File

@@ -0,0 +1,25 @@
//:://////////////////////////////////////////////
//:: Dynamic Conversation: Show wait node?
//:: dynconv_end
//:://////////////////////////////////////////////
/** @file
Determines whether to show the wait node. The
waiting feature is used if the conversation
is being built in several steps instead of
at once.
@author Primogenitor
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "inc_dynconv"
int StartingConditional()
{
object oPC = GetPCSpeaker();
if(GetLocalInt(oPC, "DynConv_Waiting"))
return TRUE;
return FALSE;
}

View File

@@ -0,0 +1,33 @@
//:////////////////////////////////////
//: Eye of Gruumsh - Command the Horde
//: Gives +2 will saves to all allied
//: non-good orcs and half-orcs
//:////////////////////////////////////
#include "prc_alterations"
#include "prc_class_const"
#include "prc_spell_const"
void main()
{
object oCaster = OBJECT_SELF;
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oCaster) );
while(GetIsObjectValid(oTarget))
{
if(oTarget != oCaster &&
GetIsFriend(oTarget) &&
MyPRCGetRacialType(oTarget) == RACIAL_TYPE_HALFORC ||
MyPRCGetRacialType(oTarget) == RACIAL_TYPE_HUMANOID_ORC &&
GetAlignmentGoodEvil(oTarget) != ALIGNMENT_GOOD &&
!GetHasSpellEffect(SPELL_COMMAND_THE_HORDE, oTarget) )
{
int iEOGLevel = GetLevelByClass(CLASS_TYPE_PRC_EYE_OF_GRUUMSH, oCaster);
effect eWill = EffectSavingThrowIncrease(SAVING_THROW_WILL, 2, SAVING_THROW_TYPE_ALL);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWill, oTarget, HoursToSeconds(iEOGLevel) );
effect eVis = EffectVisualEffect(VFX_IMP_WILL_SAVING_THROW_USE, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oCaster) );
}
}

View File

@@ -0,0 +1,54 @@
//:////////////////////////////////////
//: Eye of Gruumsh - Blinding Spittle
//: ranged touch attack
//: Reflex save (DC 10 + Eye of Gruumsh level + EoG Con bonus)
//: Causes blindness
//:////////////////////////////////////
#include "prc_inc_sp_tch"
void CheckBlindness(object oTarget)
{
if (GetIsDead(oTarget) || !PRCGetIsFighting(oTarget) && PRCGetHasEffect(EFFECT_TYPE_BLINDNESS, oTarget) )
{
PRCRemoveSpecificEffect(EFFECT_TYPE_BLINDNESS, oTarget);
}
else if(PRCGetHasEffect(EFFECT_TYPE_BLINDNESS, oTarget) )
{
DelayCommand(6.0, CheckBlindness(oTarget) );
}
}
void main()
{
object oCaster = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int iTargetRace = MyPRCGetRacialType(oTarget);
int iBeholder = iTargetRace == RACIAL_TYPE_ABERRATION && GetHasSpell(710, oTarget) && GetHasSpell(711, oTarget) && GetHasSpell(712, oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_ACID_S), oTarget);
if(GetDistanceBetween(oCaster, oTarget) < 6.2 && // has to be within 20 ft.
iTargetRace != RACIAL_TYPE_OOZE && // has to use sight to attack
iTargetRace != RACIAL_TYPE_CONSTRUCT &&
iTargetRace != RACIAL_TYPE_UNDEAD &&
iTargetRace != RACIAL_TYPE_ELEMENTAL &&
iTargetRace != RACIAL_TYPE_VERMIN &&
!iBeholder)
{
int iHitEnemy = PRCDoRangedTouchAttack(oTarget);;
if(iHitEnemy > 0)
{
int iDC = 10 + GetLevelByClass(CLASS_TYPE_PRC_EYE_OF_GRUUMSH, oCaster) + GetAbilityModifier(ABILITY_CONSTITUTION, oCaster);
if(ReflexSave(oTarget, iDC, SAVING_THROW_TYPE_ACID, oCaster) == 0 && !GetIsImmune(oTarget, IMMUNITY_TYPE_BLINDNESS))
{
effect eBlind = EffectBlindness();
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBlind, oTarget);
DelayCommand(6.0,CheckBlindness(oTarget) );
}
}
}
}

View File

@@ -0,0 +1,18 @@
/*
Tenser's Floating Disk script
Causes any creature attacking the disk to instead attack the caster.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
*/
void main()
{
object oDisk = OBJECT_SELF;
object oCaster = GetMaster();
object oAttacker = GetLastAttacker(oDisk);
AssignCommand(oAttacker, ClearAllActions());
AssignCommand(oAttacker, ActionAttack(oCaster));
}

View File

@@ -0,0 +1,16 @@
/*
Tenser's Floating Disk script
Disk tries to follow the caster, even through doors.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
*/
void main()
{
object oDisk = OBJECT_SELF;
object oCaster = GetMaster();
DelayCommand(6.0, ActionJumpToLocation(GetLocation(oCaster)));
}

View File

@@ -0,0 +1,24 @@
/*
Tenser's Floating Disk script
This will start the disk's conversation if the PC is the caster of the spell.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
Modified by: xwarren
Modified: August 15, 2009
*/
int StartingConditional()
{
object oDisk = OBJECT_SELF;
object oCaster = GetPCSpeaker();
object oMaster = GetLocalObject(oDisk, "caster");
if(oMaster == oCaster)
{
if(GetMaster(oDisk) != oCaster)
AddHenchman(oCaster, oDisk);
return TRUE;
}
return FALSE;
}

View File

@@ -0,0 +1,21 @@
/*
Tenser's Floating Disk script
This will transfer ALL items from the disk's inventory, then destroy the disk.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
Modified by: xwarren
Modified: August 15, 2009
*/
#include "spinc_fdisk"
void main()
{
object oDisk = OBJECT_SELF;
object oCaster = GetPCSpeaker();
SetLocalInt(oDisk, "bDiskBussy", TRUE);
ActionDoCommand(TransferItems(oDisk, oCaster));
ActionDoCommand(DestroyDisk(oDisk));
}

View File

@@ -0,0 +1,19 @@
/*
Tenser's Floating Disk script
This will transfer ALL items from the disk's inventory.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
*/
#include "spinc_fdisk"
void main()
{
object oDisk = OBJECT_SELF;
object oCaster = GetPCSpeaker();
SetLocalInt(oDisk, "bDiskBussy", TRUE);
ActionDoCommand(TransferItems(oDisk, oCaster));
ActionDoCommand(SetLocalInt(oDisk, "bDiskBussy", FALSE));
}

View File

@@ -0,0 +1,21 @@
/*
Tenser's Floating Disk script
This fires when the disk's duration ends.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
Modified by: xwarren
Modified: August 15, 2009
*/
#include "spinc_fdisk"
void main()
{
object oDisk = OBJECT_SELF;
object oCaster = GetMaster();
SetLocalInt(oDisk, "bDiskBussy", TRUE);
ActionDoCommand(TransferItems(oDisk, oCaster));
ActionDoCommand(DestroyDisk(oDisk));
}

View File

@@ -0,0 +1,58 @@
/*
Tenser's Floating Disk script
Disk's heartbeat script. If not in conversation with the caster, it will follow the caster around.
Created by: xwarren
Created: August 15, 2009
*/
void CheckRange(float fRange, object oMaster, object oDisk)
{
if(GetDistanceToObject(oMaster) > fRange)
{
DelayCommand(0.5, ExecuteScript("fdisk_end", oDisk));
}
}
void main()
{
//check if enything is equipped in weapon inventory slots (not vital, but looks better without weapons)
//if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, OBJECT_SELF))) ActionUnequipItem(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, OBJECT_SELF));
//if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, OBJECT_SELF))) ActionUnequipItem(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, OBJECT_SELF));
object oDisk = OBJECT_SELF;
object oMaster = GetMaster(oDisk);
//check if caster is in spells range
int nCasterLevel = GetLocalInt(oDisk, "CasterLevel");
float fRange = 8.33 + 1.67 * nCasterLevel / 2;
if(GetDistanceToObject(oMaster) > fRange - 2)
{
FloatingTextStringOnCreature("You are walking too far form your floating disk", oMaster, FALSE);
DelayCommand(3.0, CheckRange(fRange, oMaster, oDisk));
}
//check if disk is not overloaded
int nWeight = GetWeight();
int nLimit = GetLocalInt(oDisk, "Weight_Limit") + 1;
if(nWeight > nLimit)
{
//if overloaded disk will not follow PC
if(!GetLocalInt(oDisk, "overloaded"))
{
FloatingTextStringOnCreature("A floating disk is holding too much", oMaster, FALSE);
SetLocalInt(oDisk, "overloaded", 1);
}
}
else
{
//follow the PC
DeleteLocalInt(oDisk, "overloaded");
if(!GetLocalInt(oDisk, "bDiskBussy"))
{
ClearAllActions();
ActionMoveToObject(oMaster, TRUE, 2.0);
}
}
}

View File

@@ -0,0 +1,22 @@
#include "nw_i0_generic"
void main()
{
int nMatch = GetListenPatternNumber();
object oDisk = OBJECT_SELF;
object oShouter = GetLastSpeaker();
if(nMatch == -1)
{
// Not a match -- start an ordinary conversation
if(GetCommandable(oDisk))
{
ClearActions(CLEAR_NW_C2_DEFAULT4_29);
BeginConversation();
}
}
else if(nMatch == ASSOCIATE_COMMAND_INVENTORY)
{
OpenInventory(oDisk, oShouter);
}
}

View File

@@ -0,0 +1,21 @@
/*
Tenser's Floating Disk script
Disk's OnSpawn script.
Created by: xwarren
Created: August 15, 2009
*/
void ApplyDuration()
{
int nDuration = GetLocalInt(OBJECT_SELF, "nDuration");
float fDelay = HoursToSeconds(nDuration)-1.5;
DelayCommand(fDelay, ExecuteScript("fdisk_end", OBJECT_SELF));
}
void main()
{
DelayCommand(1.0f, ApplyDuration());
}

View File

@@ -0,0 +1,50 @@
/*
Tenser's Floating Disk script
Disk's OnSpellCastAt script.
Created by: xwarren
Created: August 15, 2009
*/
#include "prc_alterations"
#include "psi_inc_psifunc"
void main()
{
object oMaster = GetMaster();
object oSCaster = GetLastSpellCaster();
int nMasterCLevel = PRCGetCasterLevel(oMaster);
int nSCLevel = PRCGetCasterLevel(oSCaster);
int nSpell = GetLastSpell();
int nTest;
switch(nSpell)
{
case SPELL_LESSER_DISPEL : nTest = d20(1) + min(5, nSCLevel); break;
case SPELL_DISPEL_MAGIC : nTest = d20(1) + min(10, nSCLevel); break;
case SPELL_DISPELLING_TOUCH : nTest = d20(1) + min(10, nSCLevel); break;
case SPELL_SLASHING_DISPEL : nTest = d20(1) + min(10, nSCLevel); break;
case POWER_DISPELPSIONICS : nTest = d20(1) + min(15, GetManifesterLevel(oSCaster)); break;
case SPELL_GREATER_DISPELLING : nTest = d20(1) + min(20, nSCLevel); break;
case SPELL_GREAT_WALL_OF_DISPEL : nTest = d20(1) + min(20, nSCLevel); break;
case SPELL_MORDENKAINENS_DISJUNCTION: nTest = d20(1) + min(40, nSCLevel); break;
case 4061 : nTest = d20(1) + min(40, nSCLevel); break;//Superb Dispelling
default : nTest = 0; break;
}
if (nTest >= 11 + nMasterCLevel)
{
ExecuteScript("fdisk_end", OBJECT_SELF);
}
else
{
if(!GetLocalInt(OBJECT_SELF, "bDiskBussy"))
{
ClearAllActions(TRUE);
ActionMoveToObject(oMaster, TRUE, 2.0);
}
}
}

View File

@@ -0,0 +1,17 @@
/*
Tenser's Floating Disk script
This will open the disk's inventory for the disk's creator, so that items can
be placed on it or taken off.
Created by: The Amethyst Dragon (www.amethyst-dragon.com/nwn)
Created: June 18, 2008
*/
void main()
{
object oDisk = OBJECT_SELF;
object oCaster = GetPCSpeaker();
OpenInventory(oDisk, oCaster);
}

View File

@@ -0,0 +1,39 @@
//::///////////////////////////////////////////////
//:: Magic Cirle Against Evil
//:: NW_S0_CircEvilA
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Add basic protection from evil effects to
entering allies.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2001
//:://////////////////////////////////////////////
//:: modified by mr_bumpkin Dec 4, 2003
#include "prc_alterations"
#include "x2_inc_spellhook"
void main()
{
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_ABJURATION);
object oTarget = GetEnteringObject();
if(GetIsFriend(oTarget, GetAreaOfEffectCreator()))
{
//effect eVis = EffectVisualEffect(VFX_IMP_GOOD_HELP);
effect eLink = PRCCreateProtectionFromAlignmentLink(ALIGNMENT_EVIL);
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_MAGIC_CIRCLE_AGAINST_EVIL, FALSE));
//Apply the VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
}
}

View File

@@ -0,0 +1,49 @@
//::///////////////////////////////////////////////
//:: Magic Cirle Against Evil
//:: NW_S0_CircEvilB
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Add basic protection from evil effects to
entering allies.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2001
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "x2_inc_spellhook"
void main()
{
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_ABJURATION);
//Declare major variables
//Get the object that is exiting the AOE
object oTarget = GetExitingObject();
int bValid = FALSE;
effect eAOE;
if(GetHasSpellEffect(SPELL_SU_CIRCEVIL, oTarget))
{
//Search through the valid effects on the target.
eAOE = GetFirstEffect(oTarget);
while (GetIsEffectValid(eAOE))
{
if (GetEffectCreator(eAOE) == GetAreaOfEffectCreator())
{
//If the effect was created by the AOE then remove it
if(GetEffectSpellId(eAOE) == SPELL_SU_CIRCEVIL)
{
RemoveEffect(oTarget, eAOE);
}
}
//Get next effect on the target
eAOE = GetNextEffect(oTarget);
}
}
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
// delete the variable showing the spell's school
}

Some files were not shown because too many files have changed in this diff Show More