mirror of https://github.com/yaz0r/FITD.git
765 lines
30 KiB
C++
765 lines
30 KiB
C++
#include "common.h"
|
|
#include "math.h"
|
|
|
|
#define TL_INIT_COOR 0
|
|
#define TL_GOTO 1
|
|
#define TL_END 2
|
|
#define TL_REPEAT 3
|
|
#define TL_MARK 4
|
|
#define TL_WALK 5 // removed in AITD2+
|
|
#define TL_RUN 6 // removed in AITD2+
|
|
#define TL_STOP 7
|
|
#define TL_BACK 8 // removed in AITD2+
|
|
#define TL_SET_ANGLE 9
|
|
#define TL_COL_OFF 10
|
|
#define TL_COL_ON 11
|
|
#define TL_SET_DIST 12
|
|
#define TL_DEC_OFF 13
|
|
#define TL_DEC_ON 14
|
|
#define TL_GOTO_3D 15
|
|
#define TL_MEMO_COOR 16
|
|
#define TL_GOTO_3DX 17
|
|
#define TL_GOTO_3DZ 18
|
|
#define TL_ANGLE 19
|
|
#define TL_CLOSE 20
|
|
|
|
// AITD2+ has removed a few entries, so covert the enum to match
|
|
s16 convertTrackMacro(s16 inTrackMacro) {
|
|
if (g_gameId == AITD1) {
|
|
return inTrackMacro;
|
|
}
|
|
|
|
if (inTrackMacro <= 4)
|
|
return inTrackMacro;
|
|
|
|
if (inTrackMacro >= 6)
|
|
return inTrackMacro + 3;
|
|
|
|
assert(inTrackMacro == 5);
|
|
return TL_STOP;
|
|
}
|
|
|
|
int makeProportional(int x1, int x2, int y1, int y2)
|
|
{
|
|
return x1 + ((x2 - x1) * y2) / y1;
|
|
}
|
|
|
|
int computeAngleModificatorToPositionSub1(int ax)
|
|
{
|
|
int xOut;
|
|
int yOut;
|
|
|
|
Rotate(ax,0,1000,&xOut,&yOut);
|
|
|
|
yOut *= angleCompZ;
|
|
xOut *= angleCompX;
|
|
|
|
yOut -= xOut;
|
|
|
|
if(yOut==0)
|
|
return(0);
|
|
|
|
if(yOut>0)
|
|
return(1);
|
|
else
|
|
return(-1);
|
|
}
|
|
|
|
int CapObjet(int x1,int z1, int beta, int x2, int z2)
|
|
{
|
|
int resultMin;
|
|
int resultMax;
|
|
|
|
angleCompX = x2 - x1;
|
|
angleCompZ = z2 - z1;
|
|
angleCompBeta = beta;
|
|
|
|
resultMin = computeAngleModificatorToPositionSub1(beta - 4);
|
|
resultMax = computeAngleModificatorToPositionSub1(beta + 4);
|
|
|
|
if(resultMax == -1 && resultMin == 1) // in the middle
|
|
{
|
|
return(computeAngleModificatorToPositionSub1(beta));
|
|
}
|
|
else
|
|
{
|
|
return(((resultMax+resultMin)+1)>>1);
|
|
}
|
|
}
|
|
|
|
void GereManualRot(int param)
|
|
{
|
|
if(localJoyD&4)
|
|
{
|
|
if(currentProcessedActorPtr->direction != 1)
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = 1;
|
|
|
|
if(currentProcessedActorPtr->rotate.numSteps == 0)
|
|
{
|
|
int oldBeta = currentProcessedActorPtr->beta;
|
|
|
|
if(currentProcessedActorPtr->speed == 0)
|
|
{
|
|
InitRealValue(oldBeta,oldBeta+0x100,param/2,¤tProcessedActorPtr->rotate);
|
|
}
|
|
else
|
|
{
|
|
InitRealValue(oldBeta,oldBeta+0x100,param,¤tProcessedActorPtr->rotate);
|
|
}
|
|
}
|
|
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
if(localJoyD&8)
|
|
{
|
|
if(currentProcessedActorPtr->direction != -1)
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = -1;
|
|
|
|
if(currentProcessedActorPtr->rotate.numSteps == 0)
|
|
{
|
|
int oldBeta = currentProcessedActorPtr->beta;
|
|
|
|
if(currentProcessedActorPtr->speed == 0)
|
|
{
|
|
InitRealValue(oldBeta,oldBeta-0x100,param/2,¤tProcessedActorPtr->rotate);
|
|
}
|
|
else
|
|
{
|
|
InitRealValue(oldBeta,oldBeta-0x100,param,¤tProcessedActorPtr->rotate);
|
|
}
|
|
}
|
|
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
if(!(localJoyD&0xC))
|
|
{
|
|
currentProcessedActorPtr->direction = 0;
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
}
|
|
|
|
#define DISTANCE_TO_POINT_TRESSHOLD 400
|
|
|
|
unsigned int lastTimeForward = 0;
|
|
|
|
char* getRoomLink(unsigned int room1, unsigned int room2)
|
|
{
|
|
int i;
|
|
s16 numOfZones;
|
|
char* zoneData = (char*)getRoomData(room1);
|
|
char* bestZone;
|
|
|
|
zoneData += *(s16*)(zoneData);
|
|
numOfZones = *(s16*)zoneData;
|
|
zoneData+=2;
|
|
|
|
bestZone = zoneData;
|
|
|
|
for(i=0;i<numOfZones;i++)
|
|
{
|
|
if(*(s16*)(zoneData+14) == 4)
|
|
{
|
|
bestZone = zoneData;
|
|
|
|
if(*(s16*)(zoneData+12) == room2)
|
|
{
|
|
return bestZone;
|
|
}
|
|
}
|
|
|
|
zoneData += 16;
|
|
}
|
|
|
|
return bestZone;
|
|
}
|
|
|
|
void processTrack(void)
|
|
{
|
|
switch(currentProcessedActorPtr->trackMode)
|
|
{
|
|
case 1: // manual
|
|
{
|
|
GereManualRot(60);
|
|
if(localJoyD&1) // forward
|
|
{
|
|
if(timer - lastTimeForward < 10 && currentProcessedActorPtr->speed != 4) // start running ?
|
|
{
|
|
currentProcessedActorPtr->speed = 5;
|
|
}
|
|
else
|
|
{
|
|
if(currentProcessedActorPtr->speed == 0 || currentProcessedActorPtr->speed == -1)
|
|
{
|
|
currentProcessedActorPtr->speed = 4;
|
|
}
|
|
}
|
|
|
|
/* if(currentProcessedActorPtr->speed>0 && currentProcessedActorPtr->speed<4)
|
|
currentProcessedActorPtr->speed = 5; */
|
|
|
|
|
|
lastTimeForward = timer;
|
|
}
|
|
else
|
|
{
|
|
if((currentProcessedActorPtr->speed > 0) && (currentProcessedActorPtr->speed<=4))
|
|
{
|
|
currentProcessedActorPtr->speed--;
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->speed = 0;
|
|
}
|
|
}
|
|
|
|
if(localJoyD&2) // backward
|
|
{
|
|
if(currentProcessedActorPtr->speed == 0 || currentProcessedActorPtr->speed >= 4)
|
|
currentProcessedActorPtr->speed = -1;
|
|
|
|
if(currentProcessedActorPtr->speed == 5)
|
|
currentProcessedActorPtr->speed = 0;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 2: // follow
|
|
{
|
|
int followedActorIdx = ListWorldObjets[currentProcessedActorPtr->trackNumber].objIndex;
|
|
|
|
if(followedActorIdx == -1)
|
|
{
|
|
currentProcessedActorPtr->direction = 0;
|
|
currentProcessedActorPtr->speed = 0;
|
|
}
|
|
else
|
|
{
|
|
tObject* followedActorPtr = &ListObjets[followedActorIdx];
|
|
|
|
int targetRoomNumber = followedActorPtr->room;
|
|
int targetX = followedActorPtr->roomX;
|
|
int targetY = followedActorPtr->roomY;
|
|
int targetZ = followedActorPtr->roomZ;
|
|
int angleModif;
|
|
|
|
if (g_gameId == AITD1) {
|
|
// in AITD1, if the target entity is in a different room, the entity would aim for the center of the trigger zone to get to that room
|
|
if (currentProcessedActorPtr->room != targetRoomNumber)
|
|
{
|
|
char* link = getRoomLink(currentProcessedActorPtr->room, targetRoomNumber);
|
|
|
|
targetX = *(s16*)(link + 0) + (((*(s16*)(link + 2)) - (*(s16*)(link + 0))) / 2);
|
|
targetY = *(s16*)(link + 4) + (((*(s16*)(link + 6)) - (*(s16*)(link + 4))) / 2);
|
|
targetZ = *(s16*)(link + 8) + (((*(s16*)(link + 10)) - (*(s16*)(link + 8))) / 2);
|
|
}
|
|
}
|
|
else {
|
|
// This was changed from AITD2+ to aim for the target in world-space
|
|
if((followedActorPtr->room >= 0) && (currentProcessedActorPtr->room>=0))
|
|
{
|
|
const auto& targetRoom = roomDataTable[followedActorPtr->room];
|
|
const auto& sourceRoom = roomDataTable[currentProcessedActorPtr->room];
|
|
|
|
targetX -= (sourceRoom.worldX - targetRoom.worldX) * 10;
|
|
targetZ += (sourceRoom.worldZ - targetRoom.worldZ) * 10;
|
|
}
|
|
}
|
|
|
|
angleModif = CapObjet( currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX,
|
|
currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ,
|
|
currentProcessedActorPtr->beta, targetX, targetZ);
|
|
|
|
if( (currentProcessedActorPtr->rotate.numSteps == 0) || (currentProcessedActorPtr->direction != angleModif) )
|
|
{
|
|
InitRealValue( currentProcessedActorPtr->beta, currentProcessedActorPtr->beta - (angleModif * 256), 60, ¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = angleModif;
|
|
|
|
if( currentProcessedActorPtr->direction == 0 )
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->speed = 4;
|
|
|
|
}
|
|
break;
|
|
}
|
|
case 3: // track
|
|
{
|
|
char* trackPtr = HQR_Get(listTrack,currentProcessedActorPtr->trackNumber);
|
|
trackPtr+=currentProcessedActorPtr->positionInTrack * 2;
|
|
|
|
s16 trackMacro = convertTrackMacro(*(s16*)trackPtr);
|
|
trackPtr += 2;
|
|
|
|
//printf("Track macro %X\n",trackMacro);
|
|
|
|
switch(trackMacro)
|
|
{
|
|
case TL_INIT_COOR: // warp
|
|
{
|
|
int roomNumber = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
if(currentProcessedActorPtr->room != roomNumber)
|
|
{
|
|
if(currentCameraTargetActor == currentProcessedActorIdx)
|
|
{
|
|
FlagChangeSalle = 1;
|
|
NewNumSalle = roomNumber;
|
|
}
|
|
|
|
currentProcessedActorPtr->room = roomNumber;
|
|
}
|
|
|
|
currentProcessedActorPtr->zv.ZVX1 -= currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX;
|
|
currentProcessedActorPtr->zv.ZVX2 -= currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX;
|
|
currentProcessedActorPtr->zv.ZVY1 -= currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY;
|
|
currentProcessedActorPtr->zv.ZVY2 -= currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY;
|
|
currentProcessedActorPtr->zv.ZVZ1 -= currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ;
|
|
currentProcessedActorPtr->zv.ZVZ2 -= currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ;
|
|
|
|
currentProcessedActorPtr->worldX = currentProcessedActorPtr->roomX = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
currentProcessedActorPtr->worldY = currentProcessedActorPtr->roomY = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
currentProcessedActorPtr->worldZ = currentProcessedActorPtr->roomZ = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
currentProcessedActorPtr->worldX -= (s16)((roomDataTable[currentRoom].worldX - roomDataTable[currentProcessedActorPtr->room].worldX) * 10);
|
|
currentProcessedActorPtr->worldY += (s16)((roomDataTable[currentRoom].worldY - roomDataTable[currentProcessedActorPtr->room].worldY) * 10);
|
|
currentProcessedActorPtr->worldZ += (s16)((roomDataTable[currentRoom].worldZ - roomDataTable[currentProcessedActorPtr->room].worldZ) * 10);
|
|
|
|
currentProcessedActorPtr->zv.ZVX1 += currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX;
|
|
currentProcessedActorPtr->zv.ZVX2 += currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX;
|
|
currentProcessedActorPtr->zv.ZVY1 += currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY;
|
|
currentProcessedActorPtr->zv.ZVY2 += currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY;
|
|
currentProcessedActorPtr->zv.ZVZ1 += currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ;
|
|
currentProcessedActorPtr->zv.ZVZ2 += currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ;
|
|
|
|
currentProcessedActorPtr->speed = 0;
|
|
currentProcessedActorPtr->direction = 0;
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
currentProcessedActorPtr->positionInTrack += 5;
|
|
|
|
break;
|
|
}
|
|
case TL_GOTO: // goToPosition
|
|
{
|
|
int roomNumber = *(s16*)(trackPtr);
|
|
int x;
|
|
int y;
|
|
int z;
|
|
unsigned int distanceToPoint;
|
|
|
|
trackPtr += 2;
|
|
|
|
x = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
y = 0;
|
|
z = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
if(roomNumber != currentProcessedActorPtr->room)
|
|
{
|
|
// TODO: fix bug here...
|
|
x -= (roomDataTable[currentProcessedActorPtr->room].worldX - roomDataTable[roomNumber].worldX) * 10;
|
|
z += (roomDataTable[currentProcessedActorPtr->room].worldZ - roomDataTable[roomNumber].worldZ) * 10;
|
|
}
|
|
|
|
distanceToPoint = GiveDistance2D( currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX,
|
|
currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ,
|
|
x,z );
|
|
|
|
|
|
if(distanceToPoint >= DISTANCE_TO_POINT_TRESSHOLD) // not yet at position
|
|
{
|
|
int angleModif = CapObjet( currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX,
|
|
currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ,
|
|
currentProcessedActorPtr->beta,
|
|
x,z );
|
|
|
|
if((currentProcessedActorPtr->rotate.numSteps == 0) || (currentProcessedActorPtr->direction != angleModif))
|
|
{
|
|
InitRealValue(currentProcessedActorPtr->beta, currentProcessedActorPtr->beta - (angleModif * 64), 15, ¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = angleModif;
|
|
|
|
if(!angleModif)
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
}
|
|
else // reached position
|
|
{
|
|
currentProcessedActorPtr->positionInTrack += 4;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TL_GOTO_3D: // goToPosition
|
|
{
|
|
int roomNumber = *(s16*)(trackPtr);
|
|
int x;
|
|
int y;
|
|
int z;
|
|
unsigned int distanceToPoint;
|
|
|
|
trackPtr += 2;
|
|
|
|
x = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
y = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
z = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
int time = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
if (roomNumber != currentProcessedActorPtr->room)
|
|
{
|
|
// TODO: fix bug here...
|
|
x -= (roomDataTable[currentProcessedActorPtr->room].worldX - roomDataTable[roomNumber].worldX) * 10;
|
|
y += (roomDataTable[currentProcessedActorPtr->room].worldY - roomDataTable[roomNumber].worldY) * 10;
|
|
z += (roomDataTable[currentProcessedActorPtr->room].worldZ - roomDataTable[roomNumber].worldZ) * 10;
|
|
}
|
|
|
|
// reached position?
|
|
if (y == currentProcessedActorPtr->roomY)
|
|
{
|
|
int distance = GiveDistance2D(currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX, currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ, x, z);
|
|
if (distance < DISTANCE_TO_POINT_TRESSHOLD) {
|
|
currentProcessedActorPtr->positionInTrack += 6;
|
|
break;
|
|
}
|
|
}
|
|
|
|
{
|
|
int direction = CapObjet(
|
|
currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX,
|
|
currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ,
|
|
currentProcessedActorPtr->beta,
|
|
x, z);
|
|
|
|
if (currentProcessedActorPtr->YHandler.numSteps == 0)
|
|
{
|
|
InitRealValue(0, y - (currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY), time, ¤tProcessedActorPtr->YHandler);
|
|
}
|
|
|
|
if ((currentProcessedActorPtr->rotate.numSteps == 0) || (currentProcessedActorPtr->direction != direction))
|
|
{
|
|
InitRealValue(currentProcessedActorPtr->beta, currentProcessedActorPtr->beta - (direction * 256), 60, ¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = direction;
|
|
|
|
if (!direction)
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TL_END: // stop
|
|
{
|
|
currentProcessedActorPtr->speed = 0;
|
|
currentProcessedActorPtr->trackNumber = -1;
|
|
InitDeplacement(0,0);
|
|
break;
|
|
}
|
|
case TL_REPEAT:
|
|
{
|
|
currentProcessedActorPtr->positionInTrack = 0;
|
|
break;
|
|
}
|
|
case TL_MARK: // MARK
|
|
{
|
|
currentProcessedActorPtr->MARK = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
currentProcessedActorPtr->positionInTrack += 2;
|
|
break;
|
|
}
|
|
case TL_WALK:
|
|
{
|
|
currentProcessedActorPtr->speed = 4;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
break;
|
|
}
|
|
case TL_RUN:
|
|
{
|
|
currentProcessedActorPtr->speed = 5;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
break;
|
|
}
|
|
case TL_STOP:
|
|
{
|
|
// Stop only has a meaning in AITD1 where it means stop walking
|
|
if (g_gameId == AITD1)
|
|
{
|
|
currentProcessedActorPtr->speed = 0;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
}
|
|
break;
|
|
}
|
|
case TL_SET_ANGLE: // TL_SET_ANGLE
|
|
{
|
|
int betaDif = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
if(((currentProcessedActorPtr->beta - betaDif)&1023) > 512)
|
|
{
|
|
currentProcessedActorPtr->direction = 1; // left
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->direction = -1; // right
|
|
}
|
|
|
|
if(!currentProcessedActorPtr->rotate.numSteps)
|
|
{
|
|
InitRealValue(currentProcessedActorPtr->beta, betaDif, 120, ¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
|
|
if(currentProcessedActorPtr->beta == betaDif)
|
|
{
|
|
currentProcessedActorPtr->direction = 0;
|
|
|
|
currentProcessedActorPtr->positionInTrack+=2;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TL_COL_OFF:
|
|
{
|
|
currentProcessedActorPtr->dynFlags &= ~1;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
break;
|
|
}
|
|
case TL_COL_ON:
|
|
{
|
|
currentProcessedActorPtr->dynFlags |= 1;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
break;
|
|
}
|
|
case TL_DEC_OFF: // background collision off
|
|
{
|
|
currentProcessedActorPtr->objectType &= ~AF_TRIGGER;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
break;
|
|
}
|
|
case TL_DEC_ON: // background collision on
|
|
{
|
|
currentProcessedActorPtr->objectType |= AF_TRIGGER;
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
break;
|
|
}
|
|
case TL_MEMO_COOR:
|
|
{
|
|
int objNum = currentProcessedActorPtr->indexInWorld;
|
|
|
|
ListWorldObjets[objNum].x = currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX;
|
|
ListWorldObjets[objNum].y = currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY;
|
|
ListWorldObjets[objNum].z = currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ;
|
|
|
|
currentProcessedActorPtr->positionInTrack++;
|
|
|
|
break;
|
|
}
|
|
case TL_GOTO_3DX: // walk up/down stairs on X
|
|
{
|
|
int x;
|
|
int y;
|
|
int z;
|
|
int objX;
|
|
int objY;
|
|
int objZ;
|
|
|
|
x = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
y = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
z = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
objX = ListWorldObjets[currentProcessedActorPtr->indexInWorld].x;
|
|
objY = ListWorldObjets[currentProcessedActorPtr->indexInWorld].y;
|
|
objZ = ListWorldObjets[currentProcessedActorPtr->indexInWorld].z;
|
|
|
|
if( currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY < y - 100
|
|
|| currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY > y + 100)
|
|
{
|
|
int propX = makeProportional(objY, y, x - objX, (currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX) - objX);
|
|
|
|
int difY = propX - currentProcessedActorPtr->worldY;
|
|
int angleModif;
|
|
|
|
currentProcessedActorPtr->worldY += difY;
|
|
currentProcessedActorPtr->roomY += difY;
|
|
currentProcessedActorPtr->zv.ZVY1 += difY;
|
|
currentProcessedActorPtr->zv.ZVY2 += difY;
|
|
|
|
angleModif = CapObjet( currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX,
|
|
currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ,
|
|
currentProcessedActorPtr->beta,
|
|
x,z );
|
|
|
|
if(!currentProcessedActorPtr->rotate.numSteps || currentProcessedActorPtr->direction != angleModif)
|
|
{
|
|
InitRealValue(currentProcessedActorPtr->beta, currentProcessedActorPtr->beta - (angleModif<<8), 60, ¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = angleModif;
|
|
|
|
if(angleModif)
|
|
{
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
int difY = y - currentProcessedActorPtr->worldY;
|
|
|
|
currentProcessedActorPtr->stepY = 0;
|
|
currentProcessedActorPtr->worldY += difY;
|
|
currentProcessedActorPtr->roomY += difY;
|
|
currentProcessedActorPtr->zv.ZVY1 += difY;
|
|
currentProcessedActorPtr->zv.ZVY2 += difY;
|
|
|
|
currentProcessedActorPtr->positionInTrack +=4;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TL_GOTO_3DZ: // walk up/down stairs on Z
|
|
{
|
|
int x;
|
|
int y;
|
|
int z;
|
|
int objX;
|
|
int objY;
|
|
int objZ;
|
|
|
|
x = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
y = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
z = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
objX = ListWorldObjets[currentProcessedActorPtr->indexInWorld].x;
|
|
objY = ListWorldObjets[currentProcessedActorPtr->indexInWorld].y;
|
|
objZ = ListWorldObjets[currentProcessedActorPtr->indexInWorld].z;
|
|
|
|
if( currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY < y - 100
|
|
|| currentProcessedActorPtr->roomY + currentProcessedActorPtr->stepY > y + 100)
|
|
{
|
|
int propZ = makeProportional(objY, y, z - objZ, (currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ) - objZ);
|
|
|
|
int difY = propZ - currentProcessedActorPtr->worldY;
|
|
|
|
int angleModif;
|
|
|
|
currentProcessedActorPtr->worldY += difY;
|
|
currentProcessedActorPtr->roomY += difY;
|
|
currentProcessedActorPtr->zv.ZVY1 += difY;
|
|
currentProcessedActorPtr->zv.ZVY2 += difY;
|
|
|
|
angleModif = CapObjet( currentProcessedActorPtr->roomX + currentProcessedActorPtr->stepX,
|
|
currentProcessedActorPtr->roomZ + currentProcessedActorPtr->stepZ,
|
|
currentProcessedActorPtr->beta,
|
|
x,z );
|
|
|
|
if(!currentProcessedActorPtr->rotate.numSteps || currentProcessedActorPtr->direction != angleModif)
|
|
{
|
|
InitRealValue(currentProcessedActorPtr->beta, currentProcessedActorPtr->beta - (angleModif<<8), 60, ¤tProcessedActorPtr->rotate);
|
|
}
|
|
|
|
currentProcessedActorPtr->direction = angleModif;
|
|
|
|
if(angleModif)
|
|
{
|
|
currentProcessedActorPtr->beta = updateActorRotation(¤tProcessedActorPtr->rotate);
|
|
}
|
|
else
|
|
{
|
|
currentProcessedActorPtr->rotate.numSteps = 0;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
int difY = y - currentProcessedActorPtr->worldY;
|
|
|
|
currentProcessedActorPtr->stepY = 0;
|
|
currentProcessedActorPtr->worldY += difY;
|
|
currentProcessedActorPtr->roomY += difY;
|
|
currentProcessedActorPtr->zv.ZVY1 += difY;
|
|
currentProcessedActorPtr->zv.ZVY2 += difY;
|
|
|
|
currentProcessedActorPtr->positionInTrack +=4;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TL_ANGLE: // rotate
|
|
{
|
|
currentProcessedActorPtr->alpha = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
currentProcessedActorPtr->beta = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
currentProcessedActorPtr->gamma = *(s16*)(trackPtr);
|
|
trackPtr += 2;
|
|
|
|
currentProcessedActorPtr->direction = 0;
|
|
|
|
currentProcessedActorPtr->positionInTrack +=4;
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
printf("Unknown track macro %X\n",trackMacro);
|
|
assert(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
currentProcessedActorPtr->beta &= 0x3FF;
|
|
}
|
|
|