Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
354 lines
17 KiB
Plaintext
354 lines
17 KiB
Plaintext
/*
|
|
----------------
|
|
Eternal Blade class script
|
|
|
|
tob_eternalblade.nss
|
|
----------------
|
|
|
|
10 MAR 09 by GC
|
|
*/ /** @file
|
|
|
|
This file handles the following:
|
|
|
|
- Addition of maneuvers upon levelup
|
|
- Blade guide death/revive
|
|
- Application of Eternal Knowledge
|
|
- Appliation of Uncanny Dodge
|
|
*/
|
|
|
|
#include "tob_inc_tobfunc"
|
|
#include "tob_inc_recovery"
|
|
////#include "prc_alterations"
|
|
//#include "tob_inc_etbl"
|
|
|
|
void ApplyLore(object oInitiator)
|
|
{
|
|
object oSkin = GetPCSkin(oInitiator);
|
|
int nSkill = GetSkillRank(SKILL_LORE, oInitiator, TRUE);
|
|
int nBonus = GetLevelByClass(CLASS_TYPE_ETERNAL_BLADE, oInitiator);// + GetAbilityModifier(ABILITY_INTELLIGENCE, oInitiator)); caster gets this bonus normaly
|
|
nBonus = (nBonus - nSkill >= 1) ? (nBonus - nSkill) : 0; // if blade guide won't help lore score, return
|
|
|
|
if(GetLocalInt(oSkin, "EternalKnowledge") != nBonus && nBonus >= 1)
|
|
SetCompositeBonus(oSkin, "EternalKnowledge", nBonus, ITEM_PROPERTY_SKILL_BONUS,SKILL_LORE);
|
|
//if(DEBUG) DoDebug("nBonus lore: " + IntToString(nBonus));
|
|
}
|
|
|
|
void RemoveLore(object oInitiator)
|
|
{
|
|
object oSkin = GetPCSkin(oInitiator);
|
|
SetCompositeBonus(oSkin, "EternalKnowledge", 0, ITEM_PROPERTY_SKILL_BONUS,SKILL_LORE);
|
|
}
|
|
|
|
void ApplyUncannyDodge(object oInitiator)
|
|
{
|
|
if(!GetLocalInt(oInitiator, "ETBL_AUD_Applied"))
|
|
{
|
|
object oSkin = GetPCSkin(oInitiator);
|
|
itemproperty ipUD;
|
|
if(GetHasFeat(FEAT_UNCANNY_DODGE_1, oInitiator))
|
|
{
|
|
// if they have uncanny dodge already, give them version 2
|
|
ipUD = PRCItemPropertyBonusFeat(IP_CONST_FEAT_UNCANNY_DODGE2);
|
|
//if(DEBUG) DoDebug("Adding Uncanny Doddge 2");
|
|
}
|
|
else
|
|
{
|
|
//if(DEBUG) DoDebug("Adding Uncanny Doddge 1");
|
|
ipUD = PRCItemPropertyBonusFeat(IP_CONST_FEAT_UNCANNY_DODGE1);
|
|
}
|
|
IPSafeAddItemProperty(oSkin, ipUD, 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
SetLocalInt(oInitiator, "ETBL_AUD_Applied", TRUE);
|
|
}
|
|
}
|
|
|
|
void RemoveUncannyDodge(object oInitiator)
|
|
{
|
|
if(GetLocalInt(oInitiator, "ETBL_AUD_Applied") == TRUE)
|
|
{
|
|
object oSkin = GetPCSkin(oInitiator);
|
|
if(GetHasFeat(FEAT_UNCANNY_DODGE_1, oInitiator))
|
|
{
|
|
//if(DEBUG) DoDebug("Removing Uncanny Doddge 2");
|
|
RemoveSpecificProperty(oSkin, ITEM_PROPERTY_BONUS_FEAT, IP_CONST_FEAT_UNCANNY_DODGE2, -1, -1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
}
|
|
else
|
|
{
|
|
//if(DEBUG) DoDebug("Removing Uncanny Doddge 1");
|
|
RemoveSpecificProperty(oSkin, ITEM_PROPERTY_BONUS_FEAT, IP_CONST_FEAT_UNCANNY_DODGE1, -1, -1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
}
|
|
DeleteLocalInt(oInitiator, "ETBL_AUD_Applied");
|
|
}
|
|
}
|
|
void BladeGuide(object oInitiator, object oItem)
|
|
{
|
|
if (GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
|
|
{
|
|
|
|
//://////////////////////////////////////
|
|
//: Blade Guide death/resurrection
|
|
/*
|
|
Adds/removed passive boni from the
|
|
Eternal Blade's blade guide presence
|
|
|
|
The way granting abilities is handled,
|
|
this can be run through EVENT_DAMAGED alone
|
|
*/
|
|
//://////////////////////////////////////
|
|
if(DEBUG) DoDebug("etbl EVENT_DAMAGED: running");
|
|
object oAttacker = GetLastDamager();
|
|
int nDamageTaken = GetTotalDamageDealt();
|
|
int nHitPoints = GetMaxHitPoints(oInitiator);
|
|
if(DEBUG) DoDebug("EVENT_DAMAGED: damage dealt: " + IntToString(nDamageTaken));
|
|
if(DEBUG) DoDebug("EVENT_DAMAGED: PC MAX hitpoints: " + IntToString(nHitPoints));
|
|
|
|
// since player can have armor, dr, various immunities, etc., apply reasonable damage multiplyer for blage guide
|
|
nDamageTaken *= 2;
|
|
|
|
// Blade guide alive, but no HP int.
|
|
// This would be the first hit after he respawns or the player rests or after load
|
|
if(!GetLocalInt(oInitiator, "ETBL_BladeGuideDead") && !GetLocalInt(oInitiator, "ETBL_BladeGuideHP"))
|
|
{
|
|
SetLocalInt(oInitiator, "ETBL_BladeGuideHP", nHitPoints);
|
|
if(DEBUG) DoDebug("EVENT_DAMAGED: New blade guide HP set to: " + IntToString(nHitPoints));
|
|
}
|
|
|
|
// Damage taken and blade guide alive
|
|
if(nDamageTaken > 0 && !GetLocalInt(oInitiator, "ETBL_BladeGuideDead"))
|
|
{
|
|
int nCurrent = GetLocalInt(oInitiator, "ETBL_BladeGuideHP");
|
|
if(DEBUG) DoDebug("EVENT_DAMAGED: current blade guide HP: " + IntToString(nCurrent));
|
|
|
|
// blade guide is killed
|
|
if(nCurrent - nDamageTaken <= 0)
|
|
{
|
|
//effect eGuide = EffectVisualEffect(VFX_DUR_IOUNSTONE_BLUE);
|
|
if(DEBUG) DoDebug("EVENT_DAMAGED: blade guide killed");
|
|
|
|
// mark blade guide dead and remove stored HP
|
|
// checked for class abilities
|
|
SetLocalInt(oInitiator, "ETBL_BladeGuideDead", TRUE);
|
|
DeleteLocalInt(oInitiator, "ETBL_BladeGuideHP");
|
|
DeleteLocalInt(oInitiator, "ETBL_BladeGuideVis");
|
|
|
|
// let the player know he died :(
|
|
FloatingTextStringOnCreature("*Blade Guide destroyed*", oInitiator, FALSE);
|
|
|
|
// remove blade guide vfx
|
|
PRCRemoveEffectsFromSpell(oInitiator, ETBL_BLADE_GUIDE);
|
|
|
|
DeleteLocalInt(oInitiator, "ETBL_BladeGuideVis");
|
|
// remove bonuses blade guide provides
|
|
RemoveLore(oInitiator);
|
|
RemoveUncannyDodge(oInitiator);
|
|
|
|
// blade guide comes back in 1d6 rounds, yay!
|
|
// remove dead marker, let player know he's back, reapply visual
|
|
float fDur = RoundsToSeconds(d6(1));
|
|
|
|
DelayCommand(fDur, DeleteLocalInt(oInitiator, "ETBL_BladeGuideDead"));
|
|
DelayCommand(fDur, FloatingTextStringOnCreature("*Blade Guide returned*", oInitiator, FALSE));
|
|
DelayCommand(fDur, ActionCastSpellOnSelf(ETBL_BLADE_GUIDE));
|
|
}
|
|
else
|
|
SetLocalInt(oInitiator, "ETBL_BladeGuideHP", (nCurrent - nDamageTaken));
|
|
if(DEBUG) DoDebug("blade guide hp: "+ IntToString((nCurrent - nDamageTaken)));
|
|
}
|
|
// if blade guide is dead at the moment, do nothing
|
|
}
|
|
}
|
|
|
|
|
|
void main()
|
|
{
|
|
|
|
object oInitiator, oItem;
|
|
int nEvent = GetRunningEvent();
|
|
|
|
switch(nEvent)
|
|
{
|
|
case EVENT_ITEM_ONHIT: oInitiator = OBJECT_SELF; break;
|
|
case EVENT_ONPLAYEREQUIPITEM: oInitiator = GetItemLastEquippedBy(); oItem = GetItemLastEquipped(); break;
|
|
case EVENT_ONPLAYERUNEQUIPITEM: oInitiator = GetItemLastUnequippedBy(); oItem = GetItemLastUnequipped(); break;
|
|
case EVENT_ONHEARTBEAT: oInitiator = OBJECT_SELF; break;
|
|
|
|
default:
|
|
oInitiator = OBJECT_SELF;
|
|
oItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oInitiator);
|
|
}
|
|
|
|
int nClass = CLASS_TYPE_ETERNAL_BLADE;
|
|
int nLevel = GetLevelByClass(CLASS_TYPE_ETERNAL_BLADE, oInitiator);
|
|
int nMoveTotal = GetKnownManeuversModifier(oInitiator, nClass, MANEUVER_TYPE_MANEUVER);
|
|
int nStncTotal = GetKnownManeuversModifier(oInitiator, nClass, MANEUVER_TYPE_STANCE);
|
|
int nRdyTotal = GetReadiedManeuversModifier(oInitiator, nClass);
|
|
|
|
if(DEBUG) DoDebug("tob_eternalblade running, event: " + IntToString(nEvent));
|
|
|
|
// We aren't being called from any event, instead from EvalPRCFeats
|
|
if(nEvent == FALSE)
|
|
{
|
|
// let them know our friend, Blade Guide is with them
|
|
if(!GetHasSpellEffect(ETBL_BLADE_GUIDE, oInitiator) && !GetLocalInt(oInitiator, "ETBL_BladeGuideDead"))
|
|
ActionCastSpellOnSelf(ETBL_BLADE_GUIDE);
|
|
|
|
// Hook in the events, needed for various abilities
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding eventhooks");
|
|
AddEventScript(oInitiator, EVENT_ONHEARTBEAT, "tob_eternalblade", TRUE, FALSE);
|
|
AddEventScript(oInitiator, EVENT_ONPLAYEREQUIPITEM, "tob_eternalblade", TRUE, FALSE);
|
|
AddEventScript(oInitiator, EVENT_ONPLAYERUNEQUIPITEM, "tob_eternalblade", TRUE, FALSE);
|
|
|
|
// Allows gaining of maneuvers by prestige classes
|
|
// It's not pretty, but it works
|
|
if (nLevel >= 1 && !GetPersistantLocalInt(oInitiator, "ToBEternalBlade1"))
|
|
{
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding Maneuver 1");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
SetPersistantLocalInt(oInitiator, "ToBEternalBlade1", TRUE);
|
|
SetPersistantLocalInt(oInitiator, "AllowedDisciplines", 270);//DISCIPLINE_DEVOTED_SPIRIT + DISCIPLINE_DIAMOND_MIND + DISCIPLINE_IRON_HEART + DISCIPLINE_WHITE_RAVEN
|
|
}
|
|
|
|
if (nLevel >= 3 &&!GetPersistantLocalInt(oInitiator, "ToBEternalBlade3"))
|
|
{
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding Maneuver 3");
|
|
SetReadiedManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nRdyTotal);
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
SetPersistantLocalInt(oInitiator, "ToBEternalBlade3", TRUE);
|
|
SetPersistantLocalInt(oInitiator, "AllowedDisciplines", 270);//DISCIPLINE_DEVOTED_SPIRIT + DISCIPLINE_DIAMOND_MIND + DISCIPLINE_IRON_HEART + DISCIPLINE_WHITE_RAVEN
|
|
}
|
|
|
|
if (nLevel >= 5 && !GetPersistantLocalInt(oInitiator, "ToBEternalBlade5"))
|
|
{
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding Maneuver 5");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nStncTotal, MANEUVER_TYPE_STANCE);
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
SetPersistantLocalInt(oInitiator, "ToBEternalBlade5", TRUE);
|
|
SetPersistantLocalInt(oInitiator, "AllowedDisciplines", 270);//DISCIPLINE_DEVOTED_SPIRIT + DISCIPLINE_DIAMOND_MIND + DISCIPLINE_IRON_HEART + DISCIPLINE_WHITE_RAVEN
|
|
}
|
|
|
|
if (nLevel >= 6 && !GetPersistantLocalInt(oInitiator, "ToBEternalBlade6"))
|
|
{
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding Maneuver 6");
|
|
SetReadiedManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nRdyTotal);
|
|
SetPersistantLocalInt(oInitiator, "ToBEternalBlade6", TRUE);
|
|
}
|
|
|
|
if (nLevel >= 7 && !GetPersistantLocalInt(oInitiator, "ToBEternalBlade7"))
|
|
{
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding Maneuver 7");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
SetPersistantLocalInt(oInitiator, "ToBEternalBlade7", TRUE);
|
|
SetPersistantLocalInt(oInitiator, "AllowedDisciplines", 270);//DISCIPLINE_DEVOTED_SPIRIT + DISCIPLINE_DIAMOND_MIND + DISCIPLINE_IRON_HEART + DISCIPLINE_WHITE_RAVEN
|
|
}
|
|
|
|
if (nLevel >= 9 && !GetPersistantLocalInt(oInitiator, "ToBEternalBlade9"))
|
|
{
|
|
if(DEBUG) DoDebug("tob_eternalblade: Adding Maneuver 9");
|
|
SetReadiedManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nRdyTotal);
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), ++nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
SetPersistantLocalInt(oInitiator, "ToBEternalBlade9", TRUE);
|
|
SetPersistantLocalInt(oInitiator, "AllowedDisciplines", 270);//DISCIPLINE_DEVOTED_SPIRIT + DISCIPLINE_DIAMOND_MIND + DISCIPLINE_IRON_HEART + DISCIPLINE_WHITE_RAVEN
|
|
}
|
|
|
|
// Hook to OnLevelDown to remove the maneuver slots granted here
|
|
AddEventScript(oInitiator, EVENT_ONPLAYERLEVELDOWN, "tob_eternalblade", TRUE, FALSE);
|
|
}
|
|
else if(nEvent == EVENT_ONPLAYERLEVELDOWN)
|
|
{
|
|
// Has lost Maneuver, but the slot is still present
|
|
if(GetPersistantLocalInt(oInitiator, "ToBEternalBlade1") && nLevel < 1)
|
|
{
|
|
DeletePersistantLocalInt(oInitiator, "ToBEternalBlade1");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
}
|
|
// Has lost Maneuver, but the slot is still present
|
|
if(GetPersistantLocalInt(oInitiator, "ToBEternalBlade3") && nLevel < 3)
|
|
{
|
|
DeletePersistantLocalInt(oInitiator, "ToBEternalBlade3");
|
|
SetReadiedManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nRdyTotal);
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
}
|
|
// Has lost Maneuver, but the slot is still present
|
|
if(GetPersistantLocalInt(oInitiator, "ToBEternalBlade5") && nLevel < 5)
|
|
{
|
|
DeletePersistantLocalInt(oInitiator, "ToBEternalBlade5");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nStncTotal, MANEUVER_TYPE_STANCE);
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
}
|
|
// Has lost Maneuver, but the slot is still present
|
|
if(GetPersistantLocalInt(oInitiator, "ToBEternalBlade6") && nLevel < 6)
|
|
{
|
|
DeletePersistantLocalInt(oInitiator, "ToBEternalBlade6");
|
|
SetReadiedManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nRdyTotal);
|
|
}
|
|
// Has lost Maneuver, but the slot is still present
|
|
if(GetPersistantLocalInt(oInitiator, "ToBEternalBlade7") && nLevel < 7)
|
|
{
|
|
DeletePersistantLocalInt(oInitiator, "ToBEternalBlade7");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
}
|
|
// Has lost Maneuver, but the slot is still present
|
|
if(GetPersistantLocalInt(oInitiator, "ToBEternalBlade9") && nLevel < 9)
|
|
{
|
|
DeletePersistantLocalInt(oInitiator, "ToBEternalBlade9");
|
|
SetKnownManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nMoveTotal, MANEUVER_TYPE_MANEUVER);
|
|
SetReadiedManeuversModifier(oInitiator, GetPrimaryBladeMagicClass(oInitiator), --nRdyTotal);
|
|
}
|
|
|
|
// Remove eventhook if the character no longer has levels in Eernal Blade
|
|
if(nLevel == 0)
|
|
{
|
|
RemoveEventScript(oInitiator, EVENT_ONPLAYERLEVELDOWN, "tob_eternalblade", TRUE, FALSE);
|
|
RemoveEventScript(oInitiator, EVENT_ONHEARTBEAT, "tob_eternalblade", TRUE, FALSE);
|
|
RemoveEventScript(oInitiator, EVENT_ONPLAYEREQUIPITEM, "tob_eternalblade", TRUE, FALSE);
|
|
RemoveEventScript(oInitiator, EVENT_ONPLAYERUNEQUIPITEM, "tob_eternalblade", TRUE, FALSE);
|
|
}
|
|
}
|
|
else if(nEvent == EVENT_ITEM_ONHIT)
|
|
{
|
|
oItem = GetSpellCastItem();
|
|
if(oItem == GetItemInSlot(INVENTORY_SLOT_CHEST, oInitiator))
|
|
{
|
|
BladeGuide(oInitiator, oItem);
|
|
}
|
|
}
|
|
else if(nEvent == EVENT_ONHEARTBEAT)
|
|
{
|
|
//if(DEBUG) DoDebug("ETBL OnHeartbeat running");
|
|
// If the blade guide is alive, add passsive abilities
|
|
if(!GetLocalInt(oInitiator, "ETBL_BladeGuideDead"))
|
|
{
|
|
if(nLevel >= 3) ApplyUncannyDodge(oInitiator);
|
|
if(nLevel >= 4) ApplyLore(oInitiator);
|
|
}
|
|
else
|
|
{// Else remove them
|
|
RemoveUncannyDodge(oInitiator);
|
|
RemoveLore(oInitiator);
|
|
}
|
|
|
|
//DoBladeGuideHB(oInitiator);
|
|
}
|
|
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
|
|
{
|
|
if(oItem == GetItemInSlot(INVENTORY_SLOT_CHEST, oInitiator))
|
|
{
|
|
// Add eventhook to the item
|
|
AddEventScript(oItem, EVENT_ITEM_ONHIT, "tob_eternalblade", TRUE, FALSE);
|
|
|
|
// Add the OnHitCastSpell: Unique needed to trigger the event
|
|
IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
|
}
|
|
}
|
|
// We are called from the OnPlayerUnEquipItem eventhook. Remove OnHitCast: Unique Power from oInitiator's weapon
|
|
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
|
|
{
|
|
if(oItem == GetItemInSlot(INVENTORY_SLOT_CHEST, oInitiator))
|
|
{
|
|
// Add eventhook to the item
|
|
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "tob_eternalblade", TRUE, FALSE);
|
|
|
|
// Add the OnHitCastSpell: Unique needed to trigger the event
|
|
RemoveSpecificProperty(oItem, ITEM_PROPERTY_ONHITCASTSPELL, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 0, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
|
}
|
|
}
|
|
} |