The saga of "The Moving Moon" or "How I Learned to Love Pulling my Hair Out" (apologies to the late Stanley Kubrick)
So Rolo wants his moon to travel around that dial. He keeps mentioning rotation. Now I know that rotation won't work but... So I write the code to do rotation just to prove it. As expected the moon duly rotates about the SW corner of the area. Here is the demo code. It goes in the OnHeartbeat of the area.
#include "x0_i0_position"
location Rotate(float fAngle, location lcurrent, object oArea);
void MovePlaceable(location lNewLocation, object oPlaceable, string sResRef);
void main()
{
object oMoon = GetObjectByTag("CelestialOrbMoon");
location lMoon = GetLocation(oMoon);
object oArea = GetAreaFromLocation(lMoon);
location lNewLocation = Rotate(12.0f, lMoon, oArea);
vector vToHere = GetPositionFromLocation(lNewLocation);
// only move to a location if it is inside the area
if((vToHere.x >= 0.0f) && (vToHere.y >= 0.0f))
{
if(vToHere.x < IntToFloat(GetAreaSize(AREA_WIDTH, oArea) * 10 - 1))
{
if(vToHere.y < IntToFloat(GetAreaSize(AREA_HEIGHT, oArea) * 10 - 1))
MovePlaceable(lNewLocation, oMoon, "blueprint001");
}
}
}
location Rotate(float fAngle, location lcurrent, object oArea)
{
float fFacing = GetFacingFromLocation(lcurrent);
vector vStartPosition = GetPositionFromLocation(lcurrent);
//rotate about the origin (0,0)
float fSine = sin(fAngle);
float fCosine = cos(fAngle);
float fNewX = vStartPosition.x * fCosine - vStartPosition.y * fSine;
float fNewY = vStartPosition.x * fSine + vStartPosition.y * fCosine;
float fNewZ = vStartPosition.z;
vector vNewPosition = Vector(fNewX,fNewY,fNewZ);
return (Location(oArea, vNewPosition, fFacing));
}
void MovePlaceable(location lNewLocation, object oPlaceable, string sResRef)
{
int iStatic = GetUseableFlag(oPlaceable);
object oNew = CreateObject(OBJECT_TYPE_PLACEABLE, sResRef, lNewLocation, FALSE);
if(iStatic)
SetUseableFlag(oPlaceable, 1);
DestroyObject(oPlaceable, 0.5);
}
I did however have an idea of what might work. If you look at the area in the toolset with the moon selected, you will see the directional arrow which tells you the facing of the placeable. If you don't spot it straight away, that's OK. Unlike most placeables, with this moon it is not in the immediate vicinity of it but in the (rough) centre of the dial and pointing at the (x,y) centre of the moon. So I thought that if I could change the facing I could make the moon orbit the centre of the dial. And it works (but see later). Again, here is the demo code. It goes in the OnHeartbeat of the area.
void main()
{
object oMoon = GetObjectByTag("CelestialOrbMoon");
location lMoon = GetLocation(oMoon);
object oArea = GetAreaFromLocation(lMoon);
int iStatic = GetUseableFlag(oMoon);
if(GetLocalInt(oArea, "iIsFirstTime"))
{
SetLocalInt(oArea, "iIsFirstTime", FALSE);
SetLocalFloat(oArea, "fFaceDirection", GetFacing(oMoon));
return;
}
float fNewDirection = GetLocalFloat(oArea, "fFaceDirection");
fNewDirection = fNewDirection - 12.0f;
if(fNewDirection < 0.0f)
fNewDirection = 360.0f - fNewDirection;
SetLocalFloat(oArea, "fFaceDirection", fNewDirection);
if(iStatic)
SetUseableFlag(oMoon, 1);
DestroyObject(oMoon, 0.01f);
object oNew = CreateObject(OBJECT_TYPE_PLACEABLE, "blueprint001", lMoon, FALSE);
AssignCommand(oNew, SetFacing(fNewDirection));
}
The above code could do with optimizing of course. The main problem is that you can only change the facing of an object once it exists and the OnSpawn event doesn't exist for placeables. So what happens is that the new moon is created in exactly the same position as the old moon. Even putting the call to DestroyObject before the call to CreateObject doesn't help as objects do not disappear immediately but rather fade away. Now this wouldn't matter too much except when hb code is called there is a doubling of light because of 2 moons being there instead of one.
Hair restorer anyone, please...
TR