Camera

Répondre
Partager Rechercher
je n'ai trouvé aucun topic concernant ce sujet? je me doute que la quetion a dejà été posé, mais a t'elle etait traité?

J'aimerai faire un simple zoom sur le personnage entrain de parler au cour d'une conversation... Donc un changement d'angle a chaque fois qu'un personnage prend le dialogue..

voici les fonction de base.

StoreCameraFacing
RestoreCameraFacing
SetCameraFacing
SetCameraMode

apparement il faut créer un point de naviguation en guise de camera.

Mais je n'ai aucune idée de comment ça marche. si quelqu'un m'aider a faire dejà un premier script afin que je puisse evoluer ds cet direction ça serait sympas.
C'est vrai que l'utilisation des caméras n'a pas été beaucoup traité sur maskado. je te conseille d'ouvrir une cutscene de bioware pour comprendre comment ça marche. Ce que tu cherches est fait au début de leurs scenes normalement.

Personnelement je suis en train d'essayer de créer un système simple pour créer ses propres cutscene en modifiant les scripts de bioware (il y a tellement de trucs à vérifier que c'est vraiment trop dur de penser à tout pour un néophyte). Dès que j'ai terminé (pas tout de suite donc^^) je le mets ici.
merci pour ce lien que tu viens de m'offrir.
Cependant j'avais eu ça aussi

http://nwn.bioware.com/forums/viewto...&forum=47&sp=0

j'ai réussi avec mon anglais moyen a comprendre comment ça marcher a peu pret.

j'ai meme réussi a simplifier certain truc.
Je garde pour moi en attendant mon travail car c'est encore a l'etat de brouillion et donc tres bordelique.

Je vais donc créer une petite mise en scene avec une lien sur mon MOD afin que vous puissiez bénéficier de mon travail de la nuit derniere. (mon dieu je n'ai pas dormi)

Ce qui serait interessant, c de créer des scripts avec different mode de plan de camera! ainsi..il suffirait de les appelé avec un simple include pour avoir certains gros plan ou vu d'ensemble lors d'un dialogue.

pour les interessés, je pense que pour lundi ou mardi vous aurrez quelques chose qui tient la route.


A savoir qu'il est possible de prendre en charge, les son, le dialogue, les expressions(EMOTE), les movement des personnages, la gestion du tps et des angles de camera etc...

il est meme possible de faire une cutscene regardé par le joueur, la partie ou tous les joueurs du serveur!

Enfin la total... par contre je n'ai pas encore trop bien saisi la manip pour faire des tours a 360° avec la cam, mais bon c'est juste une question de tps.

je vous detail tous ça prochainement afin que maskado possede son propre topic de camera
Bien je vais essayer de devellopé ce que j'ai dejà un peu compris.

dans un premier tps un script a ajouter a la base. Ce script regroupe des fonctions pour l'utilisation de la camera

"in_g_cutscene"

Code PHP:

const int ANIMATION_NONE 999;
const 
int NORMAL ANIMATION_LOOPING_TALK_NORMAL;
const 
int FORCEFUL ANIMATION_LOOPING_TALK_FORCEFUL;
const 
int LAUGHING ANIMATION_LOOPING_TALK_LAUGHING;
const 
int PLEADING ANIMATION_LOOPING_TALK_PLEADING;
const 
int INVENTORY_SLOT_BEST_MELEE 999;
const 
int INVENTORY_SLOT_BEST_RANGED 998;
const 
int INVENTORY_SLOT_BEST_ARMOUR 997;
const 
int INSTANT DURATION_TYPE_INSTANT;
const 
int PERMANENT DURATION_TYPE_PERMANENT;
const 
int TEMPORARY DURATION_TYPE_TEMPORARY;

// Initializes the cutscene, setting its name and putting the selected player(s) into CutsceneMode
    // oPC              the player you want the cutscene to run for
    // sName            the name of the cutscene - this is stored on all the party members as a LocalString called "cutscene"
    // iParty           sets whether the cutscene is being seen by only oPC (0), all the players in oPC's party (1) or all the players on the server (2)
void GestaltStartCutscene(object oPCstring sNameint iParty 0);
// Stops the current cutscene, cancelling all camera movements and Gestalt* actions in cutscene
    // oPC              the player running the cutscene you want to stop
    // bMode            sets whether or not to cancel CutsceneMode
    // bCamera          sets whether or not to cancel all camera movements
    // iParty           make this the same as you used in GestaltStartCutscene to make sure the cutscene is cancelled for everyone together
void GestaltStopCutscene(object oPCint bMode TRUEint bCamera TRUEint iParty 0);
// Sets the speed of the selected character so that they will go fDistance metres in fTime seconds
    // fDelay           how many seconds to wait before setting the character's speed
    // oActor           the character whose speed you want to adjust
    // fTime            how long you want them to take ..
    // fDistance        .. to move this far
    // iRun             sets whether they will be walking (0) or running (1)
    // fStops           how much longer the effect should last (for overrun or pauses along the way)
void GestaltSetSpeed(float fDelayobject oActorfloat fTimefloat fDistanceint iRunfloat fStops 0.0);
// Removes any movement-related effects (speed increase / decrease, haste / slow or entangle) from oActor
void GestaltResetSpeed(object oActor);
// Moves the selected actor to a target object in a specified time
    // fDelay           how many seconds to wait before movement is added to oActor's action queue
    // oActor           the character you want to move
    // oDestination     the object or waypoint they should move to
    // iRun             sets whether the actor will walk (FALSE) or run (TRUE)
    // fRange           how many metres from the target the actor should be at the end of movement (keep this number low if you're timing the movement!)
        // NOTE - due to a bug in BioWare's ActionMoveToObject function, if you set fRange > 0.0 for a PC, the PC will run regardless of what you set iRun to be
    // fTime            how many seconds the movement should take - leave at 0.0 if you don't want to adjust the actor's speed
void GestaltActionMove(float fDelayobject oActorobject oDestinationint iRun FALSEfloat fRange 0.0float fTime 0.0);
// Jumps the selected actor to the position of another object
    // fDelay           how many seconds to wait before jump is added to oActor's action queue
    // oActor           the character you want to jump
    // oTarget          the object or waypoint they should jump to
void GestaltActionJump(float fDelayobject oActorobject oTarget);
// Jumps the selected actor to the position of another object
    // fDelay           how many seconds to wait before oActor jumps
    // oActor           the character you want to jump
    // oTarget          the object or waypoint they should jump to
void GestaltJump(float fDelayobject oActorobject oTarget);
// Tell the selected actor to play an animation
    // fDelay           how many seconds to wait before animation is added to oActor's action queue
    // oActor           the character you want to play the animation
    // iAnim            the animation you want them to play (ANIMATION_*)
    // fDuration        how long the animation should last (leave at 0.0 for fire-and-forget animations)
    // fSpeed           the speed of the animation (defaults to 1.0)
void GestaltActionAnimate(float fDelayobject oActorint iAnimfloat fDuration 0.0float fSpeed 1.0);
// Tell the selected actor to play an animation
    // fDelay           how many seconds to wait before playing the animation
    // oActor           the character you want to play the animation
    // iAnim            the animation you want them to play (ANIMATION_*)
    // fDuration        how long the animation should last (leave at 0.0 for fire-and-forget animations)
    // fSpeed           the speed of the animation (defaults to 1.0)
void GestaltAnimate(float fDelayobject oActorint iAnimfloat fDuration 0.0float fSpeed 1.0);
// Tell the selected actor to speak a line
    // fDelay           how many seconds to wait before speech is added to oActor's action queue
    // oActor           the character you want to speak the line
    // sLine            the line you want them to speak
    // iAnim            the animation you want them to play whilst speaking the line (leave as ANIMATION_NONE for no animation)
        // NOTE - if you are using a ANIMATION_LOOPING_TALK_* animation, all you need to use is the last word (eg FORCEFUL))
    // fDuration        how long the animation should last (leave at 0.0 for fire-and-forget animations)
    // fSpeed           the speed of the animation (defaults to 1.0)
void GestaltActionSpeak(float fDelayobject oActorstring sLineint iAnimation ANIMATION_NONEfloat fDuration 0.0float fSpeed 1.0);
// Tell the selected actor to speak a line
    // fDelay           how many seconds to wait before speaking line
    // oActor           the character you want to speak the line
    // sLine            the line you want them to speak
    // iAnim            the animation you want them to play whilst speaking the line (leave as ANIMATION_NONE for no animation)
    // fDuration        how long the animation should last (leave at 0.0 for fire-and-forget animations)
    // fSpeed           the speed of the animation (defaults to 1.0)
void GestaltSpeak(float fDelayobject oActorstring sLineint iAnimation ANIMATION_NONEfloat fDuration 0.0float fSpeed 1.0);
// Tells the selected actor to face in a particular direction
    // fDelay           how many seconds to wait before facing command is added to oActor's action queue
    // oActor           the character you want to turn
    // fFace            the direction you want the actor to face in (due east is 0.0, count in degrees anti-clockwise)
        // NOTE - fFace is ignored if iFace is not set to 0
    // iFace            whether the actor should face in a specific direction (0), face in the direction the target is facing (1), or face the target (2)
    // oTarget          the object they should face (leave as OBJECT_INVALID if you don't want them to face an object)
void GestaltActionFace(float fDelayobject oActorfloat fFaceint iFace 0object oTarget OBJECT_INVALID);
// Tells the selected actor to face in a particular direction
    // fDelay           how many seconds to wait before turning
    // oActor           the character you want to turn
    // fFace            the direction you want the actor to face in (due east is 0.0, count in degrees anti-clockwise)
        // NOTE - fFace is ignored if iFace is not set to 0
    // iFace            whether the actor should face in a specific direction (0), face in the direction the target is facing (1), or face the target (2)
    // oTarget          the object they should face (leave as OBJECT_INVALID if you don't want them to face an object)
void GestaltFace(float fDelayobject oActorfloat fFaceint iFace 0object oTarget OBJECT_INVALID);
// Tells the selected actor to equip an item
    // fDelay           how many seconds to wait before equip command is added to oActor's action queue
    // oActor           the character you want to equip
    // iSlot            the inventory slot to put the item in
        // INVENTORY_SLOT_BEST_MELEE will equip the actor's best melee weapon in his right hand
        // INVENTORY_SLOT_BEST_RANGED will equip the actor's best ranged weapon in his right hand
        // INVENTORY_SLOT_BEST_ARMOUR will equip the actor's best armour in his chest slot
    // oItem            the item you want to equip (leave as OBJECT_INVALID if you're auto-equipping an INVENTORY_SLOT_BEST_*)
void GestaltActionEquip(float fDelayobject oActorint iSlot INVENTORY_SLOT_BEST_MELEEobject oItem OBJECT_INVALID);
// Tells the selected actor to attack something
    // fDelay           how many seconds to wait before attack is added to oActor's action queue
    // oActor           the character you want to carry out the attack
    // oTarget          the object or character you want them to attack
    // bPassive         whether or not to attack in passive mode
void GestaltActionAttack(float fDelayobject oActorobject oTargetint bPassive FALSE);
// Applies an effect to a target
    // fDelay           how many seconds to wait before applying the effect
    // oTarget          the object to apply the effect to
    // eFect            the effect to apply to the object (eg, EffectDeath())
    // iDuration        the DURATION_TYPE_* (NOTE you only need to use the last word - INSTANT, TEMPORARY or PERMANENT)
    // fDuration        how long the effect should last (only needed if iDuration is TEMPORARY)
void GestaltApplyEffect(float fDelayobject oTargeteffect eFectint iDuration PERMANENTfloat fDuration 0.0);
// Tells the actor to wait before proceeding with the actions in their queue
    // fDelay           how many seconds to wait before adding the pause to their action queue
    // oActor           the character you want to pause
    // fPause           how many seconds they should pause for
void GestaltActionWait(float fDelayobject oActorfloat fPause);
// Tells the selected actor to stop everything he's doing and prepare for new orders
    // fDelay           how many seconds to wait before applying this to oActor
    // oActor           the character whose action queue you want to clear
void GestaltClearActions(float fDelayobject oActor);
// Stops all camera movements immediately
    // oPC              the player whose camera movements you want to stop
    // iParty           sets whether to stop the camera of only oPC (0), all the players in oPC's party (1) or all the players on the server (2)
// DO NOT CHANGE THE FOLLOWING SETTINGS!
    // bAuto            sets whether the function should stop all camera movement (TRUE) or only ones with an id lower than iCamID (FALSE)
    // iCamID           the ID of the last camera move you want to stop (this is only needed if bAuto is set to FALSE)
void GestaltStopCameraMoves(object oPCint iParty 0int bAuto TRUEint iCamID 0);
// Gets the vector linking object A to object B
vector GetVectorAB(object oAobject oB);
// Finds the horizontal distance between two objects, ignoring any vertical component
float GetHorizontalDistanceBetween(object oAobject oB);
// Finds the compass direction from the PC to a target object
float GestaltGetDirection(object oTargetobject oPC);
// Moves the camera smoothly from one position to another over the specified time
    // STARTING TIME -
        // fDelay           how many seconds to wait before starting the movement
    // STARTING CONDITIONS -
        // fDirection       initial direction (0.0 = due east)
        // fRange           initial distance between player and camera
        // fPitch           initial pitch (vertical tilt)
    // FINAL CONDITIONS -
        // fDirection2      finishing direction
        // fRange2          finishing distance
        // fPitch2          finishing tilt
    // TIME SETTINGS -
        // fTime            number of seconds it takes camera to complete movement
        // fFrameRate       number of movements per second (governs how smooth the motion is)
    // MISC SETTINGS -
        // oPC              the PC you want to apply the camera movement to
        // iClockwise       set to 1 if you want the camera to rotate clockwise, 0 for anti-clockwise, or 2 for auto-select
        // iFace            sets whether the camera (0), the character (2) or both (1) turn to face the specified direction
        // iParty           sets whether to move the camera of only oPC (0), all the players in oPC's party (1) or all the players on the server (2)
void GestaltCameraMove(float fDelayfloat fDirectionfloat fRangefloat fPitchfloat fDirection2float fRange2float fPitch2float fTimefloat fFrameRateobject oPCint iClockwise 0int iFace 0int iParty 0);
// Produces smooth transitions between different camera movements by setting initial and final speeds
// The function then interpolates between the two so that the movement rate changes smoothly over the
//  duration of the movement.
    // STARTING TIME -
        // fDelay           how many seconds to wait before starting the movement
    // MOVEMENT RATES AT START OF MOTION -
        // fdDirection1     how fast the camera's compass direction should change by in degrees per second
                            // positive numbers produce an anti-clockwise movement, negative anti-clockwise
        // fdRange1         how fast the camera's range should change in meters per second
                            // positive numbers move the camera away from the player, negative towards them
        // fdPitch1         how fast the camera's pitch should change in degrees per second
                            // positive numbers tilt the camera down towards the ground, negative up towards vertical
    // MOVEMENT RATES AT END OF MOTION -
        // fdDirection2     how fast the camera's compass direction should change by in degrees per second
                            // positive numbers produce an anti-clockwise movement, negative anti-clockwise
        // fdRange2         how fast the camera's range should change in meters per second
                            // positive numbers move the camera away from the player, negative towards them
        // fdPitch2         how fast the camera's pitch should change in degrees per second
                            // positive numbers tilt the camera down towards the ground, negative up towards vertical
    // TIME SETTINGS -
        // fTime            number of seconds it should take the camera to complete movement
        // fFrameRate       number of movements per second (governs how smooth the motion is)
    // MISC SETTINGS -
        // oPC              the player whose camera you want to move
        // iParty           sets whether to move the camera of only oPC (0), all the players in oPC's party (1) or all the players on the server (2)
        // iSync            sets whether to use separate camera starting positions for every player (0) or sync them all to oPC's camera position (1)
void GestaltCameraSmooth(float fDelayfloat fdDirection1float fdRange1float fdPitch1float fdDirection2float fdRange2float fdPitch2float fTimefloat fFrameRateobject oPCint iParty 0int iSync 1);
// Turns the camera and/or player between two objects
// NOTE that this will only work properly if the player and target objects are stationary while the function is active
    // STARTING TIME -
        // fDelay           how many seconds to wait before starting the movement
    // STARTING CONDITIONS -
        // oStart           object to face at start of movement
        // fRange           initial distance between player and camera
        // fPitch           initial pitch (vertical tilt)
    // FINAL CONDITIONS -
        // oEnd             object to finish movement facing
        // fRange2          finishing distance
        // fPitch2          finishing tilt
    // TIME SETTINGS -
        // fTime            number of seconds it takes camera to complete movement
        // fFrameRate       number of movements per second (governs how smooth the motion is)
    // MISC SETTINGS -
        // oPC              the player whose camera you want to move
        // iClockwise       set to 1 if you want the camera to rotate clockwise, 0 for anti-clockwise, or 2 for auto-select
        // iFace            controls whether the camera (0), the character (2) or both (1) turn
        // iParty           sets whether to move the camera of only oPC (0), all the players in oPC's party (1) or all the players on the server (2)
void GestaltCameraFace(float fDelayobject oStartfloat fRangefloat fPitchobject oEndfloat fRange2float fPitch2float fTimefloat fFrameRateobject oPCint iClockwise 0int iFace 0int iParty 0);
// Tracks a moving object, turning the player's camera so that it always faces towards it
    // STARTING TIME -
        // fDelay           how many seconds to wait before starting the movement
    // TARGET -
        // oTrack           object to track the movement of
    // STARTING CONDITIONS -
        // fRange           initial distance between player and camera
        // fPitch           initial pitch (vertical tilt)
    // FINAL CONDITIONS -
        // fRange2          finishing distance
        // fPitch2          finishing tilt
    // TIME SETTINGS -
        // fTime            how long the camera will track the object for
        // fFrameRate       number of movements per second (governs how smooth the motion is)
    // MISC SETTINGS -
        // oPC              the PC you want to apply the camera movement to
        // iFace            controls whether the camera (0), the character (2) or both (1) turn
        // iParty           sets whether to move the camera of only oPC (0), all the players in oPC's party (1) or all the players on the server (2)
void GestaltCameraTrack(float fDelayobject oTrackfloat fRangefloat fPitchfloat fRange2float fPitch2float fTimefloat fFrameRateobject oPCint iFace 0int iParty 0);
// Gives the illusion of the camera being fixed in one place and rotating to face the player as they move
    // oPC              the PC you want to apply the camera movement to
    // fFrameRate       number of movements per second (governs how smooth the motion is)
//
// To setup a fixed camera position, place a waypoint with a unique tag in your area
    // Set the camera's tag as a LocalString "sGestaltFixedCamera" on the PC to let them know to use that camera
    // Set a LocalFloat "fGestaltFixedCamera" on the PC to set the camera's vertical position
    // Set "sGestaltFixedCamera" to "" to pause the tracking, or to "STOP" to end the tracking
void GestaltFixedCamera(object oPCfloat fFrameRate 50.0);




// General functions
void GestaltDebugOutput(object oPC)
{
    
// Get the current position of oPC's camera
    
float fDirection GetLocalFloat(oPC,"fCameraDirection");
    
float fRange GetLocalFloat(oPC,"fCameraRange");
    
float fPitch GetLocalFloat(oPC,"fCameraPitch");
    
// Fire a message to say where the camera is
    
AssignCommand(oPC,SpeakString(FloatToString(fDirection) + ", " FloatToString(fRange) + ", " FloatToString(fPitch)));
}

void GestaltStartCutscene(object oPCstring sNameint iParty 0)
{
    
object oParty;
    if (
iParty == 1)            { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2)       { oParty GetFirstPC(); }
    else                        { 
oParty oPC; }
    
SetLocalString(GetModule(),"cutscene",sName);
    
SetLocalInt(GetModule(),sName,0);
    while (
GetIsObjectValid(oParty))
        {
        
SetCutsceneMode(oParty,TRUE);
        
AssignCommand(oParty,ClearAllActions(TRUE));
        
SetLocalString(oParty,"cutscene",sName);
        if (
iParty == 1)        { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)   { oParty GetNextPC(); }
        else                    { return; }
        }
}

void GestaltStopCutscene(object oPCint bMode TRUEint bCamera TRUEint iParty 0)
{
    
// Check cutscene hasn't been stopped already
    
string sName GetLocalString(oPC,"cutscene");
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    
// Otherwise stop cutscene
    
SetLocalInt(GetModule(),sName,1);
    
object oParty;
    
string sCam;
    
int iCount;
    if (
iParty == 1)            { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2)       { oParty GetFirstPC(); }
    else                        { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        
// End cutscene mode
        
if (bMode)              { SetCutsceneMode(oParty,FALSE); }
        if (
bCamera)            { GestaltStopCameraMoves(oPC); }
        
AssignCommand(oParty,ClearAllActions(TRUE));
        
DeleteLocalString(oParty,"cutscene");
        if (
iParty == 1)        { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)   { oParty GetNextPC(); }
        else                    { return; }
        }
}




// Action functions
float GestaltGetSpeed(object oActor,int iRun)
{
    
float fSpeed 0.0;
    
int iRate GetMovementRate(oActor);
    switch(
iRate)
        {
        case 
0:               fSpeed 2.00;      break;    // PCs
        
case 1:               fSpeed 0.00;      break;    // Immobile
        
case 2:               fSpeed 0.75;      break;    // Very Slow
        
case 3:               fSpeed 1.25;      break;    // Slow
        
case 4:               fSpeed 1.75;      break;    // Normal
        
case 5:               fSpeed 2.25;      break;    // Fast
        
case 6:               fSpeed 2.75;      break;    // Very Fast
        
case 7:               fSpeed 5.50;      break;    // DM Fast
        
}
    if (
iRun == TRUE)       { fSpeed fSpeed 2; }
//    AssignCommand(oActor,SpeakString(FloatToString(fSpeed),TALKVOLUME_SHOUT));  // DEBUG LINE
    
return fSpeed;
}

void GestaltResetSpeed(object oActor)
{
    
effect eEffect GetFirstEffect(oActor);
    
int iType GetEffectType(eEffect);
    while (
iType != EFFECT_TYPE_INVALIDEFFECT)
        {
        if (
iType == EFFECT_TYPE_MOVEMENT_SPEED_DECREASE
         
|| iType == EFFECT_TYPE_MOVEMENT_SPEED_INCREASE
         
|| iType == EFFECT_TYPE_ENTANGLE
         
|| iType == EFFECT_TYPE_HASTE
         
|| iType == EFFECT_TYPE_SLOW)
            { 
RemoveEffect(oActor,eEffect); }
        
eEffect GetNextEffect(oActor);
        
iType GetEffectType(eEffect);
        }
}

void GestaltDoSetSpeed(string sNameobject oActor,float fTime,float fDistance,int iRun,float fStops 0.0)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    
GestaltResetSpeed(oActor);
    if (
fTime == 0.0)                               { return; }
    
float fActualSpeed GestaltGetSpeed(oActor,iRun);
    
float fTargetSpeed = (fDistance fTime);
    
float fPercent 0.0;
    
int iPercent 0;
    if (
fActualSpeed == fTargetSpeed)               { return; }
    if (
fActualSpeed fTargetSpeed)
        {
        
fTime fTime fStops;
        
fPercent 100 * ((fTargetSpeed fActualSpeed) / fTargetSpeed);
        
iPercent FloatToInt(fPercent);
//      AssignCommand(oActor,SpeakString("Speed increase " + IntToString(iPercent),TALKVOLUME_SHOUT));     // DEBUG LINE
        
if (fStops == -1.0)
            { 
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectMovementSpeedIncrease(iPercent),oActor); }
        else
            { 
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectMovementSpeedIncrease(iPercent),oActor,fTime); }
        }
    if (
fActualSpeed fTargetSpeed)
        {
        
fTime fTime fStops;
        
fPercent 100 * ((fActualSpeed fTargetSpeed) / fActualSpeed);
        
iPercent FloatToInt(fPercent);
//      AssignCommand(oActor,SpeakString("Speed decrease " + IntToString(iPercent),TALKVOLUME_SHOUT));     // DEBUG LINE
        
if (fStops == -1.0)
            { 
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectMovementSpeedDecrease(iPercent),oActor); }
        else
            { 
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectMovementSpeedDecrease(iPercent),oActor,fTime); }
        }
}

void GestaltSetSpeed(float fDelayobject oActorfloat fTimefloat fDistanceint iRunfloat fStops 0.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoSetSpeed(sName,oActor,fTime,fDistance,iRun,fStops));
}

void GestaltDoMove(string sNameobject oActorobject oDestinationint iRunfloat fRangefloat fTime)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    if (
fTime 0.0)
        { 
AssignCommand(oActor,ActionDoCommand(GestaltDoSetSpeed(sName,oActor,fTime,GetDistanceBetween(oActor,oDestination),iRun))); }
    if (
fRange 0.0)   { AssignCommand(oActor,ActionMoveToObject(oDestination,iRun,fRange)); }
    else                { 
AssignCommand(oActor,ActionMoveToLocation(GetLocation(oDestination),iRun)); }
}

void GestaltActionMove(float fDelayobject oActorobject oDestinationint iRun FALSEfloat fRange 0.0float fTime 0.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoMove(sName,oActor,oDestination,iRun,fRange,fTime));
}

void GestaltDoJump(string sNameobject oActorobject oTargetint bAction FALSE)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    if (
bAction)        { AssignCommand(oActor,ActionJumpToObject(oTarget,FALSE)); }
    else                { 
AssignCommand(oActor,JumpToObject(oTarget,FALSE)); }
}

void GestaltActionJump(float fDelayobject oActorobject oTarget)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoJump(sName,oActor,oTarget,TRUE));
}

void GestaltJump(float fDelayobject oActorobject oTarget)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoJump(sName,oActor,oTarget));
}

void GestaltDoAnimate(string sNameobject oActorint iAnimfloat fDuration 0.0float fSpeed 1.0int bAction FALSE)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    if (
bAction)        { AssignCommand(oActor,ActionPlayAnimation(iAnim,fSpeed,fDuration)); }
    else                { 
AssignCommand(oActor,PlayAnimation(iAnim,fSpeed,fDuration)); }
}

void GestaltActionAnimate(float fDelayobject oActorint iAnimfloat fDuration 0.0float fSpeed 1.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoAnimate(sName,oActor,iAnim,fDuration,fSpeed,TRUE));
}

void GestaltAnimate(float fDelayobject oActorint iAnimfloat fDuration 0.0float fSpeed 1.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoAnimate(sName,oActor,iAnim,fDuration,fSpeed));
}

void GestaltDoSpeak(string sNameobject oActorstring sLineint iAnimation ANIMATION_NONEfloat fDuration 0.0float fSpeed 1.0int bAction FALSE)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    if (
bAction)
        {
        
AssignCommand(oActor,ActionSpeakString(sLine));
        if (
iAnimation != ANIMATION_NONE)
            { 
AssignCommand(oActor,ActionPlayAnimation(iAnimation,fSpeed,fDuration)); }
        }
    else
        {
        
AssignCommand(oActor,SpeakString(sLine));
        if (
iAnimation != ANIMATION_NONE)
            { 
AssignCommand(oActor,PlayAnimation(iAnimation,fSpeed,fDuration)); }
        }
}

void GestaltActionSpeak(float fDelayobject oActorstring sLineint iAnimation ANIMATION_NONEfloat fDuration 0.0float fSpeed 1.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoSpeak(sName,oActor,sLine,iAnimation,fDuration,fSpeed,TRUE));
}

void GestaltSpeak(float fDelayobject oActorstring sLineint iAnimation ANIMATION_NONEfloat fDuration 0.0float fSpeed 1.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoSpeak(sName,oActor,sLine,iAnimation,fDuration,fSpeed));
}

void GestaltDoClear(string sNameobject oActor)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    
AssignCommand(oActor,ClearAllActions(TRUE));
}

void GestaltDoFace(string sNameobject oActorobject oTargetint iFacefloat fFaceint bAction FALSE)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    if (
iFace == 0)
        {
        if (
bAction)    { AssignCommand(oActor,ActionDoCommand(SetFacing(fFace))); }
        else            { 
AssignCommand(oActor,SetFacing(fFace)); }
        }
    else if (
iFace == 1)
        {
        if (
bAction)    { AssignCommand(oActor,ActionDoCommand(SetFacing(GetFacing(oTarget)))); }
        else            { 
AssignCommand(oActor,SetFacing(GetFacing(oTarget))); }
        }
    else
        {
        if (
bAction)    { AssignCommand(oActor,ActionDoCommand(SetFacingPoint(GetPosition(oTarget)))); }
        else            { 
AssignCommand(oActor,SetFacingPoint(GetPosition(oTarget))); }
        }
}

void GestaltActionFace(float fDelayobject oActorfloat fFaceint iFace 0object oTarget OBJECT_INVALID)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoFace(sName,oActor,oTarget,iFace,fFace,TRUE));
}

void GestaltFace(float fDelayobject oActorfloat fFaceint iFace 0object oTarget OBJECT_INVALID)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoFace(sName,oActor,oTarget,iFace,fFace));
}

void GestaltDoEquip(string sNameobject oActorint iSlotobject oItem)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    if (
iSlot == 999)       { AssignCommand(oActor,ActionEquipMostDamagingMelee()); }
    else if (
iSlot == 998)  { AssignCommand(oActor,ActionEquipMostDamagingRanged()); }
    else if (
iSlot == 997)  { AssignCommand(oActor,ActionEquipMostEffectiveArmor()); }
    else                    { 
AssignCommand(oActor,ActionEquipItem(oItem,iSlot)); }
}

void GestaltActionEquip(float fDelayobject oActorint iSlot INVENTORY_SLOT_BEST_MELEEobject oItem OBJECT_INVALID)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoEquip(sName,oActor,iSlot,oItem));
}

void GestaltDoAttack(string sNameobject oActorobject oTargetint bPassive)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    
AssignCommand(oActor,ActionAttack(oTarget,bPassive));
}

void GestaltActionAttack(float fDelayobject oActorobject oTargetint bPassive FALSE)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoAttack(sName,oActor,oTarget,bPassive));
}

void GestaltDoEffect(string sNameobject oTargeteffect eFectint iDuration PERMANENTfloat fDuration 0.0)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    
ApplyEffectToObject(iDuration,eFect,oTarget,fDuration);
}

void GestaltApplyEffect(float fDelayobject oTargeteffect eFectint iDuration PERMANENTfloat fDuration 0.0)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoEffect(sName,oTarget,eFect,iDuration,fDuration));
}

void GestaltDoWait(string sNameobject oActorfloat fPause)
{
    if (
GetLocalInt(GetModule(),sName) == 1)
        { return; }
    
AssignCommand(oActor,ActionWait(fPause));
}

void GestaltActionWait(float fDelayobject oActorfloat fPause)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoWait(sName,oActor,fPause));
}

void GestaltClearActions(float fDelayobject oActor)
{
    
string sName GetLocalString(GetModule(),"cutscene");
    
DelayCommand(fDelay,GestaltDoClear(sName,oActor));
}
   
// Camera functions

void GestaltStopCameraMoves(object oPCint iParty 0int bAuto TRUEint iCamID 0)
{
    
object oParty;
    
string sCam;
    
int iCount;
    if (
iParty == 1)      { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2) { oParty GetFirstPC(); }
    else                  { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        if (
bAuto)
            { 
iCamID GetLocalInt(oParty,"iCamCount"); }
        
iCount iCamID;
        while (
iCount 0)
            {
            
// Find the camera movement
            
sCam "iCamStop" IntToString(iCount);
            
SetLocalInt(oParty,sCam,1);
            
iCount--;
            
// Uncomment the line below to get a message in the game confirming each id which is cancelled
            // AssignCommand(oParty,SpeakString("Camera movement id " + IntToString(iCount) + "has been stopped"));
            
}
        if (
iParty == 1)                       { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)                  { oParty GetNextPC(); }
        else                                   { return; }
        }
}

vector GetVectorAB(object oAobject oB)
{
    
vector vA GetPosition(oA);
    
vector vB GetPosition(oB);
    
vector vDelta = (vA vB);
    return 
vDelta;
}

float GetHorizontalDistanceBetween(object oAobject oB)
{
    
vector vHorizontal GetVectorAB(oA,oB);
    
float fDistance sqrt(pow(vHorizontal.x,2.0) + pow(vHorizontal.y,2.0));
    return 
fDistance;
}

float GestaltGetDirection(object oTargetobject oPC)
{
    
vector vdTarget GetVectorAB(oTarget,oPC);
    
float fDirection VectorToAngle(vdTarget);
    return 
fDirection;
}

void GestaltCameraPoint(float fDirectionfloat fRangefloat fPitchfloat fdDirectionfloat fdRangefloat fdPitchfloat fd2Directionfloat fd2Rangefloat fd2Pitchfloat fCountobject oPCint iCamIDint iFace 0)
{
    
// Check whether this camera movement has been stopped
    
string sCam "iCamStop" IntToString(iCamID);
    if (
GetLocalInt(oPC,sCam) == 1)
        { return; }
    
// Work out where to point the camera
    
fDirection fDirection + ((fd2Direction pow(fCount,2.0)) / 2) + (fdDirection fCount);
    
fRange fRange + ((fd2Range pow(fCount,2.0)) / 2) + (fdRange fCount);
    
fPitch fPitch + ((fd2Pitch pow(fCount,2.0)) / 2) + (fdPitch fCount);
    
// Reset fDirectionNew if it's gone past 0 or 360 degrees
    
while (fDirection 0.0)    { fDirection = (fDirection 360.0); }
    while (
fDirection 360.0)  { fDirection = (fDirection 360.0); }
    
// Set the camera and/or player facing, according to iFace
    
if (iFace 2)        { AssignCommand(oPC,SetCameraFacing(fDirection,fRange,fPitch)); }
    if (
iFace 0)        { AssignCommand(oPC,SetFacing(fDirection)); }
    
// Store the current position of the camera
    
SetLocalFloat(oPC,"fCameraDirection",fDirection);
    
SetLocalFloat(oPC,"fCameraRange",fRange);
    
SetLocalFloat(oPC,"fCameraPitch",fPitch);
}

void GestaltCameraFaceTarget(object oTargetfloat fRangefloat fPitchobject oPCint iFaceint iParty 0int iCamID 0)
{
    
// Check whether this camera movement has been stopped
    
string sCam "iCamStop" IntToString(iCamID);
    if (
iCamID && GetLocalInt(oPC,sCam) == 1)
        { return; }
    
float fDirection;
    
object oParty;
    if (
iParty == 1)      { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2) { oParty GetFirstPC(); }
    else                  { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        
fDirection GestaltGetDirection(oTarget,oParty);
        if (
iFace 2)        { AssignCommand(oParty,SetCameraFacing(fDirection,fRange,fPitch)); }
        if (
iFace 0)        { AssignCommand(oParty,SetFacing(fDirection)); }
        if (
iParty == 1)                       { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)                  { oParty GetNextPC(); }
        else                                   { return; }
        }
}

float GestaltGetPanRate(float fDirectionfloat fDirection2float fTicksint iClockwise)
{
    
// Calculates how far the camera needs to move each to tick to go from fDirection to fDirection2
    // in fTicks steps, correcting as necessary to account for clockwise or anti-clockwise movement
    
float fdDirection;
    if (
iClockwise == 0)
        {
        if (
fDirection fDirection2)               { fdDirection = ((fDirection2 360.0 fDirection) / fTicks); }
        else                                        { 
fdDirection = ((fDirection2 fDirection) / fTicks); }
        }
    if (
iClockwise == 1)
        {
        if (
fDirection2 fDirection)               { fdDirection = ((fDirection2 fDirection 360.0) / fTicks); }
        else                                        { 
fdDirection = ((fDirection2 fDirection) / fTicks); }
        }
    if (
iClockwise == 2)
        {
        
float fCheck fDirection2 fDirection;
        if (
fCheck 180.0)                         { fdDirection = ((fDirection2 fDirection 360.0) / fTicks); }
        else if (
fCheck < -180.0)                   { fdDirection = ((fDirection2 360.0 fDirection) / fTicks); }
        else                                        { 
fdDirection = ((fDirection2 fDirection) / fTicks); }
        }
    return 
fdDirection;
}

void GestaltCameraMove(float fDelayfloat fDirectionfloat fRangefloat fPitchfloat fDirection2float fRange2float fPitch2float fTimefloat fFrameRateobject oPCint iClockwise 0int iFace 0int iParty 0)
{
    
// Get timing information
    
float fTicks = (fTime fFrameRate);
    
float fdTime = (fTime fTicks);
    
float fStart fDelay;
    
float fCount;
    
float fdDirection GestaltGetPanRate(fDirection,fDirection2,fTicks,iClockwise);
    
float fdRange = ((fRange2 fRange) / fTicks);
    
float fdPitch = ((fPitch2 fPitch) / fTicks);
    
int iCamID;
    
object oParty;
    if (
iParty == 1)      { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2) { oParty GetFirstPC(); }
    else                  { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        
// Set the camera to top down mode
        
SetCameraMode(oParty,CAMERA_MODE_TOP_DOWN);
        
// Give the camera movement a unique id code so that it can be stopped
        
iCamID GetLocalInt(oParty,"iCamCount") + 1;
        
SetLocalInt(oParty,"iCamCount",iCamID);
        
// reset variables
        
fCount 0.0;
        
fDelay fStart;
        
// Uncomment the line below to get a message in the game telling you the id of this camera movement
        // AssignCommand(oParty,SpeakString("Camera id - " + IntToString(iCamID)));
        // After delay, stop any older camera movements and start this one
        
DelayCommand(fStart,GestaltStopCameraMoves(oParty,0,FALSE,iCamID 1));
        while (
fCount <= fTicks)
            {
            
DelayCommand(fDelay,GestaltCameraPoint(fDirection,fRange,fPitch,fdDirection,fdRange,fdPitch,0.0,0.0,0.0,fCount,oParty,iCamID,iFace));
            
fCount = (fCount 1.0);
            
fDelay fStart + (fCount fdTime);
            }
        if (
iParty == 1)                       { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)                  { oParty GetNextPC(); }
        else                                   { return; }
        }
}

void GestaltCameraSmoothStart(float fdDirection1float fdRange1float fdPitch1float fdDirection2float fdRange2float fdPitch2float fTimefloat fFrameRateobject oPartyobject oSyncint iCamID)
{
    
// Get starting position for camera
    
float fDirection GetLocalFloat(oSync,"fCameraDirection");
    
float fRange GetLocalFloat(oSync,"fCameraRange");
    
float fPitch GetLocalFloat(oSync,"fCameraPitch");
    
// Get timing information
    
float fTicks = (fTime fFrameRate);
    
float fdTime = (fTime fTicks);
    
float fDelay 0.0;
    
float fCount 0.0;
    
// Get camera speed and acceleration
    
float fdDirection fdDirection1 fFrameRate;
    
float fdRange fdRange1 fFrameRate;
    
float fdPitch fdPitch1 fFrameRate;
    
float fd2Direction = (fdDirection2 fdDirection1) / ((fTicks 1) * fFrameRate);
    
float fd2Range = (fdRange2 fdRange1) / ((fTicks 1) * fFrameRate);
    
float fd2Pitch = (fdPitch2 fdPitch1) / ((fTicks 1) * fFrameRate);
    
// Start camera movement
    
while (fCount fTicks)
        {
        
DelayCommand(fDelay,GestaltCameraPoint(fDirection,fRange,fPitch,fdDirection,fdRange,fdPitch,fd2Direction,fd2Range,fd2Pitch,fCount,oParty,iCamID));
        
fCount = (fCount 1.0);
        
fDelay = (fCount fdTime);
        }
    
// Uncomment the line below to display the starting position of the camera movement
    // GestaltDebugOutput(oSync);
    // Uncomment the line below to display the finishing position of the camera movement
    // DelayCommand(fDelay,GestaltDebugOutput(oSync));
}

void GestaltCameraSmooth(float fDelayfloat fdDirection1float fdRange1float fdPitch1float fdDirection2float fdRange2float fdPitch2float fTimefloat fFrameRateobject oPCint iParty 0int iSync 1)
{
    
object oParty;
    
object oSync;
    
int iCamID;
    if (
iParty == 1)      { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2) { oParty GetFirstPC(); }
    else                  { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        
// Work out whose camera position to use as the starting position
        
if (iSync == 1)   { oSync oPC; }
        else              { 
oSync oParty; }
        
// Set the camera to top down mode
        
SetCameraMode(oParty,CAMERA_MODE_TOP_DOWN);
        
// Give the camera movement a unique id code so that it can be stopped
        
iCamID GetLocalInt(oParty,"iCamCount") + 1;
        
SetLocalInt(oParty,"iCamCount",iCamID);
        
// Uncomment the line below to get a message in the game telling you the id of this camera movement
        // AssignCommand(oParty,SpeakString("Camera id - " + IntToString(iCamID)));
        // After delay, stop any older camera movements and start this one
        
DelayCommand(fDelay,GestaltStopCameraMoves(oParty,0,FALSE,iCamID 1));
        
DelayCommand(fDelay,GestaltCameraSmoothStart(fdDirection1,fdRange1,fdPitch1,fdDirection2,fdRange2,fdPitch2,fTime,fFrameRate,oParty,oSync,iCamID));
        if (
iParty == 1)                       { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)                  { oParty GetNextPC(); }
        else                                   { return; }
        }
}

void GestaltCameraFace(float fDelayobject oStartfloat fRangefloat fPitchobject oEndfloat fRange2float fPitch2float fTimefloat fFrameRateobject oPCint iClockwise 0int iFace 0int iParty 0)
{
    
// Get timing information
    
float fCount 0.0;
    
float fStart fDelay;
    
float fTicks = (fTime fFrameRate);
    
float fdTime = (fTime fTicks);
    
float fDirection;
    
float fDirection2;
    
float fdDirection;
    
float fdRange = ((fRange2 fRange) / fTicks);
    
float fdPitch = ((fPitch2 fPitch) / fTicks);
    
object oParty;
    
int iCamID;
    
// Get first player
    
if (iParty == 1)      { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2) { oParty GetFirstPC(); }
    else                  { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        
// Set the camera to top down mode
        
SetCameraMode(oParty,CAMERA_MODE_TOP_DOWN);
        
// Give the camera movement a unique id code so that it can be stopped
        
iCamID GetLocalInt(oParty,"iCamCount") + 1;
        
SetLocalInt(oParty,"iCamCount",iCamID);
        
// reset variables
        
fCount 0.0;
        
fDelay fStart;
        
// Work out rotation rate for this player
        
fDirection GestaltGetDirection(oStart,oParty);
        
fDirection2 GestaltGetDirection(oEnd,oParty);
        
fdDirection GestaltGetPanRate(fDirection,fDirection2,fTicks,iClockwise);
        
// After delay, stop any older camera movements and start this one
        
DelayCommand(fStart,GestaltStopCameraMoves(oParty,0,FALSE,iCamID 1));
        while (
fCount <= fTicks)
            {
            
DelayCommand(fDelay,GestaltCameraPoint(fDirection,fRange,fPitch,fdDirection,fdRange,fdPitch,0.0,0.0,0.0,fCount,oParty,iCamID,iFace));
            
fCount = (fCount 1.0);
            
fDelay fStart + (fCount fdTime);
            }
        if (
iParty == 1)                       { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)                  { oParty GetNextPC(); }
        else                                   { return; }
        }
}

void GestaltCameraTrack(float fDelayobject oTrackfloat fRangefloat fPitchfloat fRange2float fPitch2float fTimefloat fFrameRateobject oPCint iFace 0int iParty 0)
{
    
// Get timing information
    
float fCount;
    
float fStart fDelay;
    
float fTicks = (fTime fFrameRate);
    
float fdTime = (fTime fTicks);
    
float fSRange fRange;
    
float fSPitch fPitch;
    
float fdRange = ((fRange2 fRange) / fTicks);
    
float fdPitch = ((fPitch2 fPitch) / fTicks);
    
object oParty;
    
int iCamID;
    if (
iParty == 1)      { oParty GetFirstFactionMember(oPC); }
    else if (
iParty == 2) { oParty GetFirstPC(); }
    else                  { 
oParty oPC; }
    while (
GetIsObjectValid(oParty))
        {
        
// Set the camera to top down mode
        
SetCameraMode(oParty,CAMERA_MODE_TOP_DOWN);
        
// Give the camera movement a unique id code so that it can be stopped
        
iCamID GetLocalInt(oParty,"iCamCount") + 1;
        
SetLocalInt(oParty,"iCamCount",iCamID);
        
// reset variables
        
fCount 0.0;
        
fDelay fStart;
        
fRange fSRange;
        
fPitch fSPitch;
        
// After delay, stop any older camera movements and start this one
        
DelayCommand(fStart,GestaltStopCameraMoves(oParty,0,FALSE,iCamID 1));
        while (
fCount <= fTicks)
            {
            
DelayCommand(fDelay,GestaltCameraFaceTarget(oTrack,fRange,fPitch,oParty,iFace,0,iCamID));
            
fPitch = (fPitch fdPitch);
            
fRange = (fRange fdRange);
            
fCount = (fCount 1.0);
            
fDelay = (fCount fdTime);
            }
        if (
iParty == 1)                       { oParty GetNextFactionMember(oParty,TRUE); }
        else if (
iParty == 2)                  { oParty GetNextPC(); }
        else                                   { return; }
        }
}

void GestaltFixedCamera(object oPCfloat fFrameRate 50.0)
{
    
// Thanks to Tenchi Masaki for the idea for this function
    
string sCamera GetLocalString(oPC,"sGestaltFixedCamera");     // Gets the camera position to use
    
if (sCamera == "STOP")                                          // Camera tracking is turned off, stop script and don't recheck
        
{ return; }
    if (
sCamera == "")                                              // Camera tracking is inactive, stop script but recheck in a second
        
{
        
DelayCommand(1.0,GestaltFixedCamera(oPC,fFrameRate));
        return;
        }
    
float fHeight GetLocalFloat(oPC,"fGestaltFixedCamera");       // Gets the camera height to use
    
if (fHeight == 0.0)         { fHeight 10.0; }                 // Defaults camera height to 10.0 if none has been set yet
    
object oCamera GetObjectByTag(sCamera);
    
float fDelay 1.0 fFrameRate;
    
float fRange GetHorizontalDistanceBetween(oPC,oCamera);
    
float fAngle GestaltGetDirection(oPC,oCamera);                // Works out angle between camera and player
    
float fPitch atan(fRange/fHeight);                            // Works out vertical tilt
    
float fDistance sqrt(pow(fHeight,2.0) + pow(fRange,2.0));     // Works out camera distance from player
    
if (fDistance 30.0)       { fDistance 30.0; }               // Sets distance to 30.0 if player is too far away
    
if (fDistance 5.0)        { fDistance 5.0; }                // Sets distance to 5.0 if player is too close
    
AssignCommand(oPC,SetCameraFacing(fAngle,fDistance,fPitch));
    
DelayCommand(fDelay,GestaltFixedCamera(oPC,fFrameRate));


Ce script devra donc etre appelé par un #include pour pouvoir faire appel au differente fonctions de mouvement de camera.



"in_g_cutscene" a été ecrit par gestal qui est bien plus simple que celui ecris par bioware!
Celui de bioware est appelé "xp1_cutscene" sur lequel je me suis cassé les dents dessu pendant des heures sans avancer d'une cacaouette!
nous avons donc un #include"in_g_cutscene" a appelé a chaque debut de script de mise en scene.


Il faut savoir que la camera a pour point fixe le joueur uniquement! impossible de faire une vue sur un npc ou un point de naviguation! Il faut donc ruser (voir si-dessou).

Tous les angles et les mouvement de rotation sont calculé a partir du joueur.


Pour declancher une mise en scene, il va falloir passer par un strigger avec le OnEnter. ( Ce n'est probablement pas la seule alternative mais c'est celle que nous traiteron ds un premier cas)

Differentes etapes du script "scene"

1) il va falloir verifier si le joueur a dejà traversé le strigger ou non.

2) il va falloir rendre le joueur invissible et interdir son deplacement pendant le deroulkement de la scene.

3) on declare toutes les object necessaire a la mise en scene. personnage, waypoint etc...

4) ensuite on ecris tous le deroulement de la scene! le deplacement des personnages, le dialogue, les emotes etc...

5) et enfin les variables définissant l'angle de camera et les deplacement.


Comme je disait plus haut il est impossible de faire un plan de camera sur les differents NPC. il va falloir donc teleporter le joueur sur different waypoint pour pouvoir effectuer different plan sur la zone.

Si vous souhaitez que le joueur face parti de la mise en scene vous allez devoir le cloner.

Voilà en somme les premieres informations a tenir compte lors de la création d'une mise en scene.

Je vais créer une petite demo détaillé ou deux de façon a ce que vous puissiez faire vos premiers pas ds ce domaine.
Bien, voici le script "scene" que j'ai beaucoup modifié afin de le simplifier. Il est écris le plus simplement de façon à ce que vous puissiez saisir les bases.
Un NPC va en direction de 2 waypoints, et la camera va le suivre sur les 2 waypoints.


Il faut donc créer une ZONE, on y placera:

-> 1 strigger.

-> 5 waypoints avec les tag suivant:
"NW_WAYPOINT001"
"NW_WAYPOINT002"
"FINCUTSCENE"
"Camera001"
"Camera002"

-> 1 npc avec le tag "actor1"


*Note:*
Positionnez la "camera001" a coter du "waypoint001" & la seconde camera avec le second waypoint. Cela a pour but d'avoir une vue sur les 2 differents waypoints par lequel passera le NPC.

Le waypoint "FINCUTSCENE" sera le dernier waypoint ou sera teleporter le joueur à la fin de la mise en scene. Alors placez celui-ci au milieu du strigger.






ds le onenter du strigger, le script "scene"

Code PHP:


//On appelle le fameux script ecrit par gestal
#include "in_g_cutscene"


void main()
{
    
// On effectue un test pour voir si le joueur ai dejà passé sur le strigger, celà évite de faire rejouer la mise en scene en boucle continue.

    
object oPC GetEnteringObject();
    if (!
GetIsPC(oPC))
        { return; }
    if (
GetLocalInt(oPC,"c3in_intro") > 0)
        { return; }
    
SetLocalInt(oPC,"c3in_intro",1);

    
// Strip PC
    
ExecuteScript("c3in_strip",oPC);
    
// SetCutsceneMode
    
GestaltStartCutscene(oPC,"c3in_mv_intro");

    
//le joueur perd le control et devient invissible pendant une dure 15.0 secondes (durée de la mise en scene.)
    
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectMovementSpeedDecrease(60),oPC,15.0);
    
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY),oPC,15.0);


     
//***********DECLARATION D'OBJET*****************
    // Get actors
    
object oActor1 GetObjectByTag("actor1");


    
// Get objects
    
object oSword GetItemPossessedBy(oActor3,"nw_wblmhw012");

    
// Get waypoints
    
object oWay1 GetWaypointByTag("NW_WAYPOINT001");
    
object oWay2 GetWaypointByTag("NW_WAYPOINT002");
    
object oWPEND GetWaypointByTag("FINCUTSCENE");

    
// Get cameras
    
object oCamera1 GetWaypointByTag("Camera001");
    
object oCamera2 GetWaypointByTag("Camera002");





    
GestaltActionMove   (0.0,oActor1 ,oWay1);
    
GestaltActionMove   (3.0,oActor1 ,oWay2);

    
GestaltActionSpeak  (8.0,oActor1,"salut la compagnie",ANIMATION_FIREFORGET_GREETING);





    
//*********** Camera movements*******************

    //position de base de la camera
    
SetLocalFloat(oPC,"fCameraDirection",35.0);
    
SetLocalFloat(oPC,"fStoreCameraFacingRange",20.0);
    
SetLocalFloat(oPC,"fCameraPitch",5.0);

                                                                          

    
DelayCommand(0.0,AssignCommand(oPCActionJumpToObjectoCamera1)));

    
DelayCommand(3.0,AssignCommand(oPCActionJumpToObjectoCamera2)));

    
GestaltCameraMove(4.00.020.090.0360.05.090.010.030.0,oPC);


    
DelayCommand(15.0,AssignCommand(oPCActionJumpToObject(oWPEND)));


//***********on arrete la mise en scene*****************
    
DelayCommand(16.0,GestaltStopCutscene(oPC));











detail de gestaltCameraMove:
Code PHP:

 GestaltCameraMove (4.00.020.090.0360.05.090.010.030.0,oPC); 

4.0 -> 4 secondes passerons avant que la camera s'enclanche.

0.0 -> l'angle horizontal de depart (0.0, 90.0, 180.0, 270.0, 360.0 pour les direction est, nord, ouest & sud en sence inverse de l'horloge)
20.0 -> la distance entre la camera et le joueur
90.0 -> l'angle vertical (90.0 face au joueur & 0.0 vue de dessu)

les 3 valeurs suivante sont les meme! c donc le parcour que va faire la camera.

la camera va donc effectuer 0.0, 20.0, 90.0 vers 360.0, 5.0, 90.0.
Ce qui signifie, que la camera va effectuer une rotaion à 360°, celle-ci, eloigné de 20 metre et ce retrouver a 5 metre du joueur, tous ça.

les 2 dernieres valeurs sont:
10.0 le tps (10 secondes) que va mettre pour réliser sont mouvement.

30.0 le nombre fps de l'annimation.


*Note:
Les angle de camera et les distances sont limités par le programme lui meme ds NWN, SoU.Vous avez remarqué qu'il est impossible de voir le ciel ds NWN & SoU.

Il existe toute fois un programme qui debloque l'angle de camera. Il est tjs bon de savoir que celà existe si vous souhaiter develloper ça pour vos futur hackpacks. HoU n'a apparement plus cet restriction de vu.


Si il y a des questions pour ce premier jet.
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés