XEEN: Shifted more logic for 3d view drawing from Interface to InterfaceMap
This commit is contained in:
parent
16a5a99c3a
commit
4c0c40c25d
6 changed files with 837 additions and 784 deletions
|
@ -29,24 +29,9 @@ namespace Xeen {
|
||||||
|
|
||||||
Interface::Interface(XeenEngine *vm) : ButtonContainer(), InterfaceMap(vm), _vm(vm) {
|
Interface::Interface(XeenEngine *vm) : ButtonContainer(), InterfaceMap(vm), _vm(vm) {
|
||||||
Common::fill(&_partyFaces[0], &_partyFaces[MAX_ACTIVE_PARTY], (SpriteResource *)nullptr);
|
Common::fill(&_partyFaces[0], &_partyFaces[MAX_ACTIVE_PARTY], (SpriteResource *)nullptr);
|
||||||
_batUIFrame = 0;
|
|
||||||
_spotDoorsUIFrame = 0;
|
|
||||||
_dangerSenseUIFrame = 0;
|
|
||||||
_face1UIFrame = 0;
|
|
||||||
_face2UIFrame = 0;
|
|
||||||
_blessedUIFrame = 0;
|
|
||||||
_powerShieldUIFrame = 0;
|
|
||||||
_holyBonusUIFrame = 0;
|
|
||||||
_heroismUIFrame = 0;
|
|
||||||
_flipUIFrame = 0;
|
|
||||||
_buttonsLoaded = false;
|
_buttonsLoaded = false;
|
||||||
_hiliteChar = -1;
|
_hiliteChar = -1;
|
||||||
_intrIndex1 = 0;
|
_intrIndex1 = 0;
|
||||||
_flag1 = false;
|
|
||||||
_isAnimReset = false;
|
|
||||||
_tillMove = 0;
|
|
||||||
_overallFrame = 0;
|
|
||||||
_upDoorText = false;
|
|
||||||
_steppingFX = 0;
|
_steppingFX = 0;
|
||||||
|
|
||||||
Common::fill(&_combatCharIds[0], &_combatCharIds[8], 0);
|
Common::fill(&_combatCharIds[0], &_combatCharIds[8], 0);
|
||||||
|
@ -79,15 +64,10 @@ void Interface::initDrawStructs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::setup() {
|
void Interface::setup() {
|
||||||
_globalSprites.load("global.icn");
|
InterfaceMap::setup();
|
||||||
_borderSprites.load("border.icn");
|
|
||||||
_spellFxSprites.load("spellfx.icn");
|
|
||||||
_fecpSprites.load("fecp.brd");
|
|
||||||
_blessSprites.load("bless.icn");
|
|
||||||
_restoreSprites.load("restorex.icn");
|
_restoreSprites.load("restorex.icn");
|
||||||
_hpSprites.load("hpbars.icn");
|
_hpSprites.load("hpbars.icn");
|
||||||
_uiSprites.load("inn.icn");
|
_uiSprites.load("inn.icn");
|
||||||
_charPowSprites.load("charpow.icn");
|
|
||||||
|
|
||||||
// Get mappings to the active characters in the party
|
// Get mappings to the active characters in the party
|
||||||
_vm->_party->_activeParty.resize(_vm->_party->_partyCount);
|
_vm->_party->_activeParty.resize(_vm->_party->_partyCount);
|
||||||
|
@ -277,14 +257,6 @@ start:
|
||||||
|
|
||||||
for (int i = 0; i < TOTAL_CHARACTERS; ++i)
|
for (int i = 0; i < TOTAL_CHARACTERS; ++i)
|
||||||
_charFaces[i].clear();
|
_charFaces[i].clear();
|
||||||
_globalSprites.clear();
|
|
||||||
_borderSprites.clear();
|
|
||||||
_spellFxSprites.clear();
|
|
||||||
_fecpSprites.clear();
|
|
||||||
_blessSprites.clear();
|
|
||||||
_restoreSprites.clear();
|
|
||||||
_hpSprites.clear();
|
|
||||||
_uiSprites.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::loadCharIcons() {
|
void Interface::loadCharIcons() {
|
||||||
|
@ -307,114 +279,6 @@ void Interface::setupBackground() {
|
||||||
assembleBorder();
|
assembleBorder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::assembleBorder() {
|
|
||||||
Screen &screen = *_vm->_screen;
|
|
||||||
|
|
||||||
// Draw the outer frame
|
|
||||||
_globalSprites.draw(screen._windows[0], 0, Common::Point(8, 8));
|
|
||||||
|
|
||||||
// Draw the animating bat character used to show when levitate is active
|
|
||||||
_borderSprites.draw(screen._windows[0], _vm->_party->_levitateActive ? _batUIFrame + 16 : 16,
|
|
||||||
Common::Point(0, 82));
|
|
||||||
_batUIFrame = (_batUIFrame + 1) % 12;
|
|
||||||
|
|
||||||
// Draw UI element to indicate whether can spot hidden doors
|
|
||||||
_borderSprites.draw(screen,
|
|
||||||
(_thinWall && _vm->_party->checkSkill(SPOT_DOORS)) ? _spotDoorsUIFrame + 28 : 28,
|
|
||||||
Common::Point(194, 91));
|
|
||||||
_spotDoorsUIFrame = (_spotDoorsUIFrame + 1) % 12;
|
|
||||||
|
|
||||||
// Draw UI element to indicate whether can sense danger
|
|
||||||
_borderSprites.draw(screen,
|
|
||||||
(_vm->_dangerSenseAllowed && _vm->_party->checkSkill(DANGER_SENSE)) ? _spotDoorsUIFrame + 40 : 40,
|
|
||||||
Common::Point(107, 9));
|
|
||||||
_dangerSenseUIFrame = (_dangerSenseUIFrame + 1) % 12;
|
|
||||||
|
|
||||||
// Handle the face UI elements for indicating clairvoyance status
|
|
||||||
_face1UIFrame = (_face1UIFrame + 1) % 4;
|
|
||||||
if (_vm->_face1State == 0)
|
|
||||||
_face1UIFrame += 4;
|
|
||||||
else if (_vm->_face1State == 2)
|
|
||||||
_face1UIFrame = 0;
|
|
||||||
|
|
||||||
_face2UIFrame = (_face2UIFrame + 1) % 4 + 12;
|
|
||||||
if (_vm->_face2State == 0)
|
|
||||||
_face2UIFrame += 252;
|
|
||||||
else if (_vm->_face2State == 2)
|
|
||||||
_face2UIFrame = 0;
|
|
||||||
|
|
||||||
if (!_vm->_party->_clairvoyanceActive) {
|
|
||||||
_face1UIFrame = 0;
|
|
||||||
_face2UIFrame = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
_borderSprites.draw(screen, _face1UIFrame, Common::Point(0, 32));
|
|
||||||
_borderSprites.draw(screen,
|
|
||||||
screen._windows[10]._enabled || screen._windows[2]._enabled ?
|
|
||||||
52 : _face2UIFrame,
|
|
||||||
Common::Point(215, 32));
|
|
||||||
|
|
||||||
// Draw resistence indicators
|
|
||||||
if (!screen._windows[10]._enabled && !screen._windows[2]._enabled
|
|
||||||
&& screen._windows[38]._enabled) {
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_fireResistence ? 1 : 0,
|
|
||||||
Common::Point(2, 2));
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_electricityResistence ? 3 : 2,
|
|
||||||
Common::Point(219, 2));
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_coldResistence ? 5 : 4,
|
|
||||||
Common::Point(2, 134));
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_poisonResistence ? 7 : 6,
|
|
||||||
Common::Point(219, 134));
|
|
||||||
} else {
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_fireResistence ? 9 : 8,
|
|
||||||
Common::Point(8, 8));
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_electricityResistence ? 10 : 11,
|
|
||||||
Common::Point(219, 8));
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_coldResistence ? 12 : 13,
|
|
||||||
Common::Point(8, 134));
|
|
||||||
_fecpSprites.draw(screen, _vm->_party->_poisonResistence ? 14 : 15,
|
|
||||||
Common::Point(219, 134));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw UI element for blessed
|
|
||||||
_blessSprites.draw(screen, 16, Common::Point(33, 137));
|
|
||||||
if (_vm->_party->_blessedActive) {
|
|
||||||
_blessedUIFrame = (_blessedUIFrame + 1) % 4;
|
|
||||||
_blessSprites.draw(screen, _blessedUIFrame, Common::Point(33, 137));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw UI element for power shield
|
|
||||||
if (_vm->_party->_powerShieldActive) {
|
|
||||||
_powerShieldUIFrame = (_powerShieldUIFrame + 1) % 4;
|
|
||||||
_blessSprites.draw(screen, _powerShieldUIFrame + 4,
|
|
||||||
Common::Point(55, 137));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw UI element for holy bonus
|
|
||||||
if (_vm->_party->_holyBonusActive) {
|
|
||||||
_holyBonusUIFrame = (_holyBonusUIFrame + 1) % 4;
|
|
||||||
_blessSprites.draw(screen, _holyBonusUIFrame + 8, Common::Point(160, 137));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw UI element for heroism
|
|
||||||
if (_vm->_party->_heroismActive) {
|
|
||||||
_heroismUIFrame = (_heroismUIFrame + 1) % 4;
|
|
||||||
_blessSprites.draw(screen, _heroismUIFrame + 12, Common::Point(182, 137));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw direction character if direction sense is active
|
|
||||||
if (_vm->_party->checkSkill(DIRECTION_SENSE) && !_vm->_noDirectionSense) {
|
|
||||||
const char *dirText = DIRECTION_TEXT[_vm->_party->_mazeDirection];
|
|
||||||
Common::String msg = Common::String::format(
|
|
||||||
"\002""08\003""c\013""139\011""116%c\014""d\001", *dirText);
|
|
||||||
screen._windows[0].writeString(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw view frame
|
|
||||||
if (screen._windows[12]._enabled)
|
|
||||||
screen._windows[12].frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag) {
|
void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag) {
|
||||||
Common::String playerNames[4];
|
Common::String playerNames[4];
|
||||||
Common::String playerRaces[4];
|
Common::String playerRaces[4];
|
||||||
|
@ -535,228 +399,6 @@ void Interface::moveCharacterToRoster() {
|
||||||
error("TODO");
|
error("TODO");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::draw3d(bool updateFlag) {
|
|
||||||
Combat &combat = *_vm->_combat;
|
|
||||||
EventsManager &events = *_vm->_events;
|
|
||||||
Map &map = *_vm->_map;
|
|
||||||
Party &party = *_vm->_party;
|
|
||||||
Screen &screen = *_vm->_screen;
|
|
||||||
Scripts &scripts = *_vm->_scripts;
|
|
||||||
|
|
||||||
if (screen._windows[11]._enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_flipUIFrame = (_flipUIFrame + 1) % 4;
|
|
||||||
if (_flipUIFrame == 0)
|
|
||||||
_flipWater = !_flipWater;
|
|
||||||
if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_2) &&
|
|
||||||
!_flag1 && _vm->_moveMonsters) {
|
|
||||||
if (--_tillMove == 0)
|
|
||||||
moveMonsters();
|
|
||||||
}
|
|
||||||
|
|
||||||
MazeObject &objObject = map._mobData._objects[_objNumber];
|
|
||||||
Direction partyDirection = _vm->_party->_mazeDirection;
|
|
||||||
int objNum = _objNumber - 1;
|
|
||||||
|
|
||||||
// Loop to update the frame numbers for each maze object, applying the animation frame
|
|
||||||
// limits as specified by the map's _animationInfo listing
|
|
||||||
for (uint idx = 0; idx < map._mobData._objects.size(); ++idx) {
|
|
||||||
MazeObject &mazeObject = map._mobData._objects[idx];
|
|
||||||
AnimationEntry &animEntry = map._animationInfo[mazeObject._spriteId];
|
|
||||||
int directionIndex = DIRECTION_ANIM_POSITIONS[mazeObject._direction][partyDirection];
|
|
||||||
|
|
||||||
if (_isAnimReset) {
|
|
||||||
mazeObject._frame = animEntry._frame1._frames[directionIndex];
|
|
||||||
} else {
|
|
||||||
++mazeObject._frame;
|
|
||||||
if ((int)idx == objNum && scripts._animCounter > 0 && (
|
|
||||||
objObject._spriteId == (_vm->_files->_isDarkCc ? 15 : 16) ||
|
|
||||||
objObject._spriteId == 58 || objObject._spriteId == 73)) {
|
|
||||||
if (mazeObject._frame > 4 || mazeObject._spriteId == 58)
|
|
||||||
mazeObject._frame = 1;
|
|
||||||
} else if (mazeObject._frame >= animEntry._frame2._frames[directionIndex]) {
|
|
||||||
mazeObject._frame = animEntry._frame1._frames[directionIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mazeObject._flipped = animEntry._flipped._flags[directionIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (map._isOutdoors) {
|
|
||||||
error("TODO: draw3d outdoors handling");
|
|
||||||
} else {
|
|
||||||
// Default all the parts of draw struct not to be drawn by default
|
|
||||||
for (int idx = 3; idx < _indoorList.size(); ++idx)
|
|
||||||
_indoorList[idx]._frame = -1;
|
|
||||||
|
|
||||||
if (_flag1) {
|
|
||||||
for (int idx = 0; idx < 96; ++idx) {
|
|
||||||
if (_indoorList[79 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[79 + idx]._frame = 0;
|
|
||||||
} else if (_indoorList[111 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[111 + idx]._frame = 1;
|
|
||||||
} else if (_indoorList[135 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[135 + idx]._frame = 2;
|
|
||||||
} else if (_indoorList[162 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[162 + idx]._frame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (_charsShooting) {
|
|
||||||
for (int idx = 0; idx < 96; ++idx) {
|
|
||||||
if (_indoorList[162 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[162 + idx]._frame = 0;
|
|
||||||
} else if (_indoorList[135 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[135 + idx]._frame = 1;
|
|
||||||
} else if (_indoorList[111 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[111 + idx]._frame = 2;
|
|
||||||
} else if (_indoorList[79 + idx]._sprites != nullptr) {
|
|
||||||
_indoorList[79 + idx]._frame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setMazeBits();
|
|
||||||
_isAnimReset = false;
|
|
||||||
const int INDOOR_INDEXES[3] = { 157, 151, 154 };
|
|
||||||
const int INDOOR_COMBAT_POS[3][2] = { { 102, 134 }, { 36, 67 }, { 161, 161 } };
|
|
||||||
const int INDOOR_COMBAT_POS2[4] = { 8, 6, 4, 2 };
|
|
||||||
|
|
||||||
// Double check this, since it's not being used?
|
|
||||||
//MazeObject &objObject = map._mobData._objects[_objNumber - 1];
|
|
||||||
|
|
||||||
for (int idx = 0; idx < 3; ++idx) {
|
|
||||||
DrawStruct &ds1 = _indoorList[INDOOR_INDEXES[idx]];
|
|
||||||
DrawStruct &ds2 = _indoorList[INDOOR_INDEXES[idx] + 1];
|
|
||||||
ds1._sprites = nullptr;
|
|
||||||
ds2._sprites = nullptr;
|
|
||||||
|
|
||||||
if (combat._charsArray1[idx]) {
|
|
||||||
int posIndex= combat._attackMonsters[1] && !combat._attackMonsters[2] ? 1 : 0;
|
|
||||||
--combat._charsArray1[idx];
|
|
||||||
|
|
||||||
if (combat._monPow[idx]) {
|
|
||||||
ds1._x = INDOOR_COMBAT_POS[idx][0];
|
|
||||||
ds1._frame = 0;
|
|
||||||
ds1._scale = combat._monsterScale[idx];
|
|
||||||
if (ds1._scale == 0x8000) {
|
|
||||||
ds1._x /= 3;
|
|
||||||
ds1._y = 60;
|
|
||||||
} else {
|
|
||||||
ds1._y = 73;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds1._flags = SPRFLAG_4000 | SPRFLAG_2000;
|
|
||||||
ds1._sprites = &_charPowSprites;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (combat._elemPow[idx]) {
|
|
||||||
ds2._x = INDOOR_COMBAT_POS[idx][posIndex] + INDOOR_COMBAT_POS2[idx];
|
|
||||||
ds2._frame = combat._elemPow[idx];
|
|
||||||
ds2._scale = combat._elemScale[idx];
|
|
||||||
if (ds2._scale == 0x8000)
|
|
||||||
ds2._x /= 3;
|
|
||||||
ds2._flags = SPRFLAG_4000 | SPRFLAG_2000;
|
|
||||||
ds2._sprites = &_charPowSprites;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setIndoorsMonsters();
|
|
||||||
setIndoorsObjects();
|
|
||||||
setIndoorsWallPics();
|
|
||||||
|
|
||||||
_indoorList[161]._sprites = nullptr;
|
|
||||||
_indoorList[160]._sprites = nullptr;
|
|
||||||
_indoorList[159]._sprites = nullptr;
|
|
||||||
|
|
||||||
// Handle attacking monsters
|
|
||||||
int monsterIndex = 0;
|
|
||||||
if (combat._attackMonsters[0] != -1 && map._mobData._monsters[combat._attackMonsters[0]]._frame >= 0) {
|
|
||||||
_indoorList[159] = _indoorList[156];
|
|
||||||
_indoorList[160] = _indoorList[157];
|
|
||||||
_indoorList[161] = _indoorList[158];
|
|
||||||
_indoorList[158]._sprites = nullptr;
|
|
||||||
_indoorList[156]._sprites = nullptr;
|
|
||||||
_indoorList[157]._sprites = nullptr;
|
|
||||||
monsterIndex = 1;
|
|
||||||
} else if (combat._attackMonsters[1] != -1 && map._mobData._monsters[combat._attackMonsters[1]]._frame >= 0) {
|
|
||||||
_indoorList[159] = _indoorList[150];
|
|
||||||
_indoorList[160] = _indoorList[151];
|
|
||||||
_indoorList[161] = _indoorList[152];
|
|
||||||
_indoorList[152]._sprites = nullptr;
|
|
||||||
_indoorList[151]._sprites = nullptr;
|
|
||||||
_indoorList[150]._sprites = nullptr;
|
|
||||||
monsterIndex = 2;
|
|
||||||
} else if (combat._attackMonsters[2] != -1 && map._mobData._monsters[combat._attackMonsters[2]]._frame >= 0) {
|
|
||||||
_indoorList[159] = _indoorList[153];
|
|
||||||
_indoorList[160] = _indoorList[154];
|
|
||||||
_indoorList[161] = _indoorList[155];
|
|
||||||
_indoorList[153]._sprites = nullptr;
|
|
||||||
_indoorList[154]._sprites = nullptr;
|
|
||||||
_indoorList[155]._sprites = nullptr;
|
|
||||||
monsterIndex = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawIndoors();
|
|
||||||
|
|
||||||
switch (monsterIndex) {
|
|
||||||
case 1:
|
|
||||||
_indoorList[156] = _indoorList[159];
|
|
||||||
_indoorList[157] = _indoorList[160];
|
|
||||||
_indoorList[158] = _indoorList[161];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
_indoorList[150] = _indoorList[159];
|
|
||||||
_indoorList[151] = _indoorList[160];
|
|
||||||
_indoorList[152] = _indoorList[161];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
_indoorList[153] = _indoorList[159];
|
|
||||||
_indoorList[154] = _indoorList[160];
|
|
||||||
_indoorList[155] = _indoorList[161];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
animate3d();
|
|
||||||
drawMiniMap();
|
|
||||||
|
|
||||||
if (party._falling == 1) {
|
|
||||||
error("TODO: Indoor falling");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (party._falling == 2) {
|
|
||||||
screen.saveBackground(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
assembleBorder();
|
|
||||||
|
|
||||||
// Draw any on-screen text if flagged to do so
|
|
||||||
if (_upDoorText && combat._attackMonsters[0] == -1) {
|
|
||||||
screen._windows[3].writeString(_screenText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateFlag) {
|
|
||||||
screen._windows[1].update();
|
|
||||||
screen._windows[3].update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: more stuff
|
|
||||||
|
|
||||||
_vm->_party->_stepped = false;
|
|
||||||
if (_vm->_mode == MODE_9) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
events.wait(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Interface::animate3d() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Interface::startup() {
|
void Interface::startup() {
|
||||||
Screen &screen = *_vm->_screen;
|
Screen &screen = *_vm->_screen;
|
||||||
loadCharIcons();
|
loadCharIcons();
|
||||||
|
@ -792,10 +434,6 @@ void Interface::mainIconsPrint() {
|
||||||
screen._windows[34].update();
|
screen._windows[34].update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::moveMonsters() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Interface::setMainButtons() {
|
void Interface::setMainButtons() {
|
||||||
clearButtons();
|
clearButtons();
|
||||||
|
|
||||||
|
@ -821,381 +459,6 @@ void Interface::setMainButtons() {
|
||||||
addButton(Common::Rect(239, 47, 312, 57), Common::KEYCODE_3, &_iconSprites, false);
|
addButton(Common::Rect(239, 47, 312, 57), Common::KEYCODE_3, &_iconSprites, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interface::drawMiniMap() {
|
|
||||||
Map &map = *_vm->_map;
|
|
||||||
Party &party = *_vm->_party;
|
|
||||||
Screen &screen = *_vm->_screen;
|
|
||||||
Window &window1 = screen._windows[1];
|
|
||||||
|
|
||||||
if (screen._windows[2]._enabled || screen._windows[10]._enabled)
|
|
||||||
return;
|
|
||||||
if (!party._automapOn && !party._wizardEyeActive) {
|
|
||||||
// Draw the Might & Magic logo
|
|
||||||
_globalSprites.draw(window1, 5, Common::Point(232, 9));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int v, frame;
|
|
||||||
int frame2 = _overallFrame * 2;
|
|
||||||
bool eyeActive = party._wizardEyeActive;
|
|
||||||
if (party._automapOn)
|
|
||||||
party._wizardEyeActive = false;
|
|
||||||
|
|
||||||
if (map._isOutdoors) {
|
|
||||||
_globalSprites.draw(window1, 15, Common::Point(237, 12));
|
|
||||||
|
|
||||||
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
|
||||||
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
|
||||||
4);
|
|
||||||
frame = map.mazeDataCurrent()._surfaceTypes[v];
|
|
||||||
|
|
||||||
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, frame, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
|
||||||
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
|
||||||
4);
|
|
||||||
frame = map.mazeData()._wallTypes[v];
|
|
||||||
|
|
||||||
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, frame + 16, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
|
||||||
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
|
||||||
4);
|
|
||||||
|
|
||||||
if (v != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, v + 32, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the direction arrow
|
|
||||||
_globalSprites.draw(window1, party._mazeDirection + 1,
|
|
||||||
Common::Point(267, 36));
|
|
||||||
} else {
|
|
||||||
frame2 = (frame2 + 2) % 8;
|
|
||||||
|
|
||||||
// First draw the default surface bases for each cell to show
|
|
||||||
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
|
||||||
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
|
||||||
0, 0xffff);
|
|
||||||
|
|
||||||
if (v != INVALID_CELL && (map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, 0, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw correct surface bases for revealed tiles
|
|
||||||
for (int rowNum = 0, yp = 17, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
|
||||||
for (int colNum = 0, xp = 242, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
|
||||||
0, 0xffff);
|
|
||||||
int surfaceId = map.mazeData()._surfaceTypes[map._currentSurfaceId];
|
|
||||||
|
|
||||||
if (v != INVALID_CELL && map._currentSurfaceId &&
|
|
||||||
(map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, surfaceId + 36, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v = map.mazeLookup(Common::Point(party._mazePosition.x - 4, party._mazePosition.y + 4), 0xffff, 0);
|
|
||||||
if (v != INVALID_CELL && map._currentSurfaceId &&
|
|
||||||
(map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1,
|
|
||||||
map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36,
|
|
||||||
Common::Point(232, 9));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle drawing surface sprites partially clipped at the left edge
|
|
||||||
for (int rowNum = 0, yp = 17, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, --yDiff, yp += 8) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x - 4, party._mazePosition.y + yDiff),
|
|
||||||
0, 0xffff);
|
|
||||||
|
|
||||||
if (v != INVALID_CELL && map._currentSurfaceId &&
|
|
||||||
(map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1,
|
|
||||||
map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36,
|
|
||||||
Common::Point(232, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle drawing surface sprites partially clipped at the top edge
|
|
||||||
for (int colNum = 0, xp = 242, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, ++xDiff, xp += 8) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + 4),
|
|
||||||
0, 0xffff);
|
|
||||||
|
|
||||||
if (v != INVALID_CELL && map._currentSurfaceId &&
|
|
||||||
(map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1,
|
|
||||||
map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36,
|
|
||||||
Common::Point(xp, 9));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
for (int idx = 0, xp = 237, yp = 60, xDiff = -3; idx < MINIMAP_SIZE;
|
|
||||||
++idx, ++xDiff, xp += 10, yp -= 8) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x - 4, party._mazePosition.y - 3 + idx),
|
|
||||||
12, 0xffff);
|
|
||||||
|
|
||||||
switch (v) {
|
|
||||||
case 1:
|
|
||||||
frame = 18;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
frame = 22;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 13:
|
|
||||||
frame = 16;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 8:
|
|
||||||
frame = 2;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
frame = 30;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
frame = 32;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
frame = 24;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
frame = 28;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
frame = 14;
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
frame = frame2 + 4;
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
frame = 24;
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
frame = 26;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
frame = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive))
|
|
||||||
map._tileSprites.draw(window1, frame, Common::Point(222, yp));
|
|
||||||
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x - 3 + idx, party._mazePosition.y + 4),
|
|
||||||
0);
|
|
||||||
|
|
||||||
switch (v) {
|
|
||||||
case 1:
|
|
||||||
frame = 19;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
frame = 35;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
frame = 23;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 13:
|
|
||||||
frame = 17;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 8:
|
|
||||||
frame = 3;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
frame = 31;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
frame = 33;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
frame = 21;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
frame = 29;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
frame = 15;
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
frame = frame2 + 5;
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
frame = 25;
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
frame = 27;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
frame = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive))
|
|
||||||
map._tileSprites.draw(window1, frame, Common::Point(xp, 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the front/back walls of cells in the minimap
|
|
||||||
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE;
|
|
||||||
++rowNum, --yDiff, yp += 8) {
|
|
||||||
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE;
|
|
||||||
++colNum, ++xDiff, xp += 10) {
|
|
||||||
if (colNum == 4 && rowNum == 4) {
|
|
||||||
// Center of the minimap. Draw the direction arrow
|
|
||||||
_globalSprites.draw(window1, party._mazeDirection + 1,
|
|
||||||
Common::Point(272, 40));
|
|
||||||
}
|
|
||||||
|
|
||||||
v = map.mazeLookup(Common::Point(party._mazePosition.x + xDiff,
|
|
||||||
party._mazePosition.y + yDiff), 12, 0xffff);
|
|
||||||
switch (v) {
|
|
||||||
case 1:
|
|
||||||
frame = 18;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
frame = 22;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 13:
|
|
||||||
frame = 16;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 8:
|
|
||||||
frame = 2;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
frame = 30;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
frame = 32;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
frame = 20;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
frame = 28;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
frame = 14;
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
frame = frame2 + 4;
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
frame = 24;
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
frame = 26;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
frame = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, frame, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
|
|
||||||
v = map.mazeLookup(Common::Point(party._mazePosition.x + xDiff,
|
|
||||||
party._mazePosition.y + yDiff), 12, 0xffff);
|
|
||||||
switch (v) {
|
|
||||||
case 1:
|
|
||||||
frame = 19;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
frame = 35;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
frame = 23;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 13:
|
|
||||||
frame = 17;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 8:
|
|
||||||
frame = 3;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
frame = 31;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
frame = 33;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
frame = 21;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
frame = 29;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
frame = 15;
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
frame = frame2 + 5;
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
frame = 25;
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
frame = 27;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
frame = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v == -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, frame, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the top of blocked/wall cells on the map
|
|
||||||
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
|
||||||
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
|
||||||
v = map.mazeLookup(
|
|
||||||
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
|
||||||
0, 0xffff);
|
|
||||||
|
|
||||||
if (v == INVALID_CELL || (!map._currentSteppedOn && !party._wizardEyeActive)) {
|
|
||||||
map._tileSprites.draw(window1, 1, Common::Point(xp, yp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw outer rectangle around the automap
|
|
||||||
_globalSprites.draw(window1, 6, Common::Point(223, 3));
|
|
||||||
party._wizardEyeActive = eyeActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for a keypress or click, whilst still allowing the game scene to
|
* Waits for a keypress or click, whilst still allowing the game scene to
|
||||||
* be animated.
|
* be animated.
|
||||||
|
|
|
@ -38,39 +38,19 @@ class XeenEngine;
|
||||||
class Interface: public ButtonContainer, public InterfaceMap {
|
class Interface: public ButtonContainer, public InterfaceMap {
|
||||||
private:
|
private:
|
||||||
XeenEngine *_vm;
|
XeenEngine *_vm;
|
||||||
SpriteResource _dseFace;
|
|
||||||
SpriteResource _globalSprites;
|
|
||||||
SpriteResource _borderSprites;
|
|
||||||
SpriteResource _spellFxSprites;
|
|
||||||
SpriteResource _fecpSprites;
|
|
||||||
SpriteResource _blessSprites;
|
|
||||||
SpriteResource _restoreSprites;
|
SpriteResource _restoreSprites;
|
||||||
|
SpriteResource _dseFace;
|
||||||
SpriteResource _hpSprites;
|
SpriteResource _hpSprites;
|
||||||
SpriteResource _uiSprites;
|
SpriteResource _uiSprites;
|
||||||
SpriteResource _iconSprites;
|
SpriteResource _iconSprites;
|
||||||
SpriteResource _charPowSprites;
|
|
||||||
SpriteResource _charFaces[TOTAL_CHARACTERS];
|
SpriteResource _charFaces[TOTAL_CHARACTERS];
|
||||||
SpriteResource *_partyFaces[MAX_ACTIVE_PARTY];
|
SpriteResource *_partyFaces[MAX_ACTIVE_PARTY];
|
||||||
DrawStruct _faceDrawStructs[4];
|
DrawStruct _faceDrawStructs[4];
|
||||||
DrawStruct _mainList[16];
|
DrawStruct _mainList[16];
|
||||||
int _combatCharIds[8];
|
int _combatCharIds[8];
|
||||||
|
|
||||||
int _batUIFrame;
|
|
||||||
int _spotDoorsUIFrame;
|
|
||||||
int _dangerSenseUIFrame;
|
|
||||||
int _face1UIFrame;
|
|
||||||
int _face2UIFrame;
|
|
||||||
int _blessedUIFrame;
|
|
||||||
int _powerShieldUIFrame;
|
|
||||||
int _holyBonusUIFrame;
|
|
||||||
int _heroismUIFrame;
|
|
||||||
int _flipUIFrame;
|
|
||||||
bool _buttonsLoaded;
|
bool _buttonsLoaded;
|
||||||
int _hiliteChar;
|
int _hiliteChar;
|
||||||
bool _flag1;
|
|
||||||
bool _isAnimReset;
|
|
||||||
byte _tillMove;
|
|
||||||
int _overallFrame;
|
|
||||||
int _steppingFX;
|
int _steppingFX;
|
||||||
Common::String _interfaceText;
|
Common::String _interfaceText;
|
||||||
|
|
||||||
|
@ -78,8 +58,6 @@ private:
|
||||||
|
|
||||||
void loadSprites();
|
void loadSprites();
|
||||||
|
|
||||||
void assembleBorder();
|
|
||||||
|
|
||||||
void setupBackground();
|
void setupBackground();
|
||||||
|
|
||||||
void setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag);
|
void setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool updateFlag);
|
||||||
|
@ -88,14 +66,8 @@ private:
|
||||||
|
|
||||||
void moveCharacterToRoster();
|
void moveCharacterToRoster();
|
||||||
|
|
||||||
void animate3d();
|
|
||||||
|
|
||||||
void moveMonsters();
|
|
||||||
|
|
||||||
void setMainButtons();
|
void setMainButtons();
|
||||||
|
|
||||||
void drawMiniMap();
|
|
||||||
|
|
||||||
void chargeStep();
|
void chargeStep();
|
||||||
|
|
||||||
void stepTime();
|
void stepTime();
|
||||||
|
@ -105,12 +77,12 @@ private:
|
||||||
bool checkMoveDirection(int key);
|
bool checkMoveDirection(int key);
|
||||||
public:
|
public:
|
||||||
int _intrIndex1;
|
int _intrIndex1;
|
||||||
Common::String _screenText;
|
|
||||||
bool _upDoorText;
|
|
||||||
public:
|
public:
|
||||||
Interface(XeenEngine *vm);
|
Interface(XeenEngine *vm);
|
||||||
|
|
||||||
void setup();
|
virtual ~Interface() {}
|
||||||
|
|
||||||
|
virtual void setup();
|
||||||
|
|
||||||
void manageCharacters(bool soundPlayed);
|
void manageCharacters(bool soundPlayed);
|
||||||
|
|
||||||
|
@ -118,8 +90,6 @@ public:
|
||||||
|
|
||||||
void loadPartyIcons();
|
void loadPartyIcons();
|
||||||
|
|
||||||
void draw3d(bool updateFlag);
|
|
||||||
|
|
||||||
void startup();
|
void startup();
|
||||||
|
|
||||||
void mainIconsPrint();
|
void mainIconsPrint();
|
||||||
|
|
|
@ -374,9 +374,266 @@ InterfaceMap::InterfaceMap(XeenEngine *vm): _vm(vm) {
|
||||||
_objNumber = 0;
|
_objNumber = 0;
|
||||||
_combatFloatCounter = 0;
|
_combatFloatCounter = 0;
|
||||||
_thinWall = false;
|
_thinWall = false;
|
||||||
|
_isAnimReset = false;
|
||||||
|
_upDoorText = false;
|
||||||
|
_batUIFrame = 0;
|
||||||
|
_spotDoorsUIFrame = 0;
|
||||||
|
_dangerSenseUIFrame = 0;
|
||||||
|
_face1UIFrame = 0;
|
||||||
|
_face2UIFrame = 0;
|
||||||
|
_blessedUIFrame = 0;
|
||||||
|
_powerShieldUIFrame = 0;
|
||||||
|
_holyBonusUIFrame = 0;
|
||||||
|
_heroismUIFrame = 0;
|
||||||
|
_flipUIFrame = 0;
|
||||||
|
_tillMove = 0;
|
||||||
|
_flag1 = false;
|
||||||
|
_overallFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterfaceMap::setup() {
|
||||||
|
_globalSprites.load("global.icn");
|
||||||
|
_borderSprites.load("border.icn");
|
||||||
|
_spellFxSprites.load("spellfx.icn");
|
||||||
|
_fecpSprites.load("fecp.brd");
|
||||||
|
_blessSprites.load("bless.icn");
|
||||||
|
_charPowSprites.load("charpow.icn");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceMap::draw3d(bool updateFlag) {
|
||||||
|
Combat &combat = *_vm->_combat;
|
||||||
|
EventsManager &events = *_vm->_events;
|
||||||
|
Map &map = *_vm->_map;
|
||||||
|
Party &party = *_vm->_party;
|
||||||
|
Screen &screen = *_vm->_screen;
|
||||||
|
Scripts &scripts = *_vm->_scripts;
|
||||||
|
|
||||||
|
if (screen._windows[11]._enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_flipUIFrame = (_flipUIFrame + 1) % 4;
|
||||||
|
if (_flipUIFrame == 0)
|
||||||
|
_flipWater = !_flipWater;
|
||||||
|
if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_2) &&
|
||||||
|
!_flag1 && _vm->_moveMonsters) {
|
||||||
|
if (--_tillMove == 0)
|
||||||
|
moveMonsters();
|
||||||
|
}
|
||||||
|
|
||||||
|
MazeObject &objObject = map._mobData._objects[_objNumber];
|
||||||
|
Direction partyDirection = _vm->_party->_mazeDirection;
|
||||||
|
int objNum = _objNumber - 1;
|
||||||
|
|
||||||
|
// Loop to update the frame numbers for each maze object, applying the animation frame
|
||||||
|
// limits as specified by the map's _animationInfo listing
|
||||||
|
for (uint idx = 0; idx < map._mobData._objects.size(); ++idx) {
|
||||||
|
MazeObject &mazeObject = map._mobData._objects[idx];
|
||||||
|
AnimationEntry &animEntry = map._animationInfo[mazeObject._spriteId];
|
||||||
|
int directionIndex = DIRECTION_ANIM_POSITIONS[mazeObject._direction][partyDirection];
|
||||||
|
|
||||||
|
if (_isAnimReset) {
|
||||||
|
mazeObject._frame = animEntry._frame1._frames[directionIndex];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++mazeObject._frame;
|
||||||
|
if ((int)idx == objNum && scripts._animCounter > 0 && (
|
||||||
|
objObject._spriteId == (_vm->_files->_isDarkCc ? 15 : 16) ||
|
||||||
|
objObject._spriteId == 58 || objObject._spriteId == 73)) {
|
||||||
|
if (mazeObject._frame > 4 || mazeObject._spriteId == 58)
|
||||||
|
mazeObject._frame = 1;
|
||||||
|
}
|
||||||
|
else if (mazeObject._frame >= animEntry._frame2._frames[directionIndex]) {
|
||||||
|
mazeObject._frame = animEntry._frame1._frames[directionIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mazeObject._flipped = animEntry._flipped._flags[directionIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map._isOutdoors) {
|
||||||
|
error("TODO: draw3d outdoors handling");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Default all the parts of draw struct not to be drawn by default
|
||||||
|
for (int idx = 3; idx < _indoorList.size(); ++idx)
|
||||||
|
_indoorList[idx]._frame = -1;
|
||||||
|
|
||||||
|
if (_flag1) {
|
||||||
|
for (int idx = 0; idx < 96; ++idx) {
|
||||||
|
if (_indoorList[79 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[79 + idx]._frame = 0;
|
||||||
|
}
|
||||||
|
else if (_indoorList[111 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[111 + idx]._frame = 1;
|
||||||
|
}
|
||||||
|
else if (_indoorList[135 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[135 + idx]._frame = 2;
|
||||||
|
}
|
||||||
|
else if (_indoorList[162 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[162 + idx]._frame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_charsShooting) {
|
||||||
|
for (int idx = 0; idx < 96; ++idx) {
|
||||||
|
if (_indoorList[162 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[162 + idx]._frame = 0;
|
||||||
|
}
|
||||||
|
else if (_indoorList[135 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[135 + idx]._frame = 1;
|
||||||
|
}
|
||||||
|
else if (_indoorList[111 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[111 + idx]._frame = 2;
|
||||||
|
}
|
||||||
|
else if (_indoorList[79 + idx]._sprites != nullptr) {
|
||||||
|
_indoorList[79 + idx]._frame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setMazeBits();
|
||||||
|
_isAnimReset = false;
|
||||||
|
const int INDOOR_INDEXES[3] = { 157, 151, 154 };
|
||||||
|
const int INDOOR_COMBAT_POS[3][2] = { { 102, 134 }, { 36, 67 }, { 161, 161 } };
|
||||||
|
const int INDOOR_COMBAT_POS2[4] = { 8, 6, 4, 2 };
|
||||||
|
|
||||||
|
// Double check this, since it's not being used?
|
||||||
|
//MazeObject &objObject = map._mobData._objects[_objNumber - 1];
|
||||||
|
|
||||||
|
for (int idx = 0; idx < 3; ++idx) {
|
||||||
|
DrawStruct &ds1 = _indoorList[INDOOR_INDEXES[idx]];
|
||||||
|
DrawStruct &ds2 = _indoorList[INDOOR_INDEXES[idx] + 1];
|
||||||
|
ds1._sprites = nullptr;
|
||||||
|
ds2._sprites = nullptr;
|
||||||
|
|
||||||
|
if (combat._charsArray1[idx]) {
|
||||||
|
int posIndex = combat._attackMonsters[1] && !combat._attackMonsters[2] ? 1 : 0;
|
||||||
|
--combat._charsArray1[idx];
|
||||||
|
|
||||||
|
if (combat._monPow[idx]) {
|
||||||
|
ds1._x = INDOOR_COMBAT_POS[idx][0];
|
||||||
|
ds1._frame = 0;
|
||||||
|
ds1._scale = combat._monsterScale[idx];
|
||||||
|
if (ds1._scale == 0x8000) {
|
||||||
|
ds1._x /= 3;
|
||||||
|
ds1._y = 60;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ds1._y = 73;
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1._flags = SPRFLAG_4000 | SPRFLAG_2000;
|
||||||
|
ds1._sprites = &_charPowSprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (combat._elemPow[idx]) {
|
||||||
|
ds2._x = INDOOR_COMBAT_POS[idx][posIndex] + INDOOR_COMBAT_POS2[idx];
|
||||||
|
ds2._frame = combat._elemPow[idx];
|
||||||
|
ds2._scale = combat._elemScale[idx];
|
||||||
|
if (ds2._scale == 0x8000)
|
||||||
|
ds2._x /= 3;
|
||||||
|
ds2._flags = SPRFLAG_4000 | SPRFLAG_2000;
|
||||||
|
ds2._sprites = &_charPowSprites;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setIndoorsMonsters();
|
||||||
|
setIndoorsObjects();
|
||||||
|
setIndoorsWallPics();
|
||||||
|
|
||||||
|
_indoorList[161]._sprites = nullptr;
|
||||||
|
_indoorList[160]._sprites = nullptr;
|
||||||
|
_indoorList[159]._sprites = nullptr;
|
||||||
|
|
||||||
|
// Handle attacking monsters
|
||||||
|
int monsterIndex = 0;
|
||||||
|
if (combat._attackMonsters[0] != -1 && map._mobData._monsters[combat._attackMonsters[0]]._frame >= 0) {
|
||||||
|
_indoorList[159] = _indoorList[156];
|
||||||
|
_indoorList[160] = _indoorList[157];
|
||||||
|
_indoorList[161] = _indoorList[158];
|
||||||
|
_indoorList[158]._sprites = nullptr;
|
||||||
|
_indoorList[156]._sprites = nullptr;
|
||||||
|
_indoorList[157]._sprites = nullptr;
|
||||||
|
monsterIndex = 1;
|
||||||
|
}
|
||||||
|
else if (combat._attackMonsters[1] != -1 && map._mobData._monsters[combat._attackMonsters[1]]._frame >= 0) {
|
||||||
|
_indoorList[159] = _indoorList[150];
|
||||||
|
_indoorList[160] = _indoorList[151];
|
||||||
|
_indoorList[161] = _indoorList[152];
|
||||||
|
_indoorList[152]._sprites = nullptr;
|
||||||
|
_indoorList[151]._sprites = nullptr;
|
||||||
|
_indoorList[150]._sprites = nullptr;
|
||||||
|
monsterIndex = 2;
|
||||||
|
}
|
||||||
|
else if (combat._attackMonsters[2] != -1 && map._mobData._monsters[combat._attackMonsters[2]]._frame >= 0) {
|
||||||
|
_indoorList[159] = _indoorList[153];
|
||||||
|
_indoorList[160] = _indoorList[154];
|
||||||
|
_indoorList[161] = _indoorList[155];
|
||||||
|
_indoorList[153]._sprites = nullptr;
|
||||||
|
_indoorList[154]._sprites = nullptr;
|
||||||
|
_indoorList[155]._sprites = nullptr;
|
||||||
|
monsterIndex = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawIndoors();
|
||||||
|
|
||||||
|
switch (monsterIndex) {
|
||||||
|
case 1:
|
||||||
|
_indoorList[156] = _indoorList[159];
|
||||||
|
_indoorList[157] = _indoorList[160];
|
||||||
|
_indoorList[158] = _indoorList[161];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_indoorList[150] = _indoorList[159];
|
||||||
|
_indoorList[151] = _indoorList[160];
|
||||||
|
_indoorList[152] = _indoorList[161];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_indoorList[153] = _indoorList[159];
|
||||||
|
_indoorList[154] = _indoorList[160];
|
||||||
|
_indoorList[155] = _indoorList[161];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate3d();
|
||||||
|
drawMiniMap();
|
||||||
|
|
||||||
|
if (party._falling == 1) {
|
||||||
|
error("TODO: Indoor falling");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (party._falling == 2) {
|
||||||
|
screen.saveBackground(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assembleBorder();
|
||||||
|
|
||||||
|
// Draw any on-screen text if flagged to do so
|
||||||
|
if (_upDoorText && combat._attackMonsters[0] == -1) {
|
||||||
|
screen._windows[3].writeString(_screenText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateFlag) {
|
||||||
|
screen._windows[1].update();
|
||||||
|
screen._windows[3].update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: more stuff
|
||||||
|
|
||||||
|
_vm->_party->_stepped = false;
|
||||||
|
if (_vm->_mode == MODE_9) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
events.wait(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceMap::animate3d() {
|
||||||
|
|
||||||
|
}
|
||||||
void InterfaceMap::setMazeBits() {
|
void InterfaceMap::setMazeBits() {
|
||||||
Common::fill(&_wo[0], &_wo[308], 0);
|
Common::fill(&_wo[0], &_wo[308], 0);
|
||||||
|
|
||||||
|
@ -3453,4 +3710,491 @@ void InterfaceMap::drawIndoors() {
|
||||||
_charsShooting = _isShooting;
|
_charsShooting = _isShooting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterfaceMap::moveMonsters() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceMap::assembleBorder() {
|
||||||
|
Screen &screen = *_vm->_screen;
|
||||||
|
|
||||||
|
// Draw the outer frame
|
||||||
|
_globalSprites.draw(screen._windows[0], 0, Common::Point(8, 8));
|
||||||
|
|
||||||
|
// Draw the animating bat character used to show when levitate is active
|
||||||
|
_borderSprites.draw(screen._windows[0], _vm->_party->_levitateActive ? _batUIFrame + 16 : 16,
|
||||||
|
Common::Point(0, 82));
|
||||||
|
_batUIFrame = (_batUIFrame + 1) % 12;
|
||||||
|
|
||||||
|
// Draw UI element to indicate whether can spot hidden doors
|
||||||
|
_borderSprites.draw(screen,
|
||||||
|
(_thinWall && _vm->_party->checkSkill(SPOT_DOORS)) ? _spotDoorsUIFrame + 28 : 28,
|
||||||
|
Common::Point(194, 91));
|
||||||
|
_spotDoorsUIFrame = (_spotDoorsUIFrame + 1) % 12;
|
||||||
|
|
||||||
|
// Draw UI element to indicate whether can sense danger
|
||||||
|
_borderSprites.draw(screen,
|
||||||
|
(_vm->_dangerSenseAllowed && _vm->_party->checkSkill(DANGER_SENSE)) ? _spotDoorsUIFrame + 40 : 40,
|
||||||
|
Common::Point(107, 9));
|
||||||
|
_dangerSenseUIFrame = (_dangerSenseUIFrame + 1) % 12;
|
||||||
|
|
||||||
|
// Handle the face UI elements for indicating clairvoyance status
|
||||||
|
_face1UIFrame = (_face1UIFrame + 1) % 4;
|
||||||
|
if (_vm->_face1State == 0)
|
||||||
|
_face1UIFrame += 4;
|
||||||
|
else if (_vm->_face1State == 2)
|
||||||
|
_face1UIFrame = 0;
|
||||||
|
|
||||||
|
_face2UIFrame = (_face2UIFrame + 1) % 4 + 12;
|
||||||
|
if (_vm->_face2State == 0)
|
||||||
|
_face2UIFrame += 252;
|
||||||
|
else if (_vm->_face2State == 2)
|
||||||
|
_face2UIFrame = 0;
|
||||||
|
|
||||||
|
if (!_vm->_party->_clairvoyanceActive) {
|
||||||
|
_face1UIFrame = 0;
|
||||||
|
_face2UIFrame = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
_borderSprites.draw(screen, _face1UIFrame, Common::Point(0, 32));
|
||||||
|
_borderSprites.draw(screen,
|
||||||
|
screen._windows[10]._enabled || screen._windows[2]._enabled ?
|
||||||
|
52 : _face2UIFrame,
|
||||||
|
Common::Point(215, 32));
|
||||||
|
|
||||||
|
// Draw resistence indicators
|
||||||
|
if (!screen._windows[10]._enabled && !screen._windows[2]._enabled
|
||||||
|
&& screen._windows[38]._enabled) {
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_fireResistence ? 1 : 0,
|
||||||
|
Common::Point(2, 2));
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_electricityResistence ? 3 : 2,
|
||||||
|
Common::Point(219, 2));
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_coldResistence ? 5 : 4,
|
||||||
|
Common::Point(2, 134));
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_poisonResistence ? 7 : 6,
|
||||||
|
Common::Point(219, 134));
|
||||||
|
} else {
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_fireResistence ? 9 : 8,
|
||||||
|
Common::Point(8, 8));
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_electricityResistence ? 10 : 11,
|
||||||
|
Common::Point(219, 8));
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_coldResistence ? 12 : 13,
|
||||||
|
Common::Point(8, 134));
|
||||||
|
_fecpSprites.draw(screen, _vm->_party->_poisonResistence ? 14 : 15,
|
||||||
|
Common::Point(219, 134));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw UI element for blessed
|
||||||
|
_blessSprites.draw(screen, 16, Common::Point(33, 137));
|
||||||
|
if (_vm->_party->_blessedActive) {
|
||||||
|
_blessedUIFrame = (_blessedUIFrame + 1) % 4;
|
||||||
|
_blessSprites.draw(screen, _blessedUIFrame, Common::Point(33, 137));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw UI element for power shield
|
||||||
|
if (_vm->_party->_powerShieldActive) {
|
||||||
|
_powerShieldUIFrame = (_powerShieldUIFrame + 1) % 4;
|
||||||
|
_blessSprites.draw(screen, _powerShieldUIFrame + 4,
|
||||||
|
Common::Point(55, 137));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw UI element for holy bonus
|
||||||
|
if (_vm->_party->_holyBonusActive) {
|
||||||
|
_holyBonusUIFrame = (_holyBonusUIFrame + 1) % 4;
|
||||||
|
_blessSprites.draw(screen, _holyBonusUIFrame + 8, Common::Point(160, 137));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw UI element for heroism
|
||||||
|
if (_vm->_party->_heroismActive) {
|
||||||
|
_heroismUIFrame = (_heroismUIFrame + 1) % 4;
|
||||||
|
_blessSprites.draw(screen, _heroismUIFrame + 12, Common::Point(182, 137));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw direction character if direction sense is active
|
||||||
|
if (_vm->_party->checkSkill(DIRECTION_SENSE) && !_vm->_noDirectionSense) {
|
||||||
|
const char *dirText = DIRECTION_TEXT[_vm->_party->_mazeDirection];
|
||||||
|
Common::String msg = Common::String::format(
|
||||||
|
"\002""08\003""c\013""139\011""116%c\014""d\001", *dirText);
|
||||||
|
screen._windows[0].writeString(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw view frame
|
||||||
|
if (screen._windows[12]._enabled)
|
||||||
|
screen._windows[12].frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceMap::drawMiniMap() {
|
||||||
|
Map &map = *_vm->_map;
|
||||||
|
Party &party = *_vm->_party;
|
||||||
|
Screen &screen = *_vm->_screen;
|
||||||
|
Window &window1 = screen._windows[1];
|
||||||
|
|
||||||
|
if (screen._windows[2]._enabled || screen._windows[10]._enabled)
|
||||||
|
return;
|
||||||
|
if (!party._automapOn && !party._wizardEyeActive) {
|
||||||
|
// Draw the Might & Magic logo
|
||||||
|
_globalSprites.draw(window1, 5, Common::Point(232, 9));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v, frame;
|
||||||
|
int frame2 = _overallFrame * 2;
|
||||||
|
bool eyeActive = party._wizardEyeActive;
|
||||||
|
if (party._automapOn)
|
||||||
|
party._wizardEyeActive = false;
|
||||||
|
|
||||||
|
if (map._isOutdoors) {
|
||||||
|
_globalSprites.draw(window1, 15, Common::Point(237, 12));
|
||||||
|
|
||||||
|
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
||||||
|
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
||||||
|
4);
|
||||||
|
frame = map.mazeDataCurrent()._surfaceTypes[v];
|
||||||
|
|
||||||
|
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, frame, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
||||||
|
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
||||||
|
4);
|
||||||
|
frame = map.mazeData()._wallTypes[v];
|
||||||
|
|
||||||
|
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, frame + 16, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
||||||
|
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
||||||
|
4);
|
||||||
|
|
||||||
|
if (v != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, v + 32, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the direction arrow
|
||||||
|
_globalSprites.draw(window1, party._mazeDirection + 1,
|
||||||
|
Common::Point(267, 36));
|
||||||
|
} else {
|
||||||
|
frame2 = (frame2 + 2) % 8;
|
||||||
|
|
||||||
|
// First draw the default surface bases for each cell to show
|
||||||
|
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
||||||
|
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
||||||
|
0, 0xffff);
|
||||||
|
|
||||||
|
if (v != INVALID_CELL && (map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, 0, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw correct surface bases for revealed tiles
|
||||||
|
for (int rowNum = 0, yp = 17, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
||||||
|
for (int colNum = 0, xp = 242, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
||||||
|
0, 0xffff);
|
||||||
|
int surfaceId = map.mazeData()._surfaceTypes[map._currentSurfaceId];
|
||||||
|
|
||||||
|
if (v != INVALID_CELL && map._currentSurfaceId &&
|
||||||
|
(map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, surfaceId + 36, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v = map.mazeLookup(Common::Point(party._mazePosition.x - 4, party._mazePosition.y + 4), 0xffff, 0);
|
||||||
|
if (v != INVALID_CELL && map._currentSurfaceId &&
|
||||||
|
(map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1,
|
||||||
|
map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36,
|
||||||
|
Common::Point(232, 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle drawing surface sprites partially clipped at the left edge
|
||||||
|
for (int rowNum = 0, yp = 17, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, --yDiff, yp += 8) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x - 4, party._mazePosition.y + yDiff),
|
||||||
|
0, 0xffff);
|
||||||
|
|
||||||
|
if (v != INVALID_CELL && map._currentSurfaceId &&
|
||||||
|
(map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1,
|
||||||
|
map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36,
|
||||||
|
Common::Point(232, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle drawing surface sprites partially clipped at the top edge
|
||||||
|
for (int colNum = 0, xp = 242, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, ++xDiff, xp += 8) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + 4),
|
||||||
|
0, 0xffff);
|
||||||
|
|
||||||
|
if (v != INVALID_CELL && map._currentSurfaceId &&
|
||||||
|
(map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1,
|
||||||
|
map.mazeData()._surfaceTypes[map._currentSurfaceId] + 36,
|
||||||
|
Common::Point(xp, 9));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int idx = 0, xp = 237, yp = 60, xDiff = -3; idx < MINIMAP_SIZE;
|
||||||
|
++idx, ++xDiff, xp += 10, yp -= 8) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x - 4, party._mazePosition.y - 3 + idx),
|
||||||
|
12, 0xffff);
|
||||||
|
|
||||||
|
switch (v) {
|
||||||
|
case 1:
|
||||||
|
frame = 18;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
frame = 22;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 13:
|
||||||
|
frame = 16;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 8:
|
||||||
|
frame = 2;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
frame = 30;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
frame = 32;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
frame = 24;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
frame = 28;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
frame = 14;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
frame = frame2 + 4;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
frame = 24;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
frame = 26;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
frame = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive))
|
||||||
|
map._tileSprites.draw(window1, frame, Common::Point(222, yp));
|
||||||
|
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x - 3 + idx, party._mazePosition.y + 4),
|
||||||
|
0);
|
||||||
|
|
||||||
|
switch (v) {
|
||||||
|
case 1:
|
||||||
|
frame = 19;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
frame = 35;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
frame = 23;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 13:
|
||||||
|
frame = 17;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 8:
|
||||||
|
frame = 3;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
frame = 31;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
frame = 33;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
frame = 21;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
frame = 29;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
frame = 15;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
frame = frame2 + 5;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
frame = 25;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
frame = 27;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
frame = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive))
|
||||||
|
map._tileSprites.draw(window1, frame, Common::Point(xp, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the front/back walls of cells in the minimap
|
||||||
|
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE;
|
||||||
|
++rowNum, --yDiff, yp += 8) {
|
||||||
|
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE;
|
||||||
|
++colNum, ++xDiff, xp += 10) {
|
||||||
|
if (colNum == 4 && rowNum == 4) {
|
||||||
|
// Center of the minimap. Draw the direction arrow
|
||||||
|
_globalSprites.draw(window1, party._mazeDirection + 1,
|
||||||
|
Common::Point(272, 40));
|
||||||
|
}
|
||||||
|
|
||||||
|
v = map.mazeLookup(Common::Point(party._mazePosition.x + xDiff,
|
||||||
|
party._mazePosition.y + yDiff), 12, 0xffff);
|
||||||
|
switch (v) {
|
||||||
|
case 1:
|
||||||
|
frame = 18;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
frame = 22;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 13:
|
||||||
|
frame = 16;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 8:
|
||||||
|
frame = 2;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
frame = 30;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
frame = 32;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
frame = 20;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
frame = 28;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
frame = 14;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
frame = frame2 + 4;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
frame = 24;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
frame = 26;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
frame = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame != -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, frame, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
|
||||||
|
v = map.mazeLookup(Common::Point(party._mazePosition.x + xDiff,
|
||||||
|
party._mazePosition.y + yDiff), 12, 0xffff);
|
||||||
|
switch (v) {
|
||||||
|
case 1:
|
||||||
|
frame = 19;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
frame = 35;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
frame = 23;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 13:
|
||||||
|
frame = 17;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 8:
|
||||||
|
frame = 3;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
frame = 31;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
frame = 33;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
frame = 21;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
frame = 29;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
frame = 15;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
frame = frame2 + 5;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
frame = 25;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
frame = 27;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
frame = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v == -1 && (map._currentSteppedOn || party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, frame, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the top of blocked/wall cells on the map
|
||||||
|
for (int rowNum = 0, yp = 12, yDiff = 3; rowNum < MINIMAP_SIZE; ++rowNum, yp += 8, --yDiff) {
|
||||||
|
for (int colNum = 0, xp = 237, xDiff = -3; colNum < MINIMAP_SIZE; ++colNum, xp += 10, ++xDiff) {
|
||||||
|
v = map.mazeLookup(
|
||||||
|
Common::Point(party._mazePosition.x + xDiff, party._mazePosition.y + yDiff),
|
||||||
|
0, 0xffff);
|
||||||
|
|
||||||
|
if (v == INVALID_CELL || (!map._currentSteppedOn && !party._wizardEyeActive)) {
|
||||||
|
map._tileSprites.draw(window1, 1, Common::Point(xp, yp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw outer rectangle around the automap
|
||||||
|
_globalSprites.draw(window1, 6, Common::Point(223, 3));
|
||||||
|
party._wizardEyeActive = eyeActive;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Xeen
|
} // End of namespace Xeen
|
||||||
|
|
|
@ -83,6 +83,11 @@ public:
|
||||||
class InterfaceMap {
|
class InterfaceMap {
|
||||||
private:
|
private:
|
||||||
XeenEngine *_vm;
|
XeenEngine *_vm;
|
||||||
|
SpriteResource _borderSprites;
|
||||||
|
SpriteResource _spellFxSprites;
|
||||||
|
SpriteResource _fecpSprites;
|
||||||
|
SpriteResource _blessSprites;
|
||||||
|
SpriteResource _charPowSprites;
|
||||||
int _combatFloatCounter;
|
int _combatFloatCounter;
|
||||||
|
|
||||||
void initDrawStructs();
|
void initDrawStructs();
|
||||||
|
@ -90,9 +95,9 @@ private:
|
||||||
void setMonsterSprite(DrawStruct &drawStruct, MazeMonster &monster,
|
void setMonsterSprite(DrawStruct &drawStruct, MazeMonster &monster,
|
||||||
SpriteResource *sprites, int frame, int defaultY);
|
SpriteResource *sprites, int frame, int defaultY);
|
||||||
protected:
|
protected:
|
||||||
|
SpriteResource _globalSprites;
|
||||||
int8 _wp[20];
|
int8 _wp[20];
|
||||||
byte _wo[308];
|
byte _wo[308];
|
||||||
int _overallFrame;
|
|
||||||
bool _flipWater;
|
bool _flipWater;
|
||||||
bool _flipGround;
|
bool _flipGround;
|
||||||
bool _flipSky;
|
bool _flipSky;
|
||||||
|
@ -101,14 +106,44 @@ protected:
|
||||||
bool _charsShooting;
|
bool _charsShooting;
|
||||||
int _objNumber;
|
int _objNumber;
|
||||||
bool _thinWall;
|
bool _thinWall;
|
||||||
|
bool _isAnimReset;
|
||||||
|
int _batUIFrame;
|
||||||
|
int _spotDoorsUIFrame;
|
||||||
|
int _dangerSenseUIFrame;
|
||||||
|
int _face1UIFrame;
|
||||||
|
int _face2UIFrame;
|
||||||
|
int _blessedUIFrame;
|
||||||
|
int _powerShieldUIFrame;
|
||||||
|
int _holyBonusUIFrame;
|
||||||
|
int _heroismUIFrame;
|
||||||
|
int _flipUIFrame;
|
||||||
|
byte _tillMove;
|
||||||
|
bool _flag1;
|
||||||
|
int _overallFrame;
|
||||||
|
|
||||||
void setMazeBits();
|
void setMazeBits();
|
||||||
|
|
||||||
|
void animate3d();
|
||||||
|
|
||||||
|
void moveMonsters();
|
||||||
|
|
||||||
|
void drawMiniMap();
|
||||||
|
|
||||||
|
void assembleBorder();
|
||||||
|
|
||||||
|
virtual void setup();
|
||||||
public:
|
public:
|
||||||
OutdoorDrawList _outdoorList;
|
OutdoorDrawList _outdoorList;
|
||||||
IndoorDrawList _indoorList;
|
IndoorDrawList _indoorList;
|
||||||
|
bool _upDoorText;
|
||||||
|
Common::String _screenText;
|
||||||
public:
|
public:
|
||||||
InterfaceMap(XeenEngine *vm);
|
InterfaceMap(XeenEngine *vm);
|
||||||
|
|
||||||
|
virtual ~InterfaceMap() {}
|
||||||
|
|
||||||
|
void draw3d(bool updateFlag);
|
||||||
|
|
||||||
void setIndoorsMonsters();
|
void setIndoorsMonsters();
|
||||||
|
|
||||||
void setIndoorsObjects();
|
void setIndoorsObjects();
|
||||||
|
|
|
@ -129,7 +129,7 @@ void Scripts::checkEvents() {
|
||||||
_vm->_mode = MODE_9;
|
_vm->_mode = MODE_9;
|
||||||
_paramText = event._parameters.size() == 0 ? "" :
|
_paramText = event._parameters.size() == 0 ? "" :
|
||||||
map._events._text[event._parameters[0]];
|
map._events._text[event._parameters[0]];
|
||||||
doOpcode(event._opcode, event._parameters);
|
doOpcode(event);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
var50 = true;
|
var50 = true;
|
||||||
|
@ -154,7 +154,10 @@ void Scripts::openGrate(int v1, int v2) {
|
||||||
|
|
||||||
typedef void(Scripts::*ScriptMethodPtr)(Common::Array<byte> &);
|
typedef void(Scripts::*ScriptMethodPtr)(Common::Array<byte> &);
|
||||||
|
|
||||||
void Scripts::doOpcode(Opcode opcode, Common::Array<byte> ¶ms) {
|
/**
|
||||||
|
* Handles executing a given script command
|
||||||
|
*/
|
||||||
|
void Scripts::doOpcode(MazeEvent &event) {
|
||||||
static const ScriptMethodPtr COMMAND_LIST[] = {
|
static const ScriptMethodPtr COMMAND_LIST[] = {
|
||||||
nullptr, &Scripts::cmdDisplay1, &Scripts::cmdDoorTextSml,
|
nullptr, &Scripts::cmdDisplay1, &Scripts::cmdDoorTextSml,
|
||||||
&Scripts::cmdDoorTextLrg, &Scripts::cmdSignText,
|
&Scripts::cmdDoorTextLrg, &Scripts::cmdSignText,
|
||||||
|
@ -180,7 +183,8 @@ void Scripts::doOpcode(Opcode opcode, Common::Array<byte> ¶ms) {
|
||||||
&Scripts::cmdCutsceneEdWorld, &Scripts::cmdFlipWorld, &Scripts::cmdPlayCD
|
&Scripts::cmdCutsceneEdWorld, &Scripts::cmdFlipWorld, &Scripts::cmdPlayCD
|
||||||
};
|
};
|
||||||
|
|
||||||
(this->*COMMAND_LIST[opcode])(params);
|
_event = &event;
|
||||||
|
(this->*COMMAND_LIST[event._opcode])(event._parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,8 +213,8 @@ void Scripts::cmdDoorTextSml(Common::Array<byte> ¶ms) {
|
||||||
_paramText.c_str());
|
_paramText.c_str());
|
||||||
intf._upDoorText = true;
|
intf._upDoorText = true;
|
||||||
intf.draw3d(true);
|
intf.draw3d(true);
|
||||||
_var4F = true;
|
|
||||||
|
|
||||||
|
_var4F = true;
|
||||||
cmdNoAction(params);
|
cmdNoAction(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,16 +227,52 @@ void Scripts::cmdDoorTextLrg(Common::Array<byte> ¶ms) {
|
||||||
_paramText.c_str());
|
_paramText.c_str());
|
||||||
intf._upDoorText = true;
|
intf._upDoorText = true;
|
||||||
intf.draw3d(true);
|
intf.draw3d(true);
|
||||||
_var4F = true;
|
|
||||||
|
|
||||||
|
_var4F = true;
|
||||||
cmdNoAction(params);
|
cmdNoAction(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scripts::cmdSignText(Common::Array<byte> ¶ms) {}
|
void Scripts::cmdSignText(Common::Array<byte> ¶ms) {
|
||||||
void Scripts::cmdNPC(Common::Array<byte> ¶ms) {}
|
Interface &intf = *_vm->_interface;
|
||||||
void Scripts::cmdPlayFX(Common::Array<byte> ¶ms) {}
|
intf._screenText = Common::String::format("\f08\x03""c\t120\v088%s\x03""l\fd",
|
||||||
void Scripts::cmdTeleport(Common::Array<byte> ¶ms) {}
|
_paramText.c_str());
|
||||||
void Scripts::cmdIf(Common::Array<byte> ¶ms) {}
|
intf._upDoorText = true;
|
||||||
|
intf.draw3d(true);
|
||||||
|
|
||||||
|
_var4F = true;
|
||||||
|
cmdNoAction(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripts::cmdNPC(Common::Array<byte> ¶ms) {
|
||||||
|
warning("TODO: cmdNPC");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripts::cmdPlayFX(Common::Array<byte> ¶ms) {
|
||||||
|
_vm->_sound->playFX(params[0]);
|
||||||
|
|
||||||
|
_var4F = true;
|
||||||
|
cmdNoAction(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripts::cmdTeleport(Common::Array<byte> ¶ms) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripts::cmdIf(Common::Array<byte> ¶ms) {
|
||||||
|
switch (params[0]) {
|
||||||
|
case 16:
|
||||||
|
case 34:
|
||||||
|
case 100:
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
case 35:
|
||||||
|
case 101:
|
||||||
|
case 106:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Scripts::cmdMoveObj(Common::Array<byte> ¶ms) {}
|
void Scripts::cmdMoveObj(Common::Array<byte> ¶ms) {}
|
||||||
void Scripts::cmdTakeOrGive(Common::Array<byte> ¶ms) {}
|
void Scripts::cmdTakeOrGive(Common::Array<byte> ¶ms) {}
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,9 @@ private:
|
||||||
int _var4F;
|
int _var4F;
|
||||||
int _nEdamageType;
|
int _nEdamageType;
|
||||||
Common::String _paramText;
|
Common::String _paramText;
|
||||||
|
MazeEvent *_event;
|
||||||
|
|
||||||
void doOpcode(Opcode opcode, Common::Array<byte> ¶ms);
|
void doOpcode(MazeEvent &event);
|
||||||
void cmdDisplay1(Common::Array<byte> ¶ms);
|
void cmdDisplay1(Common::Array<byte> ¶ms);
|
||||||
void cmdDoorTextSml(Common::Array<byte> ¶ms);
|
void cmdDoorTextSml(Common::Array<byte> ¶ms);
|
||||||
void cmdDoorTextLrg(Common::Array<byte> ¶ms);
|
void cmdDoorTextLrg(Common::Array<byte> ¶ms);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue