Aller au contenu

Photo

Spawning placeables


  • Veuillez vous connecter pour répondre
5 réponses à ce sujet

#1
andysks

andysks
  • Members
  • 1 651 messages
Hi all. I got a situation here, which I can make work but I was wandering if there is a better way. There is an area with some ruins, which are concealed until certain actions are completed (something like a riddle let's say). I can place all placeables, create blueprints for them, then add a waypoint with the exact location and spawn them there.
Is there however a better way, like something I saw on a video on youtube from a trailer of a module, where the placeable actually comes from the ground?



I have no idea how he did it.

Or, is there some way to actually no spawn the placeables but have them hidden somehow?

In any case, any info on the matter, or an idea on how others would do this could be helpful :).

#2
Morbane

Morbane
  • Members
  • 1 883 messages
there is a script set that creates and destroys a placeable at incrementing positions - but (sorry) i cannot find my copy or a reference to its name ion the vault or its creator.

but its a lead anyway, aye

#3
Morbane

Morbane
  • Members
  • 1 883 messages
found it - im pretty sure it was created by "spelljammer" "sunjammer"
:wizard:

Modifié par Morbane, 05 janvier 2014 - 09:04 .


#4
Morbane

Morbane
  • Members
  • 1 883 messages
in case its gone missing:

//--------------------------------------------------------------------------------------------------
// sj_move_plc_inc
//--------------------------------------------------------------------------------------------------
/*
A library of functions to "move" placeable objects.

Placeables, by definition, cannot move. There were to work-arounds for this in NWN1: either a
custom creature was created from the placeable's appearance and it was moved; or a series of
clones were quickly created and destroyed with an appropriate offset to give the illusion of
movement. The first technique is still valid for NWN2 however the latter is longer viable as
objects take far too long to appear and disappear in NWN2.

To overcome NWN2's limitations new MovePlaceable* functions will create an array of invisible
objects between the original object and the destination object or location. The objects are
temporarily revealed in sequence to give the illusion of movement. Finally the original object
and all but the last of the array objects are destroyed.


USAGE NOTES
===========

- the placeable object to be moved must have its own blueprint, it must be non-static and have
dynamic collisions; and it must have a unique tag

- any object reference to the original placeable will become invalid after the move so, for
example, to move the placeable back a new reference must be obtained using GetObjectByTag etc.

- ensure that each placeable only receives one move command at a time, for example by making the
switch unusable, as concurrent commands will produce undesired effects and rogue placeables

- the impact on performance and the smoothness of the move can be controlled using the nSteps
and fDuration arguments on the MovePlaceable* functions: 12 frames/s and 4 frames/m provides
a reasonably smooth effect.


TODO @ 05 Apr 2008
==================

- add the ability to rotate the object (both internally and externally)
- convert to an action to prevent concurrent command?
- rewrite to use a custom struct?
- rewrite to use pseudo-arrays?
*/
//--------------------------------------------------------------------------------------------------
/*
Created: 05 Apr 2008 - Sunjammer
*/
//--------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------
// PROTOTYPES
//--------------------------------------------------------------------------------------------------

// Helper function to create an array of objects between the original object and the destination.
// - oOriginal: the original placeable
// - nCount: the number of tweening objects
// - vDestination: destination position
void CreateTweeningObjects(object oOriginal, int nCount, vector vDestination);

// Helper function to destroy the original object and all but the last of the array of objects between
// the original object and the destination.
// - oOriginal: the original placeable
// - nCount: the number of tweening objects
// * Returns: noteR
// * OnError: noteE
void DestroyTweeningObjects(object oOriginal, int nCount);

// Makes a placeable appear to move by creating a series of invisible clones between its location
// and the destination location and then temporarily revealing in sequence.
// - oPlaceable: the original placeable
// - lDestination: location of the destination
// - nSteps: the number of steps in the move (affects performance and smoothness)
// - fDelay: the delay (normally 0.5 seconds) to allow for object creation
// - fDuration: the duration of the move (affects performance and smoothness)
// - oSound: a sound object to be played during the move
void MovePlaceableToLocation(object oPlaceable, location lDestination, int nSteps, float fDelay, float fDuration, object oSound=OBJECT_INVALID);

// Makes a placeable appear to move by creating a series of invisible clones between its location
// and the destination object and then temporarily revealing in sequence.
// - oPlaceable: the original placeable
// - oDestination: an object (normally a waypoint) indicating the destination
// - nSteps: the number of steps in the move (affects performance and smoothness)
// - fDelay: the delay (normally 0.5 seconds) to allow for object creation
// - fDuration: the duration of the move (affects performance and smoothness)
// - oSound: a sound object to be played during the move
void MovePlaceableToObject(object oPlaceable, object oDestination, int nSteps, float fDelay, float fDuration, object oSound=OBJECT_INVALID);

// Removes all Cutscene Invisibility visual effects from an object.
// - oObject: object with CSI visual effect
void RemoveCutsceneInvisibility(object oObject);

// Helper function to reveal each tweening objects in sequence to give the illusion of movement.
// original object is in fact moving.
// - oOriginal: the original placeable
// - nCount: the number of tweening objects
// - fDuration: the duration of the tween, i.e. the "move"
void RevealTweeningObjects(object oOriginal, int nCount, float fDuration);


//--------------------------------------------------------------------------------------------------
// FUNCTIONS
//--------------------------------------------------------------------------------------------------

void CreateTweeningObjects(object oOriginal, int nCount, vector vDestination)
{
int n;
object oNew;

effect eCSI = EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY);

// decompose the original object
string sRes = GetResRef(oOriginal);
string sTag = GetTag(oOriginal);

// decompose the original location
object oArea = GetArea(oOriginal);
vector vPosition = GetPosition(oOriginal);
float fFacing = GetFacing(oOriginal);

// calculate the translation vector for each tween
vector vTranslation = (vDestination - vPosition) / IntToFloat(nCount);

// create tweening objects between original object and the destination
// NOTE: that for GetObjectByTag purposes the original object starts as nNth = 0 but is pushed
// down the stack until nNth = nCount and the last tweening object (i.e. the one we want to
// persist) becomes nNth = 0
for(n = 0; n < nCount; n++)
{
vPosition += vTranslation;

// create a new object and instantly make it cutscene-invisible
oNew = CreateObject(OBJECT_TYPE_PLACEABLE, sRes, Location(oArea, vPosition, fFacing), FALSE, sTag);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCSI, oNew);
}
}


void DestroyTweeningObjects(object oOriginal, int nCount)
{
int n;

// decompose object
string sTag = GetTag(oOriginal);

// destroy the original object and all tweening objects except the last
// NOTE: that for GetObjectByTag purposes the original object starts as nNth = 0 but is pushed
// down the stack until nNth = nCount and the last tweening object (i.e. the one we want to
// persist) becomes nNth = 0
for(n = nCount; n > 1; n--)
{
DestroyObject(GetObjectByTag(sTag, n));
}
}


void RemoveCutsceneInvisibility(object oObject)
{
effect eEffect = GetFirstEffect(oObject);
while(GetIsEffectValid(eEffect))
{
// only remove the effect if it is a cutscene invisible visual effect
// NOTE: the first entry in a visual effect's (0-based) IntList is the visual effect id
if(GetEffectType(eEffect) == EFFECT_TYPE_VISUALEFFECT
&& GetEffectInteger(eEffect, 0) == VFX_DUR_CUTSCENE_INVISIBILITY)
{
RemoveEffect(oObject, eEffect);
}
eEffect = GetNextEffect(oObject);
}
}


void RevealTweeningObjects(object oTarget, int nCount, float fDuration)
{
int n;

effect eCSI = EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY);
float fInterval = fDuration / nCount;
string sTag = GetTag(oTarget);

// NOTE: that for GetObjectByTag purposes the original object starts as nNth = 0 but is pushed
// down the stack until nNth = nCount and the last tweening object (i.e. the one we want to
// persist) becomes nNth = 0
for(n = 0; n < nCount; n++)
{
// hide the previous object and reveal the next
DelayCommand(fInterval * (nCount - n), ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCSI, GetObjectByTag(sTag, n + 1)));
DelayCommand(fInterval * (nCount - n), RemoveCutsceneInvisibility(GetObjectByTag(sTag, n)));
}
}


void MovePlaceableToLocation(object oPlaceable, location lDestination, int nSteps, float fDelay, float fDuration, object oSound=OBJECT_INVALID)
{
// create, reveal and destroy all the tweening objects
CreateTweeningObjects(oPlaceable, nSteps, GetPositionFromLocation(lDestination));
DelayCommand(fDelay, RevealTweeningObjects(oPlaceable, nSteps, fDuration));
DelayCommand(fDelay + fDuration, DestroyTweeningObjects(oPlaceable, nSteps));

// start and stop the sound object (if appropriate)
if(GetIsObjectValid(oSound))
{
DelayCommand(fDelay, SoundObjectPlay(oSound));
DelayCommand(fDelay + fDuration, SoundObjectStop(oSound));
}
}


void MovePlaceableToObject(object oPlaceable, object oDestination, int nSteps, float fDelay, float fDuration, object oSound=OBJECT_INVALID)
{
MovePlaceableToLocation(oPlaceable, GetLocation(oDestination), nSteps, fDelay, fDuration, oSound);
}

#5
andysks

andysks
  • Members
  • 1 651 messages
Now that's something :D. I have to go now, but will look at it later today. Thanks ;).

#6
Darin

Darin
  • Members
  • 282 messages
To do that, you need to spawn and destroy at various heights (or use the scale functions to set up the object at scale 1,1,0 and rescale to the proper scale).