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.
390 lines
12 KiB
Plaintext
390 lines
12 KiB
Plaintext
//:://////////////////////////////////////////////
|
|
/*
|
|
This file is for the code/const for any custom skills.
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
|
|
/**
|
|
* Returns the height differential between the two locations.
|
|
* Return value is in feet.
|
|
*/
|
|
float GetHeight(location lPC, location lTarget);
|
|
|
|
// * Returns true or false depending on whether the creature is flying
|
|
// * or not
|
|
int PRCIsFlying(object oCreature);
|
|
|
|
// * Returns true or false depending on whether the creature has flying
|
|
// * mount or not
|
|
int PRCHasFlyingMount(object oCreature);
|
|
|
|
#include "prc_inc_clsfunc"
|
|
#include "moi_inc_moifunc"
|
|
#include "x3_inc_horse"
|
|
|
|
//:://////////////////////////////////////////////
|
|
//:: Skill Functions
|
|
//:://////////////////////////////////////////////
|
|
|
|
// returns true if they pass the jump check
|
|
// also handles animations and knockdown
|
|
int PerformJump(object oPC, location lLoc, int bDoKnockDown = TRUE)
|
|
{
|
|
object oArea = GetArea(oPC);
|
|
int bCanFly = FALSE;
|
|
// if jumping is disabled in this place.
|
|
if( GetLocalInt(oArea, "AreaJumpOff") == TRUE )
|
|
{
|
|
SendMessageToPC(oPC, "Jumping is not allowed in this area.");
|
|
return FALSE;
|
|
}
|
|
|
|
// Simulate "leap of the clouds", or RDD's having wings can "fly"
|
|
if((GetLevelByClass(CLASS_TYPE_MONK, oPC) >= 7
|
|
|| GetLevelByClass(CLASS_TYPE_NINJA_SPY, oPC) >= 3
|
|
|| PRCIsFlying(oPC))
|
|
&& GetLocalInt(oArea, "AreaFlyOff") == FALSE)
|
|
bCanFly = TRUE;
|
|
|
|
// This meld allows someone to fly when bound to a chakra
|
|
if (GetIsMeldBound(oPC, MELD_ACROBAT_BOOTS))
|
|
bCanFly = TRUE;
|
|
|
|
// This meld allows someone to fly when bound to a chakra
|
|
if (GetIsMeldBound(oPC, MELD_MANTICORE_BELT) == CHAKRA_WAIST)
|
|
bCanFly = TRUE;
|
|
|
|
//ebonfowl: Can fly temporarily when using Borne Aloft
|
|
if (GetLocalInt(oPC, "BorneAloft"))
|
|
bCanFly = TRUE;
|
|
|
|
// can't fly while mounted
|
|
if (HorseGetIsMounted(oPC) && !PRCHasFlyingMount(oPC))
|
|
bCanFly = FALSE;
|
|
|
|
// Height restriction on jumping
|
|
if (GetHeight(GetLocation(oPC), lLoc) > 5.0 && !bCanFly)
|
|
{
|
|
SendMessageToPC(oPC, "The target location is too high to jump to. Please pick a lower target.");
|
|
return FALSE;
|
|
}
|
|
|
|
// Immobilized creatures can't jump
|
|
effect eCheck = GetFirstEffect(oPC);
|
|
int nCheck;
|
|
while(GetIsEffectValid(eCheck)){
|
|
nCheck = GetEffectType(eCheck);
|
|
if(nCheck == EFFECT_TYPE_CUTSCENEIMMOBILIZE ||
|
|
nCheck == EFFECT_TYPE_ENTANGLE)
|
|
{
|
|
SendMessageToPC(oPC, "You cannot move.");
|
|
return FALSE;
|
|
}
|
|
|
|
eCheck = GetNextEffect(oPC);
|
|
}
|
|
|
|
int bIsRunningJump = FALSE;
|
|
int bPassedJumpCheck = FALSE;
|
|
int iMinJumpDistance = 0;
|
|
int iMaxJumpDistance = 6;
|
|
int iDivisor = 1;
|
|
int iJumpDistance = 0;
|
|
int bIsInHeavyArmor = FALSE;
|
|
|
|
// Goliaths and Garguns treat all jumps as running
|
|
if(GetRacialType(oPC) == RACIAL_TYPE_GOLIATH || GetRacialType(oPC) == RACIAL_TYPE_FERAL_GARGUN)
|
|
bIsRunningJump = TRUE;
|
|
|
|
int iDistance = FloatToInt(MetersToFeet(GetDistanceBetweenLocations(GetLocation(oPC), lLoc ) ) );
|
|
|
|
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oPC);
|
|
int AC = GetBaseAC(oArmor);
|
|
if(AC >= 6) bIsInHeavyArmor = TRUE;
|
|
|
|
// Jump check rules depend on a running jump or standing jump
|
|
// running jumps require at least 20 feet run length
|
|
if (iDistance >= 18 && !bIsInHeavyArmor) bIsRunningJump = TRUE;
|
|
|
|
int iBonus = 0;
|
|
if (GetHasFeat(FEAT_GREAT_LEAP, oPC))
|
|
{
|
|
if (Ninja_AbilitiesEnabled(oPC))
|
|
{
|
|
bIsRunningJump = TRUE;
|
|
iBonus = 4;
|
|
}
|
|
}
|
|
/*if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
|
|
{
|
|
bIsRunningJump = TRUE;
|
|
iBonus = 10;
|
|
} */
|
|
// PnP rules are height * 6 for run and height * 2 for jump.
|
|
// I can't get height so that is assumed to be 6.
|
|
// Changed maxed jump distance because the NwN distance is rather short
|
|
// at least compared to height it is.
|
|
if(bIsRunningJump)
|
|
{
|
|
iMinJumpDistance = 5;
|
|
iDivisor = 1;
|
|
iMaxJumpDistance *= 6;
|
|
}
|
|
else
|
|
{
|
|
iMinJumpDistance = 3;
|
|
iDivisor = 2;
|
|
iMaxJumpDistance *= 3;
|
|
}
|
|
|
|
// skill 28 = jump
|
|
int iJumpRoll = d20() + GetSkillRank(SKILL_JUMP, oPC) + iBonus + GetAbilityModifier(ABILITY_STRENGTH, oPC);
|
|
|
|
if(bCanFly)
|
|
{
|
|
iMaxJumpDistance *= 100;
|
|
iJumpRoll *= 100;
|
|
}
|
|
|
|
// Use Dex instead of Strength
|
|
if (GetHasFeat(FEAT_AGILE_ATHLETE, oPC))
|
|
{
|
|
iJumpRoll -= GetAbilityModifier(ABILITY_STRENGTH, oPC);
|
|
iJumpRoll += GetAbilityModifier(ABILITY_DEXTERITY, oPC);
|
|
}
|
|
|
|
if(GetSkillRank(SKILL_TUMBLE, oPC, TRUE) >= 5) iJumpRoll += 2;
|
|
|
|
// Jump distance is determined by the number exceeding 10
|
|
// divided based on running or standing jump.
|
|
iJumpRoll -= 10;
|
|
if(iJumpRoll < 1) iJumpRoll = 1;
|
|
iJumpRoll /= iDivisor;
|
|
iJumpDistance = iMinJumpDistance + iJumpRoll;
|
|
|
|
// Hadozee gliding doubles jump distance
|
|
if(GetRacialType(oPC) == RACIAL_TYPE_HADOZEE)
|
|
{
|
|
iMaxJumpDistance *= 2;
|
|
iJumpDistance *= 2;
|
|
}
|
|
|
|
if(iJumpDistance >= iDistance && iDistance <= iMaxJumpDistance)
|
|
{
|
|
// they passed jump check
|
|
bPassedJumpCheck = TRUE;
|
|
|
|
effect eJump = EffectDisappearAppear(lLoc);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eJump, oPC, 3.1);
|
|
}
|
|
else
|
|
{
|
|
// they failed jump check
|
|
FloatingTextStringOnCreature("Jump check failed.", oPC);
|
|
bPassedJumpCheck = FALSE;
|
|
|
|
if(bDoKnockDown)
|
|
{
|
|
effect eKnockDown = EffectKnockdown();
|
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eKnockDown, oPC);
|
|
}
|
|
}
|
|
|
|
return bPassedJumpCheck;
|
|
}
|
|
|
|
float GetHeight(location lPC, location lTarget)
|
|
{
|
|
vector vPC = GetPositionFromLocation(lPC);
|
|
vector vTarget = GetPositionFromLocation(lTarget);
|
|
|
|
return MetersToFeet(vTarget.z - vPC.z);
|
|
}
|
|
|
|
float GetDistanceForClimbing(object oPC, location lLoc)
|
|
{
|
|
object oArea = GetAreaFromLocation(lLoc);
|
|
vector vTest1 = GetPositionFromLocation(GetLocation(oPC));
|
|
vector vTest2 = GetPositionFromLocation(lLoc);
|
|
float fDistance = GetDistanceBetweenLocations(Location(oArea, Vector(vTest1.x, vTest1.y, 0.0), 0.0),
|
|
Location(oArea, Vector(vTest2.x, vTest2.y, 0.0), 0.0));
|
|
|
|
return MetersToFeet(fDistance);
|
|
}
|
|
|
|
int DoClimb(object oPC, location lLoc, int bDoKnockDown = TRUE)
|
|
{
|
|
// check to see if abort due to being mounted
|
|
if(HorseGetIsMounted(oPC))
|
|
return FALSE; // abort
|
|
|
|
// if Climbing is disabled in this place.
|
|
if(GetLocalInt(GetArea(oPC), "AreaClimbOff") == TRUE)
|
|
{
|
|
SendMessageToPC(oPC, "Climbing is not allowed in this area.");
|
|
return FALSE;
|
|
}
|
|
|
|
// Immobilized creatures can't Climb
|
|
effect eCheck = GetFirstEffect(oPC);
|
|
int nCheck;
|
|
while(GetIsEffectValid(eCheck))
|
|
{
|
|
nCheck = GetEffectType(eCheck);
|
|
if(nCheck == EFFECT_TYPE_CUTSCENEIMMOBILIZE ||
|
|
nCheck == EFFECT_TYPE_ENTANGLE)
|
|
{
|
|
SendMessageToPC(oPC, "You cannot move.");
|
|
return FALSE;
|
|
}
|
|
|
|
eCheck = GetNextEffect(oPC);
|
|
}
|
|
|
|
if(GetDistanceForClimbing(oPC, lLoc) > 10.0)
|
|
{
|
|
SendMessageToPC(oPC, "The target location is too far away to climb to. Please pick a closer target.");
|
|
return FALSE;
|
|
}
|
|
// Height restriction on climbing. Has to be at least 5 up or 5 down.
|
|
if(5.0 > GetHeight(GetLocation(oPC), lLoc) && GetHeight(GetLocation(oPC), lLoc) > -5.0)
|
|
{
|
|
SendMessageToPC(oPC, "The target location is too low to climb to. Please pick a higher target.");
|
|
return FALSE;
|
|
}
|
|
int bPassedClimbCheck = FALSE;
|
|
|
|
int iClimbRoll = d20() + GetSkillRank(SKILL_CLIMB, oPC) + GetAbilityModifier(ABILITY_STRENGTH, oPC);
|
|
|
|
// Flat DC, one of the hardest
|
|
if(iClimbRoll >= 25)
|
|
{
|
|
// they passed Climb check
|
|
bPassedClimbCheck = TRUE;
|
|
|
|
effect eClimb = EffectDisappearAppear(lLoc);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eClimb, oPC, 3.1);
|
|
}
|
|
else
|
|
{
|
|
// they failed Climb check
|
|
FloatingTextStringOnCreature("Climb check failed.", oPC);
|
|
|
|
if(bDoKnockDown)
|
|
{
|
|
effect eKnockDown = EffectKnockdown();
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnockDown, oPC, 5.0);
|
|
}
|
|
}
|
|
|
|
return bPassedClimbCheck;
|
|
}
|
|
|
|
// * Returns true or false depending on whether the creature is flying
|
|
// * or not
|
|
int PRCIsFlying(object oCreature)
|
|
{
|
|
int nAppearance = GetAppearanceType(oCreature);
|
|
int nWings = GetCreatureWingType(oCreature);
|
|
int bFlying = FALSE;
|
|
switch(nAppearance)
|
|
{
|
|
case APPEARANCE_TYPE_PARROT:
|
|
case APPEARANCE_TYPE_BAT:
|
|
case APPEARANCE_TYPE_BAT_HORROR:
|
|
case APPEARANCE_TYPE_DRAGON_BLACK:
|
|
case APPEARANCE_TYPE_DRAGON_BLUE:
|
|
case APPEARANCE_TYPE_DRAGON_BRASS:
|
|
case APPEARANCE_TYPE_DRAGON_BRONZE:
|
|
case APPEARANCE_TYPE_DRAGON_COPPER:
|
|
case APPEARANCE_TYPE_DRAGON_GOLD:
|
|
case APPEARANCE_TYPE_DRAGON_GREEN:
|
|
case APPEARANCE_TYPE_DRAGON_PRIS:
|
|
case APPEARANCE_TYPE_DRAGON_RED:
|
|
case APPEARANCE_TYPE_DRAGON_SHADOW:
|
|
case APPEARANCE_TYPE_DRAGON_SILVER:
|
|
case APPEARANCE_TYPE_DRAGON_WHITE:
|
|
case APPEARANCE_TYPE_ELEMENTAL_AIR:
|
|
case APPEARANCE_TYPE_ELEMENTAL_AIR_ELDER:
|
|
case APPEARANCE_TYPE_FAIRY:
|
|
case APPEARANCE_TYPE_GARGOYLE:
|
|
case APPEARANCE_TYPE_HELMED_HORROR:
|
|
case APPEARANCE_TYPE_LANTERN_ARCHON:
|
|
case APPEARANCE_TYPE_QUASIT:
|
|
case APPEARANCE_TYPE_IMP:
|
|
case APPEARANCE_TYPE_MEPHIT_AIR:
|
|
case APPEARANCE_TYPE_MEPHIT_DUST:
|
|
case APPEARANCE_TYPE_MEPHIT_EARTH:
|
|
case APPEARANCE_TYPE_MEPHIT_FIRE:
|
|
case APPEARANCE_TYPE_MEPHIT_ICE:
|
|
case APPEARANCE_TYPE_MEPHIT_MAGMA:
|
|
case APPEARANCE_TYPE_MEPHIT_OOZE:
|
|
case APPEARANCE_TYPE_MEPHIT_SALT:
|
|
case APPEARANCE_TYPE_MEPHIT_STEAM:
|
|
case APPEARANCE_TYPE_MEPHIT_WATER:
|
|
case APPEARANCE_TYPE_WILL_O_WISP:
|
|
case APPEARANCE_TYPE_FALCON:
|
|
case APPEARANCE_TYPE_RAVEN:
|
|
case APPEARANCE_TYPE_SHADOW:
|
|
case APPEARANCE_TYPE_SHADOW_FIEND:
|
|
case APPEARANCE_TYPE_SPECTRE:
|
|
case APPEARANCE_TYPE_SUCCUBUS:
|
|
case APPEARANCE_TYPE_ALLIP:
|
|
case APPEARANCE_TYPE_WRAITH:
|
|
case APPEARANCE_TYPE_SEAGULL_FLYING:
|
|
case APPEARANCE_TYPE_SPHINX:
|
|
case APPEARANCE_TYPE_GYNOSPHINX:
|
|
case APPEARANCE_TYPE_MANTICORE:
|
|
case APPEARANCE_TYPE_COCKATRICE:
|
|
case APPEARANCE_TYPE_FAERIE_DRAGON:
|
|
case APPEARANCE_TYPE_PSEUDODRAGON:
|
|
case APPEARANCE_TYPE_WYRMLING_BLACK:
|
|
case APPEARANCE_TYPE_WYRMLING_BLUE:
|
|
case APPEARANCE_TYPE_WYRMLING_BRASS:
|
|
case APPEARANCE_TYPE_WYRMLING_BRONZE:
|
|
case APPEARANCE_TYPE_WYRMLING_COPPER:
|
|
case APPEARANCE_TYPE_WYRMLING_GOLD:
|
|
case APPEARANCE_TYPE_WYRMLING_GREEN:
|
|
case APPEARANCE_TYPE_WYRMLING_RED:
|
|
case APPEARANCE_TYPE_WYRMLING_SILVER:
|
|
case APPEARANCE_TYPE_WYRMLING_WHITE:
|
|
case APPEARANCE_TYPE_DEVIL:
|
|
case APPEARANCE_TYPE_BEHOLDER:
|
|
case APPEARANCE_TYPE_BEHOLDER_MAGE:
|
|
case APPEARANCE_TYPE_BEHOLDER_EYEBALL:
|
|
case APPEARANCE_TYPE_DRACOLICH:
|
|
case APPEARANCE_TYPE_HARPY:
|
|
case APPEARANCE_TYPE_DEMI_LICH:
|
|
case 455: // Wyvern: Adult
|
|
case 456: // Wyvern: Great
|
|
case 457: // Wyvern: Juvenile
|
|
case 458: // Wyvern: Young
|
|
case APPEARANCE_TYPE_BEHOLDER_MOTHER:
|
|
bFlying = TRUE;
|
|
}
|
|
if(!bFlying
|
|
&& ((nWings > 0 && nWings < 79) || nWings == 90))//CEP and Project Q wing models
|
|
bFlying = TRUE;
|
|
|
|
if (GetHasSpellEffect(MOVE_SH_BALANCE_SKY, oCreature))
|
|
bFlying = TRUE;
|
|
|
|
if (GetLocalInt(oCreature, "GeryonFlight"))
|
|
bFlying = TRUE;
|
|
|
|
if(GetRacialType(oCreature) == RACIAL_TYPE_GLOURA)
|
|
bFlying = TRUE;
|
|
|
|
if(GetRacialType(oCreature) == RACIAL_TYPE_SPIRETOPDRAGON)
|
|
bFlying = TRUE;
|
|
|
|
return bFlying;
|
|
}
|
|
|
|
int PRCHasFlyingMount(object oCreature)
|
|
{
|
|
int nMount = GetCreatureTailType(oCreature);
|
|
int bFlying = FALSE;
|
|
//no flying mounts in original NWN - TODO: add check for CEP mounts
|
|
return bFlying;
|
|
} |