if (GetIsObjectValid(oOb)&&GetIsObjectValid(oRider))
{ // has master make sure is part of party
if (oOb!=oRider&&GetMaster(oRider)!=oOb)
{ // not part of party
return StringToRGBString(GetStringByStrRef(112001),STRING_COLOR_ROSE);
} // not part of party
} // has master make sure is part of party
if (GetLocalInt(oTarget,"X3_HORSE_NOT_RIDEABLE_OWNER"))
{ // not rideable due to owner
return StringToRGBString(GetStringByStrRef(112002),STRING_COLOR_PINK);
} // not rideable due to owner
if (GetLocalInt(GetArea(oTarget),"X3_NO_MOUNTING"))
{ // no mounting allowed in this area
return StringToRGBString(GetStringByStrRef(112003),STRING_COLOR_PINK);
} // no mounting allowed in this area
sS=GetResRef(oTarget);
if (GetStringLeft(sS,GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX&&GetIsObjectValid(oRider))
{ // paladin mount
if (HorseGetOwner(oTarget)!=oRider) return StringToRGBString(GetStringByStrRef(112004),STRING_COLOR_PINK);
} // paladin mount
if (!HorseGetIsAMount(oTarget)) return StringToRGBString(GetStringByStrRef(112005),STRING_COLOR_PINK);
} // valid oTarget type
else
{
// The target is not a mount (as its not a creature).
return StringToRGBString(GetStringByStrRef(112005),STRING_COLOR_ROSE);
}
return "";
} // HorseGetMountFailureMessage()
void HorseSetOwner(object oHorse,object oOwner,int bAssign=FALSE)
{ // PURPOSE: Set oHorse to be owned by oOwner
object oPreviousOwner;
string sName;
int nHenchmen=HORSE_SupportCountHenchmen(oOwner);
int nMax=GetLocalInt(GetModule(),"X3_HORSE_MAX_HENCHMEN");
int bIncHenchmen=GetLocalInt(GetModule(),"X3_HORSE_NO_HENCHMAN_INCREASE");
int nCurr=GetMaxHenchmen();
if (GetObjectType(oHorse)==OBJECT_TYPE_CREATURE&&GetObjectType(oOwner)==OBJECT_TYPE_CREATURE)
{ // valid parameters
//oPreviousOwner=GetMaster(oHorse);
//if (oPreviousOwner==oOwner) return; // already is the owner
if ((HorseGetCanBeMounted(oHorse,oOwner,TRUE)||GetIsPC(oOwner))&&!HorseGetIsAMount(oOwner))
{ // horse can be mounted
oPreviousOwner=GetMaster(oHorse);
if (oPreviousOwner!=oOwner)
{ // new owner
if (GetObjectType(oPreviousOwner)==OBJECT_TYPE_CREATURE)
{ // remove as henchman from previous owner
RemoveHenchman(oPreviousOwner,oHorse);
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oPreviousOwner)) SetLocalInt(oPreviousOwner,"bX3_STORE_MOUNT_INFO",TRUE);
} // remove as henchman from previous owner
if (nHenchmen==nCurr)
{ // see if increase possible
if (!bIncHenchmen)
{ // increase is permissable
if (nMax==0||nMax>0)
{ // do the increase
SetMaxHenchmen(nCurr+1);
} // do the increase
} // increase is permissable
} // see if increase possible
AssignCommand(oHorse,ClearAllActions());
AddHenchman(oOwner,oHorse);
SetLocalObject(oHorse,"oX3_HorseOwner",oOwner);
//AssignCommand(oHorse,SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE));
DelayCommand(1.0,SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE,oHorse));
if (bAssign) SetLocalObject(oOwner,"oAssignedHorse",oHorse);
} // new owner
else
{ // make sure variables on oHorse are correct
SetLocalObject(oHorse,"oX3_HorseOwner",oOwner);
//AssignCommand(oHorse,SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE));
SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE,oHorse);
if (bAssign) SetLocalObject(oOwner,"oAssignedHorse",oHorse);
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oOwner)) SetLocalInt(oOwner,"bX3_STORE_MOUNT_INFO",TRUE);
} // make sure variables on oHorse are correct
sName=GetLocalString(oHorse,"sX3_OriginalName");
if (GetStringLength(sName)<1)
{ // define original name
sName=GetName(oHorse);
SetLocalString(oHorse,"sX3_OriginalName",sName);
} // define original name
if (GetMaster(oHorse)==oOwner)
{ // was set okay
if (GetStringLowerCase(GetStringRight(GetName(oOwner),1))=="s"||GetStringLowerCase(GetStringRight(GetName(oOwner),1))=="z")
SetName(oHorse,GetName(oOwner)+"' "+sName);
else { SetName(oHorse,GetName(oOwner)+"'s "+sName); }
} // was set okay
} // horse can be mounted
else
{ // not valid
if (GetIsPC(oOwner))
{ // PC
PrintString("X3 HORSE ERROR: Attempt made to set "+GetName(oOwner)+" as owner of "+GetName(oHorse)+" is an invalid assignment.");
} // PC
else
{ // error
PrintString("X3 HORSE ERROR: Attempt made to set "+GetName(oOwner)+" as owner of "+GetName(oHorse)+" is an invalid assignment.");
} // error
} // not valid
} // valid parameters
} // HorseSetOwner()
void HorseRemoveOwner(object oHorse)
{ // PURPOSE: Remove the owner from oHorse
object oOwner;
string sString;
if (GetObjectType(oHorse)==OBJECT_TYPE_CREATURE)
{ // valid parameter
oOwner=GetLocalObject(oHorse,"oX3_HorseOwner");
if (GetObjectType(oOwner)==OBJECT_TYPE_CREATURE)
{ // owner found
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oOwner)) SetLocalInt(oOwner,"bX3_STORE_MOUNT_INFO",TRUE);
sString=GetResRef(oHorse);
// do not allow removing paladin horses from owner
if (GetStringLeft(sString,GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) return;
if (GetMaster(oHorse)==oOwner) RemoveHenchman(oOwner,oHorse);
DeleteLocalObject(oHorse,"oX3_HorseOwner");
if (oHorse==GetLocalObject(oOwner,"oAssignedHorse"))
{
DeleteLocalObject(oOwner,"oAssignedHorse");
HORSE_Support_AssignRemainingMount(oOwner);
}
} // owner found
} // valid parameter
sString=GetLocalString(oHorse,"sX3_OriginalName");
if (GetStringLength(sString)>0) SetName(oHorse,sString);
} // HorseRemoveOwner()
object HorseGetOwner(object oHorse)
{ // PURPOSE: Return who the owner of oHorse is or return OBJECT_INVALID
object oOwner;
if (GetObjectType(oHorse)==OBJECT_TYPE_CREATURE)
{ // valid parameter
oOwner=GetLocalObject(oHorse,"oX3_HorseOwner");
if (GetObjectType(oOwner)==OBJECT_TYPE_CREATURE) return oOwner;
} // valid parameter
return OBJECT_INVALID;
} // HorseGetOwner()
void HorseAddHorseMenu(object oPC)
{ // PURPOSE: Add Horse Menu to the PC
object oSkin=SKIN_SupportGetSkin(oPC);
itemproperty iProp;
if (GetIsPC(oPC))
{ // valid parameter
iProp=ItemPropertyBonusFeat(IP_CONST_HORSE_MENU);
AddItemProperty(DURATION_TYPE_PERMANENT,iProp,oSkin);
} // valid parameter
} // HorseAddHorseMenu()
void HorseSetPhenotype(object oRider,int bJoust=FALSE)
{ // PURPOSE: To set the proper phenotype for oRider when mounted
int nCurrent=GetPhenoType(oRider);
int nPheno=-1;
if (bJoust)
{ // jousting
if (GetLocalInt(oRider,"X3_CUSTOM_RACE_JOUST_PHENO")>0) nPheno=GetLocalInt(oRider,"X3_CUSTOM_RACE_JOUST_PHENO");
else if (nCurrent==PHENOTYPE_NORMAL||nCurrent==HORSE_PHENOTYPE_MOUNTED_N) nPheno=HORSE_PHENOTYPE_JOUSTING_N;
else if (nCurrent==PHENOTYPE_BIG||nCurrent==HORSE_PHENOTYPE_MOUNTED_L) nPheno=HORSE_PHENOTYPE_JOUSTING_L;
} // jousting
else
{ // not jousting
if (GetLocalInt(oRider,"X3_CUSTOM_RACE_MOUNTED_PHENO")>0) nPheno=GetLocalInt(oRider,"X3_CUSTOM_RACE_MOUNTED_PHENO");
else if (nCurrent==PHENOTYPE_NORMAL||nCurrent==HORSE_PHENOTYPE_JOUSTING_N) nPheno=HORSE_PHENOTYPE_MOUNTED_N;
else if (nCurrent==PHENOTYPE_BIG||nCurrent==HORSE_PHENOTYPE_JOUSTING_L) nPheno=HORSE_PHENOTYPE_MOUNTED_L;
} // not jousting
if (nPheno!=-1) SetPhenoType(nPheno,oRider);
} // HorseSetPhenotype()
int HorseGetIsDisabled(object oCreature)
{ // PURPOSE: blocked path, death, entanglement, confusion, paralysis, stun, petrification, fear, turned, sleep, knockdown detection by Azbest
int bDisabled=FALSE;
if (GetIsDead(oCreature)||GetLocalInt(oCreature,"bPathIsBlocked"))
{
bDisabled=TRUE;
}
else
{
effect eEffect=GetFirstEffect(oCreature);
while(GetIsEffectValid(eEffect)&&!bDisabled)
{ // traverse effects
if ((GetEffectType(eEffect)==EFFECT_TYPE_INVALIDEFFECT&&(GetEffectDurationType(eEffect)==DURATION_TYPE_TEMPORARY||GetEffectDurationType(eEffect)==DURATION_TYPE_PERMANENT))||
GetEffectType(eEffect)==EFFECT_TYPE_ENTANGLE||
GetEffectType(eEffect)==EFFECT_TYPE_CONFUSED||
GetEffectType(eEffect)==EFFECT_TYPE_PARALYZE||
GetEffectType(eEffect)==EFFECT_TYPE_STUNNED||
GetEffectType(eEffect)==EFFECT_TYPE_PETRIFY||
GetEffectType(eEffect)==EFFECT_TYPE_FRIGHTENED||
GetEffectType(eEffect)==EFFECT_TYPE_TURNED||
GetEffectType(eEffect)==EFFECT_TYPE_SLEEP)
{ // match
bDisabled=TRUE;
} // match
eEffect=GetNextEffect(oCreature);
} // traverse effects
}
return bDisabled;
} // HorseGetIsDisabled()
void HorseMount(object oHorse,int bAnimate=TRUE,int bInstant=FALSE,int nState=0)
{ // PURPOSE: Handle the mounting of oHorse
// 0 = Initial state
// 1 = move to horse
// 2 = adjust for animation
// 3 = animate
// 4 = store horse and premount info
// 5 = set appearances
// 6 = destroy oHorse
object oRider=OBJECT_SELF;
float fMonitorSpeed=0.4f;
float fDenominator=3.0; // fraction denominator used to calculate synchronised timing of the process that runs concurently with animation
string sS;
string sTag;
string sResRef;
int nApp,nTail,nPheno,nN;
location lLoc;
float fF;
object oOb;
int nStoredState=GetLocalInt(oRider,"nX3_StoredMountState");
int bPostMount=FALSE;
float fTimeDelay; // used to hold delay common references and reduce some repeated math
int bAct=GetLocalInt(GetModule(),"X3_HORSE_ACT_VS_DELAY");
float fX3_MOUNT_MULTIPLE=GetLocalFloat(GetArea(oRider),"fX3_MOUNT_MULTIPLE");
float fX3_TIMEOUT_TO_MOUNT=GetLocalFloat(GetModule(),"fX3_TIMEOUT_TO_MOUNT");
if (GetLocalFloat(oRider,"fX3_MOUNT_MULTIPLE")>fX3_MOUNT_MULTIPLE) fX3_MOUNT_MULTIPLE=GetLocalFloat(oRider,"fX3_MOUNT_MULTIPLE");
if (fX3_MOUNT_MULTIPLE<=0.0) fX3_MOUNT_MULTIPLE=1.0;
if (GetLocalFloat(oRider,"fX3_TIMEOUT_TO_MOUNT")!=0.0) fX3_TIMEOUT_TO_MOUNT=GetLocalFloat(oRider,"fX3_TIMEOUT_TO_MOUNT");
if (fX3_TIMEOUT_TO_MOUNT<6.0) fX3_TIMEOUT_TO_MOUNT=18.0;
if (GetStringLength(GetLocalString(oHorse,"X3_HORSE_POSTMOUNT_SCRIPT"))>0) bPostMount=TRUE;
if (HorseGetIsDisabled()) return; // drop out if disabled
if (GetObjectType(oHorse)!=OBJECT_TYPE_CREATURE) return;
if (GetIsInCombat(oRider)||GetIsInCombat(oHorse)||IsInConversation(oRider)) return;
if (nState!=0&&nStoredState>nState) return; // abort recursion of this state
switch(nState)
{ // main mounting switch
case 0:
{ // ----- 0 - Initial State
DeleteLocalInt(oRider,"nX3_StoredMountState");
if (!HorseGetCanBeMounted(oHorse,oRider))
{ // not mountable
if (GetIsPC(oRider))
{ // provide error message
FloatingTextStrRefOnCreature(111983,oRider,FALSE);
} // provide error message
return;
} // not mountable
if (GetDistanceBetween(oHorse,oRider)>20.0)
{ // too far
ClearAllActions();
ActionMoveToObject(oHorse,TRUE,15.0);
return;
} // too far
sS=GetLocalString(oHorse,"X3_HORSE_PREMOUNT_SCRIPT");
if (GetStringLength(sS)>0)
{ // premount script
SetLocalObject(oRider,"oX3_TempHorse",oHorse);
ExecuteScript(sS,oRider);
if (GetLocalInt(oHorse,"X3_HORSE_NOMOUNT"))
{ // no mount set
DeleteLocalInt(oHorse,"X3_HORSE_NOMOUNT");
return;
} // no mount set
} // premount script
SetLocalInt(oHorse,"X3_DOING_HORSE_ACTION",TRUE);
SetLocalInt(oRider,"X3_DOING_HORSE_ACTION",TRUE);
if (bAct)
{ // make sure horse action can be cancelled if actions cancelled
fTimeDelay=8.0*fX3_MOUNT_MULTIPLE;
DelayCommand(fTimeDelay,DeleteLocalInt(oHorse,"X3_DOING_HORSE_ACTION"));
DelayCommand(fTimeDelay,DeleteLocalInt(oRider,"X3_DOING_HORSE_ACTION"));
} // make sure horse action can be cancelled if actions cancelled
SetSkinInt(oRider,"nX3_StoredFootstep",GetFootstepType(oRider));
SetSkinInt(oRider,"nX3_HorseRiderPhenotype",GetPhenoType(oRider));
SetLocalInt(oRider,"X3_HORSE_TAIL",HorseGetMountTail(oHorse));
SetSkinInt(oRider,"nX3_HorseRiderAppearance",GetAppearanceType(oRider));
SetSkinInt(oRider,"nX3_HorseTail",GetCreatureTailType(oHorse));
SetSkinInt(oRider,"nX3_HorseAppearance",GetAppearanceType(oHorse));
SetLocalInt(oRider,"nX3_HorsePortrait",GetPortraitId(oHorse));
SetLocalInt(oRider,"nX3_RiderHP",GetCurrentHitPoints(oRider));
SetSkinInt(oRider,"nX3_HorseHP",GetCurrentHitPoints(oHorse));
SetSkinInt(oRider,"nX3_HorseRiderTail",GetCreatureTailType(oRider));
SetLocalInt(oRider,"bX3_IS_RIDER",TRUE);
if (!GetIsPC(oRider))
{ // not a PC - set associate state
SetAssociateState(NW_ASC_IS_BUSY,TRUE,oRider);
} // not a PC - set associate state
AssignCommand(oHorse,ClearAllActions(TRUE));
fTimeDelay=(fX3_TIMEOUT_TO_MOUNT+HORSE_MOUNT_DURATION)*fX3_MOUNT_MULTIPLE;
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneImmobilize(),oHorse,fTimeDelay);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneGhost(),oHorse,fTimeDelay);
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")&&!bAct) AssignCommand(GetModule(),DelayCommand(2.0,HORSE_SupportSetMountingSentinel(oRider,oHorse,fX3_TIMEOUT_TO_MOUNT)));
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")&&!bAct) SetCommandable(FALSE,oHorse);
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")&&!bAct) SetCommandable(FALSE,oRider);
fTimeDelay=fMonitorSpeed*fX3_MOUNT_MULTIPLE;
SetLocalFloat(oRider,"X3_TOTAL_MOUNT_ANIMATION_DELAY",fDenominator*fTimeDelay); // sets a small time delay so that the following code doesnt happen at once
if (!bAnimate&&bInstant)
{ // rapid mount
DelayCommand(fTimeDelay,HorseMount(oHorse,bAnimate,bInstant,4));
} // rapid mount
else
{ // move
if (!bAct)
{ // not actions
DelayCommand(fTimeDelay,HorseMount(oHorse,bAnimate,bInstant,1));
} // not actions
else
{ // use actions - interruptable
ClearAllActions();
ActionMoveToObject(oHorse,TRUE,1.5);
ActionDoCommand(HorseMount(oHorse,bAnimate,bInstant,1));
} // use actions - interruptable
} // move
break;
} // ----- 0 - Initial State
case 1:
{ // ----- 1 - Move To Horse
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")&&GetCommandable(oHorse)&&!bAct) SetCommandable(FALSE,oHorse);
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")&&GetCommandable(oRider)&&!bAct) SetCommandable(FALSE,oRider);
oOb=GetLocalObject(oHorse,"oX3_TempRider");
if (oOb!=oRider&&GetIsObjectValid(oOb))
{ // someone else is mounting that
if (GetIsPC(oRider))
{ // someone else mounting
FloatingTextStringOnCreature(GetName(oOb)+GetStringByStrRef(111984),oRider,FALSE);
} // someone else mounting
DeleteLocalInt(oRider,"X3_DOING_HORSE_ACTION");
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")&&!bAct) SetCommandable(TRUE,oRider);
return;
} // someone else is mounting that
SetLocalObject(oHorse,"oX3_TempRider",oRider);
lLoc=HORSE_SupportGetMountLocation(oHorse,oRider,-90.0);
if (GetLocalInt(GetArea(oRider),"bX3_MOUNT_NO_ZAXIS")||GetLocalInt(GetModule(),"bX3_MOUNT_NO_ZAXIS")||GetLocalInt(oRider,"bX3_MOUNT_NO_ZAXIS"))
{ // use vector without z axis - thanks Azbest
vector vLoc=GetPositionFromLocation(lLoc);
vector vRider=GetPosition(oRider);
vLoc-=Vector(0.0,0.0,vLoc.z);
vRider-=Vector(0.0,0.0,vRider.z);
fF=VectorMagnitude(vLoc-vRider);
} // use vector without z axis - thanks Azbest
else
{ // use location including Z axis
fF=GetDistanceBetweenLocations(GetLocation(oRider),lLoc);
} // use location including Z axis
fMonitorSpeed=GetLocalFloat(GetModule(),"fX3_FREQUENCY");
if (fMonitorSpeed<0.5||fMonitorSpeed>9.0) fMonitorSpeed=1.0; // frequency
fTimeDelay=fMonitorSpeed*fX3_MOUNT_MULTIPLE;
if (fX3_TIMEOUT_TO_MOUNT<fTimeDelay) fX3_TIMEOUT_TO_MOUNT=fTimeDelay;
if (fF>0.1&&GetLocalInt(oRider,"nX3_MovingMount")<=FloatToInt(fX3_TIMEOUT_TO_MOUNT/fTimeDelay))
{ // keep moving
nN=GetLocalInt(oRider,"nX3_MovingMount");
nN++; // used to support timing out if cannot reach destination
SetLocalInt(oRider,"nX3_MovingMount",nN);
if (nN>FloatToInt(fX3_TIMEOUT_TO_MOUNT/fTimeDelay))
{ // timed out
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
ClearAllActions();
ActionWait(X3_ACTION_DELAY*fX3_MOUNT_MULTIPLE);
ActionJumpToLocation(lLoc);
SetCommandable(FALSE,oRider);
}
bAnimate=FALSE;
} // timed out
else
{ // keep trying
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
ClearAllActions();
ActionMoveToLocation(lLoc,TRUE);
SetCommandable(FALSE,oRider);
}
SetLocalInt(oRider,"nX3_StoredMountState",1);
float fLastHorseDist=GetDistanceBetween(oRider,oHorse);
if (fLastHorseDist==GetLocalFloat(oRider,"fLastHorseDist"))
{
if (GetLocalInt(GetArea(oRider),"X3_ABORT_WHEN_STUCK")||GetLocalInt(oHorse,"X3_ABORT_WHEN_STUCK"))
{ // break next call if we are found twice within the same distance from horse, which means we are stuck
SetLocalInt(oRider,"bPathIsBlocked",TRUE);
SetLocalInt(oRider,"nX3_StoredMountState",2);
} // break next call if we are found twice within the same distance from horse, which means we are stuck
else
{ // if we are stuck, we want to mount
// no need to set bPathIsBlocked flag, because forced mount continues the proper chain of commands
SetLocalInt(oRider,"nX3_MovingMount",FloatToInt(fX3_TIMEOUT_TO_MOUNT/fTimeDelay)+1);
} // if we are stuck, we want to mount
}
SetLocalFloat(oRider,"fLastHorseDist",fLastHorseDist);
} // keep trying
DelayCommand(fTimeDelay,HorseMount(oHorse,bAnimate,bInstant,1));
} // keep moving
else
{ // next state
DeleteLocalInt(oRider,"nX3_MovingMount");
DeleteLocalFloat(oRider,"fLastHorseDist");
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
ClearAllActions();
SetFacing(GetFacing(oHorse));
SetCommandable(FALSE,oRider);
}
if (bAnimate&&!GetLocalInt(oHorse,"X3_NO_MOUNT_ANIMATE"))
{ // see about animate
DelayCommand(0.1*fX3_MOUNT_MULTIPLE,HorseMount(oHorse,bAnimate,bInstant,2));
} // see about animate
else
{ // no animate
DelayCommand(0.1*fX3_MOUNT_MULTIPLE,HorseMount(oHorse,bAnimate,bInstant,4));
} // no animate
} // next state
break;
} // ----- 1 - Move to Horse
case 2:
{ // ----- 2 - Adjust for Animation
SetLocalInt(oRider,"nX3_StoredMountState",3);
nTail=GetLocalInt(oRider,"X3_HORSE_TAIL");
SetLocalInt(oHorse,"X3_HORSE_TAIL",nTail);
nApp=HORSE_SupportNullAppearance(oHorse,oRider);
if (nApp>0) SetCreatureAppearanceType(oHorse,nApp);
SetCreatureTailType(nTail,oHorse);
DelayCommand(1.0*fX3_MOUNT_MULTIPLE,HorseMount(oHorse,bAnimate,bInstant,3)); // 1.0 second seems to be long enough to set up for animation
break;
} // ----- 2 - Adjust for Animation
case 3:
{ // ----- 3 - Animate
SetLocalInt(oRider,"nX3_StoredMountState",4);
fMonitorSpeed=HORSE_MOUNT_DURATION;
if (GetLocalFloat(oHorse,"X3_HORSE_MOUNT_DURATION")>0.0) fMonitorSpeed=GetLocalFloat(oHorse,"X3_HORSE_MOUNT_DURATION");
if (fMonitorSpeed<1.0) fMonitorSpeed=1.0;
fMonitorSpeed*=fX3_MOUNT_MULTIPLE;
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneGhost(),oHorse,fMonitorSpeed+0.5);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneGhost(),oRider,fMonitorSpeed+0.5);
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
ClearAllActions();
ActionPlayAnimation(HORSE_ANIMATION_MOUNT,1.0,fMonitorSpeed);
SetCommandable(FALSE,oRider);
}
SetLocalFloat(oRider,"X3_TOTAL_MOUNT_ANIMATION_DELAY",fMonitorSpeed); // "case 4:" and "case 5:" need to happen concurrently and with the same time duration as the animation itself
'>
HorseMount(oHorse,bAnimate,bInstant,4);
break;
} // ----- 3 - Animate
case 4:
{ // ----- 4 - Store Horse and Premount Info
SetLocalInt(oRider,"nX3_StoredMountState",5);
sResRef=GetResRef(oHorse);
if (GetStringLength(sResRef)<1) SendMessageToPC(oRider,"x3_inc_horse(HorseMount): Error finding horse ResRef in case 4.");
SetSkinString(oRider,"sX3_HorseResRef",sResRef);
SetSkinString(oRider,"sX3_HorseMountTag",GetTag(oHorse));
SetLocalString(oRider,"sX3_HorseMountScript",GetLocalString(oHorse,"sX3_HORSE_CREATED_SCRIPT"));
SetSkinString(oRider,"X3_HORSE_PREDISMOUNT_SCRIPT",GetLocalString(oHorse,"X3_HORSE_PREDISMOUNT_SCRIPT"));
SetSkinString(oRider,"X3_HORSE_POSTDISMOUNT_SCRIPT",GetLocalString(oHorse,"X3_HORSE_POSTDISMOUNT_SCRIPT"));
SetLocalInt(oRider,"X3_NO_MOUNT_ANIMATE",GetLocalInt(oHorse,"X3_NO_MOUNT_ANIMATE"));
if (GetLocalInt(oHorse,"X3_ABORT_WHEN_STUCK")) SetLocalInt(oRider,"X3_ABORT_WHEN_STUCK",TRUE);
if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))
{ // saddlebags support enabled
if (GetLocalInt(oHorse,"bX3_HAS_SADDLEBAGS")&&GetLocalObject(oHorse,"oX3_HorseOwner")!=oRider) if (GetMaster(oHorse)!=oRider) HorseSetOwner(oHorse,oRider,TRUE);
SetLocalInt(oRider,"bX3_HAS_SADDLEBAGS",GetLocalInt(oHorse,"bX3_HAS_SADDLEBAGS"));
if (GetLocalInt(oHorse,"bX3_HAS_SADDLEBAGS"))
{ // transfer inventory
HorseStoreInventory(oHorse,oRider);
} // transfer inventory
} // saddlebads support enabled
fMonitorSpeed=GetLocalFloat(oRider,"X3_TOTAL_MOUNT_ANIMATION_DELAY")*(fDenominator-1.0)/fDenominator;
DelayCommand(fMonitorSpeed,HorseMount(oHorse,bAnimate,bInstant,5));
break;
} // ----- 4 - Store Horse and Premount Info
case 5:
{ // ----- 5 - Set Appearance
SetLocalInt(oRider,"nX3_StoredMountState",6);
nApp=GetAppearanceType(oHorse);
nTail=GetLocalInt(oRider,"X3_HORSE_TAIL");
SetCreatureAppearanceType(oRider,HORSE_SupportGetMountedAppearance(oRider));
HorseSetPhenotype(oRider);
SetCreatureTailType(nTail,oRider);
nApp=GetLocalInt(oHorse,"X3_HORSE_FOOTSTEP");
if (nApp>0) SetFootstepType(nApp,oRider);
else { SetFootstepType(HORSE_FOOTSTEP_SOUND,oRider); }
fMonitorSpeed=GetLocalFloat(oRider,"X3_TOTAL_MOUNT_ANIMATION_DELAY")/fDenominator;
if (!bAnimate||bInstant) fTimeDelay=fMonitorSpeed;
else fTimeDelay=0.6; // changing appearance, pheno and tail takes about 0.6 second, hide the horse after that amount of time
DelayCommand(fTimeDelay,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY),oHorse,fMonitorSpeed*fDenominator));
DelayCommand(fMonitorSpeed,HorseMount(oHorse,bAnimate,bInstant,6));
break;
} // ----- 5 - Set Appearance
case 6:
{ // ----- 6 - Destroy oHorse
SetLocalInt(oRider,"nX3_StoredMountState",7);
SetSkinInt(oRider,"bX3_IS_MOUNTED",TRUE);
SetLocalObject(oRider,"oX3_Saddlebags",GetLocalObject(oHorse,"oX3_Saddlebags"));
sS=GetLocalString(oHorse,"X3_HORSE_POSTMOUNT_SCRIPT");
if (bPostMount)
{ // run post mount script
SetLocalObject(oRider,"oX3_TempHorse",oHorse);
ExecuteScript(sS,oRider);
DeleteLocalObject(oRider,"oX3_TempHorse");
DeleteLocalInt(oRider,"bX3_HORSE_MODIFIERS");
} // run post mount script
else
{ // no post mount script
HORSE_SupportIncreaseSpeed(oRider,oHorse);
HORSE_SupportAdjustMountedArcheryPenalty(oRider);
DelayCommand(0.4,HORSE_SupportApplyMountedSkillDecreases(oRider));
HORSE_SupportApplyACBonus(oRider,oHorse);
HORSE_SupportApplyHPBonus(oRider,oHorse);
} // no post mount script
SetLocalInt(oRider,"bX3_HORSE_MODIFIERS",TRUE);
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")) SetLocalInt(oRider,"bX3_STORE_MOUNT_INFO",TRUE);
DeleteLocalFloat(oRider,"X3_TOTAL_MOUNT_ANIMATION_DELAY");
AssignCommand(oHorse,SetIsDestroyable(TRUE,FALSE,FALSE));
DestroyObject(oHorse,0.3);
DelayCommand(0.5*fX3_MOUNT_MULTIPLE,DeleteLocalInt(oRider,"X3_DOING_HORSE_ACTION"));
if (!GetIsPC(oRider))
{ // not a PC - set associate state
DelayCommand(0.5*fX3_MOUNT_MULTIPLE,SetAssociateState(NW_ASC_IS_BUSY,FALSE,oRider));
} // not a PC - set associate state
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")) DelayCommand(0.5*fX3_MOUNT_MULTIPLE,SetCommandable(TRUE,oRider));
break;
} // ----- 6 - Destroy oHorse
default: break;
} // main mounting switch
} // HorseMount()
object HorseDismount(int bAnimate=TRUE,int bSetOwner=TRUE)
{ // PURPOSE: Dismount the horse
object oRider=OBJECT_SELF;
object oHorse=OBJECT_INVALID;
object oOb;
string sS,sRR,sT;
int nN,nApp,nTail,nFootstep;
int bPostDismount=FALSE;
location lLoc;
float fX3_MOUNT_MULTIPLE=GetLocalFloat(GetArea(oRider),"fX3_MOUNT_MULTIPLE");
float fX3_DISMOUNT_MULTIPLE=GetLocalFloat(GetArea(oRider),"fX3_DISMOUNT_MULTIPLE");
if (GetLocalFloat(oRider,"fX3_MOUNT_MULTIPLE")>fX3_MOUNT_MULTIPLE) fX3_MOUNT_MULTIPLE=GetLocalFloat(oRider,"fX3_MOUNT_MULTIPLE");
if (fX3_MOUNT_MULTIPLE<=0.0) fX3_MOUNT_MULTIPLE=1.0;
if (GetLocalFloat(oRider,"fX3_DISMOUNT_MULTIPLE")>0.0) fX3_DISMOUNT_MULTIPLE=GetLocalFloat(oRider,"fX3_DISMOUNT_MULTIPLE");
if (fX3_DISMOUNT_MULTIPLE>0.0) fX3_MOUNT_MULTIPLE=fX3_DISMOUNT_MULTIPLE; // use dismount multiple instead of mount multiple
float fDelay=1.0*fX3_MOUNT_MULTIPLE; // base delay for non-animated dismount
if (GetStringLength(GetLocalString(oHorse,"X3_HORSE_POSTDISMOUNT_SCRIPT"))>0) bPostDismount=TRUE;
if (GetIsObjectValid(oRider))
{ // oRider is a valid object
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")) SetCommandable(FALSE,oRider);
if (HorseGetIsMounted(oRider))
{ // Mounted
if (!GetIsPC(oRider))
{ // not PC - set associate state busy
SetAssociateState(NW_ASC_IS_BUSY,TRUE,oRider);
} // not PC - set associate state busy
sS=GetSkinString(oRider,"X3_HORSE_PREDISMOUNT_SCRIPT");
if (GetStringLength(sS)>0)
{ // PREDISMOUNT SCRIPT
ExecuteScript(sS,oRider);
if (GetLocalInt(oRider,"X3_HORSE_NOMOUNT"))
{ // abort
DeleteLocalInt(oRider,"X3_HORSE_NOMOUNT");
return OBJECT_INVALID;
} // abort
} // PREDISMOUNT SCRIPT
DeleteSkinString(oRider,"X3_HORSE_PREDISMOUNT_SCRIPT");
SetLocalInt(oRider,"X3_DOING_HORSE_ACTION",TRUE);
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
ClearAllActions();
SetCommandable(FALSE,oRider);
}
if (bAnimate&&!GetLocalInt(oRider,"X3_NO_MOUNT_ANIMATE"))
{ // animated dismount
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
ActionWait(X3_ACTION_DELAY*fX3_MOUNT_MULTIPLE);
ActionPlayAnimation(HORSE_ANIMATION_DISMOUNT,1.0,HORSE_DISMOUNT_DURATION*fX3_MOUNT_MULTIPLE);
SetCommandable(FALSE,oRider);
}
fDelay=(X3_ACTION_DELAY+HORSE_DISMOUNT_DURATION)*fX3_MOUNT_MULTIPLE; // delay for animated dismount
}
sRR=GetSkinString(oRider,"sX3_HorseResRef");
if (GetStringLength(sRR)>0)
{ // create dismounted horse
if (bSetOwner) oOb=oRider;
sT=GetSkinString(oRider,"sX3_HorseMountTag");
nApp=GetSkinInt(oRider,"nX3_HorseAppearance");
nTail=GetSkinInt(oRider,"nX3_HorseTail"); // add this to be preserved
if (nApp<7) nApp=-1;
if (nTail<3) nTail=-1;
if (nFootstep<2) nFootstep=-1;
nFootstep=GetFootstepType(oRider);
sS=GetLocalString(oRider,"sX3_HorseMountScript");
lLoc=HORSE_SupportGetMountLocation(oRider,oRider,-90.0);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneGhost(),oRider,fDelay+1.0*fX3_MOUNT_MULTIPLE);
oHorse=HorseCreateHorse(sRR,GetLocation(oRider),oOb,sT,nApp,nTail,nFootstep,sS);
SetLocalInt(oHorse,"X3_DOING_HORSE_ACTION",TRUE);
if (GetLocalInt(oRider,"X3_ABORT_WHEN_STUCK")) SetLocalInt(oHorse,"X3_ABORT_WHEN_STUCK",TRUE);
if (!GetIsObjectValid(oHorse))
{ // failed to create
SendMessageToPC(oRider,"x3_inc_horse(HorseDismount): Failed to create horse.");
} // failed to create
if (oOb==oRider) SetLocalObject(oRider,"oAssignedHorse",oHorse);
if (GetLocalInt(oRider,"nX3_HorsePortrait")>0) SetPortraitId(oHorse,GetLocalInt(oRider,"nX3_HorsePortrait"));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY),oHorse,fDelay+0.5*fX3_MOUNT_MULTIPLE);
if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS")&&GetIsObjectValid(oHorse))
{ // saddlebags support enabled
SetLocalInt(oHorse,"bX3_HAS_SADDLEBAGS",GetLocalInt(oRider,"bX3_HAS_SADDLEBAGS"));
if (GetLocalInt(oRider,"bX3_HAS_SADDLEBAGS"))
{ // transfer contents
HorseRestoreInventory(oHorse);
} // transfer contents
} // saddlebads support enabled
} // create dismounted horse
else
{ // resref not defined
SendMessageToPC(oRider,"x3_inc_horse(HorseDismount): Error resref missing.");
} // resref not defined
DeleteSkinInt(oRider,"bX3_IS_MOUNTED");
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")) SetLocalInt(oRider,"bX3_STORE_MOUNT_INFO",TRUE);
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE"))
{
SetCommandable(TRUE,oRider);
if (!bAnimate||GetLocalInt(oRider,"X3_NO_MOUNT_ANIMATE")) ActionWait(fDelay);
ActionMoveToLocation(lLoc,FALSE);
SetCommandable(FALSE,oRider);
}
DelayCommand(fDelay-0.8*fX3_MOUNT_MULTIPLE,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectCutsceneGhost(),oHorse,1.7*fX3_MOUNT_MULTIPLE));
//DelayCommand(fDelay-0.8*fX3_MOUNT_MULTIPLE+1.7*fX3_MOUNT_MULTIPLE, FloatingTextStringOnCreature("ghost off",oRider)); // this tells us when the ghost effect from the above line wears off
DelayCommand(fDelay-0.7*fX3_MOUNT_MULTIPLE,HORSE_SupportResetUnmountedAppearance(oRider)); // keep in mind: changing mounted appearances takes about 0.6 seconds
DelayCommand(fDelay+0.0*fX3_MOUNT_MULTIPLE,HORSE_SupportTransferPreservedValues(oRider,oHorse));
DelayCommand(fDelay+0.7*fX3_MOUNT_MULTIPLE,HORSE_SupportCleanVariables(oRider));
DelayCommand(fDelay+1.0*fX3_MOUNT_MULTIPLE,DeleteLocalInt(oRider,"X3_DOING_HORSE_ACTION"));
DelayCommand(fDelay+1.0*fX3_MOUNT_MULTIPLE,DeleteLocalInt(oHorse,"X3_DOING_HORSE_ACTION"));
if (!GetIsPC(oRider))
{ // not PC - set associate state not busy
DelayCommand(fDelay+1.0*fX3_MOUNT_MULTIPLE,SetAssociateState(NW_ASC_IS_BUSY,FALSE,oRider));
} // not PC - set associate state not busy
if (!GetLocalInt(GetModule(),"X3_NO_MOUNT_COMMANDABLE")) DelayCommand(fDelay+1.0*fX3_MOUNT_MULTIPLE,SetCommandable(TRUE,oRider));
} // Mounted
} // oRider is a valid object
return oHorse;
} // HorseDismount()
int HorseGetMountTail(object oHorse)
{ // PURPOSE: Determine the tail that is needed to represent this horse
int nTail=GetCreatureTailType(oHorse);
int nApp=GetAppearanceType(oHorse);
if (GetLocalInt(oHorse,"X3_HORSE_TAIL")>0) return GetLocalInt(oHorse,"X3_HORSE_TAIL");
if (nApp>=HORSE_APPEARANCE_OFFSET&&nApp<=HORSE_APPEARANCE_OFFSET+HORSE_NUMBER_OF_HORSES)
{ // default horses
return (nApp-HORSE_APPEARANCE_OFFSET)+HORSE_TAIL_OFFSET;
} // default horses
else if (nApp>=HORSE_NULL_RACE_DWARF&&nApp<=HORSE_NULL_RACE_HUMAN) return nTail;
return CREATURE_TAIL_TYPE_NONE;
} // HorseGetMountTail()
void HorseInstantDismount(object oRider)
{ // PURPOSE: Instantly dismount oRider
float fX3_MOUNT_MULTIPLE=GetLocalFloat(GetArea(oRider),"fX3_MOUNT_MULTIPLE");
float fX3_DISMOUNT_MULTIPLE=GetLocalFloat(GetArea(oRider),"fX3_DISMOUNT_MULTIPLE");
if (GetLocalFloat(oRider,"fX3_MOUNT_MULTIPLE")>fX3_MOUNT_MULTIPLE) fX3_MOUNT_MULTIPLE=GetLocalFloat(oRider,"fX3_MOUNT_MULTIPLE");
if (fX3_MOUNT_MULTIPLE<=0.0) fX3_MOUNT_MULTIPLE=1.0;
if (GetLocalFloat(oRider,"fX3_DISMOUNT_MULTIPLE")>0.0) fX3_DISMOUNT_MULTIPLE=GetLocalFloat(oRider,"fX3_DISMOUNT_MULTIPLE");
if (fX3_DISMOUNT_MULTIPLE>0.0) fX3_MOUNT_MULTIPLE=fX3_DISMOUNT_MULTIPLE; // use dismount multiple instead of mount multiple
HORSE_SupportResetUnmountedAppearance(oRider);
DeleteLocalInt(oRider,"bX3_HORSE_MODIFIERS");
DelayCommand(0.1*fX3_MOUNT_MULTIPLE,HORSE_SupportOriginalSpeed(oRider));
DelayCommand(0.2*fX3_MOUNT_MULTIPLE,HORSE_SupportRemoveMountedSkillDecreases(oRider));
DelayCommand(0.2*fX3_MOUNT_MULTIPLE,HORSE_SupportAdjustMountedArcheryPenalty(oRider));
DelayCommand(0.3*fX3_MOUNT_MULTIPLE,HORSE_SupportRemoveACBonus(oRider));
DelayCommand(0.3*fX3_MOUNT_MULTIPLE,HORSE_SupportRemoveHPBonus(oRider));
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")) SetLocalInt(oRider,"bX3_STORE_MOUNT_INFO",TRUE);
DelayCommand(0.4*fX3_MOUNT_MULTIPLE,HORSE_SupportMountCleanVariables(oRider));
DeleteSkinInt(oRider,"bX3_IS_MOUNTED");
} // HorseInstantDismount()
void HorseInstantMount(object oRider,int nTail,int bJoust=FALSE,string sResRef="")
{ // PURPOSE: Instantly mount oRider
string sRR=sResRef;
if (GetStringLength(sRR)<1) sRR="x3_horse001";
SetSkinInt(oRider,"nX3_StoredFootstep",GetFootstepType(oRider));
SetSkinInt(oRider,"nX3_HorseRiderPhenotype",GetPhenoType(oRider));
SetSkinInt(oRider,"nX3_HorseRiderAppearance",GetAppearanceType(oRider));
SetLocalInt(oRider,"nX3_RiderHP",GetCurrentHitPoints(oRider));
SetSkinInt(oRider,"nX3_HorseRiderTail",GetCreatureTailType(oRider));
SetCreatureAppearanceType(oRider,HORSE_SupportGetMountedAppearance(oRider));
HorseSetPhenotype(oRider,bJoust);
SetCreatureTailType(nTail,oRider);
SetFootstepType(HORSE_FOOTSTEP_SOUND,oRider);
SetSkinString(oRider,"sX3_HorseResRef",sRR);
HORSE_SupportIncreaseSpeed(oRider,OBJECT_INVALID);
HORSE_SupportAdjustMountedArcheryPenalty(oRider);
SetSkinInt(oRider,"bX3_IS_MOUNTED",TRUE);
DelayCommand(0.5,HORSE_SupportApplyMountedSkillDecreases(oRider));
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")) SetLocalInt(oRider,"bX3_STORE_MOUNT_INFO",TRUE);
SetLocalInt(oRider,"bX3_HORSE_MODIFIERS",TRUE);
} // HorseInstantMount()
object HorseGetPaladinMount(object oRider)
{ // PURPOSE: Return the paladin mount for oRider
string sS;
object oNPC;
int nN=1;
if (GetIsObjectValid(oRider)&&GetObjectType(oRider)==OBJECT_TYPE_CREATURE)
{ // valid parameter
sS=GetResRef(oRider);
if (GetStringLeft(sS,GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) return oRider; // oRider IS a paladin mount
sS=GetSkinString(oRider,"sX3_HorseResRef");
if (GetStringLeft(sS,GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) return oRider; // oRider is riding a paladin mount
oNPC=GetLocalObject(oRider,"oX3PaladinMount");
if (GetIsObjectValid(oNPC)&&GetStringLeft(GetResRef(oNPC),GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) return oNPC;
oNPC=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oRider,nN);
while(GetIsObjectValid(oNPC))
{ // check henchmen
sS=GetResRef(oNPC);
if (GetStringLeft(sS,GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) return oNPC;
nN++;
oNPC=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oRider,nN);
} // check henchmen
return GetLocalObject(oRider,"oX3PaladinMount");
} // valid parameter
return OBJECT_INVALID;
} // HorseGetPaladinMount()
object HorseSummonPaladinMount(int bPHBDuration=FALSE)
{ // PURPOSE: Summon Paladin Mount
object oSummoner=OBJECT_SELF;
object oMount;
location lLoc;
int nLevel=GetLevelByclass(class_TYPE_PALADIN,oSummoner);
int nDespawnTime;
int nCurrentTime;
int nMountNum=1;
string sResRef=HORSE_PALADIN_PREFIX;
effect eVFX;
oMount=HorseGetPaladinMount(oSummoner);
if (!GetIsObjectValid(oMount)&&nLevel>4&&GetObjectType(oSummoner)==OBJECT_TYPE_CREATURE)
{ // okay to summon - only one paladin mount at a time
if ((GetIsPC(oSummoner)||GetIsDM(oSummoner))&&!GetHasFeat(FEAT_HORSE_MENU,oSummoner)) HorseAddHorseMenu(oSummoner);
if (nLevel>7&&nLevel<11) nMountNum=2;
else if (nLevel>10&&nLevel<15) nMountNum=3;
else if (nLevel>14&&nLevel<25) nMountNum=4;
else if (nLevel>24&&nLevel<30) nMountNum=5;
else if (nLevel>29&&nLevel<35) nMountNum=6;
else if (nLevel>34&&nLevel<40) nMountNum=7;
else if (nLevel>39) nMountNum=8;
lLoc=HORSE_SupportGetMountLocation(oSummoner,oSummoner);
oMount=HorseCreateHorse(sResRef+IntToString(nMountNum),lLoc,oSummoner);
if (!GetIsObjectValid(oMount)) oMount=HorseCreateHorse(sResRef+IntToString(nMountNum),GetLocation(oSummoner),oSummoner);
if (GetIsObjectValid(oMount))
{ // oMount created
eVFX=EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVFX,oMount,3.0);
eVFX=EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_2);
if (nMountNum>3) eVFX=EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eVFX,GetLocation(oMount));
if (bPHBDuration)
{ // Players Handbook 3.5 edition durations
nCurrentTime=HORSE_SupportAbsoluteMinute();
nDespawnTime=(2*nLevel*60)+nCurrentTime;
SetLocalInt(oSummoner,"nX3_PALADIN_UNSUMMON",nDespawnTime);
} // Players Handbook 3.5 edition durations
else
{ // 24 hour - popular bioware
nCurrentTime=HORSE_SupportAbsoluteMinute();
nDespawnTime=nCurrentTime+(60*24);
SetLocalInt(oSummoner,"nX3_PALADIN_UNSUMMON",nDespawnTime);
} // 24 hour - popular bioware
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oSummoner)) SetLocalInt(oSummoner,"bX3_STORE_MOUNT_INFO",TRUE);
SetLocalObject(oSummoner,"oX3PaladinMount",oMount);
} // oMount created
} // okay to summon - only one paladin mount at a time
else { oMount=OBJECT_INVALID; }
return oMount;
} // HorseSummonPaladinMount()
void HorseUnsummonPaladinMount()
{ // PURPOSE: Unsummon Paladin Mount
object oPaladin=OBJECT_SELF;
object oMount=HorseGetPaladinMount(oPaladin);
effect eVFX;
if (!GetIsObjectValid(oMount)) oMount=GetLocalObject(oPaladin,"oX3PaladinMount");
if (GetIsObjectValid(oMount)&&oMount!=oPaladin)
{ // Paladin Mount exists
if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oPaladin)) SetLocalInt(oPaladin,"bX3_STORE_MOUNT_INFO",TRUE);
if (oMount==oPaladin)
{ // Mounted - must dismount first
ClearAllActions(TRUE);
oMount=HorseDismount(FALSE,TRUE);
DelayCommand(3.0,HorseUnsummonPaladinMount());
} // Mounted - must dismount first
else
{ // is the mount
if (GetIsPC(oPaladin))
{
SendMessageToPCByStrRef(oPaladin,111985);
}
DeleteLocalInt(oPaladin,"nX3_PALADIN_UNSUMMON");
eVFX=EffectVisualEffect(VFX_IMP_UNSUMMON);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eVFX,GetLocation(oMount));
DestroyObject(oMount);
} // is the mount
} // Paladin Mount exists
else
{ // perhaps the command is being called by the mount itself
if (GetStringLeft(GetResRef(oPaladin),GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX)
{ // is a paladin mount despawning itself
oMount=oPaladin;
eVFX=EffectVisualEffect(VFX_IMP_UNSUMMON);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eVFX,GetLocation(oMount));
DestroyObject(oMount);
} // is a paladin mount despawning itself
} // perhaps the command is being called by the mount itself
} // HorseUnsummonPaladinMount()
int HorseGetIsAMount(object oTarget)
{ // PURPOSE: Return TRUE if oTarget is a mountable creature
int nApp;
int nTail;
if (GetSkinInt(oTarget,"bX3_IS_MOUNTED")) return FALSE;
if (GetLocalInt(oTarget,"bX3_IS_MOUNT")) return TRUE;
else if (GetLocalInt(oTarget,"bX3_IS_RIDER")) return FALSE;
else if (GetStringLength(GetLocalString(oTarget,"X3_HORSE_PREMOUNT_SCRIPT"))>0) return TRUE;
else if (GetStringLength(GetLocalString(oTarget,"X3_HORSE_PREDISMOUNT_SCRIPT"))>0) return TRUE;
else if (GetStringLength(GetLocalString(oTarget,"X3_HORSE_POSTDISMOUNT_SCRIPT"))>0) return TRUE;
else if (GetStringLength(GetLocalString(oTarget,"X3_HORSE_POSTMOUNT_SCRIPT"))>0) return TRUE;
else if (GetStringLength(GetLocalString(oTarget,"X3_HORSE_OWNER_TAG"))>0) return TRUE;
else if (GetLocalInt(oTarget,"X3_HORSE_NULL_APPEARANCE")>0) return TRUE;
//else if (GetSkinInt(oTarget,"X3_HORSE_APPEARANCE")>0) return TRUE;
else if (GetLocalInt(oTarget,"X3_HORSE_TAIL")>0) return TRUE;
nApp=GetAppearanceType(oTarget);
nTail=GetCreatureTailType(oTarget);
if (nApp>=HORSE_APPEARANCE_OFFSET&&nApp<=HORSE_APPEARANCE_OFFSET+HORSE_NUMBER_OF_HORSES) return TRUE;
if (nApp==HORSE_NULL_RACE_GNOME||nApp==HORSE_NULL_RACE_ELF||nApp==HORSE_NULL_RACE_GNOME||nApp==HORSE_NULL_RACE_HALFELF||
nApp==HORSE_NULL_RACE_HALFLING||nApp==HORSE_NULL_RACE_HALFORC||nApp==HORSE_NULL_RACE_HUMAN)
{ // might be a tail always based mount
if (nTail>=HORSE_TAIL_OFFSET&&nTail<=HORSE_TAIL_OFFSET+HORSE_NUMBER_OF_HORSES&&nTail!=14) return TRUE;
} // might be a tail always based mount
return FALSE;
} // HorseGetIsAMount()
void HorseStoreInventory(object oCreature,object oRider=OBJECT_INVALID)
{ // PURPOSE: To store inventory being carried by oCreature
object oWP=GetWaypointByTag("X3_HORSE_INVENTORY_STORAGE");
object oOwner=GetMaster(oCreature);
object oOwnersMaster=GetMaster(oOwner);
object oItem;
object oChest;
object oCont;
int nC;
int nN;
string sR;
string sT;
int nST;
int nCH;
string sID=GetTag(oCreature); // ID to uniquely identify for inventory storage
string sDB="X3SADDLEBAG"+GetTag(GetModule());
if (GetStringLength(GetLocalString(GetModule(),"X3_SADDLEBAG_DATABASE"))>0) sDB=GetLocalString(GetModule(),"X3_SADDLEBAG_DATABASE");
if (GetStringLength(sID)>6) sID=GetStringLeft(sID,6);
sID=sID+GetStringRight(GetResRef(oCreature),2);
if (oOwner!=oCreature&&GetIsObjectValid(oOwner))
{ // owner specified
if (!GetIsPC(oOwner))
{ // henchman owner
sT=GetTag(oOwner);
if (GetStringLength(sT)>
sT=GetStringLeft(sT,6)+GetStringRight(sT,2);
sID=sID+sT;
if (GetIsObjectValid(oOwnersMaster)&&oOwner!=oOwnersMaster&&GetIsPC(oOwnersMaster))
{ // PC
sID=sID+GetPCPublicCDKey(oOwnersMaster)+GetStringLeft(GetName(oOwnersMaster),4);
} // PC
} // henchman owner
else
{ // PC owner
sID=sID+GetPCPublicCDKey(oOwner)+GetStringLeft(GetName(oOwner),4);