Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/attack_effect.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
void AttackEffect::synchronize(Common::Serializer &s) {
s.syncAsUint16LE(_tileId);
s.syncAsUint16LE(_remainingDistance);
s.syncAsUint16LE(_agility);
s.syncAsUint16LE(_damage);
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,98 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_HIT_H
#define ULTIMA_ULTIMA1_WIDGETS_HIT_H
#include "ultima/shared/maps/map_widget.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Common base class for both physical and spell attack effects
*/
class AttackEffect : public Shared::Maps::MapWidget {
protected:
uint _tileId;
Point _delta;
uint _remainingDistance;
uint _agility;
uint _damage;
protected:
/**
* Constructor
*/
AttackEffect(Shared::Game *game, Shared::Maps::MapBase *map, uint tileId) : Shared::Maps::MapWidget(game, map),
_tileId(tileId), _remainingDistance(0), _agility(0), _damage(0) {}
public:
/**
* Constructor
*/
AttackEffect(Shared::Game *game, Shared::Maps::MapBase *map) : Shared::Maps::MapWidget(game, map),
_tileId(0), _remainingDistance(0), _agility(0), _damage(0) {}
/**
* Handles loading and saving the widget's data
*/
void synchronize(Common::Serializer &s) override;
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return _tileId; }
/**
* Set the details for t
*/
};
/**
* Physical attack effects
*/
class PhysicalAttackEffect : public AttackEffect {
public:
/**
* Constructor
*/
PhysicalAttackEffect(Shared::Game *game, Shared::Maps::MapBase *map) :
AttackEffect(game, map, 50) {}
};
/**
* Spell attack effects
*/
class SpellAttackEffect : public AttackEffect {
public:
/**
* Constructor
*/
SpellAttackEffect(Shared::Game *game, Shared::Maps::MapBase *map) :
AttackEffect(game, map, 51) {}
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,94 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/bard.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
void Bard::movement() {
if (areGuardsHostile())
return;
Point playerPos = _map->_playerWidget->_position;
bool stolen = false;
// Choose a new random position to move to
Point newPos = _position + getRandomMoveDelta();
if (canMoveTo(newPos) == YES) {
// Move to the new position
_position = newPos;
_game->playFX(4);
} else if (newPos == playerPos) {
// Moved into player, which causes them to steal a weapon from the player
stolen = stealWeapon();
}
if (!stolen && _game->getRandomNumber(1, 255) < 15)
talk();
}
bool Bard::stealWeapon() {
Shared::Character &c = *_game->_party;
for (uint idx = 1; idx < c._weapons.size(); ++idx) {
if (!c._weapons[idx]->empty() && (int)idx != c._equippedWeapon) {
c._weapons[idx]->decrQuantity();
if (_game->getRandomNumber(1, 255) < (c._agility + 128)) {
// TODO
}
return true;
}
}
return false;
}
void Bard::talk() {
if (dynamic_cast<Maps::MapCity *>(_map)) {
addInfoMsg(_game->_res->BARD_SPEECH1);
addInfoMsg(_game->_res->BARD_SPEECH2);
} else {
addInfoMsg(_game->_res->JESTER_SPEECH1);
addInfoMsg(_game->_res->JESTER_SPEECH2);
}
}
bool Bard::subtractHitPoints(uint amount) {
bool result = Person::subtractHitPoints(amount);
if (result) {
Maps::MapCastle *map = dynamic_cast<Maps::MapCastle *>(_map);
assert(map);
addInfoMsg(_game->_res->FOUND_KEY);
map->_castleKey = 1;
}
return result;
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,77 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_BARD_H
#define ULTIMA_ULTIMA1_WIDGETS_BARD_H
#include "ultima/ultima1/widgets/person.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Bard & Jester persons
*/
class Bard : public Person {
private:
/**
* Called when the bard/jester steals something from the player
* @returns True if player had a weapon to steal
*/
bool stealWeapon();
protected:
/**
* Handles moving creatures
*/
void movement() override;
public:
DECLARE_WIDGET(Bard)
/**
* Constructor
*/
Bard(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Person(game, map, 19, hitPoints) {}
/**
* Constructor
*/
Bard(Ultima1Game *game, Maps::MapBase *map) : Person(game, map, 19) {}
/**
* Talk to an NPC
*/
void talk() override;
/**
* Removes hit points from a creature
* @param amount Amount to remove
* @returns Returns true if kills the creature
*/
bool subtractHitPoints(uint amount) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,60 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/dungeon_chest.h"
#include "ultima/ultima1/maps/map_dungeon.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
DungeonChest::DungeonChest(Ultima1Game *game, Maps::MapBase *map, const Point &pt) :
DungeonItem(game, map, MONSTER_MIMIC, pt) {
_name = game->_res->DUNGEON_ITEM_NAMES[0];
}
DungeonChest::DungeonChest(Ultima1Game *game, Maps::MapBase *map) : DungeonItem(game, map, MONSTER_MIMIC) {
_name = game->_res->DUNGEON_ITEM_NAMES[0];
}
bool DungeonChest::open() {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
Maps::MapDungeon *map = static_cast<Maps::MapDungeon *>(getMap());
Shared::Character &c = *_game->_party;
if (_game->getRandomNumber(1, 75) <= c._agility || c._class == CLASS_THIEF) {
// Successfully opened
addInfoMsg(game->_res->THOU_DOST_FIND);
game->giveTreasure(game->getRandomNumber(3, map->getLevel() * map->getLevel() + 9), 0);
} else {
addInfoMsg(game->_res->SET_OFF_TRAP);
game->playFX(2);
c._hitPoints -= map->getLevel();
}
return true;
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,59 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_DUNGEON_CHEST_H
#define ULTIMA_ULTIMA1_WIDGETS_DUNGEON_CHEST_H
#include "ultima/ultima1/widgets/dungeon_item.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Chest item
*/
class DungeonChest : public DungeonItem {
public:
DECLARE_WIDGET(DungeonChest)
/**
* Constructor
*/
DungeonChest(Ultima1Game *game, Maps::MapBase *map, const Point &pt);
/**
* Constructor
*/
DungeonChest(Ultima1Game *game, Maps::MapBase *map);
/**
* Try to open/unlock the item
* @returns True if item was capable of being opened or unlocked
*/
bool open() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,72 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/dungeon_coffin.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/maps/map_tile.h"
#include "ultima/ultima1/maps/map_dungeon.h"
#include "ultima/ultima1/game.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
DungeonCoffin::DungeonCoffin(Ultima1Game *game, Maps::MapBase *map, const Point &pt) :
DungeonItem(game, map, UITEM_COFFIN, pt) {
_name = game->_res->DUNGEON_ITEM_NAMES[1];
}
DungeonCoffin::DungeonCoffin(Ultima1Game *game, Maps::MapBase *map) : DungeonItem(game, map, UITEM_COFFIN) {
_name = game->_res->DUNGEON_ITEM_NAMES[1];
}
bool DungeonCoffin::open() {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
Maps::MapDungeon *map = static_cast<Maps::MapDungeon *>(_map);
Point deltaPos = _map->getDeltaPosition(_map->getDirectionDelta());
Maps::U1MapTile deltaTile;
_map->getTileAt(deltaPos, &deltaTile);
addInfoMsg("");
if (_game->getRandomNumber(1, 255) < 104 && !deltaTile._isWall && !deltaTile._isSecretDoor && !deltaTile._widget) {
spawnMonsterAt(deltaPos);
} else {
addInfoMsg(game->_res->FIND);
game->giveTreasure(game->getRandomNumber(3, map->getLevel() * map->getLevel() + 9), 0);
map->removeWidget(this);
}
return true;
}
void DungeonCoffin::spawnMonsterAt(const Point &newPos) {
Maps::U1MapTile tile;
_map->getTileAt(newPos, &tile);
if (tile._isHallway || tile._isLadderUp || tile._isLadderDown || tile._widget) {
Maps::MapDungeon *map = static_cast<Maps::MapDungeon *>(_map);
map->spawnMonsterAt(newPos);
}
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,64 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_DUNGEON_COFFIN_H
#define ULTIMA_ULTIMA1_WIDGETS_DUNGEON_COFFIN_H
#include "ultima/ultima1/widgets/dungeon_item.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Chest item
*/
class DungeonCoffin : public DungeonItem {
private:
/**
* Spawns a monster from the coffin
*/
void spawnMonsterAt(const Point &newPos);
public:
DECLARE_WIDGET(DungeonCoffin)
/**
* Constructor
*/
DungeonCoffin(Ultima1Game *game, Maps::MapBase *map, const Point &pt);
/**
* Constructor
*/
DungeonCoffin(Ultima1Game *game, Maps::MapBase *map);
/**
* Try to open/unlock the item
* @returns True if item was capable of being opened or unlocked
*/
bool open() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,41 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/dungeon_item.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
DungeonItem::DungeonItem(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId widgetId,
const Point &pt) : DungeonWidget(game, map, widgetId, pt) {
}
DungeonItem::DungeonItem(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId widgetId) :
DungeonWidget(game, map, widgetId, Point()) {
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,58 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_DUNGEON_ITEM_H
#define ULTIMA_ULTIMA1_WIDGETS_DUNGEON_ITEM_H
#include "ultima/ultima1/widgets/dungeon_widget.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Encapsulated class for drawing widgets within dungeons
*/
class DungeonItem : public DungeonWidget {
protected:
/**
* Constructor
*/
DungeonItem(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId widgetId, const Point &pt);
/**
* Constructor
*/
DungeonItem(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId widgetId);
public:
/**
* Try to open/unlock the item
* @returns True if item was capable of being opened or unlocked
*/
virtual bool open() { return false; }
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,269 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/dungeon_monster.h"
#include "ultima/ultima1/maps/map.h"
#include "ultima/ultima1/maps/map_dungeon.h"
#include "ultima/ultima1/maps/map_tile.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/core/utils.h"
#include "ultima/shared/early/ultima_early.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
DungeonMonster::DungeonMonster(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId monsterId,
int hitPoints, const Point &pt) :
DungeonWidget(game, map, monsterId, pt), Shared::Maps::DungeonCreature(game, map, hitPoints) {
_name = getGame()->_res->DUNGEON_MONSTER_NAMES[_widgetId];
}
DungeonMonster::DungeonMonster(Ultima1Game *game, Maps::MapBase *map) :
DungeonWidget(game, map), Shared::Maps::DungeonCreature(game, map) {
}
void DungeonMonster::synchronize(Common::Serializer &s) {
DungeonWidget::synchronize(s);
Creature::synchronize(s);
s.syncAsUint16LE(_widgetId);
if (s.isLoading())
_name = getGame()->_res->DUNGEON_MONSTER_NAMES[_widgetId];
}
bool DungeonMonster::isBlockingView() const {
return _widgetId != MONSTER_INVISIBLE_SEEKER && _widgetId != MONSTER_MIMIC
&& _widgetId != MONSTER_GELATINOUS_CUBE;
}
void DungeonMonster::draw(Shared::DungeonSurface &s, uint distance) {
if (distance < 5) {
if (_widgetId == MONSTER_GELATINOUS_CUBE) {
s.drawWall(distance);
s.drawLeftEdge(distance);
s.drawRightEdge(distance);
} else {
DungeonWidget::draw(s, distance);
}
}
}
void DungeonMonster::update(bool isPreUpdate) {
assert(isPreUpdate);
Point playerPos = _map->_playerWidget->_position;
Point delta = playerPos - _position;
int distance = ABS(delta.x) + ABS(delta.y);
if (distance == 1) {
attackParty();
} else if (distance < 8) {
movement();
}
}
void DungeonMonster::movement() {
if (attackDistance())
// Dungeon monsters don't move if they're already in attack range
return;
Point playerPos = _map->_playerWidget->_position;
Point diff = playerPos - _position;
if (diff.x != 0 && canMoveTo(Point(_position.x + SGN(diff.x), _position.y)))
_position.x += SGN(diff.x);
else if (diff.y != 0 && canMoveTo(Point(_position.x, _position.y + SGN(diff.y))))
_position.y += SGN(diff.y);
}
Shared::Maps::MapWidget::CanMove DungeonMonster::canMoveTo(const Point &destPos) {
Shared::Maps::MapWidget::CanMove result = MapWidget::canMoveTo(destPos);
if (result != UNSET)
return result;
return DungeonMonster::canMoveTo(_map, this, destPos);
}
Shared::Maps::MapWidget::CanMove DungeonMonster::canMoveTo(Shared::Maps::MapBase *map, MapWidget *widget, const Point &destPos) {
// Get the details of the position
Shared::Maps::MapTile currTile, destTile;
map->getTileAt(map->getPosition(), &currTile);
map->getTileAt(destPos, &destTile);
// Can't move onto certain dungeon tile types
if (destTile._isWall || destTile._isSecretDoor || destTile._isBeams)
return NO;
// Can't move to directly adjoining doorway cells (they'd be in parallel to each other, not connected)
if (destTile._isDoor && currTile._isDoor)
return NO;
return YES;
}
void DungeonMonster::attackParty() {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
Point playerPos = _map->_playerWidget->_position;
//Point delta = playerPos - _position;
Shared::Character &c = *_game->_party;
uint threshold, damage;
bool isHit = true;
// Get tile details for both the player and the attacking creature
Maps::U1MapTile playerTile,creatureTile;
_map->getTileAt(playerPos, &playerTile);
_map->getTileAt(_position, &creatureTile);
if (playerTile._isBeams || (creatureTile._isDoor && (playerTile._isDoor || playerTile._isWall || playerTile._isSecretDoor)))
return;
// Write attack line
addInfoMsg(Common::String::format(game->_res->ATTACKED_BY, _name.c_str()));
_game->playFX(3);
threshold = (c._stamina / 2) + (c._equippedArmour * 8) + 56;
if (_game->getRandomNumber(1, 255) > threshold) {
threshold = _game->getRandomNumber(1, 255);
damage = (_widgetId * _widgetId) + _map->getLevel();
if (damage > 255) {
damage = _game->getRandomNumber(_widgetId + 1, 255);
}
if (_widgetId == MONSTER_GELATINOUS_CUBE && c.isArmourEquipped()) {
addInfoMsg(game->_res->ARMOR_DESTROYED);
c._armour[c._equippedArmour]->decrQuantity();
c.removeArmour();
isHit = false;
} else if (_widgetId == MONSTER_GREMLIN) {
addInfoMsg(game->_res->GREMLIN_STOLE);
c._food /= 2;
isHit = false;
} else if (_widgetId == MONSTER_MIND_WHIPPER && threshold < 128) {
addInfoMsg(game->_res->MENTAL_ATTACK);
c._intelligence = (c._intelligence / 2) + 5;
isHit = false;
} else if (_widgetId == MONSTER_THIEF) {
// Thief will steal the first spare weapon player has that isn't equipped
for (int weaponNum = 1; weaponNum < (int)c._weapons.size(); ++weaponNum) {
if (weaponNum != c._equippedWeapon && !c._weapons[weaponNum]->empty()) {
// TODO: May need to worry about word wrapping long line
addInfoMsg(Common::String::format(game->_res->THIEF_STOLE,
Shared::isVowel(c._weapons[weaponNum]->_longName.firstChar()) ? game->_res->AN : game->_res->A
));
c._weapons[weaponNum]->decrQuantity();
break;
}
}
}
if (isHit) {
addInfoMsg(Common::String::format("%s %2d %s", game->_res->HIT, damage, game->_res->DAMAGE));
c._hitPoints -= damage;
}
} else {
addInfoMsg(game->_res->MISSED);
}
}
void DungeonMonster::attackMonster(uint effectNum, uint agility, uint damage) {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
Maps::MapDungeon *map = static_cast<Maps::MapDungeon *>(_map);
Point currPos = map->getPosition();
Maps::U1MapTile playerTile, monsTile;
map->getTileAt(currPos, &playerTile);
map->getTileAt(_position, &monsTile);
bool flag = true;
if (!playerTile._isDoor) {
if (!monsTile._isHallway && !monsTile._isLadderUp && !monsTile._isLadderDown)
flag = false;
}
if (game->getRandomNumber(1, 100) <= agility && !playerTile._isWall && !playerTile._isSecretDoor
&& !playerTile._isBeams && flag) {
// Play effect and add hit message
game->playFX(effectNum);
if (damage != ITS_OVER_9000)
addInfoMsg(Common::String::format("%s ", game->_res->HIT), false);
if ((int)damage < _hitPoints) {
addInfoMsg(Common::String::format("%u %s!", damage, game->_res->DAMAGE));
_hitPoints -= damage;
} else {
addInfoMsg(Common::String::format("%s %s", _name.c_str(),
damage == ITS_OVER_9000 ? game->_res->DESTROYED : game->_res->KILLED));
monsterDead();
// Give some treasure
uint amount = game->getRandomNumber(2, map->getLevel() * 3 + (uint)_widgetId + 10);
addInfoMsg(game->_res->THOU_DOST_FIND);
game->giveTreasure(amount, 0);
// Give experience
Shared::Character &c = *game->_party;
uint experience = game->getRandomNumber(2, map->getLevel() * map->getLevel() + 10);
c._experience += experience;
map->_dungeonExitHitPoints = MIN(map->_dungeonExitHitPoints + experience * 2, 9999U);
// Delete the monster and create a new one
map->removeWidget(this);
map->spawnMonster();
}
} else {
// Attack missed
addInfoMsg(game->_res->MISSED);
}
}
void DungeonMonster::monsterDead() {
int index;
switch (_widgetId) {
case MONSTER_BALRON:
index = 8;
break;
case MONSTER_CARRION_CREEPER:
index = 4;
break;
case MONSTER_LICH:
index = 6;
break;
case MONSTER_GELATINOUS_CUBE:
index = 2;
break;
default:
index = 0;
break;
}
if (index) {
// Mark monster-based quests as complete if in progress
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
game->_quests[8 - index].complete();
}
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,123 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_DUNGEON_MONSTER_H
#define ULTIMA_ULTIMA1_WIDGETS_DUNGEON_MONSTER_H
#include "ultima/ultima1/widgets/dungeon_widget.h"
#include "ultima/shared/maps/creature.h"
#include "ultima/shared/maps/dungeon_creature.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
enum {
// Vegeta, what does the scouter say about his power level?
ITS_OVER_9000 = 10000
};
/**
* Implements monsters within the dungeons
*/
class DungeonMonster : public DungeonWidget, public Shared::Maps::DungeonCreature {
private:
/**
* Called when the monster is killed
*/
void monsterDead();
protected:
/**
* Handles moving creatures
*/
void movement() override;
public:
/**
* Returns true if the given widget can move to a given position on the map
*/
static Shared::Maps::MapWidget::CanMove canMoveTo(Shared::Maps::MapBase *map, MapWidget *widget, const Point &destPos);
public:
DECLARE_WIDGET(DungeonMonster)
/**
* Constructor
*/
DungeonMonster(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId monsterId, int hitPoints,
const Point &pt);
/**
* Constructor
*/
DungeonMonster(Ultima1Game *game, Maps::MapBase *map);
/**
* Destructor
*/
~DungeonMonster() override {}
/**
* Returns the monster's type
*/
DungeonWidgetId id() const { return _widgetId; }
/**
* Returns true if a monster blocks the background behind him
*/
bool isBlockingView() const override;
/**
* Handles loading and saving games
*/
void synchronize(Common::Serializer &s) override;
/**
* Draw a monster
*/
void draw(Shared::DungeonSurface &s, uint distance) override;
/**
* Called to update the widget at the end of a turn
* @param isPreUpdate Update is called twice in succession during the end of turn update.
* Once with true for all widgets, then with it false
*/
void update(bool isPreUpdate) override;
/**
* Returns true if the given widget can move to a given position on the map
*/
CanMove canMoveTo(const Point &destPos) override;
/**
* Handles attacking the player
*/
void attackParty() override;
/**
* Handles the player attacking the monster
*/
void attackMonster(uint effectNum, uint agility, uint damage);
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,40 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/dungeon_player.h"
#include "ultima/ultima1/widgets/dungeon_widget.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
Shared::Maps::MapWidget::CanMove DungeonPlayer::canMoveTo(const Point &destPos) {
Shared::Maps::MapWidget::CanMove result = Shared::Maps::DungeonWidget::canMoveTo(destPos);
if (result != Shared::Maps::DungeonWidget::UNSET)
return result;
return Shared::Maps::DungeonWidget::UNSET;
//return Shared::Maps::DungeonWidget::canMoveTo(_map, this, destPos);
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,66 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_DUNGEON_PLAYER_H
#define ULTIMA_ULTIMA1_WIDGETS_DUNGEON_PLAYER_H
#include "ultima/shared/maps/dungeon_widget.h"
#include "ultima/shared/maps/map_widget.h"
#include "ultima/shared/early/game.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
class DungeonPlayer : public Shared::Maps::DungeonWidget {
public:
DECLARE_WIDGET(DungeonPlayer)
/**
* Constructor
*/
DungeonPlayer(Shared::Game *game, Shared::Maps::MapBase *map) : Shared::Maps::DungeonWidget(game, map) {}
DungeonPlayer(Shared::Game *game, Shared::Maps::MapBase *map, const Point &pt, Shared::Maps::Direction dir = Shared::Maps::DIR_NONE) : Shared::Maps::DungeonWidget(game, map, pt, dir) {}
DungeonPlayer(Shared::Game *game, Shared::Maps::MapBase *map, const Common::String &name, const Point &pt, Shared::Maps::Direction dir = Shared::Maps::DIR_NONE) :
Shared::Maps::DungeonWidget(game, map, name, pt, dir) {}
/**
* Destructor
*/
~DungeonPlayer() override {}
/**
* The player's viewpoint has no intrinsic drawing
*/
void draw(Shared::DungeonSurface &s, uint distance) override {}
/**
* Returns true if the given widget can move to a given position on the map
*/
CanMove canMoveTo(const Point &destPos) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,98 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/dungeon_widget.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/maps/map_base.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/early/ultima_early.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
DungeonWidget::DungeonWidget(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId widgetId,
const Point &pt) : Shared::Maps::DungeonWidget(game, map, pt), _widgetId(widgetId) {
}
DungeonWidget::DungeonWidget(Ultima1Game *game, Maps::MapBase *map) : Shared::Maps::DungeonWidget(game, map), _widgetId(MONSTER_NONE) {
}
Ultima1Game *DungeonWidget::getGame() const {
return static_cast<Ultima1Game *>(_game);
}
Maps::MapBase *DungeonWidget::getMap() const {
return static_cast<Maps::MapBase *>(_map);
}
const byte OFFSET_Y[5] = { 139, 112, 96, 88, 84 };
enum { POINT_AT = 126, END_OF_DRAW = 127 };
void DungeonWidget::drawWidget(Graphics::ManagedSurface &s, DungeonWidgetId widgetId, uint distance, byte color) {
Point pt, priorPt;
if (distance == 0)
// This can't happen in the original, but in case I add an 'etherial' cheat to allow moving
// through monsters, this will guard against a crash
distance = 1;
int yOffset = OFFSET_Y[MIN((int)distance - 1, 4)];
int shift = (distance == 5) ? 5 : distance - 1;
// Get a pointer to the drawing data
const byte *data = getData();
data += READ_LE_UINT16(data + widgetId * 2);
while (*data != END_OF_DRAW) {
// Check for a point vs a line
bool isPoint = *data == POINT_AT;
if (isPoint)
++data;
// Get the next position
getPos(data, shift, pt);
pt.y += yOffset;
// Draw point or line
if (!isPoint)
s.drawLine(priorPt.x, priorPt.y, pt.x, pt.y, color);
priorPt = pt;
}
}
const byte *DungeonWidget::getData() {
Ultima1Game *game = static_cast<Ultima1Game *>(g_vm->_game);
return game->_res->DUNGEON_DRAW_DATA;
}
void DungeonWidget::getPos(const byte *&data, int bitShift, Point &pt) {
pt.x = ((int8)*data++ >> bitShift) + 160;
pt.y = ((int8)*data++ >> bitShift);
}
void DungeonWidget::draw(Shared::DungeonSurface &s, uint distance) {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
drawWidget(s, _widgetId, distance, game->_edgeColor);
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,103 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_DUNGEON_WIDGET_H
#define ULTIMA_ULTIMA1_WIDGETS_DUNGEON_WIDGET_H
#include "ultima/shared/maps/map.h"
#include "ultima/shared/maps/dungeon_widget.h"
namespace Ultima {
namespace Ultima1 {
class Ultima1Game;
namespace Maps {
class MapBase;
}
namespace Widgets {
enum DungeonWidgetId {
MONSTER_NONE = -1, MONSTER_RANGER = 0, MONSTER_SKELETON = 1, MONSTER_THIEF = 2, MONSTER_GIANT_RAT = 3,
MONSTER_RAT = 4, MONSTER_SPIDER = 5, MONSTER_VIPER = 6, MONSTER_ORC = 7, MONSTER_CYCLOPS = 8,
MONSTER_GELATINOUS_CUBE = 9, MONSTER_ETTIN = 10, MONSTER_MIMIC = 11, MONSTER_LIZARD_MAN = 12,
MONSTER_MINOTAUR = 13, MONSTER_CARRION_CREEPER = 14, MONSTER_TANGLER = 15, MONSTER_GREMLIN = 16,
MONSTER_WANDERING_EYES = 17, MONSTER_WRAITH = 18, MONSTER_LICH = 19, MONSTER_INVISIBLE_SEEKER = 20,
MONSTER_MIND_WHIPPER = 21, MONSTER_ZORN = 22, MONSTER_DAEMON = 23, MONSTER_BALRON = 24, UITEM_COFFIN = 25,
UITEM_HOLE_UP = 26, UITEM_HOLE_DOWN = 27, UITEM_LADDER_UP = 28, UITEM_LADDER_DOWN = 29
};
/**
* Encapsulated class for drawing widgets within dungeons
*/
class DungeonWidget : public Shared::Maps::DungeonWidget {
protected:
DungeonWidgetId _widgetId;
private:
/**
* Get the drawing data table
*/
static const byte *getData();
/**
* Extracts a drawing position
*/
static void getPos(const byte *&data, int bitShift, Point &pt);
protected:
/**
* Gets the Ultima 1 game
*/
Ultima1Game *getGame() const;
/**
* Gets the Ultima 1 map
*/
Maps::MapBase *getMap() const;
public:
Common::String _name; // Name of item
public:
/**
* Constructor
*/
DungeonWidget(Ultima1Game *game, Maps::MapBase *map, DungeonWidgetId widgetId, const Point &pt);
/**
* Constructor
*/
DungeonWidget(Ultima1Game *game, Maps::MapBase *map);
/**
* Draws a dungeon widget onto the passed surface
*/
static void drawWidget(Graphics::ManagedSurface &s, DungeonWidgetId widgetId, uint distance, byte color);
/**
* Handles drawing the item
*/
void draw(Shared::DungeonSurface &s, uint distance) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,73 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/guard.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/shared/core/utils.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
uint Guard::attackDistance() const {
Point diff = _position - _map->_playerWidget->_position;
return areGuardsHostile() && ABS(diff.x) < 2 && ABS(diff.y) < 2 ? 1 : 0;
}
void Guard::movement() {
// Don't move if the guards aren't hostile, or they're already within attack distance
if (!areGuardsHostile() || attackDistance())
return;
Point diff = _position - _map->_playerWidget->_position;
Point delta(SGN(diff.x), SGN(diff.y));
int totalDiff = ABS(diff.x) + ABS(diff.y);
if (totalDiff >= 13)
return;
// Try moving horizontally or vertically towards the player
bool moved = moveBy(Point(delta.x, 0));
if (!moved)
moved = moveBy(Point(0, delta.y));
if (moved)
_game->playFX(4);
}
void Guard::attackParty() {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
Shared::Character &c = *game->_party;
addInfoMsg(Common::String::format(game->_res->ATTACKED_BY, _name.c_str()));
game->playFX(7);
uint threshold = (c._stamina / 2) + (c._equippedArmour * 8) + 56;
if (_game->getRandomNumber(1, 255) > threshold) {
int damage = _game->getRandomNumber(2, c._hitPoints / 128 + 15);
addInfoMsg(Common::String::format("%s...%2d %s", game->_res->HIT, damage, game->_res->DAMAGE));
game->playFX(2);
c._hitPoints -= damage;
} else {
addInfoMsg(game->_res->MISSED);
}
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,74 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_GUARD_H
#define ULTIMA_ULTIMA1_WIDGETS_GUARD_H
#include "ultima/ultima1/widgets/person.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
class Guard : public Person {
private:
// bool _moved;
protected:
/**
* Returns the attack distance for the guard
*/
uint attackDistance() const override;
/**
* Handles moving creatures
*/
void movement() override;
/**
* Handles attacking the party
*/
void attackParty() override;
public:
DECLARE_WIDGET(Guard)
/**
* Constructor
*/
Guard(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Person(game, map, 17, hitPoints) {}
/**
* Constructor
*/
Guard(Ultima1Game *game, Maps::MapBase *map) :
Person(game, map, 17) {}
/**
* Destructor
*/
~Guard() override {}
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,56 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/king.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/u1dialogs/king.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(King, Person);
void King::movement() {
}
bool King::subtractHitPoints(uint amount) {
Maps::MapCastle *map = static_cast<Maps::MapCastle *>(_map);
// Lord British is invincible, the nasty git
return map->isLordBritishCastle() ? false : Person::subtractHitPoints(amount);
}
void King::talk() {
if (areGuardsHostile()) {
addInfoMsg(_game->_res->HE_REJECTS_OFFER);
_game->endOfTurn();
} else {
U1Dialogs::King *dialog = new U1Dialogs::King(_game, _map->getMapIndex());
dialog->show();
}
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,73 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_KING_H
#define ULTIMA_ULTIMA1_WIDGETS_KING_H
#include "ultima/ultima1/widgets/person.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the kings within castles
*/
class King : public Person {
DECLARE_MESSAGE_MAP;
protected:
/**
* Handles moving creatures
*/
void movement() override;
public:
DECLARE_WIDGET(King)
CLASSDEF;
/**
* Constructor
*/
King(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Person(game, map, 20, hitPoints) {}
/**
* Constructor
*/
King(Ultima1Game *game, Maps::MapBase *map) : Person(game, map, 20) {}
/**
* Removes hit points from a creature
* @param amount Amount to remove
* @returns Returns true if kills the creature
*/
bool subtractHitPoints(uint amount) override;
/**
* Do a talk action
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,57 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(Merchant, Person);
bool Merchant::checkCuaghtStealing() {
Shared::Character &c = *_game->_party;
int randVal = _game->getRandomNumber(1, 255);
bool flag = areGuardsHostile() || randVal < 38;
if (!flag && c._class == CLASS_THIEF)
return false;
if (!flag && randVal > 77)
return false;
addInfoMsg("");
addInfoMsg(_game->_res->CAUGHT);
static_cast<Maps::MapCityCastle *>(_map)->_guardsHostile = true;
return true;
}
void Merchant::noKingsPermission() {
addInfoMsg("");
addInfoMsg(_game->_res->NO_KINGS_PERMISSION);
_game->playFX(1);
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,81 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_H
#include "ultima/ultima1/widgets/person.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Base class for merchants in the cities and castles
*/
class Merchant : public Person {
DECLARE_MESSAGE_MAP;
protected:
/**
* Checks whether the player is caught stealing, and if so, makes the guards hostile
*/
bool checkCuaghtStealing();
/**
* Adds a response that you don't have the king's permission
*/
void noKingsPermission();
public:
CLASSDEF;
/**
* Constructor
*/
Merchant(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Person(game, map, 50, hitPoints) {}
/**
* Constructor
*/
Merchant(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Person(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
Merchant(Ultima1Game *game, Maps::MapBase *map) : Person(game, map, 50) {}
/**
* Does the get action
*/
virtual void get() {}
/**
* Does the steal action
*/
virtual void steal() {}
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,65 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_armor.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantArmor, Merchant);
void MerchantArmor::get() {
Maps::MapCastle *map = dynamic_cast<Maps::MapCastle *>(_map);
assert(map);
if (map->_getCounter > 0) {
--map->_getCounter;
findArmor(false);
} else {
noKingsPermission();
}
}
void MerchantArmor::steal() {
findArmor(true);
}
void MerchantArmor::findArmor(bool checkStealing) {
Shared::Character &c = *_game->_party;
if (!checkStealing || !checkCuaghtStealing()) {
uint armorNum = _game->getRandomNumber(1, 5);
Common::String armorStr = _game->_res->ARMOR_NAMES[armorNum];
c._armor[armorNum]->incrQuantity();
if (armorNum == 5)
armorStr = Common::String::format("%s %s", _game->_res->A, armorStr.c_str());
addInfoMsg("");
addInfoMsg(Common::String::format(_game->_res->FIND, armorStr.c_str()));
}
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,78 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_ARMOR_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_ARMOR_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the armor merchant
*/
class MerchantArmor : public Merchant {
DECLARE_MESSAGE_MAP;
private:
/**
* Handles getting or stealing armor
* @param checkStealing If set, checks for stealing
*/
void findArmor(bool checkStealing);
public:
DECLARE_WIDGET(MerchantArmor)
CLASSDEF;
/**
* Constructor
*/
MerchantArmor(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantArmor(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantArmor(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Does the get action
*/
void get() override;
/**
* Does the steal action
*/
void steal() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,71 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_armour.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/u1dialogs/armoury.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantArmour, Merchant);
void MerchantArmour::get() {
Maps::MapCastle *map = dynamic_cast<Maps::MapCastle *>(_map);
assert(map);
if (map->_getCounter > 0) {
--map->_getCounter;
findArmor(false);
} else {
noKingsPermission();
}
}
void MerchantArmour::steal() {
findArmor(true);
}
void MerchantArmour::findArmor(bool checkStealing) {
Shared::Character &c = *_game->_party;
if (!checkStealing || !checkCuaghtStealing()) {
uint armorNum = _game->getRandomNumber(1, 5);
Common::String armorStr = _game->_res->ARMOR_NAMES[armorNum];
c._armour[armorNum]->incrQuantity();
if (armorNum == 5)
armorStr = Common::String::format("%s %s", _game->_res->A, armorStr.c_str());
addInfoMsg("");
addInfoMsg(Common::String::format(_game->_res->FIND, armorStr.c_str()));
}
}
void MerchantArmour::talk() {
U1Dialogs::Armoury *dialog = new U1Dialogs::Armoury(_game, _map->getMapStyle() - 2);
dialog->show();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,83 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_ARMOUR_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_ARMOUR_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the armor merchant
*/
class MerchantArmour : public Merchant {
DECLARE_MESSAGE_MAP;
private:
/**
* Handles getting or stealing armor
* @param checkStealing If set, checks for stealing
*/
void findArmor(bool checkStealing);
public:
DECLARE_WIDGET(MerchantArmour)
CLASSDEF;
/**
* Constructor
*/
MerchantArmour(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantArmour(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantArmour(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Does the get action
*/
void get() override;
/**
* Does the steal action
*/
void steal() override;
/**
* Does the talk action
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,66 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_grocer.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/u1dialogs/grocery.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantGrocer, Merchant);
void MerchantGrocer::get() {
Maps::MapCastle *map = dynamic_cast<Maps::MapCastle *>(_map);
assert(map);
if (map->_getCounter > 0) {
--map->_getCounter;
findFood(false);
} else {
noKingsPermission();
}
}
void MerchantGrocer::steal() {
findFood(true);
}
void MerchantGrocer::findFood(bool checkStealing) {
Shared::Character &c = *_game->_party;
if (!checkStealing || !checkCuaghtStealing()) {
uint food = _game->getRandomNumber(2, 31);
c._food += food;
addInfoMsg("");
addInfoMsg(Common::String::format(_game->_res->GROCERY_FIND_PACKS, food));
}
}
void MerchantGrocer::talk() {
U1Dialogs::Grocery *grocery = new U1Dialogs::Grocery(_game, _map->getMapIndex());
grocery->show();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,83 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_GROCER_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_GROCER_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the grocer
*/
class MerchantGrocer : public Merchant {
DECLARE_MESSAGE_MAP;
private:
/**
* Handles getting or stealing food
* @param checkStealing If set, checks for stealing
*/
void findFood(bool checkStealing);
public:
DECLARE_WIDGET(MerchantGrocer)
CLASSDEF;
/**
* Constructor
*/
MerchantGrocer(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantGrocer(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantGrocer(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Does the get action
*/
void get() override;
/**
* Does the steal action
*/
void steal() override;
/**
* Talk to an NPC
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,38 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_magic.h"
#include "ultima/ultima1/u1dialogs/magic.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantMagic, Merchant);
void MerchantMagic::talk() {
U1Dialogs::Magic *dialog = new U1Dialogs::Magic(_game, _map->getMapStyle() - 2);
dialog->show();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,67 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_MAGIC_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_MAGIC_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the magic merchant
*/
class MerchantMagic : public Merchant {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(MerchantMagic)
CLASSDEF;
/**
* Constructor
*/
MerchantMagic(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantMagic(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantMagic(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Do a talk action
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,40 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_tavern.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/u1dialogs/tavern.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantTavern, Merchant);
void MerchantTavern::talk() {
Maps::MapCityCastle *map = static_cast<Maps::MapCityCastle *>(_map);
U1Dialogs::Tavern *dialog = new U1Dialogs::Tavern(_game, map, _map->getMapStyle() - 2);
dialog->show();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,67 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_TAVERN_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_TAVERN_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the tavern keeper
*/
class MerchantTavern : public Merchant {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(MerchantTavern)
CLASSDEF;
/**
* Constructor
*/
MerchantTavern(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantTavern(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantTavern(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Do the talk action
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,38 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_transport.h"
#include "ultima/ultima1/u1dialogs/transports.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantTransport, Merchant);
void MerchantTransport::talk() {
U1Dialogs::Transports *dialog = new U1Dialogs::Transports(_game, _map->getMapStyle() - 2);
dialog->show();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,67 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_TRANSPORT_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_TRANSPORT_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the transport merchant
*/
class MerchantTransport : public Merchant {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(MerchantTransport)
CLASSDEF;
/**
* Constructor
*/
MerchantTransport(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantTransport(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantTransport(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Do the talk action
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,67 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/merchant_weapons.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/u1dialogs/weaponry.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(MerchantWeapons, Merchant);
void MerchantWeapons::get() {
Maps::MapCastle *map = dynamic_cast<Maps::MapCastle *>(_map);
assert(map);
if (map->_getCounter > 0) {
--map->_getCounter;
findWeapon(false);
} else {
noKingsPermission();
}
}
void MerchantWeapons::steal() {
findWeapon(true);
}
void MerchantWeapons::findWeapon(bool checkStealing) {
Shared::Character &c = *_game->_party;
if (!checkStealing || !checkCuaghtStealing()) {
uint weaponNum = _game->getRandomNumber(1, 15);
const char *weaponStr = _game->_res->WEAPON_NAMES_ARTICLE[weaponNum];
c._weapons[weaponNum]->incrQuantity();
addInfoMsg("");
addInfoMsg(Common::String::format(_game->_res->FIND, weaponStr));
}
}
void MerchantWeapons::talk() {
U1Dialogs::Weaponry *dialog = new U1Dialogs::Weaponry(_game, _map->getMapStyle() - 2);
dialog->show();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,83 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_MERCHANT_WEAPONS_H
#define ULTIMA_ULTIMA1_WIDGETS_MERCHANT_WEAPONS_H
#include "ultima/ultima1/widgets/merchant.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Implements the weapons merchant
*/
class MerchantWeapons : public Merchant {
DECLARE_MESSAGE_MAP;
private:
/**
* Handles getting or stealing weapons
* @param checkStealing If set, checks for stealing
*/
void findWeapon(bool checkStealing);
public:
DECLARE_WIDGET(MerchantWeapons)
CLASSDEF;
/**
* Constructor
*/
MerchantWeapons(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Merchant(game, map, 50, hitPoints) {}
/**
* Constructor
*/
MerchantWeapons(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Merchant(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
MerchantWeapons(Ultima1Game *game, Maps::MapBase *map) : Merchant(game, map, 50) {}
/**
* Does the get action
*/
void get() override;
/**
* Does the steal action
*/
void steal() override;
/**
* Talk to an NPC
*/
void talk() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,127 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/overworld_monster.h"
#include "ultima/ultima1/widgets/attack_effect.h"
#include "ultima/ultima1/core/party.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/maps/map_widget.h"
#include "ultima/shared/core/utils.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
OverworldMonster::OverworldMonster(Shared::Game *game, Shared::Maps::MapBase *map, uint tileNum, int hitPoints,
const Point &pt, Shared::Maps::Direction dir) : OverworldWidget(game, map, tileNum, pt, dir),
Shared::Maps::Creature(game, map, hitPoints) {
_monsterId = (OverworldMonsterId)((tileNum - 19) / 2);
Ultima1Game *g = static_cast<Ultima1Game *>(game);
_name = g->_res->OVERWORLD_MONSTER_NAMES[_monsterId];
_attackStrength = g->_res->OVERWORLD_MONSTER_DAMAGE[_monsterId];
}
void OverworldMonster::synchronize(Common::Serializer &s) {
OverworldWidget::synchronize(s);
Creature::synchronize(s);
s.syncAsUint16LE(_monsterId);
s.syncAsUint16LE(_attackStrength);
}
uint OverworldMonster::attackDistance() const {
Point playerPos = _map->_playerWidget->_position;
Point diff = playerPos - _position;
int threshold = _tileNum == 23 || _tileNum == 25 || _tileNum == 31 || _tileNum == 47 ? 3 : 1;
int distance = MIN(diff.x, diff.y);
return distance <= threshold ? threshold : 0;
}
void OverworldMonster::movement() {
// TODO
}
void OverworldMonster::attackParty() {
Ultima1Game *game = dynamic_cast<Ultima1Game *>(_game);
assert(game);
Point playerPos = _map->_playerWidget->_position;
Point diff = playerPos - _position;
Point delta(SGN(diff.x), SGN(diff.y));
//Point tempDiff;
//int maxDistance = attackDistance();
Shared::Maps::MapTile mapTile;
//Shared::Character &c = *_game->_party;
//uint threshold, damage;
// Print out the monster attacking
addInfoMsg(Common::String::format("%s %s %s", _name.c_str(), game->_res->ATTACKS, _name.c_str()), false);
/* TODO: Refactor to use attack effects
// Set up widget for displaying the moving hit circle
Hit *hit = new Hit(_game, _map);
_map->addWidget(hit);
//
int distance = 1;
do {
tempDiff.x = delta.x * distance + diff.x;
tempDiff.y = delta.y * distance + diff.y;
hit->_position = playerPos + tempDiff;
_game->sleep(50);
} while (++distance <= maxDistance && mapTile._tileId != 3 && (tempDiff.x != 0 || tempDiff.y != 0));
// Calculate damage threshold
threshold = (c._stamina / 2) + (c._equippedArmour * 8) + 56;
if (tempDiff.x == 0 && tempDiff.y == 0 && _game->getRandomNumber(1, 255) > threshold) {
hit->_position = playerPos;
_game->playFX(2);
damage = _game->getRandomNumber(1, _attackStrength * 2 + 1);
c._hitPoints -= damage;
if (_name.size() > 8) {
addInfoMsg("");
addInfoMsg(Common::String::format("%s %2d %s", game->_res->HIT, damage, game->_res->DAMAGE));
} else {
addInfoMsg(Common::String::format(" %s", game->_res->HIT));
addInfoMsg(Common::String::format("%2d %s", damage, game->_res->DAMAGE));
}
} else {
if (_name.size() > 8)
addInfoMsg("", true);
else
addInfoMsg(" ", false);
addInfoMsg(game->_res->MISSED);
}
_map->removeWidget(hit);
*/
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,113 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_OVERWORLD_MONSTER_H
#define ULTIMA_ULTIMA1_WIDGETS_OVERWORLD_MONSTER_H
#include "ultima/ultima1/widgets/overworld_widget.h"
#include "ultima/shared/maps/creature.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
enum OverworldMonsterId {
NESS_CREATURE = 0, GIANT_SQUID, DRAGON_TURTLE, PIRATE_SHIP, HOOD, BEAR, HIDDEN_ARCHER, DARK_KNIGHT,
EVIL_TRENT, THIEF, ORC, KNIGHT, NECROMANCER, EVIL_RANGER, WANDERING_WARLOCK
};
/**
* Implements monsters on the overworld
*/
class OverworldMonster : public OverworldWidget, public Shared::Maps::Creature {
private:
OverworldMonsterId _monsterId;
uint _attackStrength;
protected:
/**
* Handles attacking the party
*/
void attackParty() override;
/**
* Handles moving creatures
*/
void movement() override;
public:
DECLARE_WIDGET(OverworldMonster)
/**
* Constructor
*/
OverworldMonster(Shared::Game *game, Shared::Maps::MapBase *map, uint tileNum, int hitPoints,
const Point &pt, Shared::Maps::Direction dir = Shared::Maps::DIR_NONE);
/**
* Constructor
*/
OverworldMonster(Shared::Game *game, Shared::Maps::MapBase *map) : OverworldWidget(game, map),
Shared::Maps::Creature(game, map), _monsterId(NESS_CREATURE), _attackStrength(0) {}
/**
* Destructor
*/
~OverworldMonster() override {}
/**
* Returns the monster's type
*/
OverworldMonsterId id() const { return _monsterId; }
/**
* Handles loading and saving games
*/
void synchronize(Common::Serializer &s) override;
/**
* Returns either the maximum attack distance for a monster, or 0 if the monster is beyond
* that distance from the player
*/
uint attackDistance() const override;
};
/**
* Enemy vessels on the overworld
*/
class EnemyVessel : public OverworldMonster {
public:
/**
* Constructor
*/
EnemyVessel(Shared::Game *game, Shared::Maps::MapBase *map, uint tileNum, int hitPoints,
const Point &pt, Shared::Maps::Direction dir = Shared::Maps::DIR_NONE) :
OverworldMonster(game, map, tileNum, hitPoints, pt, dir) {}
/**
* Constructor
*/
EnemyVessel(Shared::Game *game, Shared::Maps::MapBase *map) : OverworldMonster(game, map) {}
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,61 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/overworld_widget.h"
#include "ultima/ultima1/maps/map_base.h"
#include "ultima/ultima1/maps/map_tile.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/early/ultima_early.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
Ultima1Game *OverworldWidget::getGame() const {
return static_cast<Ultima1Game *>(_game);
}
Maps::MapBase *OverworldWidget::getMap() const {
return static_cast<Maps::MapBase *>(_map);
}
void OverworldWidget::synchronize(Common::Serializer &s) {
MapWidget::synchronize(s);
s.syncAsUint16LE(_tileNum);
}
Shared::Maps::MapWidget::CanMove OverworldWidget::canMoveTo(const Point &destPos) {
Shared::Maps::MapWidget::CanMove result = Shared::Maps::MapWidget::canMoveTo(destPos);
if (result != Shared::Maps::MapWidget::UNSET)
return result;
Maps::U1MapTile tile;
getMap()->getTileAt(destPos, &tile);
// Default mobility for most monsters and transports is overland only
return tile.isGround() ? Shared::Maps::MapWidget::YES : Shared::Maps::MapWidget::NO;
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,91 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_OVERWORLD_WIDGET_H
#define ULTIMA_ULTIMA1_WIDGETS_OVERWORLD_WIDGET_H
#include "ultima/shared/maps/map.h"
#include "ultima/shared/maps/map_widget.h"
namespace Ultima {
namespace Ultima1 {
class Ultima1Game;
namespace Maps {
class MapBase;
}
namespace Widgets {
/**
* Encapsulated class for drawing widgets within dungeons
*/
class OverworldWidget : public Shared::Maps::MapWidget {
protected:
/**
* Gets the Ultima 1 game
*/
Ultima1Game *getGame() const;
/**
* Gets the Ultima 1 map
*/
Maps::MapBase *getMap() const;
public:
Common::String _name;
uint _tileNum;
public:
DECLARE_WIDGET(OverworldWidget)
/**
* Constructor
*/
OverworldWidget(Shared::Game *game, Shared::Maps::MapBase *map, uint tileNum, const Point &pt, Shared::Maps::Direction dir = Shared::Maps::DIR_NONE) :
Shared::Maps::MapWidget(game, map, pt, dir), _tileNum(tileNum) {}
/**
* Constructor
*/
OverworldWidget(Shared::Game *game, Shared::Maps::MapBase *map) : Shared::Maps::MapWidget(game, map),
_tileNum(0) {}
/**
* Get the tile number for the person
*/
uint getTileNum() const override { return _tileNum; }
/**
* Handles loading and saving games
*/
void synchronize(Common::Serializer &s) override;
/**
* Returns true if the given widget can move to a given position on the map
*/
CanMove canMoveTo(const Point &destPos) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,63 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/person.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/widgets/guard.h"
#include "ultima/ultima1/widgets/princess.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(Person, UrbanWidget);
bool Person::areGuardsHostile() const {
Maps::MapCityCastle *cityCastle = static_cast<Maps::MapCityCastle *>(_map);
return cityCastle->_guardsHostile;
}
int Person::getRandomDelta() const {
return _game->getRandomNumber(2) - 1;
}
void Person::synchronize(Common::Serializer &s) {
UrbanWidget::synchronize(s);
Creature::synchronize(s);
}
bool Person::subtractHitPoints(uint amount) {
bool result = Shared::Maps::Creature::subtractHitPoints(amount);
if (result) {
// Common code for gaining experience for killing different kinds of people
Shared::Character &c = *_game->_party;
if (dynamic_cast<Widgets::Princess *>(this) == nullptr)
c._experience++;
if (dynamic_cast<Widgets::Guard *>(this))
c._experience += 14;
}
return result;
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,97 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_PERSON_H
#define ULTIMA_ULTIMA1_WIDGETS_PERSON_H
#include "ultima/ultima1/widgets/urban_widget.h"
#include "ultima/ultima1/maps/map.h"
#include "ultima/ultima1/maps/map_base.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/maps/creature.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Base class for NPC creatures
*/
class Person : public UrbanWidget, public Shared::Maps::Creature {
DECLARE_MESSAGE_MAP;
protected:
Ultima1Game *_game;
Maps::MapBase *_map;
protected:
/**
* Returns true if the guards are currently hostile
*/
bool areGuardsHostile() const;
/**
* Returns a random movement delta of -1, 0, or 1
*/
int getRandomDelta() const;
/**
* Returns a random movement delta
*/
Point getRandomMoveDelta() const {
return Point(getRandomDelta(), getRandomDelta());
}
public:
CLASSDEF;
/**
* Constructor
*/
Person(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
UrbanWidget(game, map, tileNum), Shared::Maps::Creature(game, map, hitPoints), _game(game), _map(map) {}
/**
* Constructor
*/
Person(Ultima1Game *game, Maps::MapBase *map, uint tileNum) :
UrbanWidget(game, map, tileNum), Shared::Maps::Creature(game, map), _game(game), _map(map) {}
/**
* Handles loading and saving data
*/
void synchronize(Common::Serializer &s) override;
/**
* Talk to an NPC
*/
virtual void talk() {}
/**
* Removes hit points from a creature
* @param amount Amount to remove
* @returns Returns true if kills the creature
*/
bool subtractHitPoints(uint amount) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,71 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/princess.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/shared/core/utils.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
void Princess::movement() {
if (!areGuardsHostile()) {
// Until guards turn hostile, the princesses exhibit standard wench behaviour
Wench::movement();
} else {
// When the guards are hostile, keep the princess moving towards the player
Point playerPos = _map->_playerWidget->_position;
Point delta(SGN(_position.x - playerPos.x), SGN(_position.y - playerPos.y));
bool moved = false;
// Randomly choose whether to give precedence to a X or Y move
if (_game->getRandomNumber(1, 100) >= 50) {
// Delta X comes first
if (delta.x != 0)
moved = canMoveTo(Point(delta.x, 0));
if (!moved && delta.y != 0)
moved = canMoveTo(Point(0, delta.y));
} else {
// Delta Y comes first
if (delta.y != 0)
moved = canMoveTo(Point(0, delta.y));
if (!moved && delta.x != 0)
moved = canMoveTo(Point(delta.x, 0));
}
if (moved)
_game->playFX(4);
}
}
bool Princess::subtractHitPoints(uint amount) {
bool result = Person::subtractHitPoints(amount);
if (result)
// Princess is dead, you monster. So you can no longer be credited with freeing them
static_cast<Maps::MapCastle *>(_map)->_freeingPrincess = false;
return result;
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,66 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_PRINCESS_H
#define ULTIMA_ULTIMA1_WIDGETS_PRINCESS_H
#include "ultima/ultima1/widgets/wench.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Handles the princess NPCs
*/
class Princess : public Wench {
protected:
/**
* Handles moving creatures
*/
void movement() override;
public:
DECLARE_WIDGET(Princess)
/**
* Constructor
*/
Princess(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Wench(game, map, 22, hitPoints) {}
/**
* Constructor
*/
Princess(Ultima1Game *game, Maps::MapBase *map) : Wench(game, map, 22) {}
/**
* Removes hit points from a creature
* @param amount Amount to remove
* @returns Returns true if kills the creature
*/
bool subtractHitPoints(uint amount) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,154 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/transport.h"
#include "ultima/ultima1/game.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/maps/map.h"
#include "ultima/ultima1/maps/map_tile.h"
#include "ultima/ultima1/maps/map_overworld.h"
#include "common/algorithm.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
TransportOnFoot::TransportOnFoot(Ultima1Game *game, Maps::MapBase *map) : OverworldWidget(game, map) {
_name = game->_res->TRANSPORT_NAMES[0];
}
uint TransportOnFoot::getTileNum() const {
return 8;
}
/*-------------------------------------------------------------------*/
Transport::Transport(Ultima1Game *game, Maps::MapBase *map, uint transportId) :
OverworldWidget(game, map), _transportId(transportId) {
_name = game->_res->TRANSPORT_NAMES[transportId];
}
void Transport::board() {
assert(dynamic_cast<Widgets::TransportOnFoot *>(_map->_playerWidget));
_map->removeWidget(_map->_playerWidget);
_map->_playerWidget = this;
addInfoMsg(Common::String::format(" %s", _name.c_str()));
_game->endOfTurn();
}
void Transport::disembark() {
Maps::U1MapTile tile;
Point pt = _map->getPosition();
Maps::MapOverworld *map = static_cast<Maps::MapOverworld *>(_map);
// WORKAROUND: The original allowed dis-embarking if ground tiles were within two tiles of the transport.
// It makes better sense to only allow if it's within one tile of the transport (i.e. the ground is adjacent)
bool hasGround = false;
for (int deltaY = -1; deltaY <= 1 && !hasGround; ++deltaY) {
for (int deltaX = -1; deltaX <= 1 && !hasGround; ++deltaX) {
_map->getTileAt(pt + Point(deltaX, deltaY), &tile);
hasGround = tile._tileId != Maps::OTILE_OCEAN;
}
}
if (tile._tileId > Maps::OTILE_WOODS || !hasGround) {
addInfoMsg(getGame()->_res->CANT_LEAVE_IT_HERE);
} else {
map->addOnFoot();
}
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(Horse, Transport);
Horse::Horse(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 1) {
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(Cart, Transport);
Cart::Cart(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 2) {
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(Raft, Transport);
Raft::Raft(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 3) {
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(Frigate, Transport);
Frigate::Frigate(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 4) {
}
Common::String Frigate::getWeaponsName() {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
return game->_res->TRANSPORT_WEAPONS[0];
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(Aircar, Transport);
Aircar::Aircar(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 5) {
}
Common::String Aircar::getWeaponsName() {
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
return game->_res->TRANSPORT_WEAPONS[1];
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(Shuttle, Transport);
Shuttle::Shuttle(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 6),
_space1(1000), _space2(1000) {
}
void Shuttle::synchronize(Common::Serializer &s) {
Transport::synchronize(s);
s.syncAsUint16LE(_space1);
s.syncAsUint16LE(_space2);
}
/*-------------------------------------------------------------------*/
EMPTY_MESSAGE_MAP(TimeMachine, Transport);
TimeMachine::TimeMachine(Ultima1Game *game, Maps::MapBase *map) : Transport(game, map, 7) {
}
void TimeMachine::board() {
// TODO
Transport::board();
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,254 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_TRANSPORT_H
#define ULTIMA_ULTIMA1_WIDGETS_TRANSPORT_H
#include "ultima/ultima1/widgets/overworld_widget.h"
#include "ultima/shared/maps/map_base.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Widget for the player moving within the overworld on foot
*/
class TransportOnFoot : public OverworldWidget {
public:
DECLARE_WIDGET(TransportOnFoot)
/**
* Constructor
*/
TransportOnFoot(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the tile for the transport method
*/
uint getTileNum() const override;
};
/**
* Base class for the different types of transports
*/
class Transport : public OverworldWidget {
protected:
uint _transportId;
public:
/**
* Constructor
*/
Transport(Ultima1Game *game, Maps::MapBase *map, uint transportId);
/**
* Returns true if the player can move onto a tile the widget occupies
*/
bool isBlocking() const override { return false; }
/**
* Board a transport
*/
virtual void board();
/**
* Disembarks from the transport
*/
virtual void disembark();
/**
* Get the name of a transport's weapons
*/
virtual Common::String getWeaponsName() { return ""; }
/**
* Get an Id for the transport type
*/
uint transportId() const { return _transportId; }
};
/**
* Horse widget
*/
class Horse : public Transport {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(Horse);
CLASSDEF;
/**
* Constructor
*/
Horse(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 9; }
};
/**
* Cart widget
*/
class Cart : public Transport {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(Cart);
CLASSDEF;
/**
* Constructor
*/
Cart(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 10; }
};
/**
* Raft widget
*/
class Raft : public Transport {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(Raft);
CLASSDEF;
/**
* Constructor
*/
Raft(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 11; }
};
/**
* Frigate widget
*/
class Frigate : public Transport {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(Frigate);
CLASSDEF;
/**
* Constructor
*/
Frigate(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the name of a transport's weapons
*/
Common::String getWeaponsName() override;
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 12; }
};
/**
* Aircar widget
*/
class Aircar : public Transport {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(Aircar);
CLASSDEF;
/**
* Constructor
*/
Aircar(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the name of a transport's weapons
*/
Common::String getWeaponsName() override;
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 14; }
};
/**
* Shuttle widget
*/
class Shuttle : public Transport {
DECLARE_MESSAGE_MAP;
public:
uint _space1, _space2;
public:
DECLARE_WIDGET(Shuttle);
CLASSDEF;
/**
* Constructor
*/
Shuttle(Ultima1Game *game, Maps::MapBase *map);
/**
* Handles loading and saving data
*/
void synchronize(Common::Serializer &s) override;
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 15; }
};
/**
* Time machine widget
*/
class TimeMachine : public Transport {
DECLARE_MESSAGE_MAP;
public:
DECLARE_WIDGET(TimeMachine);
CLASSDEF;
/**
* Constructor
*/
TimeMachine(Ultima1Game *game, Maps::MapBase *map);
/**
* Get the tile for the transport method
*/
uint getTileNum() const override { return 16; }
/**
* Board a transport
*/
void board() override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,54 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/urban_player.h"
#include "ultima/ultima1/maps/map.h"
#include "ultima/ultima1/game.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
void UrbanPlayer::moveTo(const Point &destPos, Shared::Maps::Direction dir) {
Person::moveTo(destPos, dir);
Shared::Maps::Map *map = _game->getMap();
if (destPos.x < 0 || destPos.y < 0 || destPos.x >= (int)map->width() || destPos.y >= (int)map->height()) {
// Handling for leaving locations by walking off the edge of the map
if (isPrincessSaved())
princessSaved();
// Load the overworld map
map->load(Maps::MAP_OVERWORLD);
}
}
bool UrbanPlayer::isPrincessSaved() const {
return false;
}
void UrbanPlayer::princessSaved() {
// TODO
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,66 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_URBAN_PLAYER_H
#define ULTIMA_ULTIMA1_URBAN_PLAYER_H
#include "ultima/ultima1/widgets/person.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Specialized player class for within cities and castles
*/
class UrbanPlayer : public Person {
private:
/**
* Checks for whether a princess has been saved from a castle being left
*/
bool isPrincessSaved() const;
/**
* Called for a princess being saved
*/
void princessSaved();
public:
DECLARE_WIDGET(UrbanPlayer)
/**
* Constructor
*/
UrbanPlayer(Ultima1Game *game, Maps::MapBase *map) : Person(game, map, 18) {}
/**
* Moves to a given position
* @param destPos Specified new position
* @param dir Optional explicit direction to set. If not specified,
* the direction will be set relative to the position moved from
*/
void moveTo(const Point &destPos, Shared::Maps::Direction dir = Shared::Maps::DIR_NONE) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,62 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/urban_widget.h"
#include "ultima/ultima1/maps/map_city_castle.h"
#include "ultima/ultima1/maps/map_tile.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(UrbanWidget, Shared::Maps::MapWidget);
Shared::Maps::MapWidget::CanMove UrbanWidget::canMoveTo(const Point &destPos) {
Shared::Maps::MapWidget::CanMove result = Shared::Maps::MapWidget::canMoveTo(destPos);
if (result != UNSET)
return result;
// Get the details of the position
Maps::U1MapTile destTile;
_map->getTileAt(destPos, &destTile);
return destTile._tileId == Maps::CTILE_GROUND || destTile._tileId >= Maps::CTILE_POND_EDGE1 ? YES : NO;
}
bool UrbanWidget::moveBy(const Point &delta) {
// TODO: Movement allowed on tile 63.. is this the gate of the princess' cells?
Point newPos = _position + delta;
if (canMoveTo(newPos) == YES) {
_position = newPos;
return true;
} else {
return false;
}
}
void UrbanWidget::synchronize(Common::Serializer &s) {
MapWidget::synchronize(s);
s.syncAsUint16LE(_tileNum);
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,80 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_URBAN_WIDGET_H
#define ULTIMA_ULTIMA1_WIDGETS_URBAN_WIDGET_H
#include "ultima/shared/maps/map_widget.h"
#include "ultima/ultima1/maps/map.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
/**
* Base class for widgets in urban maps
*/
class UrbanWidget : public Shared::Maps::MapWidget {
DECLARE_MESSAGE_MAP;
private:
uint _tileNum;
protected:
CLASSDEF;
/**
* Moves by a given delta if the destination is available
* @param delta Delta to move character by
* @returns True if the move was able to be done
*/
bool moveBy(const Point &delta);
public:
/**
* Constructor
*/
UrbanWidget(Shared::Game *game, Shared::Maps::MapBase *map, uint tileNum) :
Shared::Maps::MapWidget(game, map), _tileNum(tileNum) {}
/**
* Destructor
*/
~UrbanWidget() override {}
/**
* Get the tile number for the person
*/
uint getTileNum() const override { return _tileNum; }
/**
* Returns true if the given widget can move to a given position on the map
*/
CanMove canMoveTo(const Point &destPos) override;
/**
* Handles loading and saving games
*/
void synchronize(Common::Serializer &s) override;
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,46 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima1/widgets/wench.h"
#include "ultima/ultima1/maps/map.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
EMPTY_MESSAGE_MAP(Wench, Person);
void Wench::movement() {
if (!areGuardsHostile()) {
// Get a random new position
Point delta = getRandomMoveDelta();
Point newPos = _position + delta;
if (canMoveTo(newPos) == YES) {
_position = newPos;
_game->playFX(4);
}
}
}
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima

View File

@@ -0,0 +1,69 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_ULTIMA1_WIDGETS_WENCH_H
#define ULTIMA_ULTIMA1_WIDGETS_WENCH_H
#include "ultima/ultima1/widgets/person.h"
namespace Ultima {
namespace Ultima1 {
namespace Widgets {
class Wench : public Person {
DECLARE_MESSAGE_MAP;
protected:
/**
* Handles moving creatures
*/
void movement() override;
public:
DECLARE_WIDGET(Wench)
CLASSDEF;
/**
* Constructor
*/
Wench(Ultima1Game *game, Maps::MapBase *map, int hitPoints) :
Person(game, map, 50, hitPoints) {}
/**
* Constructor
*/
Wench(Ultima1Game *game, Maps::MapBase *map, uint tileNum, int hitPoints) :
Person(game, map, tileNum, hitPoints) {}
/**
* Constructor
*/
Wench(Ultima1Game *game, Maps::MapBase *map) : Person(game, map, 50) {}
/**
* Destructor
*/
~Wench() override {}
};
} // End of namespace Widgets
} // End of namespace Ultima1
} // End of namespace Ultima
#endif