PRC8_fork/trunk/newspellbook/tob_eternalblade.nss

354 lines
17 KiB
Plaintext
Raw Normal View History

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