VOID PAL_UpdatePartyGestures( BOOL fWalking ) /*++ Purpose: Update the gestures of all the party members. Parameters: [IN] fWalking - whether the party is walking or not. Return value: None. --*/ { static int s_iThisStepFrame = 0; int iStepFrameFollower = 0, iStepFrameLeader = 0; int i; if (fWalking) { // // Update the gesture for party leader // s_iThisStepFrame = (s_iThisStepFrame + 1) % 4; if (s_iThisStepFrame & 1) { iStepFrameLeader = (s_iThisStepFrame + 1) / 2; iStepFrameFollower = 3 - iStepFrameLeader; } else { iStepFrameLeader = 0; iStepFrameFollower = 0; } gpGlobals->rgParty[0].x = PAL_X(gpGlobals->partyoffset); gpGlobals->rgParty[0].y = PAL_Y(gpGlobals->partyoffset); if (gpGlobals->g.PlayerRoles.rgwWalkFrames[gpGlobals->rgParty[0].wPlayerRole] == 4) { gpGlobals->rgParty[0].wFrame = gpGlobals->wPartyDirection * 4 + s_iThisStepFrame; } else { gpGlobals->rgParty[0].wFrame = gpGlobals->wPartyDirection * 3 + iStepFrameLeader; } // // Update the gestures and positions for other party members // for (i = 1; i <= (short)gpGlobals->wMaxPartyMemberIndex; i++) { gpGlobals->rgParty[i].x = gpGlobals->rgTrail[1].x - PAL_X(gpGlobals->viewport); gpGlobals->rgParty[i].y = gpGlobals->rgTrail[1].y - PAL_Y(gpGlobals->viewport); if (i == 2) { gpGlobals->rgParty[i].x += (gpGlobals->rgTrail[1].wDirection == kDirEast || gpGlobals->rgTrail[1].wDirection == kDirWest) ? -16 : 16; gpGlobals->rgParty[i].y += 8; } else { gpGlobals->rgParty[i].x += ((gpGlobals->rgTrail[1].wDirection == kDirWest || gpGlobals->rgTrail[1].wDirection == kDirSouth) ? 16 : -16); gpGlobals->rgParty[i].y += ((gpGlobals->rgTrail[1].wDirection == kDirWest || gpGlobals->rgTrail[1].wDirection == kDirNorth) ? 8 : -8); } // // Adjust the position if there is obstacle // if (PAL_CheckObstacle(PAL_XY(gpGlobals->rgParty[i].x + PAL_X(gpGlobals->viewport), gpGlobals->rgParty[i].y + PAL_Y(gpGlobals->viewport)), TRUE, 0)) { gpGlobals->rgParty[i].x = gpGlobals->rgTrail[1].x - PAL_X(gpGlobals->viewport); gpGlobals->rgParty[i].y = gpGlobals->rgTrail[1].y - PAL_Y(gpGlobals->viewport); } // // Update gesture for this party member // if (gpGlobals->g.PlayerRoles.rgwWalkFrames[gpGlobals->rgParty[i].wPlayerRole] == 4) { gpGlobals->rgParty[i].wFrame = gpGlobals->rgTrail[2].wDirection * 4 + s_iThisStepFrame; } else { gpGlobals->rgParty[i].wFrame = gpGlobals->rgTrail[2].wDirection * 3 + iStepFrameLeader; } } if (gpGlobals->nFollower > 0) { // // Update the position and gesture for the follower // gpGlobals->rgParty[gpGlobals->wMaxPartyMemberIndex + 1].x = gpGlobals->rgTrail[3].x - PAL_X(gpGlobals->viewport); gpGlobals->rgParty[gpGlobals->wMaxPartyMemberIndex + 1].y = gpGlobals->rgTrail[3].y - PAL_Y(gpGlobals->viewport); gpGlobals->rgParty[gpGlobals->wMaxPartyMemberIndex + 1].wFrame = gpGlobals->rgTrail[3].wDirection * 3 + iStepFrameFollower; } } else { // // Player is not moved. Use the "standing" gesture instead of "walking" one. // i = gpGlobals->g.PlayerRoles.rgwWalkFrames[gpGlobals->rgParty[0].wPlayerRole]; if (i == 0) { i = 3; } gpGlobals->rgParty[0].wFrame = gpGlobals->wPartyDirection * i; for (i = 1; i <= (short)gpGlobals->wMaxPartyMemberIndex; i++) { int f = gpGlobals->g.PlayerRoles.rgwWalkFrames[gpGlobals->rgParty[i].wPlayerRole]; if (f == 0) { f = 3; } gpGlobals->rgParty[i].wFrame = gpGlobals->rgTrail[2].wDirection * f; } if (gpGlobals->nFollower > 0) { gpGlobals->rgParty[gpGlobals->wMaxPartyMemberIndex + 1].wFrame = gpGlobals->rgTrail[3].wDirection * 3; } s_iThisStepFrame &= 2; s_iThisStepFrame ^= 2; } }
VOID PAL_UpdateParty( VOID ) /*++ Purpose: Update the location and walking gesture of all the party members. Parameters: None. Return value: None. --*/ { int xSource, ySource, xTarget, yTarget, xOffset, yOffset, i; // // Has user pressed one of the arrow keys? // if (g_InputState.dir != kDirUnknown) { xOffset = ((g_InputState.dir == kDirWest || g_InputState.dir == kDirSouth) ? -16 : 16); yOffset = ((g_InputState.dir == kDirWest || g_InputState.dir == kDirNorth) ? -8 : 8); xSource = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset); ySource = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset); xTarget = xSource + xOffset; yTarget = ySource + yOffset; gpGlobals->wPartyDirection = g_InputState.dir; // // Check for obstacles on the destination location // if (!PAL_CheckObstacle(PAL_XY(xTarget, yTarget), TRUE, 0)) { // // Player will actually be moved. Store trail. // for (i = 3; i >= 0; i--) { gpGlobals->rgTrail[i + 1] = gpGlobals->rgTrail[i]; } gpGlobals->rgTrail[0].wDirection = g_InputState.dir; gpGlobals->rgTrail[0].x = xSource; gpGlobals->rgTrail[0].y = ySource; // // Move the viewport // gpGlobals->viewport = PAL_XY(PAL_X(gpGlobals->viewport) + xOffset, PAL_Y(gpGlobals->viewport) + yOffset); // // Update gestures // PAL_UpdatePartyGestures(TRUE); return; // don't go further } } PAL_UpdatePartyGestures(FALSE); }
VOID PAL_GameUpdate( BOOL fTrigger ) /*++ Purpose: The main game logic routine. Update the status of everything. Parameters: [IN] fTrigger - whether to process trigger events or not. Return value: None. --*/ { WORD wEventObjectID, wDir; int i; LPEVENTOBJECT p; // // Check for trigger events // if (fTrigger) { // // Check if we are entering a new scene // if (gpGlobals->fEnteringScene) { // // Run the script for entering the scene // gpGlobals->fEnteringScene = FALSE; i = gpGlobals->wNumScene - 1; gpGlobals->g.rgScene[i].wScriptOnEnter = PAL_RunTriggerScript(gpGlobals->g.rgScene[i].wScriptOnEnter, 0xFFFF); if (gpGlobals->fEnteringScene || gpGlobals->fGameStart) { // // Don't go further as we're switching to another scene // return; } PAL_ClearKeyState(); PAL_MakeScene(); } // // Update the vanish time for all event objects // for (wEventObjectID = 0; wEventObjectID < gpGlobals->g.nEventObject; wEventObjectID++) { p = &gpGlobals->g.lprgEventObject[wEventObjectID]; if (p->sVanishTime != 0) { p->sVanishTime += ((p->sVanishTime < 0) ? 1 : -1); } } // // Loop through all event objects in the current scene // for (wEventObjectID = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex + 1; wEventObjectID <= gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex; wEventObjectID++) { p = &gpGlobals->g.lprgEventObject[wEventObjectID - 1]; if (p->sVanishTime != 0) { continue; } if (p->sState < 0) { if (p->x < PAL_X(gpGlobals->viewport) || p->x > PAL_X(gpGlobals->viewport) + 320 || p->y < PAL_Y(gpGlobals->viewport) || p->y > PAL_Y(gpGlobals->viewport) + 320) { p->sState = abs(p->sState); p->wCurrentFrameNum = 0; } } else if (p->sState > 0 && p->wTriggerMode >= kTriggerTouchNear) { // // This event object can be triggered without manually exploring // if (abs(PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset) - p->x) + abs(PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset) - p->y) * 2 < (p->wTriggerMode - kTriggerTouchNear) * 32 + 16) { // // Player is in the trigger zone. // if (p->nSpriteFrames) { // // The sprite has multiple frames. Try to adjust the direction. // int xOffset, yOffset; p->wCurrentFrameNum = 0; xOffset = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset) - p->x; yOffset = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset) - p->y; if (xOffset > 0) { p->wDirection = ((yOffset > 0) ? kDirEast : kDirNorth); } else { p->wDirection = ((yOffset > 0) ? kDirSouth : kDirWest); } // // Redraw the scene // PAL_UpdatePartyGestures(FALSE); PAL_MakeScene(); VIDEO_UpdateScreen(NULL); } // // Execute the script. // p->wTriggerScript = PAL_RunTriggerScript(p->wTriggerScript, wEventObjectID); PAL_ClearKeyState(); if (gpGlobals->fEnteringScene || gpGlobals->fGameStart) { // // Don't go further on scene switching // return; } } } } } // // Run autoscript for each event objects // for (wEventObjectID = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex + 1; wEventObjectID <= gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex; wEventObjectID++) { p = &gpGlobals->g.lprgEventObject[wEventObjectID - 1]; if (p->sState > 0 && p->sVanishTime == 0) { WORD wScriptEntry = p->wAutoScript; if (wScriptEntry != 0) { p->wAutoScript = PAL_RunAutoScript(wScriptEntry, wEventObjectID); if (gpGlobals->fEnteringScene || gpGlobals->fGameStart) { // // Don't go further on scene switching // return; } } } // // Check if the player is in the way // if (fTrigger && p->sState >= kObjStateBlocker && p->wSpriteNum != 0 && abs(p->x - PAL_X(gpGlobals->viewport) - PAL_X(gpGlobals->partyoffset)) + abs(p->y - PAL_Y(gpGlobals->viewport) - PAL_Y(gpGlobals->partyoffset)) * 2 <= 12) { // // Player is in the way, try to move a step // wDir = (p->wDirection + 1) % 4; for (i = 0; i < 4; i++) { int x, y; PAL_POS pos; x = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset); y = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset); x += ((wDir == kDirWest || wDir == kDirSouth) ? -16 : 16); y += ((wDir == kDirWest || wDir == kDirNorth) ? -8 : 8); pos = PAL_XY(x, y); if (!PAL_CheckObstacle(pos, TRUE, 0)) { // // move here // gpGlobals->viewport = PAL_XY( PAL_X(pos) - PAL_X(gpGlobals->partyoffset), PAL_Y(pos) - PAL_Y(gpGlobals->partyoffset)); break; } wDir = (wDir + 1) % 4; } } } gpGlobals->dwFrameNum++; }