Author Topic: Clueless  (Read 2548 times)

Legacy_SHOVA

  • Hero Member
  • *****
  • Posts: 893
  • Karma: +0/-0
Clueless
« Reply #15 on: July 22, 2010, 02:30:49 am »


               You are looking at the current on death script right? I ask this because I have made changes to  mod scripts and then realized that I was using a completely different mod script for the event. It can happen when you are combining scripting systems together. If your in doubt, open the script from the mod properties window.
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #16 on: July 22, 2010, 02:48:27 am »


               yes thats right, the script above is the current ondeath script. i have the old script saved i will put it back in and test the mod, to see if it is still happening if not then it has to be something else.

Psyammy
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #17 on: July 22, 2010, 03:00:11 am »


               ok i just put the old ondeath script in and tested and everything was fine, so it must be something in the cleaned up script i then put the cleaned up script back in and tested and the camera angle changed.

(the old ondeath was just the default ondeath script, with all the OC stuff in it)

Psyammy

               
               

               
            

Legacy_SHOVA

  • Hero Member
  • *****
  • Posts: 893
  • Karma: +0/-0
Clueless
« Reply #18 on: July 22, 2010, 03:10:33 am »


               Please post script: x3_inc_horse
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #19 on: July 22, 2010, 03:17:40 am »


               kk, here it is (it's a long one)



//::///////////////////////////////////////////////

//:: Horse Mounting and Control System

//:: x3_inc_horse

//:: Copyright © 2007-2008 Bioware Corp.

//:://////////////////////////////////////////////

/*

    Holds horse specific functionality which can  be used

    in other scripts to support horses as present in patch 1.69.

*/

//:://////////////////////////////////////////////

//:: Created By: Deva B. Winblood

//:: Tweaking By: Martin "Azbest" Psikal

//:: Created On: Dec 14th, 2007

//:: Last Update: April 21th, 2008

//:: Help from community members: Proleric,

//:: The Krit, OldMansBeard, FriendlyFire,

//:: Bannor "JP" Bloodfist, Brian Chung,

//:: Craig Welburn, Barry_1066, Jahodnik,

//:: fluffyamoeba, Axe Murderer, and more.

//:: Thank you!

//:://////////////////////////////////////////////



#include "x0_i0_position"

#include "X0_INC_HENAI"

#include "x3_inc_skin"



/*



   HOW TO GET THE MOST FROM THIS HORSE SCRIPT:

   ===========================================



   This script has been setup to simply work with the default horses but, some

   effort was made to provide you with some simple methods to hook your own

   mounts, mounting scripts, etc. into this script.





   [HORSE BLUEPRINT VARIABLES]

   ===========================



   The following variables can be set on the BLUEPRINT of a creature to extend

   this mounting system.   These scripts could be used to add database

   functionality, or extend the system however, you like.



   bX3_IS_MOUNT = integer that should be set to 1 if this is a custom blueprint

   mount that for some reason the script indicates is not a mount.



   X3_HORSE_PREMOUNT_SCRIPT = script to fire before the horse is mounted.  If

   this script determines it cannot mount then it will set X3_HORSE_NOMOUNT to

   TRUE on the mount.  You can use a script like this to create support for

   saddlebags or to

   use this to extend the mounting system.  This will be executed by the rider

   and the variable oX3_TempHorse will be set pointing to the horse so that

   the custom script knows which horse this relates to.



   X3_HORSE_POSTMOUNT_SCRIPT = can be set to a script that can be fired after

   this mount is mounted.  This may be useful for adding things like feats and

   other after mounting needs. If this

   script does not exist then the standard Speed, Skill Decreases, Mounted

   Archery Adjustments, etc. will be applied.  If you want your own post mount

   script then it is important to note you will have to apply these modifiers

   if you also want them to be used within your own script.  The horse that

   was mounted will be referenced by oX3_TempHorse as stored on the Rider. If

   you use such a custom hook script make sure to set bX3_IS_MOUNTED to TRUE by

   using the SetSkinInt() function from x3_inc_skin.

   on the rider after they mount.   This is required in some cases for the

   dismount radial to work. (mainly when working with custom mounts)



   X3_HORSE_PREDISMOUNT_SCRIPT = can be set to a script that needs to be

   executed before the dismount portion continues.  If X3_HORSE_NODISMOUNT is

   set to TRUE then the horse dismount will be aborted.



   X3_HORSE_POSTDISMOUNT_SCRIPT = can be set to a script to be executed after

   dismount to reverse steps that may have occurred with a POSTMOUNT script

   such as adding feats.  This script could be used to remove feats.



   It is possible you might want to add a new horse/mount type that does not

   fit neatly into the appearance.2da or tails.2da with the other horse types.

   The following variables if set to any number greater than 0 will override

   the default settings and use what you specifiy instead.



   X3_HORSE_NULL_APPEARANCE = the appearance to use when scaling the horse for

   the mounting animation.



   X3_HORSE_TAIL = the tail to use with the tails.2da that defines this horse.



   X3_HORSE_FOOTSTEP = the footstep number to use when this horse is mounted.



   X3_HORSE_MOUNT_DURATION = is the duration in seconds 0.0f that the mount

   animation should take with this horse.  This only needs to be set if

   the mounting animation for this blueprint is faster or longer than the

   default animations.



   X3_HORSE_MOUNT_SPEED = is the mount speed increase or decrease that should

   be used with this mount.  If the value is 0 then it will use the

   HORSE_DEFAULT_SPEED_INCREASE constant value.



   X3_HORSE_DISMOUNT_DURATION = is the duration in seconds 0.0f that the dis-

   mount animation should take with this hores.  This only needs to be set if

   the dismounting animation for this blueprint is faster or longer than the

   default animations.



   X3_HORSE_RESTRICT_race = is a variable that set to TRUE this horse cannot

   be mounted by the specified race.  Supported races are ELF, HUMAN, HALFELF,

   DWARF, HALFORC, HALFLING, and GNOME, CUSTOM# = racial type number.



   X3_CUSTOM_RACE_APPEARANCE = a variable to set on a rider if they use a custom

   racial appearance.  This value should be set to what appearance number they

   use from appearance.2da.   This will prevent custom races from being denied

   mounting rights due to the script thinking the rider is shape shifted.



   X3_CUSTOM_RACE_MOUNTED_PHENO = This variable should be used on the rider if they

   should use a special phenotype when mounted.  This is provided to support

   custom races.



   X3_CUSTOM_RACE_JOUST_PHENO = This variable should be used on the rider if

   they need a special phenotype when mounted in joust mode.



   X3_CUSTOM_RACE_PHENOTYPE = This variable should be used on the rider if they

   need a special phenotype when not mounted.



   X3_CUSTOM_RACE_MOUNTED_APPEARANCE = a variable to set on the rider to

   indicate which appearance they should use when mounted.



   X3_HORSE_OWNER_TAG = a string that can be set on the horse that will tell

   it to Add itself as a henchman to an NPC with the specified tag.



   X3_HORSE_NOT_RIDEABLE_OWNER = if this integer is set to 1 on the Horse then

   Mount will not be useable and the error it will return if asked is that it

   is NOT rideable due to it being owned by someone else.  This is useful if

   you want horses around that the PCs and Henchmen cannot mount for reasons

   such as they are owned by a store, etc.



   bX3_IS_MOUNT = a variable that should be set to TRUE if a mount is added

   as a henchman but, is still mountable.



   X3_NO_MOUNT_ANIMATE = if this integer is set to 1 then this mount does not EVER

   animate mounting or dismounting.



   X3_TOTAL_MOUNT_ANIMATION_DELAY = a variable containing a time lot indicating

   how much time the routine has before it needs to be finished. it is used for

   the sake of synchronizing animation and the process running in the background,

   exclusively used in mounting animation portion of the HorseMount() routine,

   but can be used elsewhere. Note, that the variable is artificially set even

   in case no animation is desired so that the code doesnt happen instantly. It

   is not meant to be changed, unless something bad is happening timing-wise.

   The value is precalculated and in our particular case it is supposed to hold

   the total animation length.



   The following make it easier to implement existing mount support systems

   in conjunction with this one.



   X3_HORSE_SCRIPT_MOUNT = Script to call for mounting instead of using the

   default one called by the horse menu feat.  This still checks to make sure

   mounting in the area is legal first. This is intended for making the radial

   menus do something different just for this horse and is not intended to

   alter the HorseMount(), HorseDismount(), etc. functions.   There are already

   POSTMOUNT, POSTDISMOUNT, PREMOUNT, and PREDISMOUNT hooks which make that

   functionality possible so, that is not what this variable is for.



   X3_HORSE_SCRIPT_DISMOUNT = Script to call for dismounting instead of using

   the default one called by the horse menu feat. This is intended for making

   the radial menus do something different just for this horse and is not

   intended to alter the HorseMount(), HorseDismount(), etc. functions.   There

   are already POSTMOUNT, POSTDISMOUNT, PREMOUNT, and PREDISMOUNT hooks which

   make that functionality possible so, that is not what this variable is for.



   X3_HORSE_SCRIPT_ASSIGN = Script to call for assign mount instead of using

   the default one called by the horse menu feat. This is intended for making

   the radial menus do something different just for this horse and is not

   intended to alter the HorseMount(), HorseDismount(), etc. functions.   There

   are already POSTMOUNT, POSTDISMOUNT, PREMOUNT, and PREDISMOUNT hooks which

   make that functionality possible so, that is not what this variable is for.



   bX3_HAS_SADDLEBAGS = Integer that if set to 1 on the mount will indicate

   the horse has saddle bags.  It will support inventory control if it is

   enabled (NOT: by default).  You will also want to set the dialog

   X3_DLG_SADDLEBAG on the horse blueprint.  Or, create your own dialog that

   handles what the saddlebags one does.  You will only be able to access

   saddlebags of associates in your party.





   [AREA RELATED VARIABLES TO SET]

   ===============================



   X3_NO_HORSES = Horses not allowed in this area



   X3_NO_MOUNTING = Horses may not be ridden in this area and anyone attempting

   to do so should be forcibly dismounted.



   X3_HITCHING_POST = if a placeable or waypoint in the area a person was in

   before entering a new area has a tag of this then it will move any horses

   to this object and set them to STAND_GUARD mode.



   X3_MOUNT_OK_EXCEPTION = is an integer that if set to 1 on this area will

   override the external and underground restrictions for this area that may

   be set module wide.



   fX3_MOUNT_MULTIPLE = is a floating point value that is multiplied times

   all delays if it exists on the area.   It can be used to make an area perform

   the mounting animations at a different speed if you have really busy areas

   and want to make the animation faster or slower.   If this is not defined

   then it will always be a value of 1.0.   If it is set to 0.5 then delays

   will be shortened by half.   If it is set to 2.0 then the delays will take

   200% longer.   This is something a module builder will need to be aware of

   and can adjust. NOTE: This can be set on the PC as well and whichever number

   is larger is the one that will be used.



   fX3_DISMOUNT_MULTIPLE = is similar to fX3_MOUNT_MULTIPLE and should only be

   supplied if you want the dismount to use a different speed than the mount

   multiple.   It can be set on the area or on the PC.   The PC will take

   priority over the area.



   bX3_MOUNT_NO_ZAXIS = value to set to TRUE or 1 on the module, PC, or area

   to indicate when calculating the proper mounting location you do not want

   the Z Axis to be included in the measurement.  This has been found to

   work well in areas where you do not want the Z axis to be measured in terms

   of whether to perform the mounting animation or not.



   X3_ABORT_WHEN_STUCK = if set to TRUE, distance between player and horse is

   recorded and checked in each cycle against the current one, when moving to

   a horse during the mounting procedure. Should the two ever be equal, meaning

   that the player got stuck on his way to horse, the mounting procedure will

   be terminated. This is handy in cases when horses are behind obstacles that

   are hard to overcome like walls, but the timer that ensures that rider can

   mount his horse even in difficult terrain, would eventually force-mount the

   potential rider, which could seem like an illogical act. This doesn't need

   to be used when using X3_HORSE_ACT_VS_DELAY option, where the timer starts

   ticking only after the player gets as close as 1.5m to a horse. The switch

   can be set on an area or horses (ie. using an OnEnter script of a trigger).





   [MODULE RELATED VARIABLES TO SET]

   =================================



   X3_HORSE_PALADIN_USE_PHB = integer that if set to 1 on the module object

   will cause the script to use paladin mount summoning durations as specified

   in the Player's Handbook 3.5 edition rather than just defaulting to 24 hours.



   X3_HORSE_DISABLE_SPEED = integer that if set to 1 on the module object

   will indicate you do not want a speed increase applied when a person mounts.



   X3_HORSE_DISABLE_SKILL = integer that if set to 1 on the module object will

   indicate you do not want the skill decreases to be applied when a person

   mounts.



   X3_HORSE_ENABLE_ACBOOST = integer that if set to 1 on the module object will

   indicate that you want the PCs AC to be increased if need be to at least

   match that of the horse that is being mounted.



   X3_HORSE_ENABLE_HPBOOST = integer that if set to 1 on the module object will

   indicate that you want the PCs Hit Points to  be increased by half of the

   hit points of the mount when it is mounted.



   X3_NO_MOUNT_COMMANDABLE = integer that if set to 1 on the module object will

   indicate that you do not want the SetCommandable() commands to be used with

   the module.



   X3_NO_MOUNTED_COMBAT_FEAT = integer that if set to 1 on the module object

   will indicate that you do not want the special code added to Bioware scripts

   to try to support Mounted Combat close to how it is in Player's Handbook to

   be used.



   X3_ENABLE_MOUNT_DAMAGE = integer that if set to 1 will attempt to transfer

   some damage to the mount when a rider dismounts if damage occurred while

   they were mounted.



   X3_ENABLE_MOUNT_DB = integer that if set to 1 will enable database and

   persistent world support with this script.   You will want to modify the

   HORSE_Support functions related to the database so, that they write and

   read properly however you have the database setup in your module.  You will

   also want to plan on using something like the x3_mod_def_hb script for your

   module heartbeat script if you are going to use the database.   This is not

   used on modules by default.



   X3_NO_SHAPESHIFT_SPELL_CHECK = integer that if set to 1 on the module will

   prevent the script from checking to see if a shapeshifted spell is targetted

   on a mounted creature.   If this variable is set to 1 then the

   x2_inc_spellhook scripts will work exactly like they did before horses were

   introduced with no concern whether the target is mounted or not.



   X3_MOUNT_NO_REST_DISMOUNT = integer that if set to 1 on the module will make

   it so, you are able to rest while mounted.



   X3_MOUNT_NO_REST_DESPAWN = integer that if set to 1 on the module will make

   it so, your paladin mount is not despawned when you rest and adheres

   strictly to his summoned duration.   If time is advanced by resting then

   it is still possible it will despawn.



   X3_MOUNTS_EXTERNAL_ONLY = integer that if set to 1 on the module will make

   it so mounts can only be ridden in external areas.  There is an exception

   variable that can be set on an area to override this.



   X3_MOUNTS_NO_UNDERGROUND = integer that if set to 1 on the module will make

   it so mounts cannot be ridden in underground areas.  There is an exception

   variable that can be set on an area to override this.



   X3_HORSE_ENABLE_SADDLEBAGS = integer that if set to 1 on the module will

   enable inventory support for the horse.  NOTE: If you want it to use a quick

   non-database method for storing the inventory place a waypoint with the tag

   X3_HORSE_INVENTORY_STORAGE somewhere in an area that a PC can never get to.

   If this waypoint does not exist then it will assume that the database is to

   be used.   If you are using a database it is adviseable that you change the

   support functions because, they use the standard databases and it will often

   prove slower than you may like.



   X3_SADDLEBAG_DATABASE = string to set to the name of the database to use

   for storing saddlebag inventory.   If no name is specified it will use the

   module tag and a small modifier.



   X3_HORSE_NO_HENCHMAN_INCREASE = integer that if set to 1 on the module will

   prevent the henchmen from being increased to make room for the horse.



   X3_HORSE_MAX_HENCHMEN = integer to set on the module to indicate the maximum

   number of henchmen to allow it to be increased to in order to make room for

   horses.   By default there is no maximum.



   X3_HORSE_NO_CORPSES = integer to set on the module to 1 to indicate you

   do not want lootable horse corpses created when a mounted PC or NPC dies.



   X3_RESTORE_HENCHMEN_LOCATIONS = integer to set to 1 on the module if you

   want henchmen's henchmen to be restored to a location near the henchman that

   is their master when a PC master of the henchman connects.   This is NOT

   enabled by default to prevent problems with older modules.



   X3_EXTEND_PALMOUNT = string variable that if set on the module object

   will allow a person to extend this paladin mount script to call other

   scripts in a daisy chain type situation such as saddle bag handling ones.



   X3_EXTEND_PALDMOUNT = string variable that if set on the module object

   will allow a person to extend this paladin mount script to call other

   scripts in a daisy chain type situation such as saddle bag handling ones.



   X3_HORSE_ACT_VS_DELAY = integer to set on the module to 1 to indicate you

   want the system to use Actions as opposed to delays in some portions of the

   mounting sequence.  Doing this might provide another way to handle inaccessible

   horses besides using X3_HORSE_NOT_RIDEABLE_OWNER.   It may result in not

   being able to access accidentally poorly placed horses due to scripts or

   other factors but, it may be desired by some module designers so, it has

   been provided as an option.





   [ON THE MODULE or THE PLAYER]

   =============================



   X3_PALMOUNT_SUMMONOVR = string if set on the module or the player (player has

   priority) it will do all the checks to see if a summon is okay.   Then if

   this variable is set it will execute the script you define here rather than

   using the standard summon paladin mount function.  Beware:  If you use this

   then handling all other aspects of this mount become your responsability.



   fX3_TIMEOUT_TO_MOUNT = value to set on the module or PC to indicate how long

   the PC/NPC should attempt to move into a proper mounting animation to perform

   the mounting animation.   When this time is reached if it is still not in

   position it will instant mount instead and will not animate. If this value is

   lower than 6.0 or is not set, then the default value of 18.0 will be used.



   fX3_FREQUENCY = frequency of recursive call of the HorseMount() function to

   try and initiate new pathfinding to the horse everytime until the character

   reaches the mounting position or until the time limit for mounting is up or

   unless X3_HORSE_ACT_VS_DELAY is set to TRUE, in which case the actionqueue

   is not locked and moving towards a horse is interruptable, ie. by clicking.

   if set larger than 9.0 or less than 1.0 the value defaults to 2.0 seconds.



   bX3_MOUNT_NO_ZAXIS = value to set to TRUE or 1 on the module, PC, or area

   to indicate when calculating the proper mounting location you do not want

   the Z Axis to be included in the measurement.  This has been found to

   work well in areas where you do not want the Z axis to be measured in terms

   of whether to perform the mounting animation or not.





   [SCRIPT TO OVERRIDE SKIN SYSTEM]

   ================================



   The skin system is designed to supply the horse radial menus to older characters

   and it also is used to track some of the information about the state of the

   PC semi-persistently.   The system is setup in such a way that PRC or HCR or

   other systems that use skins will still use their own skin as long as they

   run first.   If the horse system does not detect a skin it will create one.

   Thus, if it runs before PRC or HCR create their skins there might be a problem.

   To make this less of an upgrade nightmare the horse script includes support

   for a hook script.   If PRC, or HCR or other scripting package people create

   a script named [x3_mod_pre_enter] and make that script add their skin to the

   PC then this script WILL execute ALWAYS before the horse scripts create

   their skin.   This means all you need to do is make such a script and have

   it add your skin and your scripts should function as they did before (EVEN)

   if the horse scripts execute other aspects before yours.





   [DEBUGGING AND TWEAKING SCRIPTS]

   ================================



   Press ~ in game to bring up console mode.  Type DebugMode 1 and press enter.

   Press ~ in game and this time type dm_runscript scriptname and press enter.

   Press ~ in game and type DebugMode 0 when you want to disable debug mode.

   SCRIPTS:

   x3_fix_horse = use this when the PC is being treated as mounted when it is not

   x3_fix_horseout = use this to make a module not designed with horses in mind

      only allow horses in outside areas.

   x3_fix_nocmd = set it not to use the SetCommandable with mounting toggle

   x3_fix_act = set to use actions when mounting toggle

   x3_fix_speed100 = mount/dismount speed multiple set to normal 100%

   x3_fix_speed125 = mount/dismount speed multiple set to 1255 (25% slower)

   x3_fix_speed150 = mount/dismount speed multiple set to 150% (50% slower)

   x3_fix_speed200 = mount/dismount speed multiple set to 200% (100% slower)





*/



////////////////////////////////////////////////////////////////////////////////

///////////////////////////////   CONSTANTS   //////////////////////////////////

////////////////////////////////////////////////////////////////////////////////





const string X3_HORSE_DATABASE = "X3HORSE";



// The following constants are provided to facilitate extending the system

// if need be.   They are also provided in the event that a hak pack used

// in a module might rearrange the location of some of the aspects needed

// to handle horses.

// This constant points to the location in the appearance.2da where the

// unmounted horse appearances occur.

const int HORSE_APPEARANCE_OFFSET =     496;

// This constant points to the location in the tails.2da where the horse

// appearances begin.

const int HORSE_TAIL_OFFSET =           15;

// This constant lists how many horses are listed beginning at the location

// specified by the offset.

const int HORSE_NUMBER_OF_HORSES =      65;

// This is the prefix that should be used with the paladin mounts when spawning

// them.

const string HORSE_PALADIN_PREFIX =     "x3_palhrs";

// The constants that follow here specify what appearance to use when scaling

// the horse as a tail during mounting process to make the animation be handled

// properly.

const int HORSE_NULL_RACE_DWARF =       562;

const int HORSE_NULL_RACE_ELF =         563;

const int HORSE_NULL_RACE_HALFLING =    565;

const int HORSE_NULL_RACE_HUMAN =       568;

const int HORSE_NULL_RACE_HALFELF =     566;

const int HORSE_NULL_RACE_HALFORC =     567;

const int HORSE_NULL_RACE_GNOME =       564;

// The constants that follow here specify the appearance that should be used

// when the specified mount is mounted.   These appearances are often required

// to set the proper speeds, radiuses, etc.  They also have the complete

// phenotypes and animations associated with them.

const int HORSE_RACE_MOUNTED_DWARFM =   483;

const int HORSE_RACE_MOUNTED_DWARFF =   482;

const int HORSE_RACE_MOUNTED_ELFM =     485;

const int HORSE_RACE_MOUNTED_ELFF =     484;

const int HORSE_RACE_MOUNTED_GNOMEM =   487;

const int HORSE_RACE_MOUNTED_GNOMEF =   486;

const int HORSE_RACE_MOUNTED_HALFLINGM= 489;

const int HORSE_RACE_MOUNTED_HALFLINGF= 488;

const int HORSE_RACE_MOUNTED_HALFELFM = 491;

const int HORSE_RACE_MOUNTED_HALFELFF = 490;

const int HORSE_RACE_MOUNTED_HALFORCM = 493;

const int HORSE_RACE_MOUNTED_HALFORCF = 492;

const int HORSE_RACE_MOUNTED_HUMANM   = 495;

const int HORSE_RACE_MOUNTED_HUMANF   = 494;

// The following constants indicate which phenotype numbers should be used by

// the mounting system. _N specifies the mounting race started as a normal

// phenotype, and _L specifies the race started as a large phenotype.

const int HORSE_PHENOTYPE_MOUNTED_N =   3;

const int HORSE_PHENOTYPE_MOUNTED_L =   5;

const int HORSE_PHENOTYPE_JOUSTING_N =  6;

const int HORSE_PHENOTYPE_JOUSTING_L =  8;

// The following constants indicate which animation numbers indicate which

// animations can be used well with the horse system.

const int HORSE_ANIMATION_MOUNT =                      41;

const int HORSE_ANIMATION_DISMOUNT =                   42;

const int HORSE_ANIMATION_LOOPING_JOUST_VIOLENT_FALL = ANIMATION_LOOPING_CUSTOM3;

const int HORSE_ANIMATION_LOOPING_JOUST_GLANCE =       ANIMATION_LOOPING_CUSTOM4;

const int HORSE_ANIMATION_LOOPING_JOUST_FALL =         ANIMATION_LOOPING_CUSTOM5;

const int HORSE_ANIMATION_LOOPING_JOUST_STAB =         ANIMATION_LOOPING_CUSTOM10;

const int HORSE_ANIMATION_LOOPING_JOUST_HELMOFF =      ANIMATION_LOOPING_CUSTOM4;

// The following constant defines what footstep sound should be used when

// the horse is mounted.

const int HORSE_FOOTSTEP_SOUND =        17;

// The following constant defines the duration in seconds that it should take

// to complete the default animation.

const float HORSE_MOUNT_DURATION =      2.0f;

// The following constant defines the duration in seconds that it should take

// to complete the default animation.

const float HORSE_DISMOUNT_DURATION =   3.0f;

// The following constants refer to specific feats that might be needed to

// handle horses

const int IP_CONST_HORSE_MENU =         40;

// The constant below designates the default speed increase that should be

// granted when a person mounts a horse.

const int HORSE_DEFAULT_SPEED_INCREASE= 99;

// The following constants were added to support the new feats.  When these

// constants are added to the master constants list they can be removed from

// this part of the script.

//const int FEAT_MOUNTED_COMBAT =         1087;

//const int FEAT_MOUNTED_ARCHERY =        1088;

// Scripts called by the above feats

// x3_s3_horse

// x3_s3_palmount



// This constant is a safety to be inserted between the ClearAllActions and

// a command to play a dismount animation. If set to 0.0 or if missing, the

// dismount animation will not play properly when trying to dismount a horse

// while in motion. If you ever encounter problems with mounting animation,

// try inserting this small delay in the same fashion in the animated mounting

// procedure. All pending DelayCommands shall respect this delay accordingly

// for the sake of precise timing. Values of 0.8f and above are safe to use.

const float X3_ACTION_DELAY =           0.8f;





////////////////////////////////////////////////////////////////////////////////

////////////////////////////////   PROTOTYPES   ////////////////////////////////

////////////////////////////////////////////////////////////////////////////////





// FILE: x3_inc_horse       FUNCTION: HorseMount()

// This function will cause the calling object to attempt to mount oHorse.

// If bAnimate is set to TRUE this will cause the calling object and oHorse

// to be involved in the complete animating process.  If you bAnimate is false

// and bInstant is false the caller will still walk to the horse before mounting.

// If bAnimate is false and bInstant is TRUE then the script will immediately

// mount oHorse without any moving (this is the quickest method if needed for

// situations like cutscenes).  nState is a variable used by the function itself

// and need not be adjusted when this function is called.

void HorseMount(object oHorse,int bAnimate=TRUE,int bInstant=FALSE,int nState=0);





// FILE: x3_inc_horse       FUNCTION: HorseDismount()

// This function will cause the calling object to dismount if it is mounted. If

// bAnimate is TRUE then it will animate the dismount.   If bOwner is set to

// TRUE then it will set the object that dismounted as the owner.  This function

// will return the object that is the dismounted horse.

object HorseDismount(int bAnimate=TRUE,int bSetOwner=TRUE);





// FILE: x3_inc_horse       FUNCTION: HorseSetOwner()

// This function will set oOwner as the owner of oHorse. If bAssign is set to

// TRUE it will also set this horse to be oOwners assigned mount.   This is not

// done by default so more than one mount can be assigned to a single target if

// need be.

void HorseSetOwner(object oHorse,object oOwner,int bAssign=FALSE);





// FILE: x3_inc_horse       FUNCTION: HorseRemoveOwner()

// This function will remove the owner from oHorse.  This will not work on

// Paladin mounts.

void HorseRemoveOwner(object oHorse);





// FILE: x3_inc_horse       FUNCTION: HorseGetCanBeMounted()

// This function will return TRUE if oTarget can be mounted.  If oRider is

// specified it will also make sure that oTarget can be ridden by oRider.

// The bAssignMount field should be set to TRUE if the call of this function

// should ignore whether someone can mount a horse in the area or not.

int HorseGetCanBeMounted(object oTarget,object oRider=OBJECT_INVALID,int bAssignMount=FALSE);





// FILE: x3_inc_horse       FUNCTION: HorseSummonPaladinMount()

// This function can be used to cause the calling object to summon the paladin

// mount.   If bPHBDuration is set to TRUE then the mount will use the Players

// Handbook 3.0 edition rules for the duration that the mount will stay around.

object HorseSummonPaladinMount(int bPHBDuration=FALSE);





// FILE: x3_inc_horse       FUNCTION: HorseUnsummonPaladinMount()

// This function can be used to cause the calling object to unsummon its paladin

// mount.

void HorseUnsummonPaladinMount();





// FILE: x3_inc_horse       FUNCTION: HorseGetIsMounted()

// This function will return TRUE if oTarget is mounted.

int HorseGetIsMounted(object oTarget);





// FILE: x3_inc_horse       FUNCTION: HorseCreateHorse()

// This function will create a horse based on the blueprint sResRef at location

// lLoc and will set the owner of the horse to oOwner.  If sTag is set to

// something other than "" it will set the horse to that tag.  If nAppearance,

// nTail, and nFootstep are set to something other than -1 then it will set the

// horse to that appearance, tail, or footstep.  The function will return the

// horse that is spawned.   This function is setup the way it is so, that you

// could potentially use a single blueprint to store multiple appearance horses.

// sScript is a specific script that should be executed on the horse after it is

// spawned.  This is again supplied to further support multiple horses with a

// single blueprint.

object HorseCreateHorse(string sResRef,location lLoc,object oOwner=OBJECT_INVALID,string sTag="",int nAppearance=-1,int nTail=-1,int nFootstep=-1,string sScript="");





// FILE: x3_inc_horse       FUNCTION: HorseGetOwner()

// This function will return an object pointer to whom the owner of oHorse is

// if there is a valid horse.   If there is no owner it will return

// OBJECT_INVALID.

object HorseGetOwner(object oHorse);





// FILE: x3_inc_horse       FUNCTION: HorseSetPhenotype()

// This function will set oRider to the correct mounted phenotype for riding

// a horse.  If bJoust is set to TRUE it will set oRider to the mounted jousting

// phenotype.  This is a special phenotype with differing animation sets and

// designed to hold the lance in a very specific way.

void HorseSetPhenotype(object oRider,int bJoust=FALSE);





// FILE: x3_inc_horse       FUNCTION: HorseInstantMount()

// This function is primarily supplied for cutscenes and other instances where

// you simply need oRider to be switched to mounted mode as quickly as possible

// without preserving any variables or anything.  However, you can store a

// resref for the horse to dismount by setting sResRef.  If bJoust is set to

// TRUE then it will use the Joust Phenotypes.

// WARNING: This does not care whether someone meets the criteria to mount,

// or even if they are already mounted.   It will simply set them to the

// proper appearance and mode.   The ResRef is provided only in case someone

// uses HorseDismount() instead of using HorseInstantDismount() with this

// rider.   It is recommended this function only be used in conjunction with

// HorseInstantDismount().

void HorseInstantMount(object oRider,int nTail,int bJoust=FALSE,string sResRef="");





// FILE: x3_inc_horse       FUNCTION: HorseInstantDismount()

// This function is used to rapidly dismount oRider and does not produce a horse

// object.   It's intended usage is with cutscenes or other instances where

// having oRider dismounted as quickly as possible are required.  This will not

// produce horse/mount as it is primarily intende for cutscene work and not

// intended to replace the HorseDismount() function in other cases.

// WARNING: This does not protect Saddlebags so, it is recommended this only

// be used in conjunction with HorseInstantMount.   If you need to protect

// saddlebag contents use HorseDismount().

void HorseInstantDismount(object oRider);





// FILE: x3_inc_horse       FUNCTION: HorseGetMountTail()

// This function will return the tail that should be used with the specified

// horse.

int HorseGetMountTail(object oHorse);





// FILE: x3_inc_horse       FUNCTION: HorseGetMountFailureMessage()

// This is a companion function to HorseGetCanBeMounted.  If you need a text

// message that explains why the horse cannot be mounted.

string HorseGetMountFailureMessage(object oHorse,object oRider=OBJECT_INVALID);





// FILE: x3_inc_horse       FUNCTION: HorseAddHorseMenu()

// This function will add horse menus to the respective PC.  This is only

// needed for PCs that were not created new using patch 1.69.

void HorseAddHorseMenu(object oPC);





// FILE: x3_inc_horse       FUNCTION: HorseGetPaladinMount()

// If this rider has a paladin mount then it will be returned as the object.

// If the rider is currently riding their paladin mount then it will return

// oRider as the object.   If no paladin mount currently exists for oRider it

// will return OBJECT_INVALID.

object HorseGetPaladinMount(object oRider);





// FILE: x3_inc_horse       FUNCTION: HorseGetIsAMount()

// This will return TRUE if oTarget is a mountable creature.

int HorseGetIsAMount(object oTarget);





// FILE: x3_inc_horse       FUNCTION: HorseGetIsDisabled()

// This function detects if oCreature is in a disabled state. Can be used to

// detect disabling effects such as death, fear, confusion, sleep, paralysis,

// petrify, stun, entangle and knockdown (also applied in a non-hostile way,

// where oCreature doesn't enter a combat state)

int HorseGetIsDisabled(object oCreature=OBJECT_SELF);





// FILE: x3_inc_horse       FUNCTION: HorseReloadFromDatabase()

// This function is provided for use with an OnClientEnter script when you

// are using a persistent world type environment and need the PC's mounted

// state reloaded.  This will also make sure that henchmen for the PC are also

// restored as they were.

void HorseReloadFromDatabase(object oPC,string sDatabase);





// FILE: x3_inc_horse       FUNCTION: HorseSaveToDatabase()

// This will save all of the current status for the PC and the PCs henchmen.

void HorseSaveToDatabase(object oPC,string sDatabase);





// FILE: x3_inc_horse       FUNCTION: HorseStoreInventory()

// This function is used to store inventory of the horse for later recovery.

// See x3_inc_horse for complete details.

void HorseStoreInventory(object oCreature,object oRider=OBJECT_INVALID);





// FILE: x3_inc_horse       FUNCTION: HorseRestoreInventory()

// This function is used to return stored inventory back onto the horse

// See x3_inc_horse for complete details. If bDrop is set to TRUE then it

// will drop the contents where the horse is rather than putting them on the

// horse.  bDrop was primarily intended for cases where a mounted PC dies.

void HorseRestoreInventory(object oCreature,int bDrop=FALSE);





// FILE: x3_inc_horse       FUNCTION: HorseChangeToDefault()

// This function will set oCreature to the default racial appearance and is

// useful for reversing any situations where a creature or PC is stuck in some

// variation of a mounted appearance.   This will also clear ANY information

// stored on the creature relating to mounting. NOTE: If the target had a

// tail when not mounted this function will not restore that.

void HorseChangeToDefault(object oCreature);





// FILE: x3_inc_horse       FUNCTION: HorseIfNotDefaultAppearanceChange()

// This funtion will check the appearance of oCreature,   If it is not set to

// the default racial appearance (see racialtypes.2da) then it will call the

// HorseChangeToDefault() function.

void HorseIfNotDefaultAppearanceChange(object oCreature);





// FILE: x3_inc_horse       FUNCTION: HorseGetMyHorse()

// When oRider is dismounted, this function returns the horse currently assigned

// to oRider (OBJECT_INVALID if there is none). In certain script hooks

// (pre-mount, post-mount and post-dismount), the function returns the horse

// that is currently being mounted / dismounted. It should not be used when the

// rider is mounted, or in a pre-dismount script hook.

object HorseGetMyHorse(object oRider);





// FILE: x3_inc_horse       FUNCTION: HorseGetHasAHorse()

// This function will return TRUE if oRider has a mount or horse.

int HorseGetHasAHorse(object oRider);





// FILE: x3_inc_horse       FUNCTION: HorseGetHorse()

// This function will return the nNth horse that is owned by oRider.

object HorseGetHorse(object oRider,int nN=1);





// FILE: x3_inc_horse       FUNCTION: HorseRestoreHenchmenLocations()

// This function will check the module variable X3_RESTORE_HENCHMEN_LOCATIONS

// which when set to TRUE on the module will cause this function to jump any

// npc henchmen to the PC and will also make sure their henchmen also jump.

// This function is provided so, that there exists a function which will remain

// true to whether henchmen are mounted in no mount areas and whether mounts are

// prevented from entering no mount areas.   This is not the perfect function

// but, it will address some of the issues with the engine not restoring the

// locations of henchmen belonging to henchmen on a module reload.   This will

// actually NOT jump henchmen to the PC.   It's primary purpose is to make sure

// that henchmen belonging to the henchman are jumped to the proper location.

// It is assumed that the henchman that is their master will already be at the

// proper location due to a reload or due to a respawn from some special script

// for the server.

void HorseRestoreHenchmenLocations(object oPC);





// FILE: x3_inc_horse        FUNCTION: HorseHitchHorses()

// This function is designed to be used in conjunction with a transition script.

// oHitch is an object to hitch horses/mounts near.   If it is OBJECT_INVALID

// then a specific destination to hitch will not be used.  oClicker is who

// clicked the area transistion.  lPreJump is a pre-transition location which

// is used to determine where the horses should stay near (actually walk a

// small distance away) if they do not transition.

void HorseHitchHorses(object oHitch,object oClicker,location lPreJump);





// FILE: x3_inc_horse       FUNCTION: HorseForceJump()

// This is used to make sure oJumper makes it to withing fRange of oDestination.

// The nTimeOut is used to set a maximum number of attempts that will be made.

void HorseForceJump(object oJumper,object oDestination,float fRange=2.0,int nTimeOut=10);





// FILE: x3_inc_horse       FUNCTION: HorseMoveAssociates()

// This function is intended to be used after a transition has been made and

// oMaster has moved onto the target destination.   This function will cause

// any associates that also transitioned to move away from oMaster a small

// amount to make sure they do not block movement for oMaster.   This can be

// particularly important when you consider horses have a bit more personal

// space requirements than the traditional associate.

void HorseMoveAssociates(object oMaster);





// FILE: x3_inc_horse       FUNCTION: HorsePreloadAnimations()

// The mount and dismount animations are rather complex and by default the

// aurora engine does not always preload these animations.   This function was

// created to temporarily set the tail and appearance of a PC to that of one of

// the horse models that will thus, force preloading of the animations.   After

// that is done the animations should played properly.   This is a good function

// to call in the OnEnter script of the module or similar location.

void HorsePreloadAnimations(object oPC);





////////////////////////////////////////////////////////////////////////////////

// SUPPORT FUNCTIONS

//-----------------------------

// These functions are not intended to be called by external scripts to this

// file and are simply used as support functions called by other functions

// from within this script.

////////////////////////////////////////////////////////////////////////////////





int HORSE_SupportGetMountedAppearance(object oRider)

{ // PURPOSE: Return which appearance the rider should use when mounted

   int nRace=GetRacialType(oRider);

   int nGender=GetGender(oRider);

   if (GetLocalInt(oRider,"X3_CUSTOM_RACE_MOUNTED_APPEARANCE")>0) return GetLocalInt(oRider,"X3_CUSTOM_RACE_MOUNTED_APPEARANCE");

   if (nGender==GENDER_FEMALE)

   { // female

            if (nRace==RACIAL_TYPE_DWARF) return HORSE_RACE_MOUNTED_DWARFF;

       else if (nRace==RACIAL_TYPE_ELF) return HORSE_RACE_MOUNTED_ELFF;

       else if (nRace==RACIAL_TYPE_GNOME) return HORSE_RACE_MOUNTED_GNOMEF;

       else if (nRace==RACIAL_TYPE_HALFLING) return HORSE_RACE_MOUNTED_HALFLINGF;

       else if (nRace==RACIAL_TYPE_HALFELF) return HORSE_RACE_MOUNTED_HALFELFF;

       else if (nRace==RACIAL_TYPE_HALFORC) return HORSE_RACE_MOUNTED_HALFORCF;

       else if (nRace==RACIAL_TYPE_HUMAN) return HORSE_RACE_MOUNTED_HUMANF;

   } // female

   else

   { // male

            if (nRace==RACIAL_TYPE_DWARF) return HORSE_RACE_MOUNTED_DWARFM;

       else if (nRace==RACIAL_TYPE_ELF) return HORSE_RACE_MOUNTED_ELFM;

       else if (nRace==RACIAL_TYPE_GNOME) return HORSE_RACE_MOUNTED_GNOMEM;

       else if (nRace==RACIAL_TYPE_HALFLING) return HORSE_RACE_MOUNTED_HALFLINGM;

       else if (nRace==RACIAL_TYPE_HALFELF) return HORSE_RACE_MOUNTED_HALFELFM;

       else if (nRace==RACIAL_TYPE_HALFORC) return HORSE_RACE_MOUNTED_HALFORCM;

       else if (nRace==RACIAL_TYPE_HUMAN) return HORSE_RACE_MOUNTED_HUMANM;

   } // male

   return GetAppearanceType(oRider);

} // HORSE_SupportGetMountedAppearance()





string HORSE_SupportRaceRestrictString(object oRider)

{ // PURPOSE: This will return the race restriction string to use for oRider

   string sRet="X3_HORSE_RESTRICT_";

   int nRace=GetRacialType(oRider);

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid

            if (nRace==RACIAL_TYPE_DWARF) sRet=sRet+"DWARF";

       else if (nRace==RACIAL_TYPE_ELF) sRet=sRet+"ELF";

       else if (nRace==RACIAL_TYPE_GNOME) sRet=sRet+"GNOME";

       else if (nRace==RACIAL_TYPE_HALFELF) sRet=sRet+"HALFELF";

       else if (nRace==RACIAL_TYPE_HALFLING) sRet=sRet+"HALFLING";

       else if (nRace==RACIAL_TYPE_HALFORC) sRet=sRet+"HALFORC";

       else if (nRace==RACIAL_TYPE_HUMAN) sRet=sRet+"HUMAN";

       else {sRet=sRet+"CUSTOM"+IntToString(nRace);}

   } // valid

   return sRet;

} // HORSE_SupportRaceRestrictString(oRider)





string HORSE_SupportMountResRef(object oRider)

{ // PURPOSE: Return the resref of the mount oRider is on

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       return GetSkinString(oRider,"sX3_HorseResRef");

   } // valid parameter

   return "";

} // HORSE_SupportMountResRef()





int HORSE_SupportMountAppearance(object oRider)

{ // PURPOSE: Return the appearance of the mount oRider is on

    if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

    { // valid parameter

        return GetSkinInt(oRider,"nX3_HorseAppearance");

    } // valid parameter

    return -1;

} // HORSE_SupportMountAppearance()





int HORSE_SupportMountTail(object oRider)

{ // PURPOSE: Return the tail of the mount oRider is on

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       return GetCreatureTailType(oRider);

   } // valid parameter

   return -1;

} // HORSE_SupportMountTail()





int HORSE_SupportMountFootstep(object oRider)

{ // PURPOSE: Return the footstep sound of the rider is supposed to be when not

 // mounted

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       return GetSkinInt(oRider,"nX3_StoredFootstep");

   } // valid parameter

   return -1;

} // HORSE_SupportMountFootstep()





string HORSE_SupportMountTag(object oRider)

{ // PURPOSE: Return the tag of the mount that rider is riding

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       return GetSkinString(oRider,"sX3_HorseMountTag");

   } // valid parameter

   return "";

} // HORSE_SupportMountTag()





string HORSE_SupportMountScript(object oRider)

{ // PURPOSE: Return the post spawn script to run for the horse oRider is riding

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       return GetLocalString(oRider,"sX3_HorseMountString");

   } // valid parameter

   return "";

} // HORSE_SupportMountScript()





int HORSE_SupportRiderAppearance(object oRider)

{ // PURPOSE: Return the appearance of oRider when not mounted

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       return GetSkinInt(oRider,"nX3_HorseRiderAppearance");

   } // valid parameter

   return -1;

} // HORSE_SupportRiderAppearance()





int HORSE_SupportRiderPhenotype(object oRider)

{ // PURPOSE: Return the phenotype of the rider when not mounted

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       if (GetLocalInt(oRider,"X3_CUSTOM_RACE_PHENOTYPE")) return GetLocalInt(oRider,"X3_CUSTOM_RACE_PHENOTYPE");

       return GetSkinInt(oRider,"nX3_HorseRiderPhenotype");

   } // valid parameter

   return -1;

} // HORSE_SupportRiderPhenotype()





void HORSE_SupportCleanVariables(object oTarget)

{ // PURPOSE: Remove any mount related variables after dismount

   DeleteLocalInt(oTarget,"X3_HORSE_NULL_APPEARANCE");

   //DeleteSkinInt(oTarget,"X3_HORSE_APPEARANCE");

   DeleteLocalInt(oTarget,"X3_HORSE_TAIL");

   //DeleteSkinInt(oTarget,"nX3_HorseRiderAppearance");

   //DeleteSkinInt(oTarget,"nX3_HorseRiderPhenotype");

   //DeleteSkinInt(oTarget,"nX3_StoredFootstep");

   DeleteSkinString(oTarget,"X3_HORSE_PREDISMOUNT_SCRIPT");

   DeleteSkinString(oTarget,"X3_HORSE_POSTDISMOUNT_SCRIPT");

   DeleteLocalString(oTarget,"X3_HORSE_PREMOUNT_SCRIPT");

   DeleteLocalString(oTarget,"X3_HORSE_POSTMOUNT_SCRIPT");

   DeleteSkinString(oTarget,"sX3_HorseResRef");

   DeleteSkinString(oTarget,"sX3_HorseMountTag");

   DeleteLocalString(oTarget,"sX3_HorseMountScript");

   DeleteLocalInt(oTarget,"X3_NO_MOUNT_CUTSCENE");

   DeleteLocalInt(oTarget,"X3_NO_MOUNT_ANIMATE");

   DeleteLocalInt(oTarget,"nX3_RiderHP");

   DeleteSkinInt(oTarget,"nX3_HorseHP");

   DeleteLocalInt(oTarget,"nX3_HorsePortrait");

   DeleteLocalInt(oTarget,"bX3_HAS_SADDLEBAGS");

   DeleteLocalString(oTarget,"sDB_Inv");

   DeleteSkinInt(oTarget,"bX3_IS_MOUNTED");

   DeleteLocalInt(oTarget,"nX3_StoredMountState");

   DeleteLocalInt(oTarget,"X3_ABORT_WHEN_STUCK");

   //DeleteSkinInt(oTarget,"nX3_HorseRiderTail");

} // HORSE_SupportCleanVariables()





void HORSE_SupportMountCleanVariables(object oRider)

{ // PURPOSE: Clean variables off of oRider related to the mount

   if (GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       HORSE_SupportCleanVariables(oRider);

   } // valid parameter

} // HORSE_SupportMountCleanVariables()





location HORSE_SupportGetMountLocation(object oCreature,object oRider,float fDirection=90.0)

{ // PURPOSE: To Locate the location to place the mount

   object oArea=GetArea(oCreature);

   vector vPos=GetPosition(oCreature);

   float fFace=GetFacing(oCreature);

   location lLoc;

   float fDist=0.8*StringToFloat(Get2DAString("appearance","WING_TAIL_SCALE",HORSE_SupportGetMountedAppearance(oRider)));

   lLoc=Location(oArea,vPos+fDist*AngleToVector(fFace-fDirection),fFace);

   return lLoc;

} // HORSE_SupportGetMountLocation()





int HORSE_SupportNullAppearance(object oHorse,object oRider)

{ // PURPOSE: This will return which appearance should be used to handle animation

   int nRace;

   if (GetLocalInt(oHorse,"X3_HORSE_NULL_APPEARANCE")>0) return GetLocalInt(oHorse,"X3_HORSE_NULL_APPEARANCE");

   nRace=GetRacialType(oRider);

        if (nRace==RACIAL_TYPE_DWARF) return HORSE_NULL_RACE_DWARF;

   else if (nRace==RACIAL_TYPE_ELF) return HORSE_NULL_RACE_ELF;

   else if (nRace==RACIAL_TYPE_GNOME) return HORSE_NULL_RACE_GNOME;

   else if (nRace==RACIAL_TYPE_HALFELF) return HORSE_NULL_RACE_HALFELF;

   else if (nRace==RACIAL_TYPE_HALFLING) return HORSE_NULL_RACE_HALFLING;

   else if (nRace==RACIAL_TYPE_HALFORC) return HORSE_NULL_RACE_HALFORC;

   return HORSE_NULL_RACE_HUMAN;

} // HORSE_SupportNullAppearance()





int Horse_SupportRaceAppearance(int nAppearance)

{ // PURPOSE: This will return TRUE if the appearance passed as a parameter

 // is an appearance used as part of the mounting process.

        if (nAppearance==HORSE_RACE_MOUNTED_DWARFF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_DWARFM) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_ELFF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_ELFM) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_GNOMEF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_GNOMEM) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HALFELFF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HALFELFM) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HALFLINGF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HALFLINGM) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HALFORCF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HALFORCM) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HUMANF) return TRUE;

   else if (nAppearance==HORSE_RACE_MOUNTED_HUMANM) return TRUE;

   return FALSE;

} // Horse_SupportRaceAppearance()





void HORSE_SupportIncreaseSpeed(object oRider,object oHorse)

{ // PURPOSE: Change the movement speed based on that of the horse (wont work unless EffectMovementSpeedIncrease() bug is fixed)

   if (GetLocalInt(GetModule(),"X3_HORSE_DISABLE_SPEED")) return;

   int nSpeed=GetLocalInt(oHorse,"X3_HORSE_MOUNT_SPEED");
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #20 on: July 22, 2010, 03:27:00 am »


               effect eMovement;

   float fSpeed;

   int nMonkEpic;

   int nMonk=GetLevelByclass(class_TYPE_MONK,oRider);

   if (nSpeed==0) nSpeed=HORSE_DEFAULT_SPEED_INCREASE;

   if (nSpeed>50) nSpeed=50; // upper limit

   if (nSpeed<-100) nSpeed=-100;

   if (nMonk>2)

   { // find out monk adjustment

   nSpeed-=10*nMonk/3;

   //nSpeed-=GetBuggedSpeedAdjustment(oRider)+10*nMonk/3;

   } // find out monk adjustment

   if (GetLevelByclass(class_TYPE_BARBARIAN,oRider)>0)

   { // barbarian class adjustment

   nSpeed-=10;

   //nSpeed-=GetBuggedSpeedAdjustment(oRider)+10;

   } // barbarian class adjustment

   if (nSpeed<-150) nSpeed=-150;

   SetLocalInt(oRider,"nX3_SpeedIncrease",nSpeed);

   eMovement=SupernaturalEffect(EffectMovementSpeedIncrease(nSpeed)); // EffectMovementSpeedIncrease() with negative numbers is the same as EffectMovementSpeedDecrease() with positive numbers

   ApplyEffectToObject(DURATION_TYPE_PERMANENT,eMovement,oRider);

} // HORSE_SupportIncreaseSpeed()





void HORSE_SupportOriginalSpeed(object oRider)

{ // PURPOSE: Remove speed increases based upon mounted

   if (GetLocalInt(GetModule(),"X3_HORSE_DISABLE_SPEED")) return;

   effect eSearch=GetFirstEffect(oRider);

   while(GetIsEffectValid(eSearch))

   { // cycle through effects

       if((GetEffectType(eSearch) == EFFECT_TYPE_MOVEMENT_SPEED_INCREASE) &&

         (GetEffectDurationType(eSearch) == DURATION_TYPE_PERMANENT) &&

         (GetEffectSubType(eSearch) == SUBTYPE_SUPERNATURAL))

       { // check to see if matches conditions

           RemoveEffect(oRider,eSearch);

       } // check to see if matches conditions

       eSearch=GetNextEffect(oRider);

   } // cycle through effects

} // HORSE_SupportOriginalSpeed()





void HORSE_SupportAdjustMountedArcheryPenalty(object oRider)

{ // PURPOSE: Check for feats and adjust penalties to archery while mounted

   int nMountedArcheryPenalty=GetLocalInt(oRider,"nX3_MountedArchery");

   int nNewPenalty;

   effect eEffect;

   int bMatched;

   //if (HorseGetIsMounted(oRider)&&GetWeaponRanged(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oRider)))

   if (HorseGetIsMounted(oRider)&&GetLocalInt(oRider,"bX3_M_ARCHERY"))

   { // Rider is mounted and has a ranged weapon - apply penalty

       nNewPenalty=4;

       if (GetHasFeat(FEAT_MOUNTED_ARCHERY,oRider)) nNewPenalty=2;

       if (nNewPenalty!=nMountedArcheryPenalty&&nMountedArcheryPenalty>0)

       { // remove existing penalties before applying the new one

           eEffect=GetFirstEffect(oRider);

           bMatched=FALSE;

           while(GetIsEffectValid(eEffect)&&!bMatched)

           { // traverse effects

              if ((GetEffectType(eEffect)==EFFECT_TYPE_ATTACK_DECREASE)&&

              (GetEffectSubType(eEffect)==SUBTYPE_SUPERNATURAL)&&

              (GetEffectDurationType(eEffect)==DURATION_TYPE_PERMANENT))

              { // match

                  RemoveEffect(oRider,eEffect);

                  bMatched=TRUE;

              } // match

              eEffect=GetNextEffect(oRider);

          } // traverse effects

       } // remove existing penalties before applying the new one

       ApplyEffectToObject(DURATION_TYPE_PERMANENT,SupernaturalEffect(EffectAttackDecrease(nNewPenalty)),oRider);

       SetLocalInt(oRider,"nX3_MountedArchery",nNewPenalty);

   } // Rider is mounted and has a ranged weapon - apply penalty

   else if (nMountedArcheryPenalty)

   { // no penalty needed - remove it

       eEffect=GetFirstEffect(oRider);

       bMatched=FALSE;

       while(GetIsEffectValid(eEffect)&&!bMatched)

       { // traverse effects

           if ((GetEffectType(eEffect)==EFFECT_TYPE_ATTACK_DECREASE)&&

           (GetEffectSubType(eEffect)==SUBTYPE_SUPERNATURAL)&&

           (GetEffectDurationType(eEffect)==DURATION_TYPE_PERMANENT))

           { // match

               RemoveEffect(oRider,eEffect);

               bMatched=TRUE;

           } // match

           eEffect=GetNextEffect(oRider);

       } // traverse effects

       DeleteLocalInt(oRider,"nX3_MountedArchery");

   } // no penalty needed - remove it

} // HORSE_SupportAdjustMountedArcheryPenalty()





void HORSE_SupportApplyMountedSkillDecreases(object oRider)

{ // PURPOSE: Applies decreases to skills while mounted

   if (GetLocalInt(GetModule(),"X3_HORSE_DISABLE_SKILL")) return;

   object oMod=GetModule();

   effect eDisarmTrap = SupernaturalEffect(EffectSkillDecrease(SKILL_DISABLE_TRAP , 50));

   effect eOpenLock   = SupernaturalEffect(EffectSkillDecrease(SKILL_OPEN_LOCK    , 50));

   effect eHide       = SupernaturalEffect(EffectSkillDecrease(SKILL_HIDE         , 50));

   effect eMove       = SupernaturalEffect(EffectSkillDecrease(SKILL_MOVE_SILENTLY, 50));

   effect ePickPocket = SupernaturalEffect(EffectSkillDecrease(SKILL_PICK_POCKET  , 50));

   effect eSetTrap    = SupernaturalEffect(EffectSkillDecrease(SKILL_SET_TRAP     , 50));

   effect eTumble     = SupernaturalEffect(EffectSkillDecrease(SKILL_TUMBLE       , 50));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,eDisarmTrap,oRider));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,eOpenLock,oRider));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,eHide,oRider));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,eMove,oRider));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,ePickPocket,oRider));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,eSetTrap,oRider));

   AssignCommand(oMod,ApplyEffectToObject(DURATION_TYPE_PERMANENT,eTumble,oRider));

} // HORSE_SupportApplyMountedSkillDecreases()





void HORSE_SupportRemoveMountedSkillDecreases(object oRider)

{ // PURPOSE: To remove any negative effects caused by being mounted

   if (GetLocalInt(GetModule(),"X3_HORSE_DISABLE_SKILL")) return;

   effect ePenalty=GetFirstEffect(oRider);

   while (GetIsEffectValid(ePenalty))

   { // traverse effects

       if ((GetEffectType(ePenalty)==EFFECT_TYPE_SKILL_DECREASE)&&

       (GetEffectSubType(ePenalty)==SUBTYPE_SUPERNATURAL)&&

       (GetEffectDurationType(ePenalty)==DURATION_TYPE_PERMANENT))

       { // match

           RemoveEffect(oRider, ePenalty);

       } // match

       ePenalty=GetNextEffect(oRider);

   } // traverse effects

} // HORSE_SupportRemoveMountedSkillDecreases()





void HORSE_SupportResetUnmountedAppearance(object oRider)

{ // PURPOSE: Reset oRider to an unmounted appearance

   int nApp=GetSkinInt(oRider,"nX3_HorseRiderAppearance");

   int nPheno=GetSkinInt(oRider,"nX3_HorseRiderPhenotype");

   int nFoot=GetSkinInt(oRider,"nX3_StoredFootstep");

   int nTail=GetSkinInt(oRider,"nX3_HorseRiderTail");

   SetCreatureTailType(nTail,oRider);

   SetPhenoType(nPheno,oRider);

   SetCreatureAppearanceType(oRider,nApp);

   SetFootstepType(nFoot,oRider);

} // HORSE_SupportResetUnmountedAppearance()





int HORSE_SupportAbsoluteMinute()

{ // PURPOSE: Returns the current absolute time expressed in minutes

   int nTime=GetTimeMinute()+GetTimeHour()*60+GetCalendarDay()*60*24;

   int nYear=GetCalendarYear();

   if (nYear>20) nYear=nYear%20;

   nTime=nTime+GetCalendarMonth()*60*24*30+nYear*60*24*30*12;

   return nTime;

} // HORSE_SupportAbsoluteMinute()





void HORSE_SupportMonitorPaladinUnsummon(object oPaladin)

{ // PURPOSE: Monitor whether to unsummon the paladin mount

 // see hook scripts x3_s2_palmount and x3_s2_paldmount

   object oMount=GetLocalObject(oPaladin,"oX3_PALADIN_MOUNT");

   int nTime;

   if (GetIsObjectValid(oPaladin)&&oMount==oPaladin)

   { // valid

       if (GetIsObjectValid(oMount))

       { // paladin mount exists

           SetLocalObject(oPaladin,"oX3_PALADIN_MOUNT",oMount);

           nTime=HORSE_SupportAbsoluteMinute();

           if (nTime>=GetLocalInt(oPaladin,"nX3_PALADIN_UNSUMMON")&&!GetCutsceneMode(oPaladin))

           { // unsummon as long as not in a cutscene

               AssignCommand(oPaladin,HorseUnsummonPaladinMount());

           } // unsummon as long as not in a cutscene

           DelayCommand(10.0,HORSE_SupportMonitorPaladinUnsummon(oPaladin));

       } // paladin mount exists

   } // valid

} // HORSE_SupportMonitorPaladinUnsummon()





void HORSE_SupportApplyACBonus(object oRider,object oHorse)

{ // PURPOSE: Apply AC bonus

   if (!GetLocalInt(GetModule(),"X3_HORSE_ENABLE_ACBOOST")) return;

   effect eEffect;

   int nRiderAC=GetAC(oRider);

   int nHorseAC=GetAC(oHorse);

   int nDiff=nHorseAC-nRiderAC;

   if (nDiff<1) return;

   eEffect=SupernaturalEffect(EffectACIncrease(nDiff,AC_NATURAL_BONUS));

   AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oRider));

} // HORSE_SupportApplyACBonus()





void HORSE_SupportRemoveACBonus(object oRider)

{ // PURPOSE: Remove AC Bonus

   if (!GetLocalInt(GetModule(),"X3_HORSE_ENABLE_ACBOOST")) return;

   effect eEffect;

   eEffect=GetFirstEffect(oRider);

   while(GetIsEffectValid(eEffect))

   { // traverse effects

       if ((GetEffectType(eEffect)==EFFECT_TYPE_AC_INCREASE)&&

       (GetEffectSubType(eEffect)==SUBTYPE_SUPERNATURAL)&&

       (GetEffectDurationType(eEffect)==DURATION_TYPE_PERMANENT))

       { // remove

           RemoveEffect(oRider,eEffect);

           return;

       } // remove

       eEffect=GetNextEffect(oRider);

   } // traverse effects

} // HORSE_SupportRemoveACBonus()





void HORSE_SupportApplyHPBonus(object oRider,object oHorse)

{ // PURPOSE: Apply HP bonus

   if (!GetLocalInt(GetModule(),"X3_HORSE_ENABLE_HPBOOST")) return;

   effect eEffect;

   int nHP=GetCurrentHitPoints(oHorse);

   nHP=nHP/2;

   if (nHP<1) nHP=1;

   eEffect=SupernaturalEffect(EffectTemporaryHitpoints(nHP));

   AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oRider));

} // HORSE_SupportApplyHPBonus()





void HORSE_SupportRemoveHPBonus(object oRider)

{ // PURPOSE: Remove HP Bonus

   if (!GetLocalInt(GetModule(),"X3_HORSE_ENABLE_HPBOOST")) return;

   effect eEffect;

   eEffect=GetFirstEffect(oRider);

   while(GetIsEffectValid(eEffect))

   { // traverse effects

       if ((GetEffectType(eEffect)==EFFECT_TYPE_TEMPORARY_HITPOINTS)&&

       (GetEffectSubType(eEffect)==SUBTYPE_SUPERNATURAL)&&

       (GetEffectDurationType(eEffect)==DURATION_TYPE_PERMANENT))

       { // remove

           RemoveEffect(oRider,eEffect);

           return;

       } // remove

       eEffect=GetNextEffect(oRider);

   } // traverse effects

} // HORSE_SupportRemoveHPBonus()





void HORSE_SupportHandleDamage(object oRider,object oHorse)

{ // PURPOSE: Handle resetting damage to the horse back to its original setting

 // and also support damage sharing with the horse if that feature is enabled.

   int nRiderCHP=GetCurrentHitPoints(oRider);

   int nHorseCHP=GetCurrentHitPoints(oHorse);

   int nRiderSHP=GetLocalInt(oRider,"nX3_RiderHP");

   int nHorseSHP=GetSkinInt(oRider,"nX3_HorseHP");

   int nDamage;

   effect eDamage;

   effect eHeal;

   effect ePCDamage;

   int nAmount;

   if (!GetIsObjectValid(oRider)||!GetIsObjectValid(oHorse)) return;

   if (nRiderCHP<nRiderSHP) nDamage=nRiderSHP-nRiderCHP;

   if (nHorseCHP>nHorseSHP&&nHorseSHP!=0)

   { // restore horse damage

       eDamage=EffectDamage(nHorseCHP-nHorseSHP);

       nHorseCHP=nHorseSHP;

       AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oHorse));

   } // restore horse damage

   if (nDamage>0)

   { // damage was received while mounted

       if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DAMAGE"))

       { // share damage with the mount

           nAmount=nDamage/2;

           if (nAmount>(nHorseCHP-1)) nAmount=nHorseCHP-1;

           eHeal=EffectHeal(nAmount);

           eDamage=EffectDamage(nAmount);

           ePCDamage=EffectDamage(nDamage-nAmount);

           if (GetCurrentHitPoints(oRider)>(nRiderSHP-(nDamage-nAmount))) AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_INSTANT,ePCDamage,oRider));

           else if (GetCurrentHitPoints(oRider)<(nRiderSHP-(nDamage-nAmount))) AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_INSTANT,eHeal,oRider));

           AssignCommand(GetModule(),ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oHorse));

       } // share damage with the mount

   } // damage was received while mounted

} // HORSE_SupportHandleDamage()





void KillTheHorse(object oHorse,int bStart=TRUE)

{ // PURPOSE: To Kill the horse

   effect eDeath=EffectDeath();

   object oItem=GetItemInSlot(INVENTORY_SLOT_CARMOUR,oHorse);

   //SendMessageToPC(GetFirstPC(),"KillTheHorse("+GetName(oHorse)+","+IntToString(bStart)+")");

   if (GetBaseItemType(oItem)==BASE_ITEM_CREATUREITEM&&bStart)

   { // destroy

       //SendMessageToPC(GetFirstPC(),"Destroy CARMOUR '"+GetName(oHorse)+"'");

       SetPlotFlag(oItem,FALSE);

       SetDroppableFlag(oItem,FALSE);

       DestroyObject(oItem);

   } // destroy

   if (bStart) oItem=GetFirstItemInInventory(oHorse);

   else { oItem=GetNextItemInInventory(oHorse); }

   if (GetIsObjectValid(oItem))

   { // valid

       //SendMessageToPC(GetFirstPC(),"Item '"+GetName(oItem)+"'");

       if (GetBaseItemType(oItem)==BASE_ITEM_CREATUREITEM)

       { // destroy

           //SendMessageToPC(GetFirstPC(),"  Destroy");

           SetPlotFlag(oItem,FALSE);

           SetDroppableFlag(oItem,FALSE);

           DestroyObject(oItem,1.0);

       } // destroy

       DelayCommand(0.03,KillTheHorse(oHorse,FALSE));

   } // valid

   else

   { // kill

       //SendMessageToPC(GetFirstPC(),"Kill '"+GetName(oHorse)+"'");

       DelayCommand(1.0,ApplyEffectToObject(DURATION_TYPE_INSTANT,eDeath,oHorse));

   } // kill

} // KillTheHorse()





void HORSE_SupportTransferInventory(object oFrom,object oTo,location lLoc,int bDestroyFrom=FALSE,int bFirst=TRUE)

{ // PURPOSE: Delay Command transfer to handle moving inventory

   object oItem;

   object oCopy;

   if (bFirst) oItem=GetFirstItemInInventory(oFrom);

   else { oItem=GetNextItemInInventory(oFrom); }

   if (GetIsObjectValid(oItem))

   { // item found

       if (GetIsObjectValid(oTo))

       { // to object

           if (GetBaseItemType(oItem)!=BASE_ITEM_CREATUREITEM)

           { // no pchide transfers

               oCopy=CopyItem(oItem,oTo,TRUE);

           } // no pchide transfers

       } // to object

       else

       { // to location

           if (GetBaseItemType(oItem)!=BASE_ITEM_CREATUREITEM)

           { // no pchide transfers

               oCopy=CopyObject(oItem,lLoc);

               if (GetItemStackSize(oCopy)!=GetItemStackSize(oItem)) SetItemStackSize(oCopy,GetItemStackSize(oItem));

               if (GetItemCharges(oCopy)!=GetItemCharges(oItem)) SetItemCharges(oCopy,GetItemCharges(oItem));

           } // no pchide transfers

       } // to location

       DestroyObject(oItem,2.0);

       DelayCommand(0.02,HORSE_SupportTransferInventory(oFrom,oTo,lLoc,bDestroyFrom,FALSE));

   } // item found

   else

   { // transfer gold

       if (GetIsObjectValid(oTo))

       { // to object

           if (GetGold(oFrom)>0) oCopy=CreateItemOnObject("nw_it_gold001",oTo,GetGold(oFrom));

       } // to object

       else

       { // to location

           if (GetGold(oFrom)>0) oCopy=CreateObject(OBJECT_TYPE_ITEM,"nw_it_gold001",lLoc,GetGold(oFrom));

       } // to location

       if (bDestroyFrom)

       { // destroy

           DestroyObject(oFrom);

       } // destroy

       if (GetLocalInt(oTo,"bDie"))

       { // death effect

           oItem=GetItemInSlot(INVENTORY_SLOT_CARMOUR,oTo);

           if (GetBaseItemType(oItem)==BASE_ITEM_CREATUREITEM)

           { // destroy

               SetDroppableFlag(oItem,FALSE);

               SetPlotFlag(oItem,FALSE);

               DestroyObject(oItem);

           } // destroy

           DelayCommand(0.1,KillTheHorse(oTo));

       } // death effect

   } // transfer gold

} // HORSE_SupportTransferInventory()





int HORSE_SupportCountHenchmen(object oPC)

{ // PURPOSE: Return the number of henchmen

   int nC=0;

   object oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nC+1);

   while(GetIsObjectValid(oHench))

   { // count

       nC++;

       oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nC+1);

   } // count

   return nC;

} // HORSE_SupportCountHenchmen()





void HORSE_SupportTransferPreservedValues(object oRider,object oHorse)

{ // PURPOSE: This will transfer preserved values for the mounted horse to

 // oHorse from oRider and then will remove them from oRider

   string sS;

   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

   if (GetIsObjectValid(oHorse))

   { // transfer values to horse



   } // transfer values to horse

   sS=GetSkinString(oRider,"X3_HORSE_POSTDISMOUNT_SCRIPT");

   if (GetStringLength(sS)>0)

   { // run post dismount script

       SetLocalObject(oRider,"oX3_TempHorse",oHorse);

       ExecuteScript(sS,oRider);

       DeleteLocalObject(oRider,"oX3_TempHorse");

   } // run post dismount script

   // delete variables

   if (GetLocalInt(oRider,"bX3_HORSE_MODIFIERS")&&GetStringLength(sS)<1)

   { // remove horse modifiers

       DeleteLocalInt(oRider,"bX3_HORSE_MODIFIERS");

       DelayCommand(0.10*fX3_MOUNT_MULTIPLE,HORSE_SupportOriginalSpeed(oRider));

       DelayCommand(0.30*fX3_MOUNT_MULTIPLE,HORSE_SupportAdjustMountedArcheryPenalty(oRider));

       DelayCommand(0.15*fX3_MOUNT_MULTIPLE,HORSE_SupportRemoveMountedSkillDecreases(oRider));

       DelayCommand(0.25*fX3_MOUNT_MULTIPLE,HORSE_SupportRemoveACBonus(oRider));

       DelayCommand(0.25*fX3_MOUNT_MULTIPLE,HORSE_SupportRemoveHPBonus(oRider));

       DelayCommand(0.20*fX3_MOUNT_MULTIPLE,HORSE_SupportHandleDamage(oRider,oHorse));

   } // remove horse modifiers

   //HORSE_SupportMountCleanVariables(oRider);

} // HORSE_SupportTransferPreservedValues()





void HORSE_SupportDismountWrapper(int bAnimate,int bSetOwner)

{ // Wrap

   object oHorse=HorseDismount(bAnimate,bSetOwner);

   object oNPC=OBJECT_SELF;

   if (bSetOwner) SetLocalObject(oNPC,"oAssignedHorse",oHorse);

} // HORSE_SupportDismountWrapper()





void HORSE_SupportRestoreFromPreload(object oPC,int nApp,int nTail)

{ // PURPOSE: Restore to previous appearance before preload

   SetCreatureAppearanceType(oPC,nApp);

   SetCreatureTailType(nTail,oPC);

} // HORSE_SupportRestoreFromPreload()





void HORSE_SupportSetMountingSentinel(object oRider,object oHorse,float fTimeout=6.0, int nCount=0)

{ // PURPOSE: This will set a mounting process that will make sure the PC or NPC

 // is returned to commandable.   There may be a slight delay but, this will

 // insure recovery from aborted mounts that could result in PC being stuck as

 // not commandable.

   if (!HorseGetIsMounted(oRider)&&!IsInConversation(oRider)&&!GetIsInCombat(oRider)&&!HorseGetIsDisabled(oRider))

   { // keep waiting

       float fFreq=1.0; // frequency in seconds

       if (nCount<FloatToInt(fTimeout/fFreq))

       { // keep trying

           DelayCommand(fFreq,HORSE_SupportSetMountingSentinel(oRider,oHorse,fTimeout,nCount+1));

       } // keep trying

       else if (!GetCutsceneMode(oRider))

       { // make commandable

           if (!GetCommandable(oRider))

           { // commandable

               SetCommandable(TRUE,oRider);

               SetCommandable(TRUE,oHorse);

               //HORSE_SupportCleanVariables(oRider);

               DeleteLocalInt(oRider,"X3_DOING_HORSE_ACTION");

               DeleteLocalInt(oHorse,"X3_DOING_HORSE_ACTION");

               DeleteLocalObject(oHorse,"oX3_TempRider");

               DeleteLocalInt(oRider,"nX3_MovingMount");

               DeleteLocalFloat(oRider,"fLastHorseDist");

               DeleteLocalInt(oRider,"bPathIsBlocked");

           } // commandable

       } // make commandable

   } // keep waiting

   else if (!GetCutsceneMode(oRider))

   { // make sure commandable if not in a cutscene

       if (!GetCommandable(oRider))

       { // commandable

           SetCommandable(TRUE,oRider);

           SetCommandable(TRUE,oHorse);

           //HORSE_SupportCleanVariables(oRider);

           DeleteLocalInt(oRider,"X3_DOING_HORSE_ACTION");

           DeleteLocalInt(oHorse,"X3_DOING_HORSE_ACTION");

           DeleteLocalObject(oHorse,"oX3_TempRider");

           DeleteLocalInt(oRider,"nX3_MovingMount");

           DeleteLocalFloat(oRider,"fLastHorseDist");

           DeleteLocalInt(oRider,"bPathIsBlocked");

       } // commandable

   } // make sure commandable if not in a cutscene

} // HORSE_SupportSetMountingSentinel()





void HORSE_Support_AssignRemainingMount(object oOwner)

{ // PURPOSE: Make a link between the oOwner and one of the horses he may own

   int nN=1;

   object oAssociate=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oOwner,nN);

   while(GetIsObjectValid(oAssociate))

   { // traverse associtates

       if (HorseGetIsAMount(oAssociate)&&HorseGetCanBeMounted(oAssociate,oOwner,TRUE)&&oOwner==HorseGetOwner(oAssociate))

       { // pick first unmounted owned mount

           SetLocalObject(oOwner,"oAssignedHorse",oAssociate);

           return;

       } // pick first unmounted owned mount

       nN++;

       oAssociate=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oOwner,nN);

   } // traverse associtates

} // HORSE_Support_AssignRemainingMount()





////////////////////////////////////////////////////////////////////////////////

////////////////////////   DATABASE SUPPORT FUNCTIONS   ////////////////////////

////////////////////////////////////////////////////////////////////////////////



/*

   These functions were provided so, Persistent World and other multiplayer

   gamers would have some functions to look at that they can modify to make

   work with their own persistent world.   People do these in so many ways that

   while these are functional, they used the default Bioware database commands

   and as a result are slow.   This was known when they were designed but, it

   was determined that having some sample functions that could be modified

   might be beneficial to the community.

*/





void HORSE_SupportDeleteFromDatabase(object oPC,string sDatabase,int nN=1)

{ // PURPOSE: Delete Henchmen information from the database

   string sN=IntToString(nN);

   DeleteCampaignVariable(sDatabase,"sX3_RR_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_TAG_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SCR_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HAP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HTL_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HNAP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HAP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_APP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_PHEN_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_FOOT_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_NOAN_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_CAPP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_CPHE_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_CTAIL_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPRM_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPOM_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPRDM_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPODM_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"bX3_MOUNTED_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_HTAG_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"sX3_HRR_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HPOR_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HHP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_RHP_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"bX3_ISM_"+sN,oPC);

   DeleteCampaignVariable(sDatabase,"nX3_TAL_"+sN,oPC);

   if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))

   { // saddlebags enabled

       DeleteCampaignVariable(sDatabase,"bX3_HSB_"+sN,oPC);

   } // saddlebags enabled

} // HORSE_SupportDeleteFromDatabase()





void HORSE_SupportSaveToDatabase(object oPC,object oHenchman,string sDatabase,int nN=1)

{ // PURPOSE: Save henchman to database

   string sN=IntToString(nN);

   SetCampaignString(sDatabase,"sX3_RR_",GetSkinString(oHenchman,"sX3_HorseResRef"),oPC);

   SetCampaignString(sDatabase,"sX3_TAG_",GetSkinString(oHenchman,"sX3_HorseMountTag"),oPC);

   SetCampaignString(sDatabase,"sX3_SCR_",GetLocalString(oHenchman,"sX3_HorseMountScript"),oPC);

   //SetCampaignInt(sDatabase,"nX3_HAP_",GetSkinInt(oHenchman,"X3_HORSE_APPEARANCE"),oPC);

   SetCampaignInt(sDatabase,"nX3_HTL_",GetLocalInt(oHenchman,"X3_HORSE_TAIL"),oPC);

   SetCampaignInt(sDatabase,"nX3_HNAP_",GetLocalInt(oHenchman,"X3_HORSE_NULL_APPEARANCE"),oPC);

   SetCampaignInt(sDatabase,"nX3_APP_",GetSkinInt(oHenchman,"nX3_HorseRiderAppearance"),oPC);

   SetCampaignInt(sDatabase,"nX3_PHEN_",GetSkinInt(oHenchman,"nX3_HorseRiderPhenotype"),oPC);

   SetCampaignInt(sDatabase,"nX3_FOOT_",GetSkinInt(oHenchman,"nX3_StoredFootstep"),oPC);

   SetCampaignInt(sDatabase,"nX3_NOAN_",GetLocalInt(oHenchman,"X3_NO_MOUNT_ANIMATE"),oPC);

   SetCampaignInt(sDatabase,"nX3_CAPP_",GetAppearanceType(oHenchman),oPC);

   SetCampaignInt(sDatabase,"nX3_CPHE_",GetPhenoType(oHenchman),oPC);

   SetCampaignInt(sDatabase,"nX3_CTAIL_",GetCreatureTailType(oHenchman),oPC);

   SetCampaignString(sDatabase,"sX3_SPRM_",GetLocalString(oHenchman,"X3_HORSE_PREMOUNT_SCRIPT"),oPC);

   SetCampaignString(sDatabase,"sX3_SPOM_",GetLocalString(oHenchman,"X3_HORSE_POSTMOUNT_SCRIPT"),oPC);

   SetCampaignString(sDatabase,"sX3_SPRDM_",GetSkinString(oHenchman,"X3_HORSE_PREDISMOUNT_SCRIPT"),oPC);

   SetCampaignString(sDatabase,"sX3_SPODM_",GetSkinString(oHenchman,"X3_HORSE_POSTDISMOUNT_SCRIPT"),oPC);

   SetCampaignInt(sDatabase,"bX3_MOUNTED_",HorseGetIsMounted(oHenchman),oPC);

   SetCampaignString(sDatabase,"sX3_HTAG_"+sN,GetTag(oHenchman),oPC);

   SetCampaignString(sDatabase,"sX3_HRR_"+sN,GetResRef(oHenchman),oPC);

   SetCampaignInt(sDatabase,"nX3_HPOR_"+sN,GetLocalInt(oHenchman,"nX3_HorsePortrait"),oPC);

   SetCampaignInt(sDatabase,"nX3_HHP_"+sN,GetSkinInt(oHenchman,"nX3_HorseHP"),oPC);

   SetCampaignInt(sDatabase,"nX3_RHP_"+sN,GetLocalInt(oHenchman,"nX3_RiderHP"),oPC);

   SetCampaignInt(sDatabase,"bX3_ISM_"+sN,GetSkinInt(oHenchman,"bX3_IS_MOUNTED"),oPC);

   SetCampaignInt(sDatabase,"nX3_TAL_"+sN,GetSkinInt(oHenchman,"nX3_HorseRiderTail"),oPC);

   if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))

   { // saddlebags enabled

       SetCampaignInt(sDatabase,"bX3_HSB_"+sN,GetLocalInt(oHenchman,"bX3_HAS_SADDLEBAGS"),oPC);

   } // saddlebags enabled

} // HORSE_SupportSaveToDatabase()





int HORSE_SupportGetHenchmanExistsInDatabase(object oPC,string sDatabase,int nN=1)

{ // PURPOSE: Return TRUE if there is a henchman saved in the database

   string sS=GetCampaignString(sDatabase,"sX3_HTAG_"+IntToString(nN),oPC);

   if (GetStringLength(sS)>0) return TRUE;

   return FALSE;

} // HORSE_SupportGetHenchmanExistsInDatabase()





void HORSE_SupportRestoreHenchmanFromDatabase(object oPC,string sDatabase,int nN=1)

{ // PURPOSE: This will reload and assign the henchman to the PC

   object oHenchman=OBJECT_INVALID;

   string sN=IntToString(nN);

   string sTag=GetCampaignString(sDatabase,"sX3_HTAG_"+sN,oPC);

   string sResRef=GetCampaignString(sDatabase,"sX3_HRR_"+sN,oPC);

   int nNN=1;

   object oOb;

   oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nNN);

   while(!GetIsObjectValid(oHenchman)&&GetIsObjectValid(oOb))

   { // see if henchman is already in play

       if (sResRef==GetResRef(oOb)&&GetTag(oOb)==sTag) oHenchman=oOb;

       nNN++;

       oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nNN);

   } // see if henchman is already in play

   if (!GetIsObjectValid(oHenchman))

   { // create henchman

       oHenchman=CreateObject(OBJECT_TYPE_CREATURE,sResRef,GetLocation(oPC),FALSE,sTag);

       AssignCommand(oHenchman,SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE));

       DelayCommand(1.0,AddHenchman(oPC,oHenchman));

   } // create henchman

   // load and set henchman

   SetCreatureAppearanceType(oHenchman,GetCampaignInt(sDatabase,"nX3_CAPP_"+sN,oPC));

   SetPhenoType(GetCampaignInt(sDatabase,"nX3_CPHE_"+sN,oPC),oHenchman);

   SetCreatureTailType(GetCampaignInt(sDatabase,"nX3_CTAIL_"+sN,oPC),oHenchman);

   SetSkinString(oHenchman,"sX3_HorseResRef",GetCampaignString(sDatabase,"sX3_RR_"+sN,oPC));

   SetSkinString(oHenchman,"sX3_HorseMountTag",GetCampaignString(sDatabase,"sX3_TAG_"+sN,oPC));

   SetLocalString(oHenchman,"sX3_HorseMountScript",GetCampaignString(sDatabase,"sX3_SCR_"+sN,oPC));

   SetLocalString(oHenchman,"X3_HORSE_PREMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPRM_"+sN,oPC));

   SetLocalString(oHenchman,"X3_HORSE_POSTMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPOM_"+sN,oPC));

   SetSkinString(oHenchman,"X3_HORSE_PREDISMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPRDM_"+sN,oPC));

   SetSkinString(oHenchman,"X3_HORSE_POSTDISMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPODM_"+sN,oPC));

   //SetSkinInt(oHenchman,"X3_HORSE_APPEARANCE",GetCampaignInt(sDatabase,"nX3_HAP_"+sN,oPC));

   SetLocalInt(oHenchman,"X3_HORSE_TAIL",GetCampaignInt(sDatabase,"nX3_HTL_"+sN,oPC));

   SetLocalInt(oHenchman,"X3_HORSE_NULL_APPEARANCE",GetCampaignInt(sDatabase,"nX3_HNAP_"+sN,oPC));

   SetSkinInt(oHenchman,"nX3_HorseRiderAppearance",GetCampaignInt(sDatabase,"nX3_APP_"+sN,oPC));

   SetSkinInt(oHenchman,"nX3_HorseRiderPhenotype",GetCampaignInt(sDatabase,"nX3_PHEN_"+sN,oPC));

   SetSkinInt(oHenchman,"nX3_StoredFootstep",GetCampaignInt(sDatabase,"nX3_FOOT_"+sN,oPC));

   SetLocalInt(oHenchman,"X3_NO_MOUNT_ANIMATE",GetCampaignInt(sDatabase,"nX3_NOAN_"+sN,oPC));

   SetLocalInt(oHenchman,"nX3_HorsePortrait",GetCampaignInt(sDatabase,"nX3_HPOR_"+sN,oPC));

   SetSkinInt(oHenchman,"nX3_HorseHP",GetCampaignInt(sDatabase,"nX3_HHP_"+sN,oPC));

   SetLocalInt(oHenchman,"nX3_RiderHP",GetCampaignInt(sDatabase,"nX3_RHP_"+sN,oPC));

   SetSkinInt(oHenchman,"bX3_IS_MOUNTED",GetCampaignInt(sDatabase,"bX3_ISM_"+sN,oPC));

   SetSkinInt(oHenchman,"nX3_HorseRiderTail",GetCampaignInt(sDatabase,"nX3_TAL_"+sN,oPC));

   if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))

   { // saddlebags enabled

       SetLocalInt(oHenchman,"bX3_HAS_SADDLEBAGS",GetCampaignInt(sDatabase,"bX3_HSB_"+sN,oPC));

   } // saddlebags enabled

} // HORSE_SupportRestoreHenchmanFromDatabase()





void HORSE_SupportDeleteMountedPCFromDatabase(object oPC,string sDatabase)

{ // PURPOSE: This will remove the info about this PC being mounted

   DeleteCampaignVariable(sDatabase,"sX3_RR",oPC);

   DeleteCampaignVariable(sDatabase,"sX3_TAG",oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SCR",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HAP",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HTL",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HNAP",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HAP",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_APP",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_PHEN",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_FOOT",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_NOAN",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_CAPP",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_CPHE",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_CTAIL",oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPRM",oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPOM",oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPRDM",oPC);

   DeleteCampaignVariable(sDatabase,"sX3_SPODM",oPC);

   DeleteCampaignVariable(sDatabase,"bX3_MOUNTED",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_PALUS",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HPOR",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_HHP",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_RHP",oPC);

   DeleteCampaignVariable(sDatabase,"bX3_ISM",oPC);

   DeleteCampaignVariable(sDatabase,"nX3_TAL",oPC);

   if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))

   { // saddlebags enabled

       DeleteCampaignVariable(sDatabase,"bX3_HSB",oPC);

   } // saddlebags enabled

} // HORSE_SupportDeleteMountedPCFromDatabase()





void HORSE_SupportStoreMountedPCInDatabase(object oPC,string sDatabase)

{ // PURPOSE: This will store the PCs information about being mounted

   SetCampaignString(sDatabase,"sX3_RR",GetSkinString(oPC,"sX3_HorseResRef"),oPC);

   SetCampaignString(sDatabase,"sX3_TAG",GetSkinString(oPC,"sX3_HorseMountTag"),oPC);

   SetCampaignString(sDatabase,"sX3_SCR",GetLocalString(oPC,"sX3_HorseMountScript"),oPC);

   //SetCampaignInt(sDatabase,"nX3_HAP",GetSkinInt(oPC,"X3_HORSE_APPEARANCE"),oPC);

   SetCampaignInt(sDatabase,"nX3_HTL",GetLocalInt(oPC,"X3_HORSE_TAIL"),oPC);

   SetCampaignInt(sDatabase,"nX3_HNAP",GetLocalInt(oPC,"X3_HORSE_NULL_APPEARANCE"),oPC);

   SetCampaignInt(sDatabase,"nX3_APP",GetSkinInt(oPC,"nX3_HorseRiderAppearance"),oPC);

   SetCampaignInt(sDatabase,"nX3_PHEN",GetSkinInt(oPC,"nX3_HorseRiderPhenotype"),oPC);

   SetCampaignInt(sDatabase,"nX3_FOOT",GetSkinInt(oPC,"nX3_StoredFootstep"),oPC);

   SetCampaignInt(sDatabase,"nX3_NOAN",GetLocalInt(oPC,"X3_NO_MOUNT_ANIMATE"),oPC);

   SetCampaignInt(sDatabase,"nX3_CAPP",GetAppearanceType(oPC),oPC);

   SetCampaignInt(sDatabase,"nX3_CPHE",GetPhenoType(oPC),oPC);

   SetCampaignInt(sDatabase,"nX3_CTAIL",GetCreatureTailType(oPC),oPC);

   SetCampaignString(sDatabase,"sX3_SPRM",GetLocalString(oPC,"X3_HORSE_PREMOUNT_SCRIPT"),oPC);

   SetCampaignString(sDatabase,"sX3_SPOM",GetLocalString(oPC,"X3_HORSE_POSTMOUNT_SCRIPT"),oPC);

   SetCampaignString(sDatabase,"sX3_SPRDM",GetSkinString(oPC,"X3_HORSE_PREDISMOUNT_SCRIPT"),oPC);

   SetCampaignString(sDatabase,"sX3_SPODM",GetSkinString(oPC,"X3_HORSE_POSTDISMOUNT_SCRIPT"),oPC);

   SetCampaignInt(sDatabase,"nX3_HPOR",GetLocalInt(oPC,"nX3_HorsePortrait"),oPC);

   SetCampaignInt(sDatabase,"nX3_RHP",GetLocalInt(oPC,"nX3_RiderHP"),oPC);

   SetCampaignInt(sDatabase,"nX3_HHP",GetSkinInt(oPC,"nX3_HorseHP"),oPC);

   SetCampaignInt(sDatabase,"bX3_MOUNTED",TRUE,oPC);

   SetCampaignInt(sDatabase,"bX3_ISM",GetSkinInt(oPC,"bX3_IS_MOUNTED"),oPC);

   SetCampaignInt(sDatabase,"nX3_PALUS",GetLocalInt(oPC,"nX3_PALADIN_UNSUMMON"),oPC);

   SetCampaignInt(sDatabase,"nX3_TAL",GetSkinInt(oPC,"nX3_HorseRiderTail"),oPC);

   if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))

   { // saddlebags enabled

       SetCampaignInt(sDatabase,"bX3_HSB",GetLocalInt(oPC,"bX3_HAS_SADDLEBAGS"),oPC);

   } // saddlebags enabled

} // HORSE_SupportStoreMountedPCInDatabase()





void HORSE_SupportReloadMountedPCFromDatabase(object oPC,string sDatabase)

{ // PURPOSE: This will restore the mounted information about the PC

   SetCreatureAppearanceType(oPC,GetCampaignInt(sDatabase,"nX3_CAPP",oPC));

   SetPhenoType(GetCampaignInt(sDatabase,"nX3_CPHE",oPC),oPC);

   SetCreatureTailType(GetCampaignInt(sDatabase,"nX3_CTAIL",oPC),oPC);

   SetSkinString(oPC,"sX3_HorseResRef",GetCampaignString(sDatabase,"sX3_RR",oPC));

   SetSkinString(oPC,"sX3_HorseMountTag",GetCampaignString(sDatabase,"sX3_TAG",oPC));

   SetLocalString(oPC,"sX3_HorseMountScript",GetCampaignString(sDatabase,"sX3_SCR",oPC));

   SetLocalString(oPC,"X3_HORSE_PREMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPRM",oPC));

   SetLocalString(oPC,"X3_HORSE_POSTMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPOM",oPC));

   SetSkinString(oPC,"X3_HORSE_PREDISMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPRDM",oPC));

   SetSkinString(oPC,"X3_HORSE_POSTDISMOUNT_SCRIPT",GetCampaignString(sDatabase,"sX3_SPODM",oPC));

   //SetSkinInt(oPC,"X3_HORSE_APPEARANCE",GetCampaignInt(sDatabase,"nX3_HAP",oPC));

   SetLocalInt(oPC,"X3_HORSE_TAIL",GetCampaignInt(sDatabase,"nX3_HTL",oPC));

   SetLocalInt(oPC,"X3_HORSE_NULL_APPEARANCE",GetCampaignInt(sDatabase,"nX3_HNAP",oPC));

   SetSkinInt(oPC,"nX3_HorseRiderAppearance",GetCampaignInt(sDatabase,"nX3_APP",oPC));

   SetSkinInt(oPC,"nX3_HorseRiderPhenotype",GetCampaignInt(sDatabase,"nX3_PHEN",oPC));

   SetSkinInt(oPC,"nX3_StoredFootstep",GetCampaignInt(sDatabase,"nX3_FOOT",oPC));

   SetLocalInt(oPC,"X3_NO_MOUNT_ANIMATE",GetCampaignInt(sDatabase,"nX3_NOAN",oPC));

   SetLocalInt(oPC,"nX3_PALADIN_UNSUMMON",GetCampaignInt(sDatabase,"nX3_PALUS",oPC));

   SetLocalInt(oPC,"nX3_HorsePortrait",GetCampaignInt(sDatabase,"nX3_HPOR",oPC));

   SetLocalInt(oPC,"nX3_RiderHP",GetCampaignInt(sDatabase,"nX3_RHP",oPC));

   SetSkinInt(oPC,"nX3_HorseHP",GetCampaignInt(sDatabase,"nX3_HHP",oPC));

   SetSkinInt(oPC,"bX3_IS_MOUNTED",GetCampaignInt(sDatabase,"bX3_ISM",oPC));

   SetSkinInt(oPC,"nX3_HorseRiderTail",GetCampaignInt(sDatabase,"nX3_TAL",oPC));

   if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS"))

   { // saddlebags enabled

       SetLocalInt(oPC,"bX3_HAS_SADDLEBAGS",GetCampaignInt(sDatabase,"bX3_HSB",oPC));

   } // saddlebags enabled

   if (HorseGetIsMounted(oPC)&&GetStringLeft(GetSkinString(oPC,"sX3_HorseResRef"),GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) AssignCommand(oPC,HORSE_SupportMonitorPaladinUnsummon(oPC));

} // HORSE_SupportReloadMountedPCFromDatabase()





////////////////////////////////////////////////////////////////////////////////

// FUNCTIONS

//-----------------------------

// This is where the actual functions defined in the prototype section are

// completed.

////////////////////////////////////////////////////////////////////////////////





void HorseReloadFromDatabase(object oPC,string sDatabase)

{ // PURPOSE: Reload status from database and set it the same

   int nN;

   // Reload settings for oPC

   HORSE_SupportReloadMountedPCFromDatabase(oPC,sDatabase);

   nN=1;

   while(HORSE_SupportGetHenchmanExistsInDatabase(oPC,sDatabase,nN))

   { // restore henchmen

       HORSE_SupportRestoreHenchmanFromDatabase(oPC,sDatabase,nN);

       nN++;

   } // restore henchmen

} // HorseReloadFromDatabase()





void HorseSaveToDatabase(object oPC,string sDatabase)

{ // PURPOSE: Save Status to Database

   int nN=1;

   int nMax;

   object oHenchman;

   if (HorseGetIsMounted(oPC))

   { // Store mounted info

       HORSE_SupportStoreMountedPCInDatabase(oPC,sDatabase);

   } // Store mounted info

   else

   { // Delete mounted info

       HORSE_SupportDeleteMountedPCFromDatabase(oPC,sDatabase);

   } // Delete mounted info

   while(HORSE_SupportGetHenchmanExistsInDatabase(oPC,sDatabase,nN))

   { // count

       nMax++;

       nN++;

   } // count

   nN=1;

   while(nN<=nMax)

   { // remove old

       HORSE_SupportDeleteFromDatabase(oPC,sDatabase,nN);

       nN++;

   } // remove old

   nN=1;

   oHenchman=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nN);

   while(GetIsObjectValid(oHenchman))

   { // traverse henchmen

       HORSE_SupportSaveToDatabase(oPC,oHenchman,sDatabase,nN);

       nN++;

       oHenchman=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nN);

   } // traverse henchmen

} // HorseSaveToDatabase()





object HorseCreateHorse(string sResRef,location lLoc,object oOwner=OBJECT_INVALID,string sTag="",int nAppearance=-1,int nTail=-1,int nFootstep=-1,string sScript="")

{ // PURPOSE: Spawn a horse with the specified information

   object oHorse=OBJECT_INVALID;

   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 (GetStringLength(sResRef)>0)

   { // resref specified

       oHorse=CreateObject(OBJECT_TYPE_CREATURE,sResRef,lLoc,FALSE,sTag);

       if (GetIsObjectValid(oHorse))

       { // horse successfully created

           SetLocalInt(oHorse,"bX3_IS_MOUNT",TRUE);

           SetLocalString(oHorse,"sX3_OriginalName",GetName(oHorse));

           if (GetIsObjectValid(oOwner)&&GetObjectType(oOwner)==OBJECT_TYPE_CREATURE)

           { // assign owner

               SetLocalObject(oHorse,"oX3_HorseOwner",oOwner);

               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

               AddHenchman(oOwner,oHorse);

               //AssignCommand(oHorse,SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE));

               SetAssociateState(NW_ASC_DISTANCE_6_METERS,TRUE,oHorse);

               if (GetMaster(oHorse)==oOwner) SetName(oHorse,GetName(oOwner)+"'s "+GetName(oHorse));

               if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oOwner)) SetLocalInt(oOwner,"bX3_STORE_MOUNT_INFO",TRUE);

           } // assign owner

           if (nAppearance>-1)

           { // set appearance

               SetCreatureAppearanceType(oHorse,nAppearance);

           } // set appearance

           if (nTail>-1)

           { // set tail

               SetCreatureTailType(nTail,oHorse);

           } // set tail

           if (nFootstep>-1)

           { // footstep

               SetFootstepType(nFootstep,oHorse);

           } // footstep

           if (GetStringLength(sScript)>0)

           { // post spawn script

               SetLocalString(oHorse,"sX3_HORSE_CREATED_SCRIPT",sScript);

               ExecuteScript(sScript,oHorse);

           } // post spawn script

       } // horse successfully created

   } // resref specified

   return oHorse;

} // HorseCreateHorse()





int HorseGetIsMounted(object oTarget)

{ // PURPOSE: Return whether oTarget is mounted

   if (GetObjectType(oTarget)==OBJECT_TYPE_CREATURE)

   { // valid parameter

       if (GetSkinInt(oTarget,"bX3_IS_MOUNTED")) return TRUE;

   } // valid parameter

   return FALSE;

} // HorseGetIsMounted()





int HorseGetCanBeMounted(object oTarget,object oRider=OBJECT_INVALID,int bAssignMount=FALSE)

{ // PURPOSE: This will return whether oTarget can be mounted

   int nAppearance;

   string sS;

   object oOb;

   if (GetObjectType(oTarget)==OBJECT_TYPE_CREATURE)

   { // valid oTarget type

       if (GetIsDead(oTarget)) return FALSE;

       if (GetIsPC(oTarget)) return FALSE;

       if (GetIsObjectValid(oRider)&&GetObjectType(oRider)!=OBJECT_TYPE_CREATURE) return FALSE;

       if (GetIsObjectValid(oRider)&&GetIsEnemy(oRider,oTarget)) return FALSE;

       if (GetIsDMPossessed(oTarget)) return FALSE;

       if (HorseGetIsMounted(oRider)) return FALSE;

       //if (GetIsObjectValid(oRider)&&GetCreatureTailType(oRider)!=CREATURE_TAIL_TYPE_NONE) return FALSE;

       nAppearance=GetAppearanceType(oRider);

       if (GetIsPC(oRider)&&nAppearance>6&&GetLocalInt(oRider,"X3_CUSTOM_RACE_APPEARANCE")!=nAppearance&&!Horse_SupportRaceAppearance(nAppearance)) return FALSE; // PC is shape shifted

       if (GetIsObjectValid(oRider)&&GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

       { // Rider is a creature

           sS=HORSE_SupportRaceRestrictString(oRider);

           if (GetLocalInt(oTarget,sS)) return FALSE; // race restricted

       } // Rider is a creature

       oOb=GetMaster(oTarget);

       if (GetIsObjectValid(oOb)&&GetIsObjectValid(oRider))

       { // has master make sure is part of party

           if (oOb!=oRider&&oOb!=GetMaster(oRider)&&GetMaster(oOb)!=GetMaster(oRider))

           { // not part of party

               return FALSE;

           } // 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 FALSE;

       } // not rideable due to owner

       if (GetLocalInt(GetArea(oTarget),"X3_NO_MOUNTING")&&!bAssignMount)

       { // no mounting allowed in this area

           return FALSE;

       } // 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 FALSE;

       } // paladin mount

       if (!HorseGetIsAMount(oTarget)) return FALSE;

       return TRUE;

   } // valid oTarget type

   return FALSE;

} // HorseGetCanBeMounted()





string HorseGetMountFailureMessage(object oTarget,object oRider=OBJECT_INVALID)

{ // PURPOSE: This will return the error message

   int nAppearance;

   string sS;

   object oOb;

   if (GetObjectType(oTarget)==OBJECT_TYPE_CREATURE)

   { // valid oTarget type

       if (GetIsDead(oTarget)) return StringToRGBString(GetStringByStrRef(111993),STRING_COLOR_ROSE);

       if (GetIsPC(oTarget)) return StringToRGBString(GetStringByStrRef(111994),STRING_COLOR_ROSE);

       if (GetIsObjectValid(oRider)&&GetObjectType(oRider)!=OBJECT_TYPE_CREATURE) return StringToRGBString(GetStringByStrRef(111995),STRING_COLOR_ROSE);

       if (GetIsObjectValid(oRider)&&GetIsEnemy(oRider,oTarget)) return StringToRGBString(GetStringByStrRef(111996),STRING_COLOR_ROSE);

       if (GetIsDMPossessed(oTarget)) return StringToRGBString(GetStringByStrRef(111997),STRING_COLOR_ROSE);

       if (HorseGetIsMounted(oRider)) return StringToRGBString(GetStringByStrRef(111998),STRING_COLOR_ROSE);

       //if (GetIsObjectValid(oRider)&&GetCreatureTailType(oRider)!=CREATURE_TAIL_TYPE_NONE) return StringToRGBString(GetStringByStrRef(111998),STRING_COLOR_ROSE);

       nAppearance=GetAppearanceType(oRider);

       if (GetIsPC(oRider)&&nAppearance>6&&GetLocalInt(oRider,"X3_CUSTOM_RACE_APPEARANCE")!=nAppearance&&!Horse_SupportRaceAppearance(nAppearance)) return StringToRGBString(GetStringByStrRef(111999),STRING_COLOR_ROSE);

       if (GetIsObjectValid(oRider)&&GetObjectType(oRider)==OBJECT_TYPE_CREATURE)

       { // Rider is a creature

           sS=HORSE_SupportRaceRestrictString(oRider);

           if (GetLocalInt(oTarget,sS)) return StringToRGBString(GetStringByStrRef(112000),STRING_COLOR_PINK);

       } // Rider is a creature

       oOb=GetMaster(oTarget);

       if (GetIsObjectValid(oOb)&&GetIsOb
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #21 on: July 22, 2010, 03:36:51 am »


               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 '<img'>

           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)>8) 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);

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #22 on: July 22, 2010, 04:02:47 am »


               sID=sID+GetPCPublicCDKey(oOwner)+GetStringLeft(GetName(oOwner),4);

       } // PC owner

   } // owner specified

   if (GetIsObjectValid(oWP))

   { // do not use database

       // I am using a placeable that has inventory but, by default does not

       // have scripts that produce extra inventory.

       oChest=CreateObject(OBJECT_TYPE_PLACEABLE,"x3_plc_jars001",GetLocation(oWP),FALSE,"X3_"+sID);

       SetName(oChest,GetName(oCreature)+"'s Inventory");

       SetLocalObject(oCreature,"oX3_Saddlebags",oChest);

       HORSE_SupportTransferInventory(oCreature,oChest,GetLocation(oChest));

   } // do not use database

   else

   { // use database

       nC=0;

       oItem=GetFirstItemInInventory(oCreature);

       while(GetIsObjectValid(oItem))

       { // store inventory

           nC++;

           sR=GetResRef(oItem);

           sT=GetTag(oItem);

           nST=GetItemStackSize(oItem);

           nCH=GetItemCharges(oItem);

           SetCampaignString(sDB,"sR"+sID+IntToString(nC),sR);

           SetCampaignString(sDB,"sT"+sID+IntToString(nC),sT);

           SetCampaignInt(sDB,"nS"+sID+IntToString(nC),nST);

           SetCampaignInt(sDB,"nC"+sID+IntToString(nC),nCH);

           DestroyObject(oItem,0.1);

           oItem=GetNextItemInInventory(oCreature);

       } // store inventory

       SetCampaignInt(sDB,"nCO_"+sID,nC);

       if (GetIsObjectValid(oRider)) SetLocalString(oRider,"sDB_Inv",sID);

   } // use database

} // HorseStoreInventory()





void HorseRestoreInventory(object oCreature,int bDrop=FALSE)

{ // PURPOSE: To restore inventory that was stored while mounted

   object oWP=GetWaypointByTag("X3_HORSE_INVENTORY_STORAGE");

   object oOwner=GetMaster(oCreature);

   object oOwnersMaster=GetMaster(oOwner);

   object oItem;

   object oChest;

   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)>8) 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);

       } // PC owner

   } // owner specified

   if (GetIsObjectValid(oWP))

   { // do not use database

       oChest=GetObjectByTag("X3_"+sID);

       if (!GetIsObjectValid(oChest)) oChest=GetLocalObject(oOwner,"oX3_Saddlebags");

       if (GetIsObjectValid(oChest))

       { // chest found

           HORSE_SupportTransferInventory(oChest,oCreature,GetLocation(oCreature),TRUE);

       } // chest found

       else

       { // error

           PrintString("ERROR: x3_inc_horse 'HorseRestoreInventory()' Could not find chest 'X3_"+sID+"'!");

       } // error

   } // do not use database

   else

   { // use database

       nC=GetCampaignInt(sDB,"nCO_"+sID);

       while(nC>0)

       { // restore inventory

           sR=GetCampaignString(sDB,"sR"+sID+IntToString(nC));

           sT=GetCampaignString(sDB,"sT"+sID+IntToString(nC));

           nST=GetCampaignInt(sDB,"nS"+sID+IntToString(nC));

           nCH=GetCampaignInt(sDB,"nC"+sID+IntToString(nC));

           DeleteCampaignVariable(sDB,"sR"+sID+IntToString(nC));

           DeleteCampaignVariable(sDB,"sT"+sID+IntToString(nC));

           DeleteCampaignVariable(sDB,"nS"+sID+IntToString(nC));

           DeleteCampaignVariable(sDB,"nC"+sID+IntToString(nC));

           if (!bDrop) oItem=CreateItemOnObject(sR,oCreature,nST,sT);

           else

           { // drop

               oItem=CreateObject(OBJECT_TYPE_ITEM,sR,GetLocation(oCreature),FALSE,sT);

               if (GetItemStackSize(oItem)!=nST&&nST!=0) SetItemStackSize(oItem,nST);

           } // drop

           if (nCH>0) SetItemCharges(oItem,nCH);

           nC--;

       } // restore inventory

       DeleteCampaignVariable(sDB,"nCO_"+sID);

   } // use database

} // HorseRestoreInventory()





void HorseChangeToDefault(object oCreature)

{ // PURPOSE: HorseChangeToDefault

   int nRace=GetRacialType(oCreature);

   int nDefApp=StringToInt(Get2DAString("racialtypes","Appearance",nRace));

   int nDefPhen;

   int nPheno=GetPhenoType(oCreature);

   if (nPheno==HORSE_PHENOTYPE_JOUSTING_L||nPheno==HORSE_PHENOTYPE_MOUNTED_L) nDefPhen=PHENOTYPE_BIG;

   else { nDefPhen=PHENOTYPE_NORMAL; }

   SetCreatureAppearanceType(oCreature,nDefApp);

   SetPhenoType(nDefPhen,oCreature);

   SetCreatureTailType(CREATURE_TAIL_TYPE_NONE,oCreature);

   SetFootstepType(FOOTSTEP_TYPE_NORMAL,oCreature);

   DeleteLocalInt(oCreature,"bX3_HORSE_MODIFIERS");

   DelayCommand(0.1,HORSE_SupportOriginalSpeed(oCreature));

   DelayCommand(0.2,HORSE_SupportRemoveMountedSkillDecreases(oCreature));

   DelayCommand(0.2,HORSE_SupportAdjustMountedArcheryPenalty(oCreature));

   DelayCommand(0.4,HORSE_SupportRemoveACBonus(oCreature));

   DelayCommand(0.4,HORSE_SupportRemoveHPBonus(oCreature));

   DelayCommand(1.0,HORSE_SupportCleanVariables(oCreature));

   if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsPC(oCreature)) SetLocalInt(oCreature,"bX3_STORE_MOUNT_INFO",TRUE);

} // HorseChangeToDefault()





void HorseIfNotDefaultAppearanceChange(object oCreature)

{ // PURPOSE: See if not default appearance

   int nRace=GetRacialType(oCreature);

   int nDefApp=StringToInt(Get2DAString("racialtypes","Appearance",nRace));

   if (GetAppearanceType(oCreature)!=nDefApp) HorseChangeToDefault(oCreature);

} // HorseIfNotDefaultAppearanceChange()





object HorseGetMyHorse(object oRider)

{ // PURPOSE: Return active horse

   object oRet=GetLocalObject(oRider,"oX3_TempHorse");

   if (GetIsObjectValid(oRet)) return oRet;

   return GetLocalObject(oRider,"oAssignedHorse");

} // HorseGetMyHorse()





int HorseGetHasAHorse(object oRider)

{ // PURPOSE: Return if oRider has a horse

   int nN=1;

   object oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oRider,nN);

   while(GetIsObjectValid(oHench))

   { // traverse henchmen

       if (HorseGetIsAMount(oHench)) return TRUE;

       nN++;

       oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oRider,nN);

   } // traverse henchmen

   return FALSE;

} // HorseGetHasAHorse()





object HorseGetHorse(object oRider,int nN=1)

{ // PURPOSE: Return the nNth horse of oRider

   int nC=1;

   int nH=0;

   object oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oRider,nC);

   while(GetIsObjectValid(oHench))

   { // traverse henchmen

       if (HorseGetIsAMount(oHench))

       { // is a horse

          nH++;

          if (nH==nN) return oHench;

       } // is a horse

       nC++;

       oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oRider,nC);

   } // traverse henchmen

   return OBJECT_INVALID;

} // HorseGetHorse()





void HorseRestoreHenchmenLocations(object oPC)

{ // PURPOSE: Restore the locations of the henchmen of henchmen

   object oHench;

   int nN;

   int nC;

   object oAssoc;

   int bNoMounts;

   int bNoMounting;

   int bRunAgain=FALSE;

   float fDelay=0.2;

   object oArea;

   if (GetLocalInt(GetModule(),"X3_RESTORE_HENCHMEN_LOCATIONS"))

   { // restore location of henchmen belonging to henchmen

       nN=1;

       oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nN);

       while(GetIsObjectValid(oHench))

       { // hench

           oArea=GetArea(oHench);

           bNoMounts=FALSE;

           bNoMounting=FALSE;

           if (!GetLocalInt(oArea,"X3_MOUNT_OK_EXCEPTION"))

           { // find out if horses ok

               if (GetLocalInt(GetModule(),"X3_MOUNTS_EXTERNAL_ONLY")&&GetIsAreaInterior(oArea)) bNoMounts=TRUE;

               else if (GetLocalInt(GetModule(),"X3_MOUNTS_NO_UNDERGROUND")&&!GetIsAreaAboveGround(oArea)) bNoMounts=TRUE;

           } // find out if horses ok

           if (GetLocalInt(oArea,"X3_NO_MOUNTING")||GetLocalInt(oArea,"X3_NO_HORSES")||bNoMounts) bNoMounting=TRUE;

           nC=1;

           oAssoc=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nC);

           while(GetIsObjectValid(oAssoc))

           { // check each associate

               if (HorseGetIsMounted(oAssoc)&&(bNoMounts||bNoMounting))

               { // dismount

                   bRunAgain=TRUE;

                   DelayCommand(fDelay,AssignCommand(oAssoc,HORSE_SupportDismountWrapper(FALSE,TRUE)));

                   fDelay=fDelay+0.2;

               } // dismount

               else if (HorseGetIsAMount(oAssoc)&&bNoMounts)

               { // no mounts

                   DelayCommand(fDelay,RemoveHenchman(oHench,oAssoc));

                   DelayCommand(fDelay+0.01,SetAssociateState(NW_ASC_MODE_STAND_GROUND,TRUE,oAssoc));

                   fDelay=fDelay+0.2;

               } // no mounts

               else if (GetArea(oAssoc)!=oArea)

               { // jump

                   AssignCommand(oAssoc,ClearAllActions(TRUE));

                   AssignCommand(oAssoc,ActionJumpToObject(oHench));

               } // jump

               nC++;

               oAssoc=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nC);

           } // check each associate

           nN++;

           oHench=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oPC,nN);

       } // hench

       nN=1;

       oHench=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC,oPC,nN);

       while(GetIsObjectValid(oHench))

       { // test non-henchmen

           if (!GetIsObjectValid(GetMaster(oHench))||GetMaster(oHench)==oHench)

           { // test associates

               oArea=GetArea(oHench);

               bNoMounts=FALSE;

               bNoMounting=FALSE;

               if (!GetLocalInt(oArea,"X3_MOUNT_OK_EXCEPTION"))

               { // find out if horses ok

                   if (GetLocalInt(GetModule(),"X3_MOUNTS_EXTERNAL_ONLY")&&GetIsAreaInterior(oArea)) bNoMounts=TRUE;

                   else if (GetLocalInt(GetModule(),"X3_MOUNTS_NO_UNDERGROUND")&&!GetIsAreaAboveGround(oArea)) bNoMounts=TRUE;

               } // find out if horses ok

               if (GetLocalInt(oArea,"X3_NO_MOUNTING")||GetLocalInt(oArea,"X3_NO_HORSES")||bNoMounts) bNoMounting=TRUE;

               nC=1;

               oAssoc=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nC);

               while(GetIsObjectValid(oAssoc))

               { // check each associate

                   if (HorseGetIsMounted(oAssoc)&&(bNoMounts||bNoMounting))

                   { // dismount

                       bRunAgain=TRUE;

                       DelayCommand(fDelay,AssignCommand(oAssoc,HORSE_SupportDismountWrapper(FALSE,TRUE)));

                       fDelay=fDelay+0.2;

                   } // dismount

                   else if (HorseGetIsAMount(oAssoc)&&bNoMounts)

                   { // no mounts

                       DelayCommand(fDelay,RemoveHenchman(oHench,oAssoc));

                       DelayCommand(fDelay+0.01,SetAssociateState(NW_ASC_MODE_STAND_GROUND,TRUE,oAssoc));

                       fDelay=fDelay+0.2;

                   } // no mounts

                   else if (GetArea(oAssoc)!=oArea)

                   { // jump

                       AssignCommand(oAssoc,ClearAllActions(TRUE));

                       AssignCommand(oAssoc,ActionJumpToObject(oHench));

                   } // jump

                   nC++;

                   oAssoc=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nC);

               } // check each associate

           } // test associates

           nN++;

           oHench=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC,oPC,nN);

       } // test non-henchmen

       if (bRunAgain) DelayCommand(5.0+fDelay,HorseRestoreHenchmenLocations(oPC));

   } // restore location of henchmen belonging to henchmen

} // HorseRestoreHenchmenLocations()





////////////////////////////////////////////////////////////////////////////////

///////////////////////////////   TRANSITIONS   ////////////////////////////////

////////////////////////////////////////////////////////////////////////////////





void HorseHitchHorses(object oHitch,object oClicker,location lPreJump)

{ // PURPOSE: Hitch all associates to clicker

   object oOb;

   object oHench;

   int nN=1;

   int nNN;

   int bNotAllowed=FALSE;

   float fX3_MOUNT_MULTIPLE=GetLocalFloat(GetArea(oClicker),"fX3_MOUNT_MULTIPLE");

   float fX3_DISMOUNT_MULTIPLE=GetLocalFloat(GetArea(oClicker),"fX3_DISMOUNT_MULTIPLE");

   if (GetLocalFloat(oClicker,"fX3_MOUNT_MULTIPLE")>fX3_MOUNT_MULTIPLE) fX3_MOUNT_MULTIPLE=GetLocalFloat(oClicker,"fX3_MOUNT_MULTIPLE");

   if (fX3_MOUNT_MULTIPLE<=0.0) fX3_MOUNT_MULTIPLE=1.0;

   if (GetLocalFloat(oClicker,"fX3_DISMOUNT_MULTIPLE")>0.0) fX3_DISMOUNT_MULTIPLE=GetLocalFloat(oClicker,"fX3_DISMOUNT_MULTIPLE");

   if (fX3_DISMOUNT_MULTIPLE>0.0) fX3_MOUNT_MULTIPLE=fX3_DISMOUNT_MULTIPLE; // use dismount multiple instead of mount multiple

   float fDelay=0.2*fX3_MOUNT_MULTIPLE;

   oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oClicker,nN);

   while(GetIsObjectValid(oOb))

   { // traverse henchmen

       if (HorseGetIsAMount(oOb)&&(!GetLocalInt(oOb,"X3_DOING_HORSE_ACTION")))

       { // is a mount

           bNotAllowed=TRUE;

           if (GetStringLeft(GetResRef(oOb),GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) SetLocalObject(oClicker,"oX3PaladinMount",oOb);

           if (GetIsObjectValid(oHitch)&&GetDistanceBetween(oClicker,oHitch)<15.0)

           { // jump to hitch

               DelayCommand(0.1,RemoveHenchman(oClicker,oOb));

               AssignCommand(oOb,ClearAllActions(TRUE));

               //AssignCommand(oOb,ActionWait(X3_ACTION_DELAY/2*fX3_MOUNT_MULTIPLE));

               AssignCommand(oOb,ActionJumpToObject(oHitch));

               AssignCommand(oOb,ActionDoCommand(SetFacingPoint(GetPosition(oHitch))));

               SetAssociateState(NW_ASC_MODE_STAND_GROUND,TRUE,oOb);

           } // jump to hitch

           else

           { // stand where you are and make way

               DelayCommand(0.1,RemoveHenchman(oClicker,oOb));

               SetAssociateState(NW_ASC_MODE_STAND_GROUND,TRUE,oOb);

               AssignCommand(oOb,ClearAllActions(TRUE));

               if (GetDistanceBetween(oOb,oClicker)'<3'.0) DelayCommand(1.0*fX3_MOUNT_MULTIPLE,AssignCommand(oOb,ActionMoveAwayFromLocation(lPreJump,FALSE,3.0+IntToFloat(Random(15))/10.0)));

               else if (GetDistanceBetween(oOb,oClicker)>4.0) DelayCommand(1.0*fX3_MOUNT_MULTIPLE,AssignCommand(oOb,ActionMoveToLocation(GetBehindLocation(oClicker))));

           } // stand where you are and make way

       } // is a mount

       else

       { // check for mounts for this henchman

           oHench=oOb;

           nNN=1;

           oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nNN);

           while(GetIsObjectValid(oOb))

           { // traverse henchmen

               if (HorseGetIsAMount(oOb)&&(!GetLocalInt(oOb,"X3_DOING_HORSE_ACTION")))

               { // is a mount

                   bNotAllowed=TRUE;

                   if (GetStringLeft(GetResRef(oOb),GetStringLength(HORSE_PALADIN_PREFIX))==HORSE_PALADIN_PREFIX) SetLocalObject(oHench,"oX3PaladinMount",oOb);

                   if (GetIsObjectValid(oHitch)&&GetDistanceBetween(oClicker,oHitch)<15.0)

                   { // jump to hitch

                       DelayCommand(0.1,RemoveHenchman(oHench,oOb));

                       AssignCommand(oOb,ClearAllActions(TRUE));

                       //AssignCommand(oOb,ActionWait(X3_ACTION_DELAY/2*fX3_MOUNT_MULTIPLE));

                       AssignCommand(oOb,ActionJumpToObject(oHitch));

                       AssignCommand(oOb,ActionDoCommand(SetFacingPoint(GetPosition(oHitch))));

                       SetAssociateState(NW_ASC_MODE_STAND_GROUND,TRUE,oOb);

                   } // jump to hitch

                   else

                   { // stand where you are and make way

                       DelayCommand(0.1,RemoveHenchman(oHench,oOb));

                       AssignCommand(oOb,ClearAllActions(TRUE));

                       SetAssociateState(NW_ASC_MODE_STAND_GROUND,TRUE,oOb);

                       fDelay+=0.2*fX3_MOUNT_MULTIPLE;

                       //if (GetDistanceBetween(oOb,oClicker)<4.0) DelayCommand(fDelay,AssignCommand(oOb,ActionMoveAwayFromLocation(lPreJump,FALSE,4.0+IntToFloat(Random(15))/10.0)));

                       if (GetDistanceBetween(oOb,OBJECT_SELF)<4.0) DelayCommand(fDelay,AssignCommand(oOb,ActionMoveAwayFromLocation(lPreJump,FALSE,4.0+IntToFloat(Random(15))/10.0)));

                       //else if (GetDistanceBetween(oOb,oClicker)>5.0) DelayCommand(fDelay,AssignCommand(oOb,ActionMoveToLocation(GetBehindLocation(oClicker))));

                       else if (GetDistanceBetween(oOb,OBJECT_SELF)>5.0) DelayCommand(fDelay,AssignCommand(oOb,ActionMoveToObject(OBJECT_SELF,FALSE,4.0+IntToFloat(Random(15))/10.0)));

                       //SendMessageToPC(oClicker, FloatToString(GetDistanceBetween(oOb,OBJECT_SELF)));

                   } // stand where you are and make way

               } // is a mount

               nNN++;

               oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nNN);

           } // traverse henchmen

       } // check for mounts for this henchman

       nN++;

       oOb=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oClicker,nN);

   } // traverse henchmen

   if (bNotAllowed) SendMessageToPCByStrRef(oClicker,111990);

} // HorseHitchHorses()





void HorseForceJump(object oJumper,object oDestination,float fRange=2.0,int nTimeOut=10)

{ // PURPOSE: Make sure jump

   //SendMessageToPC(oJumper,"nw_g0_transition:ForceJump("+IntToString(nTimeOut)+")");

   if (nTimeOut>0&&(GetArea(oJumper)!=GetArea(oDestination)||GetDistanceBetween(oJumper,oDestination)>fRange))

   { // jump

       AssignCommand(oJumper,ClearAllActions(TRUE));

       AssignCommand(oJumper,ActionJumpToObject(oDestination));

       DelayCommand(1.0,HorseForceJump(oJumper,oDestination,fRange,nTimeOut-1));

   } // jump

} // HorseForceJump()





void HorseMoveAssociates(object oMaster)

{ // PURPOSE: Give the PC some breathing room

   int nN,nNN;

   float fDelay=0.2;

   object oHench,oAssociate,oSummon;

   nN=1;

   oAssociate=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oMaster,nN);

   while(GetIsObjectValid(oAssociate))

   { // move associates

       if (HorseGetIsAMount(oAssociate)||HorseGetIsMounted(oAssociate))

       { // only move mounts or mounted associates

           if (GetArea(oAssociate)==GetArea(oMaster)&&GetDistanceBetween(oMaster,oAssociate)'<3'.0)

           { // move away

               AssignCommand(oAssociate,ClearAllActions());

               DelayCommand(1.0,AssignCommand(oAssociate,ActionMoveAwayFromObject(oMaster,FALSE,3.0+IntToFloat(Random(10))/10.0)));

           } // move away

       } // only move mounts or mounted associates

       else

       { // henchmen of henchman

           oHench=oAssociate;

           nNN=1;

           oAssociate=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nNN);

           while(GetIsObjectValid(oAssociate))

           { // traverse henchmen

               if (HorseGetIsAMount(oAssociate)||HorseGetIsMounted(oAssociate))

               { // only move mounts or mounted associates

                   if (GetArea(oAssociate)==GetArea(oMaster)&&GetDistanceBetween(oMaster,oAssociate)'<3'.0)

                   { // move away

                       fDelay+=0.2;

                       AssignCommand(oAssociate,ClearAllActions());

                       DelayCommand(fDelay,AssignCommand(oAssociate,ActionMoveAwayFromObject(oMaster,FALSE,3.0+IntToFloat(Random(15))/10.0)));

                   } // move away

               } // only move mounts or mounted associates

               nNN++;

               oAssociate=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oHench,nNN);

               oSummon=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oHench,nNN);

           } // traverse henchmen

           nNN=1;

           oSummon=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oHench,nNN);

           while(GetIsObjectValid(oSummon))

           { // traverse summons

               if (HorseGetIsAMount(oSummon)||HorseGetIsMounted(oSummon))

               { // only move mounts or mounted associates

                   if (GetArea(oSummon)==GetArea(oMaster)&&GetDistanceBetween(oMaster,oSummon)'<3'.0)

                   { // move away

                       fDelay+=0.2;

                       AssignCommand(oSummon,ClearAllActions());

                       DelayCommand(fDelay,AssignCommand(oSummon,ActionMoveAwayFromObject(oMaster,FALSE,3.0+IntToFloat(Random(15))/10.0)));

                   } // move away

               } // only move mounts or mounted associates

               nNN++;

               oSummon=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oHench,nNN);

           } // traverse summons

       } // henchmen of henchman

       nN++;

       oAssociate=GetAssociate(ASSOCIATE_TYPE_HENCHMAN,oMaster,nN);

   } // move associates

   nN=1;

   oAssociate=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oMaster,nN);

   while(GetIsObjectValid(oAssociate))

   { // move associates

       if (HorseGetIsAMount(oAssociate)||HorseGetIsMounted(oAssociate))

       { // only move mounts or mounted associates

           if (GetArea(oAssociate)==GetArea(oMaster)&&GetDistanceBetween(oMaster,oAssociate)'<3'.0)

           { // move away

               AssignCommand(oAssociate,ClearAllActions());

               DelayCommand(1.0,AssignCommand(oAssociate,ActionMoveAwayFromObject(oMaster,FALSE,3.0+IntToFloat(Random(10))/10.0)));

           } // move away

       } // only move mounts or mounted associates

       nN++;

       oAssociate=GetAssociate(ASSOCIATE_TYPE_SUMMONED,oMaster,nN);

   } // move associates

} // HorseMoveAssociates()





////////////////////////////////////////////////////////////////////////////////

/////////////////////////////   DEATH HANDLING   ///////////////////////////////

////////////////////////////////////////////////////////////////////////////////





void HorseDismountWrapper()

{ // Wrap

   object oNPC=OBJECT_SELF;

   if (HorseGetIsMounted(oNPC))

   { // make sure dismount

       DelayCommand(0.1,HORSE_SupportResetUnmountedAppearance(oNPC));

       DelayCommand(0.8,HORSE_SupportCleanVariables(oNPC));

       DelayCommand(1.0,HORSE_SupportRemoveACBonus(oNPC));

       DelayCommand(1.0,HORSE_SupportRemoveHPBonus(oNPC));

       DelayCommand(1.0,HORSE_SupportRemoveMountedSkillDecreases(oNPC));

       DelayCommand(1.0,HORSE_SupportAdjustMountedArcheryPenalty(oNPC));

       DelayCommand(1.0,HORSE_SupportOriginalSpeed(oNPC));

       DelayCommand(2.0,HorseDismountWrapper());

   } // make sure dismount

} // HorseDismountWrapper()





void HorseReassign(object oHorse,object oHench,object oMaster)

{ // PURPOSE: To handle horse reassign

   if (GetIsObjectValid(oMaster)&&oMaster!=oHench)

   { // reassign

       HorseSetOwner(oHorse,oMaster);

       DeleteLocalObject(oHench,"oAssignedHorse");

   } // reassign

   else

   { // free

       HorseRemoveOwner(oHorse);

       DeleteLocalObject(oHench,"oAssignedHorse");

   } // free

} // HorseReassign()





int HorseHandleDeath()

{ // PURPOSE: Handle horses, re-assigning dying henchman's horse, handle mounted henchman's death (dismount, transfer saddlebag content to horse, re-assign horse to PC or free it)

   object oDied=OBJECT_SELF;

   object oHorse=HorseGetHorse(oDied);

   object oMaster=GetMaster(oDied);

   if (GetLocalInt(GetModule(),"X3_ENABLE_MOUNT_DB")&&GetIsObjectValid(GetMaster(oDied))) SetLocalInt(GetMaster(oDied),"bX3_STORE_MOUNT_INFO",TRUE);

   if (HorseGetIsAMount(oDied))

   { // check dying horse for saddlebags and eventual re-assigning to master

       if (GetLocalInt(GetModule(),"X3_HORSE_ENABLE_SADDLEBAGS")&&GetLocalInt(oDied,"bX3_HAS_SADDLEBAGS"))

       { // might have saddle bags

           object oOwner=HorseGetOwner(oDied);

           if (!GetIsPC(oOwner)&&GetIsObjectValid(oOwner)&&oOwner!=oDied)

           { // npc

               oOwner=GetMaster(oOwner);

               if (GetIsPC(oOwner))

               { // set to PC then drop

                   HorseSetOwner(oDied,oOwner);

               } // set to PC then drop

           } // npc

           else if (GetIsPC(oOwner))

           { // PC

           } // PC

           DeleteLocalInt(oDied,"bX3_HAS_SADDLEBAGS"); // if you don't want to remove saddlebags for horse resurrection purpose, make sure that the corpse's inventory content is moved to the resurrected living horse again (if you do that, you can possibly remove the check for saddlebags including the repeated call of the death script)

           DelayCommand(0.1,ExecuteScript(GetLocalString(oDied,"sX3_DEATH_SCRIPT"),oDied));

           return TRUE; // no resurrection for horses by default

       } // might have saddle bags

       return TRUE;  // horse should not respawn like other henchmen

   } // check dying horse for saddlebags and eventual re-assigning to master

   if (GetIsObjectValid(oHorse)) HorseReassign(oHorse,oDied,GetMaster(oDied)); // check henchman's horses for possible re-assigning to master or free them

   // * Bob Minors Jan 2008: added support for X3 mounts:

   // * If killed while mounted, we are dismounted. This takes about 0.5s so drop out and rerun this script again afterward

   if (HorseGetIsMounted(oDied))

   { // check if creature died in mounted state

       oHorse=HorseDismount(FALSE,TRUE);

       SetLocalObject(oDied,"oAssignedHorse",oHorse); // Kludge

       HorseReassign(oHorse,oDied,oMaster);

       ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectKnockdown(),oHorse,1.8);

       DelayCommand(2.0,AssignCommand(oHorse,ActionMoveAwayFromObject(oDied,TRUE,3.0))); // drop rider and jump aside

       DelayCommand(1.2,ExecuteScript(GetLocalString(oDied,"sX3_DEATH_SCRIPT"),oDied)); // give dismount and potential inventory transfer some space before rerun

       //return TRUE; // this return makes the dead mounted henchman non-resurrectable, so its commented out so that they can be resurrected by default

   } // check if creature died in mounted state

return FALSE;

} //HorseHandleDeath()





////////////////////////////////////////////////////////////////////////////////

///////////////////////////   PRELOAD ANIMATIONS   /////////////////////////////

////////////////////////////////////////////////////////////////////////////////





void HorsePreloadAnimations(object oPC)

{ // PURPOSE: Force a preload of mount animations

   int nApp=GetAppearanceType(oPC);

   int nTail=GetCreatureTailType(oPC);

   //SetCreatureAppearanceType(oPC,HORSE_SupportGetMountedAppearance(oPC));

   if (nTail==0) nTail=14;

   HORSE_SupportRestoreFromPreload(oPC,nApp,nTail);

} // HorsePreloadAnimations()





//void main(){}
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #23 on: July 22, 2010, 04:04:13 am »


               wow, that was longer than i thought.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Clueless
« Reply #24 on: July 22, 2010, 05:12:14 am »


               Try commenting out the visual effect that was added in the other post.  



It is really the only thing that is different in this death script and the original.



//effect eVis = EffectVisualEffect(119);



//DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPlayer));



If that stops it. try and find a different visual to add.   I am not really sure what that one does.  

               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #25 on: July 22, 2010, 05:21:40 am »


               kk i will try that now.

Psyammy
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #26 on: July 22, 2010, 05:27:05 am »


               that fixed it, i am going to play with other vis fx now.

thanks again for all the help

Psyammy
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #27 on: July 22, 2010, 05:38:27 am »


               it was the "GIB" (119) fx, i changed it to "235"  which is a large red chunk fx and it is all good now, the toon pops (blood and bones and stuff) when you die and the camera stays like it should.

thank you all for the help.

Psyammy
               
               

               
            

Legacy_Psyammy

  • Jr. Member
  • **
  • Posts: 83
  • Karma: +0/-0
Clueless
« Reply #28 on: July 22, 2010, 05:49:33 am »


               here is the working copy of the ondeath script with your toon poping (blood and bones) with no camera probs. if any one out there wants it



//mod_on_death

/*

   This is still the default NWN player death script.

   It does a lot of stuff you don't really need/want.

   It does not do stuff you really need/want.

   You need to rework this.

   The horse section should be fine.

   It was written with multi-player in mind.

   Qwildurn

*/

#include "x3_inc_horse"

void Raise(object oPlayer);

//void ClearAllFactionMembers(object oMember, object oPlayer);

/*

void ClearAllFactionMembers(object oMember, object oPlayer)

{

//    AssignCommand(oMember, SpeakString("here"));

   AdjustReputation(oPlayer, oMember, 100);

   SetLocalInt(oPlayer, "NW_G_Playerhasbeenbad", 10); // * Player bad

   object oClear = GetFirstFactionMember(oMember, FALSE);

   while (GetIsObjectValid(oClear) == TRUE)

   {

       ClearPersonalReputation(oPlayer, oClear);

       oClear = GetNextFactionMember(oMember, FALSE);

   }

}

*/

void Raise(object oPlayer)

{

effect eVisual = EffectVisualEffect(VFX_IMP_RESTORATION);

effect eBad = GetFirstEffect(oPlayer);

ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPlayer);

ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(GetMaxHitPoints(oPlayer)), oPlayer);

//Search for negative effects

while(GetIsEffectValid(eBad))

   {

   if (GetEffectType(eBad) == EFFECT_TYPE_ABILITY_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_AC_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_ATTACK_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_DAMAGE_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_SAVING_THROW_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_SPELL_RESISTANCE_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_SKILL_DECREASE ||

       GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS ||

       GetEffectType(eBad) == EFFECT_TYPE_DEAF ||

       GetEffectType(eBad) == EFFECT_TYPE_PARALYZE ||

       GetEffectType(eBad) == EFFECT_TYPE_NEGATIVELEVEL)

       {

       //Remove effect if it is negative.

       RemoveEffect(oPlayer, eBad);

       }

   eBad = GetNextEffect(oPlayer);

   }

//Fire cast spell at event for the specified target

SignalEvent(oPlayer, EventSpellCastAt(OBJECT_SELF, SPELL_RESTORATION, FALSE));

ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, oPlayer);

}

void main()

{

   object oPlayer = GetLastPlayerDied();

   object oHorse;

   object oInventory;

   string sID;

   int nC;

   string sT;

   string sR;

   int nCH;

   int nST;

   object oItem;

   effect eEffect;

//start horse section

   string sDB="X3SADDLEBAG"+GetTag(GetModule());

   if (GetStringLength(GetLocalString(GetModule(),"X3_SADDLEBAG_DATABASE"))>0) sDB=GetLocalString(GetModule(),"X3_SADDLEBAG_DATABASE");

   if (HorseGetIsMounted(oPlayer))

   { // Dismount and then die

       //SetCommandable(FALSE,oPlayer);

       //ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPlayer);

       DelayCommand(0.3,HORSE_SupportResetUnmountedAppearance(oPlayer));

       DelayCommand(3.0,HORSE_SupportCleanVariables(oPlayer));

       DelayCommand(1.0,HORSE_SupportRemoveACBonus(oPlayer));

       DelayCommand(1.0,HORSE_SupportRemoveHPBonus(oPlayer));

       DelayCommand(1.1,HORSE_SupportRemoveMountedSkillDecreases(oPlayer));

       DelayCommand(1.1,HORSE_SupportAdjustMountedArcheryPenalty(oPlayer));

       DelayCommand(1.2,HORSE_SupportOriginalSpeed(oPlayer));

       if (!GetLocalInt(GetModule(),"X3_HORSE_NO_CORPSES"))

       { // okay to create lootable horse corpses

           sR=GetSkinString(oPlayer,"sX3_HorseResRef");

           sT=GetSkinString(oPlayer,"sX3_HorseMountTag");

           nCH=GetSkinInt(oPlayer,"nX3_HorseAppearance");

           nST=GetSkinInt(oPlayer,"nX3_HorseTail");

           nC=GetLocalInt(oPlayer,"nX3_HorsePortrait");

           if (GetStringLength(sR)>0&&GetStringLeft(sR,GetStringLength(HORSE_PALADIN_PREFIX))!=HORSE_PALADIN_PREFIX)

           { // create horse

               oHorse=HorseCreateHorse(sR,GetLocation(oPlayer),oPlayer,sT,nCH,nST);

               SetLootable(oHorse,TRUE);

               SetPortraitId(oHorse,nC);

               SetLocalInt(oHorse,"bDie",TRUE);

               AssignCommand(oHorse,SetIsDestroyable(FALSE,TRUE,TRUE));

           } // create horse

       } // okay to create lootable horse corpses

       oInventory=GetLocalObject(oPlayer,"oX3_Saddlebags");

       sID=GetLocalString(oPlayer,"sDB_Inv");

       if (GetIsObjectValid(oInventory))

       { // drop horse saddlebags

           if (!GetIsObjectValid(oHorse))

           { // no horse created

               HORSE_SupportTransferInventory(oInventory,OBJECT_INVALID,GetLocation(oPlayer),TRUE);

           } // no horse created

           else

           { // transfer to horse

               HORSE_SupportTransferInventory(oInventory,oHorse,GetLocation(oHorse),TRUE);

               //DelayCommand(2.0,PurgeSkinObject(oHorse));

               //DelayCommand(3.0,KillTheHorse(oHorse));

               //DelayCommand(1.8,PurgeSkinObject(oHorse));

           } // transfer to horse

       } // drop horse saddlebags

       else if (GetStringLength(sID)>0)

       { // database based inventory

           nC=GetCampaignInt(sDB,"nCO_"+sID);

           while(nC>0)

           { // restore inventory

               sR=GetCampaignString(sDB,"sR"+sID+IntToString(nC));

               sT=GetCampaignString(sDB,"sT"+sID+IntToString(nC));

               nST=GetCampaignInt(sDB,"nS"+sID+IntToString(nC));

               nCH=GetCampaignInt(sDB,"nC"+sID+IntToString(nC));

               DeleteCampaignVariable(sDB,"sR"+sID+IntToString(nC));

               DeleteCampaignVariable(sDB,"sT"+sID+IntToString(nC));

               DeleteCampaignVariable(sDB,"nS"+sID+IntToString(nC));

               DeleteCampaignVariable(sDB,"nC"+sID+IntToString(nC));

               if (!GetIsObjectValid(oHorse))

               { // no lootable corpse

                   oItem=CreateObject(OBJECT_TYPE_ITEM,sR,GetLocation(oPlayer),FALSE,sT);

               } // no lootable corpse

               else

               { // lootable corpse

                   oItem=CreateItemOnObject(sR,oHorse,nST,sT);

               } // lootable corpse

               if (GetItemStackSize(oItem)!=nST) SetItemStackSize(oItem,nST);

               if (nCH>0) SetItemCharges(oItem,nCH);

               nC--;

           } // restore inventory

           DeleteCampaignVariable(sDB,"nCO_"+sID);

           //DelayCommand(2.0,PurgeSkinObject(oHorse));

           if (GetIsObjectValid(oHorse)&&GetLocalInt(oHorse,"bDie")) DelayCommand(3.0,KillTheHorse(oHorse));

           //DelayCommand(2.5,PurgeSkinObject(oHorse));

       } // database based inventory

       else if (GetIsObjectValid(oHorse))

       { // no inventory

           //DelayCommand(1.0,PurgeSkinObject(oHorse));

           DelayCommand(2.0,KillTheHorse(oHorse));

           //DelayCommand(1.8,PurgeSkinObject(oHorse));

       } // no inventory

       //eEffect=EffectDeath();

       //DelayCommand(1.6,ApplyEffectToObject(DURATION_TYPE_INSTANT,eEffect,oPlayer));

       //DelayCommand(1.7,SetCommandable(TRUE,oPlayer));

       //return;

   } // Dismount and then die

//end horse section

   // * increment global tracking number of times that I died

   SetLocalInt(oPlayer, "NW_L_PLAYER_DIED", GetLocalInt(oPlayer, "NW_L_PLAYER_DIED") + 1);

   // * BK: Automation Control. Autopcs ignore death

   if (GetLocalInt(oPlayer, "NW_L_AUTOMATION") == 10)

   {

       Raise(oPlayer);

       DelayCommand(1.0, ExecuteScript("crawl", OBJECT_SELF));

       return; // Raise and return

   }



   // * make friendly to Each of the 3 common factions

   AssignCommand(oPlayer, ClearAllActions());

   // * Note: waiting for Sophia to make SetStandardFactionReptuation to clear all personal reputation

   if (GetStandardFactionReputation(STANDARD_FACTION_COMMONER, oPlayer) <= 10)

   {   SetLocalInt(oPlayer, "NW_G_Playerhasbeenbad", 10); // * Player bad

       SetStandardFactionReputation(STANDARD_FACTION_COMMONER, 80, oPlayer);

   }

   if (GetStandardFactionReputation(STANDARD_FACTION_MERCHANT, oPlayer) <= 10)

   {   SetLocalInt(oPlayer, "NW_G_Playerhasbeenbad", 10); // * Player bad

       SetStandardFactionReputation(STANDARD_FACTION_MERCHANT, 80, oPlayer);

   }

   if (GetStandardFactionReputation(STANDARD_FACTION_DEFENDER, oPlayer) <= 10)

   {   SetLocalInt(oPlayer, "NW_G_Playerhasbeenbad", 10); // * Player bad

       SetStandardFactionReputation(STANDARD_FACTION_DEFENDER, 80, oPlayer);

   }

   effect eVis = EffectVisualEffect(235);

   DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPlayer));

   DelayCommand(2.5, PopUpGUIPanel(oPlayer,GUI_PANEL_PLAYER_DEATH));

}



thank you all again for the help.

Psyammy