WALK, GRAB_JOE, GRAB_DIR, USE_UNDERWEAR, USE_DRESS and USE_CLOTHES implementations

svn-id: r10924
This commit is contained in:
Gregory Montoir 2003-10-21 09:05:16 +00:00
parent 3be2f0f1e0
commit 4e2ffd8d9e
6 changed files with 331 additions and 45 deletions

View File

@ -48,7 +48,7 @@ enum {
};
enum {
enum Direction {
DIR_LEFT = 1,
DIR_RIGHT = 2,
DIR_FRONT = 3,
@ -107,6 +107,27 @@ enum Language {
};
enum Verb {
VERB_OPEN = 1,
VERB_CLOSE = 2,
VERB_MOVE = 3,
VERB_GIVE = 5,
VERB_USE = 6,
VERB_PICK_UP = 7,
VERB_LOOK_AT = 9,
VERB_TALK_TO = 8,
VERB_WALK_TO = 10,
VERB_SCROLL_UP = 11,
VERB_SCROLL_DOWN = 12,
VERB_INV_ITEM1 = 13,
VERB_INV_ITEM2 = 14,
VERB_INV_ITEM3 = 15,
VERB_INV_ITEM4 = 16,
VERB_USE_JOURNAL = 20,
VERB_SKIP_TEXT = 101
};
enum StateDirection {
STATE_DIR_BACK = 0,
STATE_DIR_RIGHT = 1,
@ -114,12 +135,21 @@ enum StateDirection {
STATE_DIR_FRONT = 3
};
enum StateTalk {
STATE_TALK_TALK,
STATE_TALK_MUTE
};
enum StateGrab {
STATE_GRAB_NONE,
STATE_GRAB_DOWN,
STATE_GRAB_UP,
STATE_GRAB_MID
};
} // End of namespace Queen
#endif

View File

@ -21,6 +21,7 @@
#include "stdafx.h"
#include "queen/logic.h"
#include "queen/cutaway.h"
#include "queen/defs.h"
#include "queen/display.h"
#include "queen/graphics.h"
@ -1460,43 +1461,52 @@ StateDirection Logic::findStateDirection(uint16 state) {
// of a STATE_DIR_*. Some (all ?) calls to FIND_STATE(, "DIR")
// are often followed by a DIR_* constant.
// see queen.c l.4016-4023
StateDirection sd = STATE_DIR_BACK;
switch ((state >> 2) & 3) {
case 0:
sd = STATE_DIR_BACK;
break;
case 1:
sd = STATE_DIR_RIGHT;
break;
case 2:
sd = STATE_DIR_LEFT;
break;
case 3:
sd = STATE_DIR_FRONT;
break;
}
return sd;
// queen.c l.4014-4021
static const StateDirection sd[] = {
STATE_DIR_BACK,
STATE_DIR_RIGHT,
STATE_DIR_LEFT,
STATE_DIR_FRONT
};
return sd[(state >> 2) & 3];
}
StateTalk Logic::findStateTalk(uint16 state) {
return (state & (1 << 9)) ? STATE_TALK_TALK : STATE_TALK_MUTE;
}
void Logic::joeSetup() {
int i;
StateGrab Logic::findStateGrab(uint16 state) {
_graphics->bankLoad("joe_a.BBK", 13);
// queen.c l.4022-4029
static const StateGrab gd[] = {
STATE_GRAB_NONE,
STATE_GRAB_DOWN,
STATE_GRAB_UP,
STATE_GRAB_MID
};
return gd[state & 3];
}
void Logic::joeSetupFromBanks(const char *bank1, const char* bank2) {
int i;
_graphics->bankLoad(bank1, 13);
for (i = 11; i <= 28 + FRAMES_JOE_XTRA; ++i) {
_graphics->bankUnpack(i - 10, i, 13);
}
_graphics->bankErase(13);
_graphics->bankLoad("joe_b.BBK", 7);
_graphics->bankLoad(bank2, 7);
_graphics->bankUnpack(1, 33 + FRAMES_JOE_XTRA, 7);
_graphics->bankUnpack(3, 34 + FRAMES_JOE_XTRA, 7);
_graphics->bankUnpack(5, 35 + FRAMES_JOE_XTRA, 7);
}
void Logic::joeSetup() {
joeSetupFromBanks("joe_a.BBK", "joe_b.BBK");
_joe.facing = DIR_FRONT;
}
@ -1632,5 +1642,205 @@ uint16 Logic::joeFace() {
}
int16 Logic::joeWalkTo(int16 x, int16 y, const Command *cmd, bool mustWalk) {
// Check to see if object is actually an exit to another
// room. If so, then set up new room
uint16 k = _roomData[_currentRoom];
ObjectData *objData = &_objectData[k + cmd->noun2];
if (objData->x != 0 || objData->y != 0) {
x = objData->x;
y = objData->y;
}
if (cmd->action2 == VERB_WALK_TO) {
_entryObj = objData->entryObj;
}
else {
_entryObj = 0;
}
_newRoom = 0;
if (_entryObj != 0 && cmd->action2 != VERB_CLOSE) {
// because this is an exit object, see if there is
// a walk off point and set (x,y) accordingly
WalkOffData *wod = walkOffPointForObject(k + cmd->noun2);
if (wod != NULL) {
x = wod->x;
y = wod->y;
}
}
// determine which way for Joe to face Object
uint16 facing = 0;
switch (findStateDirection(objData->state)) {
case STATE_DIR_BACK:
facing = DIR_BACK;
break;
case STATE_DIR_FRONT:
facing = DIR_FRONT;
break;
case STATE_DIR_LEFT:
facing = DIR_LEFT;
break;
case STATE_DIR_RIGHT:
facing = DIR_RIGHT;
break;
}
int16 p = 0;
if (mustWalk) {
BobSlot *bobJoe = _graphics->bob(0);
if (x == bobJoe->x && y == bobJoe->y) {
joeFacing(facing);
joeFace();
}
else {
// XXX inCutaway parameter
p = _walk->joeMove(facing, x, y, false);
// if(P != 0) P = FIND_VERB
}
}
return p;
}
void Logic::joeGrab(uint16 state, uint16 speed) {
StateGrab sg = findStateGrab(state);
if (sg != STATE_GRAB_NONE) {
joeGrabDirection(sg, speed);
}
}
void Logic::joeGrabDirection(StateGrab grab, uint16 speed) {
// if speed == 0, then keep Joe in position
uint16 frame = 0;
BobSlot *bobJoe = _graphics->bob(0);
switch (grab) {
case STATE_GRAB_NONE:
break;
case STATE_GRAB_MID:
if (_joe.facing == DIR_BACK) {
frame = 4;
}
else if (_joe.facing == DIR_FRONT) {
frame = 6;
}
else {
frame = 2;
}
break;
case STATE_GRAB_DOWN:
if (_joe.facing == DIR_BACK) {
frame = 9;
}
else {
frame = 8;
}
break;
case STATE_GRAB_UP:
// turn back
_graphics->bankUnpack(5, 29 + FRAMES_JOE_XTRA, 7);
bobJoe->xflip = (_joe.facing == DIR_LEFT);
bobJoe->scale = _joe.scale;
_graphics->update();
// grab up
_graphics->bankUnpack(7, 29 + FRAMES_JOE_XTRA, 7);
bobJoe->xflip = (_joe.facing == DIR_LEFT);
bobJoe->scale = _joe.scale;
_graphics->update();
// turn back
if (speed == 0) {
frame = 7;
}
else {
frame = 5;
}
break;
}
if (frame != 0) {
_graphics->bankUnpack(frame, 29 + FRAMES_JOE_XTRA, 7);
bobJoe->xflip = (_joe.facing == DIR_LEFT);
bobJoe->scale = _joe.scale;
_graphics->update();
// extra delay for grab down
if (grab == STATE_GRAB_DOWN) {
_graphics->update();
_graphics->update();
}
if (speed > 0) {
joeFace();
}
}
}
void Logic::joeUseDress(bool showCut) {
if (showCut) {
joeFacing(DIR_FRONT);
joeFace();
if (gameState(VAR_DRESSING_MODE) == 0) {
playCutaway("cdres.CUT");
// XXX INS_ITEM_NUM(58);
}
else {
playCutaway("cudrs.CUT");
}
}
_display->palSetJoe(JP_DRESS);
joeSetupFromBanks("JoeD_A.BBK", "JoeD_B.BBK");
// XXX DEL_ITEM_NUM(56, 0);
// XXX INVENTORY();
gameState(VAR_DRESSING_MODE, 2);
}
void Logic::joeUseClothes(bool showCut) {
if (showCut) {
joeFacing(DIR_FRONT);
joeFace();
playCutaway("cdclo.CUT");
// XXX INS_ITEM_NUM(56);
}
_display->palSetJoe(JP_CLOTHES);
joeSetupFromBanks("Joe_A.BBK", "Joe_B.BBK");
// XXX DEL_ITEM_NUM(58,0);
// XXX INVENTORY();
gameState(VAR_DRESSING_MODE, 0);
}
void Logic::joeUseUnderwear() {
_display->palSetJoe(JP_CLOTHES);
joeSetupFromBanks("JoeU_A.BBK", "JoeU_B.BBK");
gameState(VAR_DRESSING_MODE, 1);
}
void Logic::playCutaway(const char* cutFile) {
char next[20];
Cutaway::run(cutFile, next, _graphics, this, _resource);
}
} // End of namespace Queen

View File

@ -23,6 +23,7 @@
#define QUEENLOGIC_H
#include "queen/queen.h"
#include "queen/defs.h"
#include "queen/structs.h"
namespace Queen {
@ -44,6 +45,12 @@ struct ZoneSlot {
};
struct Command {
Verb action, action2;
uint16 noun, noun2;
};
class Graphics;
class Resource;
class Display;
@ -135,11 +142,14 @@ public:
StateDirection findStateDirection(uint16 state); // == FIND_STATE(state, "DIR");
StateTalk findStateTalk (uint16 state); // == FIND_STATE(state, "TALK");
StateGrab findStateGrab (uint16 state); // == FIND_STATE(state, "GRAB");
Walk *walk() { return _walk; }
int talkSpeed() { return _talkSpeed; }
void joeSetupFromBanks(const char *bank1, const char* bank2);
//! SETUP_JOE(), loads the various bobs needed to animate Joe
void joeSetup();
@ -149,6 +159,26 @@ public:
//! FACE_JOE()
uint16 joeFace();
//! WALK()
int16 joeWalkTo(int16 x, int16 y, const Command *cmd, bool mustWalk);
//! GRAB_JOE()
void joeGrab(uint16 state, uint16 speed);
//! GRAB_DIR
void joeGrabDirection(StateGrab grab, uint16 speed);
//! USE_DRESS
void joeUseDress(bool showCut);
//! USE_CLOTHES
void joeUseClothes(bool showCut);
//! USE_UNDERWEAR
void joeUseUnderwear();
void playCutaway(const char* cutFile);
Display *display() { return _display; }
protected:

View File

@ -64,8 +64,6 @@ void Walk::joeMoveBlock(int facing, uint16 areaNum, uint16 walkDataNum) {
warning("Walk::moveJoeBlock() partially implemented");
_graphics->bob(0)->animating = false;
// XXX CAN=-2;
// Make Joe face the right direction
_joeMoveBlock = true;
_logic->joeFacing(facing);
@ -120,7 +118,7 @@ void Walk::animateJoePrepare() {
}
void Walk::animateJoe() {
bool Walk::animateJoe() {
// queen.c l.2789-2835
uint16 lastDirection = 0;
uint16 i;
@ -136,7 +134,7 @@ void Walk::animateJoe() {
// area has been turned off, see if we should execute a cutaway
if (pwd->area->mapNeighbours < 0) {
joeMoveBlock(pwd->anim.facing, pwd->areaNum, i);
return;
return interrupted;
}
if (lastDirection != pwd->anim.facing) {
_graphics->bobAnimNormal(0, pwd->anim.firstFrame, pwd->anim.lastFrame, 1, false, false);
@ -168,6 +166,7 @@ void Walk::animateJoe() {
lastDirection = pwd->anim.facing;
}
_logic->joeFacing(lastDirection);
return interrupted;
}
@ -306,9 +305,9 @@ void Walk::animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum,
}
void Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) {
int16 Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) {
// CAN=0
int16 can = 0;
initWalkData();
uint16 oldx = _graphics->bob(0)->x;
@ -331,33 +330,46 @@ void Walk::joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway) {
if (_walkDataCount > 0) {
animateJoePrepare();
animateJoe();
if(animateJoe()) {
can = -1;
}
}
else {
// SPEAK(JOE_RESPstr[4],"JOE",find_cd_desc(4));
// path has been blocked, make Joe say so
// XXX SPEAK(JOE_RESPstr[4],"JOE",find_cd_desc(4));
can = -1;
}
_graphics->bob(0)->animating = false;
// XXX if ((CAN==-1) && (walkgameload==0)) NEW_ROOM=0;
// XXX walkgameload=0;
if (!_joeMoveBlock && direction > 0) {
if (_joeMoveBlock) {
can = -2;
}
else if (direction > 0) {
_logic->joeFacing(direction);
}
_logic->joePrevFacing(_logic->joeFacing());
_logic->joeFace();
return can;
}
void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction) {
int16 Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction) {
if (endx == 0 && endy == 0) {
warning("Walk::personMove() - endx == 0 && endy == 0");
return;
return 0;
}
// TODO: room 69 specific
// no longer walk characters in ending
if (_logic->currentRoom() == 69) {
if (strcmp(pp->name, "SPARKY") == 0 || strcmp(pp->name, "FAYE") == 0) {
return 0;
}
}
// CAN = 0;
int16 can = 0;
initWalkData();
uint16 bobNum = pp->actor->bobNum;
@ -386,6 +398,9 @@ void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImag
animatePersonPrepare(mpd, direction);
animatePerson(mpd, curImage, bobNum, bankNum, direction);
}
else {
can = -1;
}
uint16 standingFrame = 0;
if (bobNum <= 3) {
@ -416,6 +431,7 @@ void Walk::personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImag
pbs->xflip = false;
}
pbs->frameNum = standingFrame;
return can;
}

View File

@ -75,10 +75,10 @@ public:
Walk(Logic* logic, Graphics* graphics);
//! MOVE_JOE()
void joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway);
int16 joeMove(int direction, uint16 endx, uint16 endy, bool inCutaway);
//! MOVE_OTHER
void personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction);
int16 personMove(const Person *pp, uint16 endx, uint16 endy, uint16 curImage, int direction);
private:
@ -86,7 +86,7 @@ private:
void joeMoveBlock(int facing, uint16 areaNum, uint16 walkDataNum);
void animateJoePrepare();
void animateJoe();
bool animateJoe();
void animatePersonPrepare(const MovePersonData *mpd, int direction);
void animatePerson(const MovePersonData *mpd, uint16 image, uint16 bobNum, uint16 bankNum, int direction);

View File

@ -168,15 +168,18 @@ INV1,INV2,INV3,INV4
JOE
===
FACE_JOE() Logic::joeFace
GRAB_DIR()
GRAB_JOE()
GRAB_DIR() Logic::joeGrabDirection
GRAB_JOE() Logic::joeGrab
SETUP_HERO() Logic::joeSetupInRoom
SETUP_JOE() Logic::joeSetup
WALK()
USE_UNDERWEAR() Logic::joeUseUnderwear
USE_CLOTHES() Logic::joeUseClothes
USE_DRESS() Logic::joeUseDress
WALK() Logic::joeWalk
-
JOE_RESPstr Logic::_joeResponse
JOEF,JX,JY,JDIR Logic::_joe.*
JOEWALK // legal values = 0,1,2,3
JOEWALK Logic::_joe.walk // legal values = 0,1,2,3
JOURNAL
@ -217,9 +220,6 @@ SETUP_ROOM() QueenEngine::roomChanged
SETUP_SCREENS() *not needed* (only calls Graphics::loadPanel)
SETUP_VARS()
update() Graphics::update
USE_UNDERWEAR()
USE_CLOTHES()
USE_DRESS()
-
A_ANIMstr Logic::_aAnim
A_ANIM_MAX Logic::_numAAnim