/* 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 .
*
*/
#ifndef ULTIMA4_GAME_PLAYER_H
#define ULTIMA4_GAME_PLAYER_H
#include "ultima/ultima4/game/creature.h"
#include "ultima/ultima4/map/direction.h"
#include "ultima/ultima4/core/observable.h"
#include "ultima/ultima4/filesys/savegame.h"
#include "ultima/ultima4/game/script.h"
#include "ultima/ultima4/map/tile.h"
#include "ultima/ultima4/core/types.h"
namespace Ultima {
namespace Ultima4 {
class Armor;
class Party;
class Weapon;
typedef Std::vector PartyMemberVector;
#define ALL_PLAYERS -1
enum KarmaAction {
KA_FOUND_ITEM,
KA_STOLE_CHEST,
KA_GAVE_TO_BEGGAR,
KA_GAVE_ALL_TO_BEGGAR,
KA_BRAGGED,
KA_HUMBLE,
KA_HAWKWIND,
KA_MEDITATION,
KA_BAD_MANTRA,
KA_ATTACKED_GOOD,
KA_FLED_EVIL,
KA_FLED_GOOD,
KA_HEALTHY_FLED_EVIL,
KA_KILLED_EVIL,
KA_SPARED_GOOD,
KA_DONATED_BLOOD,
KA_DIDNT_DONATE_BLOOD,
KA_CHEAT_REAGENTS,
KA_DIDNT_CHEAT_REAGENTS,
KA_USED_SKULL,
KA_DESTROYED_SKULL
};
enum HealType {
HT_NONE,
HT_CURE,
HT_FULLHEAL,
HT_RESURRECT,
HT_HEAL,
HT_CAMPHEAL,
HT_INNHEAL
};
enum InventoryItem {
INV_NONE,
INV_WEAPON,
INV_ARMOR,
INV_FOOD,
INV_REAGENT,
INV_GUILDITEM,
INV_HORSE
};
enum CannotJoinError {
JOIN_SUCCEEDED,
JOIN_NOT_EXPERIENCED,
JOIN_NOT_VIRTUOUS
};
enum EquipError {
EQUIP_SUCCEEDED,
EQUIP_NONE_LEFT,
EQUIP_CLASS_RESTRICTED
};
/**
* PartyMember class
*/
class PartyMember : public Creature, public Script::Provider {
public:
PartyMember(Party *p, SaveGamePlayerRecord *pr);
virtual ~PartyMember();
/**
* Notify the party that this player has changed somehow
*/
void notifyOfChange();
/**
* Used to translate script values into something useful
*/
Common::String translate(Std::vector &parts) override;
// Accessor methods
int getHp() const override;
int getMaxHp() const {
return _player->_hpMax;
}
int getExp() const {
return _player->_xp;
}
int getStr() const {
return _player->_str;
}
int getDex() const {
return _player->_dex;
}
int getInt() const {
return _player->_intel;
}
int getMp() const {
return _player->_mp;
}
/**
* Determine the most magic points a character could have
* given his class and intelligence.
*/
int getMaxMp() const;
const Weapon *getWeapon() const;
const Armor *getArmor() const;
Common::String getName() const override;
SexType getSex() const;
ClassType getClass() const;
CreatureStatus getState() const override;
/**
* Determine what level a character has.
*/
int getRealLevel() const;
/**
* Determine the highest level a character could have with the number
* of experience points he has.
*/
int getMaxLevel() const;
/**
* Adds a status effect to the player
*/
void addStatus(StatusType status) override;
/**
* Adjusts the player's mp by 'pts'
*/
void adjustMp(int pts);
/**
* Advances the player to the next level if they have enough experience
*/
void advanceLevel();
/**
* Apply an effect to the party member
*/
void applyEffect(TileEffect effect);
/**
* Award a player experience points. Maxs out the players xp at 9999.
*/
void awardXp(int xp);
/**
* Perform a certain type of healing on the party member
*/
bool heal(HealType type);
/**
* Remove status effects from the party member
*/
void removeStatus(StatusType status) override;
void setHp(int hp) override;
void setMp(int mp);
EquipError setArmor(const Armor *a);
EquipError setWeapon(const Weapon *w);
/**
* Applies damage to a player, and changes status to dead if hit
* points drop below zero.
*
* Byplayer is ignored for now, since it should always be false for U4. (Is
* there anything special about being killed by a party member in U5?) Also
* keeps interface consistent for virtual base function Creature::applydamage()
*/
bool applyDamage(int damage, bool byplayer = false) override;
int getAttackBonus() const override;
int getDefense() const override;
bool dealDamage(Creature *m, int damage) override;
/**
* Calculate damage for an attack.
*/
int getDamage();
/**
* Returns the tile that will be displayed when the party
* member's attack hits
*/
const Common::String &getHitTile() const override;
/**
* Returns the tile that will be displayed when the party
* member's attack fails
*/
const Common::String &getMissTile() const override;
bool isDead();
bool isDisabled();
/**
* Lose the equipped weapon for the player (flaming oil, ranged daggers, etc.)
* Returns the number of weapons left of that type, including the one in
* the players hand
*/
int loseWeapon();
/**
* Put the party member to sleep
*/
void putToSleep() override;
/**
* Wakes up the party member
*/
void wakeUp() override;
protected:
static MapTile tileForClass(int klass);
SaveGamePlayerRecord *_player;
class Party *_party;
};
/**
* Party class
*/
class PartyEvent {
public:
enum Type {
GENERIC,
LOST_EIGHTH,
ADVANCED_LEVEL,
STARVING,
TRANSPORT_CHANGED,
PLAYER_KILLED,
ACTIVE_PLAYER_CHANGED,
MEMBER_JOINED,
PARTY_REVIVED,
INVENTORY_ADDED
};
PartyEvent(Type type, PartyMember *partyMember) : _type(type), _player(partyMember) { }
Type _type;
PartyMember *_player;
};
typedef Std::vector PartyMemberVector;
class Party : public Observable, public Script::Provider {
friend class PartyMember;
public:
Party(SaveGame *saveGame);
virtual ~Party();
/**
* Notify the party that something about it has changed
*/
void notifyOfChange(PartyMember *partyMember = 0, PartyEvent::Type = PartyEvent::GENERIC);
// Used to translate script values into something useful
Common::String translate(Std::vector &parts) override;
void adjustFood(int food);
void adjustGold(int gold);
/**
* Adjusts the avatar's karma level for the given action. Notify
* observers with a lost eighth event if the player has lost
* avatarhood.
*/
void adjustKarma(KarmaAction action);
/**
* Apply effects to the entire party
*/
void applyEffect(TileEffect effect);
/**
* Attempt to elevate in the given virtue
*/
bool attemptElevation(Virtue virtue);
/**
* Burns a torch's duration down a certain number of turns
*/
void burnTorch(int turns = 1);
/**
* Returns true if the party can enter the shrine
*/
bool canEnterShrine(Virtue virtue);
/**
* Returns true if the person can join the party
*/
bool canPersonJoin(Common::String name, Virtue *v);
/**
* Damages the party's ship
*/
void damageShip(uint pts);
/**
* Donates 'quantity' gold. Returns true if the donation succeeded,
* or false if there was not enough gold to make the donation
*/
bool donate(int quantity);
/**
* Ends the party's turn
*/
void endTurn();
/**
* Adds a chest worth of gold to the party's inventory
*/
int getChest();
/**
* Returns the number of turns a currently lit torch will last (or 0 if no torch lit)
*/
int getTorchDuration() const;
/**
* Heals the ship's hull strength by 'pts' points
*/
void healShip(uint pts);
/**
* Returns true if the balloon is currently in the air
*/
bool isFlying() const;
/**
* Whether or not the party can make an action.
*/
bool isImmobilized();
/**
* Whether or not all the party members are dead.
*/
bool isDead();
/**
* Returns true if the person with that name
* is already in the party
*/
bool isPersonJoined(Common::String name);
/**
* Attempts to add the person to the party.
* Returns JOIN_SUCCEEDED if successful.
*/
CannotJoinError join(Common::String name);
/**
* Lights a torch with a default duration of 100
*/
bool lightTorch(int duration = 100, bool loseTorch = true);
/**
* Extinguishes a torch
*/
void quenchTorch();
/**
* Revives the party after the entire party has been killed
*/
void reviveParty();
MapTile getTransport() const;
void setTransport(MapTile transport);
void setShipHull(int str);
Direction getDirection() const;
void setDirection(Direction dir);
void adjustReagent(int reagent, int amt);
int getReagent(int reagent) const;
short *getReagentPtr(int reagent) const;
void setActivePlayer(int p);
int getActivePlayer() const;
void swapPlayers(int p1, int p2);
/**
* Returns the size of the party
*/
int size() const;
/**
* Returns a pointer to the party member indicated
*/
PartyMember *member(int index) const;
private:
void syncMembers();
PartyMemberVector _members;
SaveGame *_saveGame;
MapTile _transport;
int _torchDuration;
int _activePlayer;
#ifdef IOS_ULTIMA4
friend void U4IOS::syncPartyMembersWithSaveGame();
#endif
};
bool isPartyMember(Object *punknown);
} // End of namespace Ultima4
} // End of namespace Ultima
#endif