mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
ULTIMA1: Added direction selection for spell casting
This commit is contained in:
committed by
Paul Gilbert
parent
a9c9c3939a
commit
10f6bb9206
@@ -26,6 +26,7 @@
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
#include "common/serializer.h"
|
||||
#include "ultima/shared/core/named_item.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Shared {
|
||||
@@ -97,9 +98,7 @@ public:
|
||||
/**
|
||||
* Spell entry
|
||||
*/
|
||||
class Spell : public Itemized {
|
||||
public:
|
||||
Common::String _name;
|
||||
class Spell : public Itemized, public NamedItem {
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -34,7 +34,7 @@ BEGIN_MESSAGE_MAP(CharacterInput, Popup)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CharacterInput::show(const Point &pt, byte color, TreeItem *respondTo) {
|
||||
Popup::show(_respondTo);
|
||||
Popup::show(respondTo);
|
||||
_color = color;
|
||||
_bounds = Rect(pt.x, pt.y, pt.x + 8, pt.y + 8);
|
||||
|
||||
@@ -43,16 +43,10 @@ void CharacterInput::show(const Point &pt, byte color, TreeItem *respondTo) {
|
||||
}
|
||||
|
||||
bool CharacterInput::KeypressMsg(CKeypressMsg &msg) {
|
||||
uint16 c = msg._keyState.ascii;
|
||||
hide();
|
||||
|
||||
if (msg._keyState.keycode == Common::KEYCODE_ESCAPE) {
|
||||
CTextInputMsg inputMsg("", true);
|
||||
inputMsg.execute(_respondTo);
|
||||
} else if (c >= ' ' && c <= 0x7f) {
|
||||
// Printable character
|
||||
CTextInputMsg inputMsg(Common::String(c), false);
|
||||
inputMsg.execute(_respondTo);
|
||||
}
|
||||
CCharacterInputMsg inputMsg(msg._keyState);
|
||||
inputMsg.execute(_respondTo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,29 @@ namespace Maps {
|
||||
|
||||
EMPTY_MESSAGE_MAP(MapWidget, MessageTarget);
|
||||
|
||||
Direction MapWidget::directionFromKey(Common::KeyCode keycode) {
|
||||
switch (keycode) {
|
||||
case Common::KEYCODE_LEFT:
|
||||
case Common::KEYCODE_KP4:
|
||||
return DIR_WEST;
|
||||
|
||||
case Common::KEYCODE_RIGHT:
|
||||
case Common::KEYCODE_KP6:
|
||||
return DIR_EAST;
|
||||
|
||||
case Common::KEYCODE_UP:
|
||||
case Common::KEYCODE_KP8:
|
||||
return DIR_NORTH;
|
||||
|
||||
case Common::KEYCODE_DOWN:
|
||||
case Common::KEYCODE_KP2:
|
||||
return DIR_SOUTH;
|
||||
|
||||
default:
|
||||
return DIR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void MapWidget::synchronize(Common::Serializer &s) {
|
||||
s.syncAsUint16LE(_position.x);
|
||||
s.syncAsSint16LE(_position.y);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef ULTIMA_SHARED_MAPS_MAP_WIDGET_H
|
||||
#define ULTIMA_SHARED_MAPS_MAP_WIDGET_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/ptr.h"
|
||||
#include "common/serializer.h"
|
||||
#include "common/str.h"
|
||||
@@ -56,6 +57,11 @@ public:
|
||||
Point _position; // Position within the map
|
||||
Direction _direction; // Direction
|
||||
Common::String _name; // Name of widget
|
||||
public:
|
||||
/**
|
||||
* Support method to get a direction from a keycode
|
||||
*/
|
||||
static Direction directionFromKey(Common::KeyCode keycode);
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
|
||||
@@ -28,6 +28,18 @@ namespace Ultima1 {
|
||||
namespace Actions {
|
||||
|
||||
#define MAP_ACTION(NAME, ACTION_NUM, MAP_METHOD) \
|
||||
using Shared::C##NAME##Msg; \
|
||||
class NAME : public Action { DECLARE_MESSAGE_MAP; bool NAME##Msg(C##NAME##Msg &msg) { \
|
||||
addInfoMsg(getRes()->ACTION_NAMES[ACTION_NUM], false); \
|
||||
getMap()->MAP_METHOD(); \
|
||||
return true; } \
|
||||
public: \
|
||||
CLASSDEF; \
|
||||
NAME(TreeItem *parent) : Action(parent) {} \
|
||||
}; \
|
||||
BEGIN_MESSAGE_MAP(NAME, Action) ON_MESSAGE(NAME##Msg) END_MESSAGE_MAP()
|
||||
|
||||
#define MAP_ACTION_END_TURN(NAME, ACTION_NUM, MAP_METHOD) \
|
||||
using Shared::C##NAME##Msg; \
|
||||
class NAME : public Action { DECLARE_MESSAGE_MAP; bool NAME##Msg(C##NAME##Msg &msg) { \
|
||||
addInfoMsg(getRes()->ACTION_NAMES[ACTION_NUM], false); \
|
||||
|
||||
@@ -46,6 +46,7 @@ void Blink::dungeonCast(Maps::MapDungeon *map) {
|
||||
// And teleport there
|
||||
addInfoMsg(_game->_res->TELEPORTED);
|
||||
map->setPosition(newPos);
|
||||
_game->endOfTurn();
|
||||
}
|
||||
|
||||
} // End of namespace Spells
|
||||
|
||||
@@ -44,6 +44,7 @@ void Create::dungeonCast(Maps::MapDungeon *map) {
|
||||
// Create beams on the tile in front of the player
|
||||
map->setTileAt(newPos, Maps::DTILE_BEAMS);
|
||||
addInfoMsg(_game->_res->FIELD_CREATED);
|
||||
_game->endOfTurn();
|
||||
} else {
|
||||
// Failed
|
||||
Spell::dungeonCast(map);
|
||||
|
||||
@@ -44,6 +44,7 @@ void Destroy::dungeonCast(Maps::MapDungeon *map) {
|
||||
// Destroy the beams in front of the player
|
||||
map->setTileAt(newPos, Maps::DTILE_HALLWAY);
|
||||
addInfoMsg(_game->_res->FIELD_DESTROYED);
|
||||
_game->endOfTurn();
|
||||
} else {
|
||||
// Failed
|
||||
Spell::dungeonCast(map);
|
||||
|
||||
@@ -26,11 +26,36 @@
|
||||
#include "ultima/ultima1/core/resources.h"
|
||||
#include "ultima/ultima1/maps/map_tile.h"
|
||||
#include "ultima/ultima1/widgets/dungeon_monster.h"
|
||||
#include "ultima/shared/maps/map_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima1 {
|
||||
namespace Spells {
|
||||
|
||||
BEGIN_MESSAGE_MAP(KillMagicMIssile, Spell)
|
||||
ON_MESSAGE(CharacterInputMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void KillMagicMIssile::cast(Maps::MapBase *map) {
|
||||
// Prompt for a direction
|
||||
addInfoMsg(": ", false);
|
||||
Shared::CInfoGetKeypress keyMsg(this);
|
||||
keyMsg.execute(_game);
|
||||
}
|
||||
|
||||
bool KillMagicMIssile::CharacterInputMsg(CCharacterInputMsg &msg) {
|
||||
Shared::Maps::Direction dir = Shared::Maps::MapWidget::directionFromKey(msg._keyState.keycode);
|
||||
|
||||
if (dir == Shared::Maps::DIR_NONE) {
|
||||
addInfoMsg(_game->_res->NONE);
|
||||
} else {
|
||||
addInfoMsg(_game->_res->DIRECTION_NAMES[(int)dir - 1]);
|
||||
}
|
||||
|
||||
_game->endOfTurn();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
Kill::Kill() : KillMagicMIssile(SPELL_KILL) {
|
||||
@@ -46,6 +71,7 @@ void Kill::dungeonCast(Maps::MapDungeon *map) {
|
||||
Widgets::DungeonMonster *monster = dynamic_cast<Widgets::DungeonMonster *>(tile._widget);
|
||||
if (monster) {
|
||||
monster->attackMonster(5, 101, Widgets::ITS_OVER_9000);
|
||||
_game->endOfTurn();
|
||||
} else {
|
||||
// Failed
|
||||
KillMagicMIssile::dungeonCast(map);
|
||||
|
||||
@@ -24,20 +24,32 @@
|
||||
#define ULTIMA_ULTIMA1_U1DIALOGS_KILL_MAGIC_MISSILE_H
|
||||
|
||||
#include "ultima/ultima1/spells/spell.h"
|
||||
#include "ultima/shared/engine/messages.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima1 {
|
||||
namespace Spells {
|
||||
|
||||
using Shared::CCharacterInputMsg;
|
||||
|
||||
/**
|
||||
* Common intermediate base class for both the Kill and Magic Missile spells
|
||||
*/
|
||||
class KillMagicMIssile : public Spell {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool CharacterInputMsg(CCharacterInputMsg &msg);
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
KillMagicMIssile(SpellId spellId) : Spell(spellId) {}
|
||||
|
||||
/**
|
||||
* Cast the spell outside a dungeon
|
||||
*/
|
||||
virtual void cast(Maps::MapBase *map) override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,7 @@ void LadderDown::dungeonCast(Maps::MapDungeon *map) {
|
||||
if (map->getLevel() < 10 && !tile._isBeams && ((pt.x & 1) || (pt.y & 1))) {
|
||||
map->setTileAt(pt, Maps::DTILE_LADDER_DOWN);
|
||||
addInfoMsg(_game->_res->LADDER_CREATED);
|
||||
_game->endOfTurn();
|
||||
} else {
|
||||
// Failed
|
||||
Spell::dungeonCast(map);
|
||||
|
||||
@@ -40,6 +40,7 @@ void LadderUp::dungeonCast(Maps::MapDungeon *map) {
|
||||
if (!tile._isBeams && ((pt.x & 1) || (pt.y & 1))) {
|
||||
map->setTileAt(pt, Maps::DTILE_LADDER_UP);
|
||||
addInfoMsg(_game->_res->LADDER_CREATED);
|
||||
_game->endOfTurn();
|
||||
} else {
|
||||
// Failed
|
||||
Spell::dungeonCast(map);
|
||||
|
||||
@@ -38,6 +38,7 @@ void OpenUnlock::dungeonCast(Maps::MapDungeon *map) {
|
||||
if (item) {
|
||||
addInfoMsg(item->_name, false);
|
||||
openItem(map, item);
|
||||
_game->endOfTurn();
|
||||
} else {
|
||||
Spell::dungeonCast(map);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ void Prayer::cast(Maps::MapBase *map) {
|
||||
addInfoMsg(_game->_res->NO_EFFECT);
|
||||
_game->playFX(6);
|
||||
}
|
||||
|
||||
_game->endOfTurn();
|
||||
}
|
||||
|
||||
void Prayer::dungeonCast(Maps::MapDungeon *map) {
|
||||
|
||||
@@ -35,7 +35,7 @@ void Spell::setGame(Ultima1Game *game) {
|
||||
|
||||
void Spell::addInfoMsg(const Common::String &text, bool newLine) {
|
||||
Shared::CInfoMsg msg(text, newLine);
|
||||
msg.execute(_game->getView());
|
||||
msg.execute("Game");
|
||||
}
|
||||
|
||||
void Spell::cast(Maps::MapBase *map) {
|
||||
@@ -43,12 +43,14 @@ void Spell::cast(Maps::MapBase *map) {
|
||||
addInfoMsg("");
|
||||
addInfoMsg(_game->_res->DUNGEON_SPELL_ONLY);
|
||||
_game->playFX(6);
|
||||
_game->endOfTurn();
|
||||
}
|
||||
|
||||
void Spell::dungeonCast(Maps::MapDungeon *map) {
|
||||
// This is the fallback the spells call if it fails
|
||||
addInfoMsg(_game->_res->FAILED);
|
||||
_game->playFX(6);
|
||||
_game->endOfTurn();
|
||||
}
|
||||
|
||||
} // End of namespace Spells
|
||||
|
||||
@@ -45,18 +45,18 @@ namespace Ultima1 {
|
||||
namespace Actions {
|
||||
MAP_ACTION(Cast, 2, cast)
|
||||
MAP_ACTION(Drop, 3, drop)
|
||||
MAP_ACTION(Enter, 4, enter)
|
||||
MAP_ACTION(Fire, 5, fire)
|
||||
MAP_ACTION(Get, 6, get)
|
||||
MAP_ACTION(HyperJump, 7, hyperjump)
|
||||
MAP_ACTION(Inform, 8, inform)
|
||||
MAP_ACTION(Climb, 10, climb)
|
||||
MAP_ACTION(Open, 14, open)
|
||||
MAP_ACTION(Steal, 18, steal)
|
||||
MAP_ACTION(Transact, 19, talk)
|
||||
MAP_ACTION(Unlock, 20, unlock)
|
||||
MAP_ACTION(ViewChange, 21, view)
|
||||
MAP_ACTION(ExitTransport, 23, disembark)
|
||||
MAP_ACTION_END_TURN(Enter, 4, enter)
|
||||
MAP_ACTION_END_TURN(Fire, 5, fire)
|
||||
MAP_ACTION_END_TURN(Get, 6, get)
|
||||
MAP_ACTION_END_TURN(HyperJump, 7, hyperjump)
|
||||
MAP_ACTION_END_TURN(Inform, 8, inform)
|
||||
MAP_ACTION_END_TURN(Climb, 10, climb)
|
||||
MAP_ACTION_END_TURN(Open, 14, open)
|
||||
MAP_ACTION_END_TURN(Steal, 18, steal)
|
||||
MAP_ACTION_END_TURN(Transact, 19, talk)
|
||||
MAP_ACTION_END_TURN(Unlock, 20, unlock)
|
||||
MAP_ACTION_END_TURN(ViewChange, 21, view)
|
||||
MAP_ACTION_END_TURN(ExitTransport, 23, disembark)
|
||||
}
|
||||
|
||||
namespace U1Gfx {
|
||||
@@ -204,9 +204,10 @@ void dispatchKey(ViewGame *game) {
|
||||
#define CHECK(KEYCODE, MSG_CLASS) else if (msg._keyState.keycode == KEYCODE) { dispatchKey<MSG_CLASS>(this); }
|
||||
|
||||
bool ViewGame::checkMovement(const Common::KeyState &keyState) {
|
||||
switch (keyState.keycode) {
|
||||
case Common::KEYCODE_LEFT:
|
||||
case Common::KEYCODE_KP4: {
|
||||
Shared::Maps::Direction dir = Shared::Maps::MapWidget::directionFromKey(keyState.keycode);
|
||||
|
||||
switch (dir) {
|
||||
case Shared::Maps::DIR_WEST: {
|
||||
if (keyState.flags & Common::KBD_SHIFT) {
|
||||
Shared::CAttackMsg attack(Shared::Maps::DIR_LEFT);
|
||||
attack.execute(this);
|
||||
@@ -216,8 +217,7 @@ bool ViewGame::checkMovement(const Common::KeyState &keyState) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Common::KEYCODE_RIGHT:
|
||||
case Common::KEYCODE_KP6: {
|
||||
case Shared::Maps::DIR_EAST: {
|
||||
if (keyState.flags & Common::KBD_SHIFT) {
|
||||
Shared::CAttackMsg attack(Shared::Maps::DIR_RIGHT);
|
||||
attack.execute(this);
|
||||
@@ -227,8 +227,7 @@ bool ViewGame::checkMovement(const Common::KeyState &keyState) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Common::KEYCODE_UP:
|
||||
case Common::KEYCODE_KP8: {
|
||||
case Shared::Maps::DIR_UP: {
|
||||
if (keyState.flags & Common::KBD_SHIFT) {
|
||||
Shared::CAttackMsg attack(Shared::Maps::DIR_UP);
|
||||
attack.execute(this);
|
||||
@@ -238,8 +237,7 @@ bool ViewGame::checkMovement(const Common::KeyState &keyState) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Common::KEYCODE_DOWN:
|
||||
case Common::KEYCODE_KP2: {
|
||||
case Shared::Maps::DIR_DOWN: {
|
||||
if (keyState.flags & Common::KBD_SHIFT) {
|
||||
Shared::CAttackMsg attack(Shared::Maps::DIR_DOWN);
|
||||
attack.execute(this);
|
||||
|
||||
Reference in New Issue
Block a user