Voici un script permettant de créer plusieurs objets autour d'une ellipse orientable.
Partique pour répartir régulièrement des sièges autour d'une table ronde et poser des assiettes en face des sièges.
Petit point négatif : je ne suis pas satisfait de l'orientation des objets quand la forme est elliptique. En cercle c'est OK. Je me pencherai plus tard pour améliorer l'orientation.
////////////////////////////////////
// Création d'objets en ellipse //
// autour d'un point d'origine. //
////////////////////////////////////
//
// Usage : création d'objets à intervalle angulaire régulier en forme d'ellipse et orientés vers le centre de l'ellipse.
// On peut faire pivoter l'ellipse sur ses axex horizontal et vertical.
//
// /____
// Y _ / |\_
// \ * (1) | \
// \ (2) / * | \ (x): Centre de l'ellipse (variable lCentreEllipse).
// _ * / * | (He) (He) : Angle d'orientation horizontal de l'ellipse (variable fOrientEllipseHoriz).
// * \(r2) /(r1) * \ (Ve) : Angle d'orientation vertical de l'ellipse (variable fOrientEllipseVert) (non implementer).
// * \_\/___ / * | (1), (2), ... : Objets créés autour de (x).
// (3) \ /\(Ve) * | (1) étant le 1er objet de la variable iQte, toujours
// * (x)-*-------- * ------*--X situé à droite de (x) + un angle de (He).
// * (6) (r1), (r2) : Rayons de l'ellipse (variables fRayon1, fRayon2).
// * *
// * *
// * *
// (4) (5)
// * --- *
//
// Avec :
// lCentreEllipse : Location du centre de l'ellipse (point d'origine).
//
// Voir CreateObject pour les paramètres suivants :
// ------------------------------------------------
// nObjectType : Type de l'objet (voir constantes OBJECT_TYPE_*, CreateObject - nObjectType).
// sTemplate : Le ResRef de l'objet à créer (voir CreateObject - sTemplate).
// bUseAppearAnimation : Animation de spawn (voir CreateObject - bUseAppearAnimation).
// sNewTag : Nouveau tag de l'objet (voir CreateObject - sNewTag).
//
// iQte : Nb d'objets à créer.
// fRayon1, fRayon2 : Rayons de l'ellipse (si un rayon est <0.0, celui-ci sera remis à 0.0).
// fOrientEllipseHoriz : Angle d'orientation de l'ellipse (0.0 (défaut) - 360.0) sur un axe horizontal.
// fOrientObject : Angle d'orientation de l'objet sur l'ellipse (0.0 (défaut) - 360.0).
// fHauteurObject : Hauteur de l'objet (si =-100.0 (défaut), la hauteur sera celle de lCentre).
//
// RETOUR : Le dernier objet créé ayant un int local "NumCreation" contenant son numéro de création (max : =iQte).
// Remarque : Les objets créés sont orientés perpendiculairement par rapport à la tangente du point de création sur l'ellipse + un angle de fOrientObject.
//
// EXEMPLE 1:
//void main()
//{
// //Création de 6 coffres en cercle autour du PJ en discution.
// CreateObjects_Ellipse(GetLocation(GetPCSpeaker()), OBJECT_TYPE_PLACEABLE, "plc_chest1", FALSE, "", 6, 3.0, 3.0);
//}
//
// EXEMPLE 2:
//void main()
//{
// //Création d'un coffre devant le PJ en discution.
// CreateObjects_Ellipse(GetLocation(GetPCSpeaker()), OBJECT_TYPE_PLACEABLE, "plc_chest1", FALSE, "", 1, 1.0, 1.0, 90.0);
//}
object CreateObjects_Ellipse(location lCentreEllipse, int nObjectType, string sTemplate, int bUseAppearAnimation=FALSE, string sNewTag="", int iQte=1, float fRayon1=0.0, float fRayon2=-1.0, float fOrientEllipseHoriz=0.0, float fOrientObject=0.0, float fHauteurObject=-100.0)
{
if (iQte<=0) iQte=1;
if (iQte>360) iQte=360;
object oSpawn=OBJECT_INVALID;
float fDist, fOrientSpawn, fRayonCentre, fSigne, fAngleSurEllipse0=0.0, fAngleEspacement=(360.0 / IntToFloat(iQte)); //Distance du spawn, orientation du spawn, position de depart, espacement entre les objets
vector vCentre=GetPositionFromLocation(lCentreEllipse), vSpawn0, vSpawn;
location lSpawn; //Position future de l'objet.
int iQteCrees;
if (fRayon1<0.0) fRayon1=0.0;
if (fRayon2<0.0) fRayon2=0.0;
//fOrientEllipseHoriz=-fOrientEllipseHoriz; //Correction trigonometrique.
while (iQte>0)
{
//Position provisoire de l'objet sur une ellipse horizontale ayant pour centre le point 0 (x=0, y=0 - sur la zone, cela correspond au Sud-Ouest)
vSpawn0.x=fRayon1*cos(fAngleSurEllipse0); vSpawn0.y=fRayon2*sin(fAngleSurEllipse0); //Calcul x,y de la position
if (vCentre.z!=0.0) {vSpawn0.z=vCentre.z; vCentre.z=0.0;}
lSpawn=Location(GetAreaFromLocation(lCentreEllipse), vSpawn0, 0.0); //Position provisoire de l'objet
//Calcul de la distance entre le point x=0, y=0 et la position provisoire de l'objet
fDist=GetDistanceBetweenLocations(Location(GetAreaFromLocation(lCentreEllipse), Vector(0.0, 0.0, vSpawn0.z), 0.0), lSpawn);
//Rotation de l'ellipse sur son axe horizontal d'un angle de fOrientEllipseHoriz
vSpawn.x=fDist*cos(fAngleSurEllipse0+fOrientEllipseHoriz); vSpawn.y=fDist*sin(fAngleSurEllipse0+fOrientEllipseHoriz);
//Hauteur de l'objet
if (fHauteurObject<=-100.0) vSpawn.z=vSpawn0.z; else vSpawn.z=fHauteurObject; //Hauteur de l'objet
//Position definitive de l'objet sur l'ellipse reelle
lSpawn=Location(GetAreaFromLocation(lCentreEllipse), vSpawn+vCentre, 0.0);
//Creation de l'objet
oSpawn=CreateObject(nObjectType, sTemplate, lSpawn, bUseAppearAnimation, sNewTag);
if (oSpawn!=OBJECT_INVALID)
{//Orientation de l'objet vers le centre de l'ellipse + fOrientObject.
AssignCommand(oSpawn, SetFacing(GetFacing(oSpawn)+fAngleSurEllipse0+fOrientEllipseHoriz+fOrientObject));
iQteCrees++;
SetLocalInt(oSpawn, "NumCreation", iQteCrees);
}
fAngleSurEllipse0=fAngleSurEllipse0+fAngleEspacement;
iQte--;
}
return oSpawn;
}