Merge branch 'master' into videoplayback

Conflicts:
	apps/openmw/mwrender/renderingmanager.cpp
pull/16/head
scrawl 12 years ago
commit c4facc233e

1
.gitignore vendored

@ -14,3 +14,4 @@ Makefile
makefile
data
*.kdev4
CMakeLists.txt.user

4
.gitmodules vendored

@ -1,3 +1 @@
[submodule "extern/shiny"]
path = extern/shiny
url = git://github.com/scrawl/shiny.git

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version
set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 18)
set (OPENMW_VERSION_MINOR 19)
set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -306,7 +306,7 @@ endif()
# Compiler settings
if (CMAKE_COMPILER_IS_GNUCC)
add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder)
add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++0x -pedantic)
# Silence warnings in OGRE headers. Remove once OGRE got fixed!
add_definitions (-Wno-ignored-qualifiers)
@ -659,7 +659,6 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
#INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" )
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" )
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" )
INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.cfg" DESTINATION "${SYSCONFDIR}" )
# Install resources
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )

@ -1,5 +1,7 @@
set(ESMTOOL
esmtool.cpp
labels.hpp
labels.cpp
record.hpp
record.cpp
)

@ -13,7 +13,7 @@
#include "record.hpp"
#define ESMTOOL_VERSION 1.1
#define ESMTOOL_VERSION 1.2
// Create a local alias for brevity
namespace bpo = boost::program_options;
@ -57,6 +57,8 @@ struct Arguments
std::string encoding;
std::string filename;
std::string outname;
std::vector<std::string> types;
ESMData data;
ESM::ESMReader reader;
@ -70,7 +72,12 @@ bool parseOptions (int argc, char** argv, Arguments &info)
desc.add_options()
("help,h", "print help message.")
("version,v", "print version information and quit.")
("raw,r", "Show an unformattet list of all records and subrecords.")
("raw,r", "Show an unformatted list of all records and subrecords.")
// The intention is that this option would interact better
// with other modes including clone, dump, and raw.
("type,t", bpo::value< std::vector<std::string> >(),
"Show only records of this type (four character record code). May "
"be specified multiple times. Only affects dump mode.")
("quiet,q", "Supress all record information. Useful for speed tests.")
("loadcells,C", "Browse through contents of all cells.")
@ -122,6 +129,9 @@ bool parseOptions (int argc, char** argv, Arguments &info)
return false;
}
if (variables.count("type") > 0)
info.types = variables["type"].as< std::vector<std::string> >();
info.mode = variables["mode"].as<std::string>();
if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp"))
{
@ -306,14 +316,23 @@ int load(Arguments& info)
uint32_t flags;
esm.getRecHeader(flags);
// Is the user interested in this record type?
bool interested = true;
if (info.types.size() > 0)
{
std::vector<std::string>::iterator match;
match = std::find(info.types.begin(), info.types.end(),
n.toString());
if (match == info.types.end()) interested = false;
}
std::string id = esm.getHNOString("NAME");
if(!quiet)
if(!quiet && interested)
std::cout << "\nRecord: " << n.toString()
<< " '" << id << "'\n";
EsmTool::RecordBase *record =
EsmTool::RecordBase::create(n.val);
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
if (record == 0) {
if (std::find(skipped.begin(), skipped.end(), n.val) == skipped.end())
@ -326,18 +345,16 @@ int load(Arguments& info)
if (quiet) break;
std::cout << " Skipping\n";
} else {
if (record->getType() == ESM::REC_GMST) {
if (record->getType().val == ESM::REC_GMST) {
// preset id for GameSetting record
record->cast<ESM::GameSetting>()->get().mId = id;
}
record->setId(id);
record->setFlags((int) flags);
record->load(esm);
if (!quiet) {
record->print();
}
if (!quiet && interested) record->print();
if (record->getType() == ESM::REC_CELL && loadCells) {
if (record->getType().val == ESM::REC_CELL && loadCells) {
loadCell(record->cast<ESM::Cell>()->get(), esm, info);
}
@ -434,7 +451,7 @@ int clone(Arguments& info)
{
EsmTool::RecordBase *record = *it;
name.val = record->getType();
name.val = record->getType().val;
esm.startRecord(name.toString(), record->getFlags());

@ -0,0 +1,881 @@
#include "labels.hpp"
#include <components/esm/loadbody.hpp>
#include <components/esm/loadcell.hpp>
#include <components/esm/loadcont.hpp>
#include <components/esm/loadcrea.hpp>
#include <components/esm/loadlevlist.hpp>
#include <components/esm/loadligh.hpp>
#include <components/esm/loadmgef.hpp>
#include <components/esm/loadnpc.hpp>
#include <components/esm/loadrace.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/loadweap.hpp>
#include <components/esm/aipackage.hpp>
#include <iostream>
#include <boost/format.hpp>
std::string bodyPartLabel(char idx)
{
const char *bodyPartLabels[] = {
"Head",
"Hair",
"Neck",
"Cuirass",
"Groin",
"Skirt",
"Right Hand",
"Left Hand",
"Right Wrist",
"Left Wrist",
"Shield",
"Right Forearm",
"Left Forearm",
"Right Upperarm",
"Left Upperarm",
"Right Foot",
"Left Foot",
"Right Ankle",
"Left Ankle",
"Right Knee",
"Left Knee",
"Right Leg",
"Left Leg",
"Right Shoulder",
"Left Shoulder",
"Weapon",
"Tail"
};
if ((int)idx >= 0 && (int)(idx) <= 26)
return bodyPartLabels[(int)(idx)];
else
return "Invalid";
}
std::string meshPartLabel(char idx)
{
const char *meshPartLabels[] = {
"Head",
"Hair",
"Neck",
"Chest",
"Groin",
"Hand",
"Wrist",
"Forearm",
"Upperarm",
"Foot",
"Ankle",
"Knee",
"Upper Leg",
"Clavicle",
"Tail"
};
if ((int)(idx) >= 0 && (int)(idx) <= ESM::BodyPart::MP_Tail)
return meshPartLabels[(int)(idx)];
else
return "Invalid";
}
std::string meshTypeLabel(char idx)
{
const char *meshTypeLabels[] = {
"Skin",
"Clothing",
"Armor"
};
if ((int)(idx) >= 0 && (int)(idx) <= ESM::BodyPart::MT_Armor)
return meshTypeLabels[(int)(idx)];
else
return "Invalid";
}
std::string clothingTypeLabel(int idx)
{
const char *clothingTypeLabels[] = {
"Pants",
"Shoes",
"Shirt",
"Belt",
"Robe",
"Right Glove",
"Left Glove",
"Skirt",
"Ring",
"Amulet"
};
if (idx >= 0 && idx <= 9)
return clothingTypeLabels[idx];
else
return "Invalid";
}
std::string armorTypeLabel(int idx)
{
const char *armorTypeLabels[] = {
"Helmet",
"Cuirass",
"Left Pauldron",
"Right Pauldron",
"Greaves",
"Boots",
"Left Gauntlet",
"Right Gauntlet",
"Shield",
"Left Bracer",
"Right Bracer"
};
if (idx >= 0 && idx <= 10)
return armorTypeLabels[idx];
else
return "Invalid";
}
std::string dialogTypeLabel(int idx)
{
const char *dialogTypeLabels[] = {
"Topic",
"Voice",
"Greeting",
"Persuasion",
"Journal"
};
if (idx >= 0 && idx <= 4)
return dialogTypeLabels[idx];
else if (idx == -1)
return "Deleted";
else
return "Invalid";
}
std::string questStatusLabel(int idx)
{
const char *questStatusLabels[] = {
"None",
"Name",
"Finished",
"Restart",
"Deleted"
};
if (idx >= 0 && idx <= 4)
return questStatusLabels[idx];
else
return "Invalid";
}
std::string creatureTypeLabel(int idx)
{
const char *creatureTypeLabels[] = {
"Creature",
"Daedra",
"Undead",
"Humanoid",
};
if (idx >= 0 && idx <= 3)
return creatureTypeLabels[idx];
else
return "Invalid";
}
std::string soundTypeLabel(int idx)
{
const char *soundTypeLabels[] = {
"Left Foot",
"Right Foot",
"Swim Left",
"Swim Right",
"Moan",
"Roar",
"Scream",
"Land"
};
if (idx >= 0 && idx <= 7)
return soundTypeLabels[idx];
else
return "Invalid";
}
std::string weaponTypeLabel(int idx)
{
const char *weaponTypeLabels[] = {
"Short Blade One Hand",
"Long Blade One Hand",
"Long Blade Two Hand",
"Blunt One Hand",
"Blunt Two Close",
"Blunt Two Wide",
"Spear Two Wide",
"Axe One Hand",
"Axe Two Hand",
"Marksman Bow",
"Marksman Crossbow",
"Marksman Thrown",
"Arrow",
"Bolt"
};
if (idx >= 0 && idx <= 13)
return weaponTypeLabels[idx];
else
return "Invalid";
}
std::string aiTypeLabel(int type)
{
if (type == ESM::AI_Wander) return "Wander";
else if (type == ESM::AI_Travel) return "Travel";
else if (type == ESM::AI_Follow) return "Follow";
else if (type == ESM::AI_Escort) return "Escort";
else if (type == ESM::AI_Activate) return "Activate";
else return "Invalid";
}
std::string magicEffectLabel(int idx)
{
const char* magicEffectLabels [] = {
"Water Breathing",
"Swift Swim",
"Water Walking",
"Shield",
"Fire Shield",
"Lightning Shield",
"Frost Shield",
"Burden",
"Feather",
"Jump",
"Levitate",
"SlowFall",
"Lock",
"Open",
"Fire Damage",
"Shock Damage",
"Frost Damage",
"Drain Attribute",
"Drain Health",
"Drain Magicka",
"Drain Fatigue",
"Drain Skill",
"Damage Attribute",
"Damage Health",
"Damage Magicka",
"Damage Fatigue",
"Damage Skill",
"Poison",
"Weakness to Fire",
"Weakness to Frost",
"Weakness to Shock",
"Weakness to Magicka",
"Weakness to Common Disease",
"Weakness to Blight Disease",
"Weakness to Corprus Disease",
"Weakness to Poison",
"Weakness to Normal Weapons",
"Disintegrate Weapon",
"Disintegrate Armor",
"Invisibility",
"Chameleon",
"Light",
"Sanctuary",
"Night Eye",
"Charm",
"Paralyze",
"Silence",
"Blind",
"Sound",
"Calm Humanoid",
"Calm Creature",
"Frenzy Humanoid",
"Frenzy Creature",
"Demoralize Humanoid",
"Demoralize Creature",
"Rally Humanoid",
"Rally Creature",
"Dispel",
"Soultrap",
"Telekinesis",
"Mark",
"Recall",
"Divine Intervention",
"Almsivi Intervention",
"Detect Animal",
"Detect Enchantment",
"Detect Key",
"Spell Absorption",
"Reflect",
"Cure Common Disease",
"Cure Blight Disease",
"Cure Corprus Disease",
"Cure Poison",
"Cure Paralyzation",
"Restore Attribute",
"Restore Health",
"Restore Magicka",
"Restore Fatigue",
"Restore Skill",
"Fortify Attribute",
"Fortify Health",
"Fortify Magicka",
"Fortify Fatigue",
"Fortify Skill",
"Fortify Maximum Magicka",
"Absorb Attribute",
"Absorb Health",
"Absorb Magicka",
"Absorb Fatigue",
"Absorb Skill",
"Resist Fire",
"Resist Frost",
"Resist Shock",
"Resist Magicka",
"Resist Common Disease",
"Resist Blight Disease",
"Resist Corprus Disease",
"Resist Poison",
"Resist Normal Weapons",
"Resist Paralysis",
"Remove Curse",
"Turn Undead",
"Summon Scamp",
"Summon Clannfear",
"Summon Daedroth",
"Summon Dremora",
"Summon Ancestral Ghost",
"Summon Skeletal Minion",
"Summon Bonewalker",
"Summon Greater Bonewalker",
"Summon Bonelord",
"Summon Winged Twilight",
"Summon Hunger",
"Summon Golden Saint",
"Summon Flame Atronach",
"Summon Frost Atronach",
"Summon Storm Atronach",
"Fortify Attack",
"Command Creature",
"Command Humanoid",
"Bound Dagger",
"Bound Longsword",
"Bound Mace",
"Bound Battle Axe",
"Bound Spear",
"Bound Longbow",
"EXTRA SPELL",
"Bound Cuirass",
"Bound Helm",
"Bound Boots",
"Bound Shield",
"Bound Gloves",
"Corprus",
"Vampirism",
"Summon Centurion Sphere",
"Sun Damage",
"Stunted Magicka",
"Summon Fabricant",
"sEffectSummonCreature01",
"sEffectSummonCreature02",
"sEffectSummonCreature03",
"sEffectSummonCreature04",
"sEffectSummonCreature05"
};
if (idx >= 0 && idx <= 143)
return magicEffectLabels[idx];
else
return "Invalid";
}
std::string attributeLabel(int idx)
{
const char* attributeLabels [] = {
"Strength",
"Intelligence",
"Willpower",
"Agility",
"Speed",
"Endurance",
"Personality",
"Luck"
};
if (idx >= 0 && idx <= 7)
return attributeLabels[idx];
else
return "Invalid";
}
std::string spellTypeLabel(int idx)
{
const char* spellTypeLabels [] = {
"Spells",
"Abilities",
"Blight Disease",
"Disease",
"Curse",
"Powers"
};
if (idx >= 0 && idx <= 5)
return spellTypeLabels[idx];
else
return "Invalid";
}
std::string specializationLabel(int idx)
{
const char* specializationLabels [] = {
"Combat",
"Magic",
"Stealth"
};
if (idx >= 0 && idx <= 2)
return specializationLabels[idx];
else
return "Invalid";
}
std::string skillLabel(int idx)
{
const char* skillLabels [] = {
"Block",
"Armorer",
"Medium Armor",
"Heavy Armor",
"Blunt Weapon",
"Long Blade",
"Axe",
"Spear",
"Athletics",
"Enchant",
"Destruction",
"Alteration",
"Illusion",
"Conjuration",
"Mysticism",
"Restoration",
"Alchemy",
"Unarmored",
"Security",
"Sneak",
"Acrobatics",
"Light Armor",
"Short Blade",
"Marksman",
"Mercantile",
"Speechcraft",
"Hand-to-hand"
};
if (idx >= 0 && idx <= 27)
return skillLabels[idx];
else
return "Invalid";
}
std::string apparatusTypeLabel(int idx)
{
const char* apparatusTypeLabels [] = {
"Mortar",
"Alembic",
"Calcinator",
"Retort",
};
if (idx >= 0 && idx <= 3)
return apparatusTypeLabels[idx];
else
return "Invalid";
}
std::string rangeTypeLabel(int idx)
{
const char* rangeTypeLabels [] = {
"Self",
"Touch",
"Target"
};
if (idx >= 0 && idx <= 3)
return rangeTypeLabels[idx];
else
return "Invalid";
}
std::string schoolLabel(int idx)
{
const char* schoolLabels [] = {
"Alteration",
"Conjuration",
"Destruction",
"Illusion",
"Mysticism",
"Restoration"
};
if (idx >= 0 && idx <= 5)
return schoolLabels[idx];
else
return "Invalid";
}
std::string enchantTypeLabel(int idx)
{
const char* enchantTypeLabels [] = {
"Cast Once",
"Cast When Strikes",
"Cast When Used",
"Constant Effect"
};
if (idx >= 0 && idx <= 3)
return enchantTypeLabels[idx];
else
return "Invalid";
}
std::string ruleFunction(int idx)
{
std::string ruleFunctions[] = {
"Reaction Low",
"Reaction High",
"Rank Requirement",
"NPC? Reputation",
"Health Percent",
"Player Reputation",
"NPC Level",
"Player Health Percent",
"Player Magicka",
"Player Fatigue",
"Player Attribute Strength",
"Player Skill Block",
"Player Skill Armorer",
"Player Skill Medium Armor",
"Player Skill Heavy Armor",
"Player Skill Blunt Weapon",
"Player Skill Long Blade",
"Player Skill Axe",
"Player Skill Spear",
"Player Skill Athletics",
"Player Skill Enchant",
"Player Skill Destruction",
"Player Skill Alteration",
"Player Skill Illusion",
"Player Skill Conjuration",
"Player Skill Mysticism",
"Player SKill Restoration",
"Player Skill Alchemy",
"Player Skill Unarmored",
"Player Skill Security",
"Player Skill Sneak",
"Player Skill Acrobatics",
"Player Skill Light Armor",
"Player Skill Short Blade",
"Player Skill Marksman",
"Player Skill Mercantile",
"Player Skill Speechcraft",
"Player Skill Hand to Hand",
"Player Gender",
"Player Expelled from Faction",
"Player Diseased (Common)",
"Player Diseased (Blight)",
"Player Clothing Modifier",
"Player Crime Level",
"Player Same Sex",
"Player Same Race",
"Player Same Faction",
"Faction Rank Difference",
"Player Detected",
"Alarmed",
"Choice Selected",
"Player Attribute Intelligence",
"Player Attribute Willpower",
"Player Attribute Agility",
"Player Attribute Speed",
"Player Attribute Endurance",
"Player Attribute Personality",
"Player Attribute Luck",
"Player Diseased (Corprus)",
"Weather",
"Player is a Vampire",
"Player Level",
"Attacked",
"NPC Talked to Player",
"Player Health",
"Creature Target",
"Friend Hit",
"Fight",
"Hello",
"Alarm",
"Flee",
"Should Attack",
//Unkown but causes NPCs to growl and roar.
"UNKNOWN 72"
};
if (idx >= 0 && idx <= 72)
return ruleFunctions[idx];
else
return "Invalid";
}
// The "unused flag bits" should probably be defined alongside the
// defined bits in the ESM component. The names of the flag bits are
// very inconsistent.
std::string bodyPartFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::BodyPart::BPF_Female) properties += "Female ";
if (flags & ESM::BodyPart::BPF_Playable) properties += "Playable ";
int unused = (0xFFFFFFFF ^
(ESM::BodyPart::BPF_Female|
ESM::BodyPart::BPF_Playable));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string cellFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::Cell::HasWater) properties += "HasWater ";
if (flags & ESM::Cell::Interior) properties += "Interior ";
if (flags & ESM::Cell::NoSleep) properties += "NoSleep ";
if (flags & ESM::Cell::QuasiEx) properties += "QuasiEx ";
// This used value is not in the ESM component.
if (flags & 0x00000040) properties += "Unknown ";
int unused = (0xFFFFFFFF ^
(ESM::Cell::HasWater|
ESM::Cell::Interior|
ESM::Cell::NoSleep|
ESM::Cell::QuasiEx|
0x00000040));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string containerFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::Container::Unknown) properties += "Unknown ";
if (flags & ESM::Container::Organic) properties += "Organic ";
if (flags & ESM::Container::Respawn) properties += "Respawn ";
int unused = (0xFFFFFFFF ^
(ESM::Container::Unknown|
ESM::Container::Organic|
ESM::Container::Respawn));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string creatureFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::Creature::None) properties += "All ";
if (flags & ESM::Creature::Walks) properties += "Walks ";
if (flags & ESM::Creature::Swims) properties += "Swims ";
if (flags & ESM::Creature::Flies) properties += "Flies ";
if (flags & ESM::Creature::Biped) properties += "Biped ";
if (flags & ESM::Creature::Respawn) properties += "Respawn ";
if (flags & ESM::Creature::Weapon) properties += "Weapon ";
if (flags & ESM::Creature::Skeleton) properties += "Skeleton ";
if (flags & ESM::Creature::Metal) properties += "Metal ";
if (flags & ESM::Creature::Essential) properties += "Essential ";
int unused = (0xFFFFFFFF ^
(ESM::Creature::None|
ESM::Creature::Walks|
ESM::Creature::Swims|
ESM::Creature::Flies|
ESM::Creature::Biped|
ESM::Creature::Respawn|
ESM::Creature::Weapon|
ESM::Creature::Skeleton|
ESM::Creature::Metal|
ESM::Creature::Essential));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string landFlags(int flags)
{
std::string properties = "";
// The ESM component says that this first four bits are used, but
// only the first three bits are used as far as I can tell.
// There's also no enumeration of the bit in the ESM component.
if (flags == 0) properties += "[None] ";
if (flags & 0x00000001) properties += "Unknown1 ";
if (flags & 0x00000004) properties += "Unknown3 ";
if (flags & 0x00000002) properties += "Unknown2 ";
if (flags & 0xFFFFFFF8) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string leveledListFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::LeveledListBase::AllLevels) properties += "AllLevels ";
// This flag apparently not present on creature lists...
if (flags & ESM::LeveledListBase::Each) properties += "Each ";
int unused = (0xFFFFFFFF ^
(ESM::LeveledListBase::AllLevels|
ESM::LeveledListBase::Each));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string lightFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::Light::Dynamic) properties += "Dynamic ";
if (flags & ESM::Light::Fire) properties += "Fire ";
if (flags & ESM::Light::Carry) properties += "Carry ";
if (flags & ESM::Light::Flicker) properties += "Flicker ";
if (flags & ESM::Light::FlickerSlow) properties += "FlickerSlow ";
if (flags & ESM::Light::Pulse) properties += "Pulse ";
if (flags & ESM::Light::PulseSlow) properties += "PulseSlow ";
if (flags & ESM::Light::Negative) properties += "Negative ";
if (flags & ESM::Light::OffDefault) properties += "OffDefault ";
int unused = (0xFFFFFFFF ^
(ESM::Light::Dynamic|
ESM::Light::Fire|
ESM::Light::Carry|
ESM::Light::Flicker|
ESM::Light::FlickerSlow|
ESM::Light::Pulse|
ESM::Light::PulseSlow|
ESM::Light::Negative|
ESM::Light::OffDefault));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string magicEffectFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
// Enchanting & SpellMaking occur on the same list of effects.
// "EXTRA SPELL" appears in the construction set under both the
// spell making and enchanting tabs as an allowed effect. Since
// most of the effects without this flags are defective in various
// ways, it's still very unclear what these flag bits are.
if (flags & ESM::MagicEffect::SpellMaking) properties += "SpellMaking ";
if (flags & ESM::MagicEffect::Enchanting) properties += "Enchanting ";
if (flags & 0x00000040) properties += "RangeNoSelf ";
if (flags & 0x00000080) properties += "RangeTouch ";
if (flags & 0x00000100) properties += "RangeTarget ";
if (flags & 0x00001000) properties += "Unknown2 ";
if (flags & 0x00000001) properties += "AffectSkill ";
if (flags & 0x00000002) properties += "AffectAttribute ";
if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration ";
if (flags & 0x00000008) properties += "NoMagnitude ";
if (flags & 0x00000010) properties += "Negative ";
if (flags & 0x00000020) properties += "Unknown1 ";
// ESM componet says 0x800 is negative, but none of the magic
// effects have this flags set.
if (flags & ESM::MagicEffect::Negative) properties += "Unused ";
// Since only Chameleon has this flag it could be anything
// that uniquely distinguishes Chameleon.
if (flags & 0x00002000) properties += "Chameleon ";
if (flags & 0x00004000) properties += "Bound ";
if (flags & 0x00008000) properties += "Summon ";
// Calm, Demoralize, Frenzy, Lock, Open, Rally, Soultrap, Turn Unded
if (flags & 0x00010000) properties += "Unknown3 ";
if (flags & 0x00020000) properties += "Absorb ";
if (flags & 0xFFFC0000) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string npcFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
// Mythicmods and the ESM component differ. Mythicmods says
// 0x8=None and 0x10=AutoCalc, while our code defines 0x8 as
// AutoCalc. The former seems to be correct. All Bethesda
// records have bit 0x8 set. A suspiciously large portion of
// females have autocalc turned off.
if (flags & ESM::NPC::Autocalc) properties += "Unknown ";
if (flags & 0x00000010) properties += "Autocalc ";
if (flags & ESM::NPC::Female) properties += "Female ";
if (flags & ESM::NPC::Respawn) properties += "Respawn ";
if (flags & ESM::NPC::Essential) properties += "Essential ";
// These two flags do not appear on any NPCs and may have been
// confused with the flags for creatures.
if (flags & ESM::NPC::Skeleton) properties += "Skeleton ";
if (flags & ESM::NPC::Metal) properties += "Metal ";
// Whether corpses persist is a bit that is unaccounted for,
// however the only unknown bit occurs on ALL records, and
// relatively few NPCs have this bit set.
int unused = (0xFFFFFFFF ^
(ESM::NPC::Autocalc|
0x00000010|
ESM::NPC::Female|
ESM::NPC::Respawn|
ESM::NPC::Essential|
ESM::NPC::Skeleton|
ESM::NPC::Metal));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string raceFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
// All races have the playable flag set in Bethesda files.
if (flags & ESM::Race::Playable) properties += "Playable ";
if (flags & ESM::Race::Beast) properties += "Beast ";
int unused = (0xFFFFFFFF ^
(ESM::Race::Playable|
ESM::Race::Beast));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string spellFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc ";
if (flags & ESM::Spell::F_PCStart) properties += "PCStart ";
if (flags & ESM::Spell::F_Always) properties += "Always ";
int unused = (0xFFFFFFFF ^
(ESM::Spell::F_Autocalc|
ESM::Spell::F_PCStart|
ESM::Spell::F_Always));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}
std::string weaponFlags(int flags)
{
std::string properties = "";
if (flags == 0) properties += "[None] ";
// The interpretation of the flags are still unclear to me.
// Apparently you can't be Silver without being Magical? Many of
// the "Magical" weapons don't have enchantments of any sort.
if (flags & ESM::Weapon::Magical) properties += "Magical ";
if (flags & ESM::Weapon::Silver) properties += "Silver ";
int unused = (0xFFFFFFFF ^
(ESM::Weapon::Magical|
ESM::Weapon::Silver));
if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags);
return properties;
}

@ -0,0 +1,64 @@
#ifndef OPENMW_ESMTOOL_LABELS_H
#define OPENMW_ESMTOOL_LABELS_H
#include <string>
std::string bodyPartLabel(char idx);
std::string meshPartLabel(char idx);
std::string meshTypeLabel(char idx);
std::string clothingTypeLabel(int idx);
std::string armorTypeLabel(int idx);
std::string dialogTypeLabel(int idx);
std::string questStatusLabel(int idx);
std::string creatureTypeLabel(int idx);
std::string soundTypeLabel(int idx);
std::string weaponTypeLabel(int idx);
// This function's a bit different because the types are record types,
// not consecutive values.
std::string aiTypeLabel(int type);
// This one's also a bit different, because it enumerates dialog
// select rule functions, not types. Structurally, it still converts
// indexes to strings for display.
std::string ruleFunction(int idx);
// The labels below here can all be loaded from GMSTs, but are not
// currently because among other things, that requires loading the
// GMSTs before dumping any of the records.
// If the data format supported ordered lists of GMSTs (post 1.0), the
// lists could define the valid values, their localization strings,
// and the indexes for referencing the types in other records in the
// database. Then a single label function could work for all types.
std::string magicEffectLabel(int idx);
std::string attributeLabel(int idx);
std::string spellTypeLabel(int idx);
std::string specializationLabel(int idx);
std::string skillLabel(int idx);
std::string apparatusTypeLabel(int idx);
std::string rangeTypeLabel(int idx);
std::string schoolLabel(int idx);
std::string enchantTypeLabel(int idx);
// The are the flag functions that convert a bitmask into a list of
// human readble strings representing the set bits.
std::string bodyPartFlags(int flags);
std::string cellFlags(int flags);
std::string containerFlags(int flags);
std::string creatureFlags(int flags);
std::string landFlags(int flags);
std::string leveledListFlags(int flags);
std::string lightFlags(int flags);
std::string magicEffectFlags(int flags);
std::string npcFlags(int flags);
std::string raceFlags(int flags);
std::string spellFlags(int flags);
std::string weaponFlags(int flags);
// Missing flags functions:
// aiServicesFlags, possibly more
#endif

File diff suppressed because it is too large Load Diff

@ -20,7 +20,7 @@ namespace EsmTool
protected:
std::string mId;
int mFlags;
int mType;
ESM::NAME mType;
public:
RecordBase () {}
@ -42,7 +42,7 @@ namespace EsmTool
mFlags = flags;
}
int getType() const {
ESM::NAME getType() const {
return mType;
}
@ -50,7 +50,7 @@ namespace EsmTool
virtual void save(ESM::ESMWriter &esm) = 0;
virtual void print() = 0;
static RecordBase *create(int type);
static RecordBase *create(ESM::NAME type);
// just make it a bit shorter
template <class T>

@ -1,42 +1,56 @@
set(LAUNCHER
datafilespage.cpp
graphicspage.cpp
lineedit.cpp
main.cpp
maindialog.cpp
naturalsort.cpp
playpage.cpp
pluginsmodel.cpp
pluginsview.cpp
filedialog.cpp
model/datafilesmodel.cpp
model/modelitem.cpp
model/esm/esmfile.cpp
utils/filedialog.cpp
utils/naturalsort.cpp
utils/lineedit.cpp
utils/profilescombobox.cpp
utils/textinputdialog.cpp
launcher.rc
)
set(LAUNCHER_HEADER
combobox.hpp
datafilespage.hpp
graphicspage.hpp
lineedit.hpp
maindialog.hpp
naturalsort.hpp
playpage.hpp
pluginsmodel.hpp
pluginsview.hpp
filedialog.hpp
model/datafilesmodel.hpp
model/modelitem.hpp
model/esm/esmfile.hpp
utils/lineedit.hpp
utils/filedialog.hpp
utils/naturalsort.hpp
utils/profilescombobox.hpp
utils/textinputdialog.hpp
)
# Headers that must be pre-processed
set(LAUNCHER_HEADER_MOC
combobox.hpp
datafilespage.hpp
graphicspage.hpp
lineedit.hpp
maindialog.hpp
playpage.hpp
pluginsmodel.hpp
pluginsview.hpp
filedialog.hpp
model/datafilesmodel.hpp
model/modelitem.hpp
model/esm/esmfile.hpp
utils/lineedit.hpp
utils/filedialog.hpp
utils/profilescombobox.hpp
utils/textinputdialog.hpp
)
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC})
@ -75,7 +89,7 @@ add_executable(omwlauncher
target_link_libraries(omwlauncher
${Boost_LIBRARIES}
${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${OGRE_STATIC_PLUGINS}
${QT_LIBRARIES}
components
)
@ -87,8 +101,6 @@ endif()
if (APPLE)
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${APP_BUNDLE_DIR}/../launcher.qss")
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg
"${APP_BUNDLE_DIR}/../launcher.cfg")
else()
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/resources/launcher.qss")
@ -96,9 +108,6 @@ else()
# Fallback in case getGlobalDataPath does not point to resources
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss")
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.cfg")
endif()
if (BUILD_WITH_CODE_COVERAGE)

@ -1,28 +0,0 @@
#ifndef COMBOBOX_H
#define COMBOBOX_H
#include <QComboBox>
class ComboBox : public QComboBox
{
Q_OBJECT
private:
QString oldText;
public:
ComboBox(QWidget *parent=0) : QComboBox(parent), oldText()
{
connect(this,SIGNAL(editTextChanged(const QString&)), this,
SLOT(textChangedSlot(const QString&)));
connect(this,SIGNAL(currentIndexChanged(const QString&)), this,
SLOT(textChangedSlot(const QString&)));
}
private slots:
void textChangedSlot(const QString &newText)
{
emit textChanged(oldText, newText);
oldText = newText;
}
signals:
void textChanged(const QString &oldText, const QString &newText);
};
#endif

File diff suppressed because it is too large Load Diff

@ -3,24 +3,20 @@
#include <QWidget>
#include <QModelIndex>
#include "utils/profilescombobox.hpp"
#include <components/files/collections.hpp>
#include "combobox.hpp"
class QTableWidget;
class QStandardItemModel;
class QItemSelection;
class QItemSelectionModel;
class QTableView;
class QSortFilterProxyModel;
class QStringListModel;
class QSettings;
class QAction;
class QToolBar;
class QMenu;
class PluginsModel;
class PluginsView;
class ComboBox;
class ProfilesComboBox;
class DataFilesModel;
class TextInputDialog;
namespace Files { struct ConfigurationManager; }
@ -31,52 +27,51 @@ class DataFilesPage : public QWidget
public:
DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0);
ComboBox *mProfilesComboBox;
ProfilesComboBox *mProfilesComboBox;
void writeConfig(QString profile = QString());
bool showDataFilesWarning();
bool setupDataFiles();
public slots:
void masterSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void setCheckState(QModelIndex index);
void filterChanged(const QString filter);
void showContextMenu(const QPoint &point);
void profileChanged(const QString &previous, const QString &current);
void profileRenamed(const QString &previous, const QString &current);
void updateOkButton(const QString &text);
// Action slots
void newProfile();
void copyProfile();
void deleteProfile();
void moveUp();
void moveDown();
void moveTop();
void moveBottom();
// void moveUp();
// void moveDown();
// void moveTop();
// void moveBottom();
void check();
void uncheck();
void refresh();
private:
QTableWidget *mMastersWidget;
PluginsView *mPluginsTable;
QStandardItemModel *mDataFilesModel;
PluginsModel *mPluginsModel;
DataFilesModel *mMastersModel;
DataFilesModel *mPluginsModel;
QSortFilterProxyModel *mPluginsProxyModel;
QItemSelectionModel *mPluginsSelectModel;
QTableView *mMastersTable;
QTableView *mPluginsTable;
QToolBar *mProfileToolBar;
QMenu *mContextMenu;
QAction *mNewProfileAction;
QAction *mCopyProfileAction;
QAction *mDeleteProfileAction;
QAction *mMoveUpAction;
QAction *mMoveDownAction;
QAction *mMoveTopAction;
QAction *mMoveBottomAction;
// QAction *mMoveUpAction;
// QAction *mMoveDownAction;
// QAction *mMoveTopAction;
// QAction *mMoveBottomAction;
QAction *mCheckAction;
QAction *mUncheckAction;
@ -86,17 +81,14 @@ private:
QSettings *mLauncherConfig;
const QStringList checkedPlugins();
const QStringList selectedMasters();
TextInputDialog *mNewProfileDialog;
// const QStringList checkedPlugins();
// const QStringList selectedMasters();
void addDataFiles(Files::Collections &fileCollections, const QString &encoding);
void addPlugins(const QModelIndex &index);
void removePlugins(const QModelIndex &index);
void uncheckPlugins();
void createActions();
void setupConfig();
void readConfig();
void scrollToSelection();
};

@ -9,8 +9,9 @@
#include <components/files/ogreplugin.hpp>
#include <components/settings/settings.hpp>
#include "utils/naturalsort.hpp"
#include "graphicspage.hpp"
#include "naturalsort.hpp"
QString getAspect(int x, int y)
{
@ -280,20 +281,18 @@ QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
assert (tokens.size() >= 3);
QString resolutionStr = tokens.at(0) + QString(" x ") + tokens.at(2);
// do not add duplicate resolutions
if (!result.contains(resolutionStr)) {
QString aspect = getAspect(tokens.at(0).toInt(),tokens.at(2).toInt());
QString aspect = getAspect(tokens.at(0).toInt(),tokens.at(2).toInt());
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
resolutionStr.append(tr("\t(Widescreen ") + aspect + ")");
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
resolutionStr.append(tr("\t(Widescreen ") + aspect + ")");
} else if (aspect == QLatin1String("4:3")) {
resolutionStr.append(tr("\t(Standard 4:3)"));
}
} else if (aspect == QLatin1String("4:3")) {
resolutionStr.append(tr("\t(Standard 4:3)"));
}
// do not add duplicate resolutions
if (!result.contains(resolutionStr))
result << resolutionStr;
}
}
}

@ -11,7 +11,7 @@ int main(int argc, char *argv[])
// Now we make sure the current dir is set to application path
QDir dir(QCoreApplication::applicationDirPath());
#if defined(Q_OS_MAC)
#ifdef Q_OS_MAC
if (dir.dirName() == "MacOS") {
dir.cdUp();
dir.cdUp();

@ -141,11 +141,11 @@ void MainDialog::createPages()
connect(mPlayPage->mProfilesComboBox,
SIGNAL(currentIndexChanged(int)),
this, SLOT(profileChanged(int)));
mDataFilesPage->mProfilesComboBox, SLOT(setCurrentIndex(int)));
connect(mDataFilesPage->mProfilesComboBox,
SIGNAL(currentIndexChanged(int)),
this, SLOT(profileChanged(int)));
mPlayPage->mProfilesComboBox, SLOT(setCurrentIndex(int)));
}
@ -196,23 +196,6 @@ bool MainDialog::setup()
return true;
}
void MainDialog::profileChanged(int index)
{
// Just to be sure, should always have a selection
if (!mIconWidget->selectionModel()->hasSelection()) {
return;
}
QString currentPage = mIconWidget->currentItem()->data(Qt::DisplayRole).toString();
if (currentPage == QLatin1String("Play")) {
mDataFilesPage->mProfilesComboBox->setCurrentIndex(index);
}
if (currentPage == QLatin1String("Data Files")) {
mPlayPage->mProfilesComboBox->setCurrentIndex(index);
}
}
void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
{
if (!current)
@ -244,10 +227,10 @@ void MainDialog::play()
const std::string settingspath = (mCfgMgr.getUserPath() / "settings.cfg").string();
mSettings.saveUser(settingspath);
#ifdef Q_WS_WIN
#ifdef Q_OS_WIN
QString game = "./openmw.exe";
QFile file(game);
#elif defined(Q_WS_MAC)
#elif defined(Q_OS_MAC)
QDir dir(QCoreApplication::applicationDirPath());
QString game = dir.absoluteFilePath("openmw");
QFile file(game);

@ -27,7 +27,6 @@ public:
public slots:
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
void play();
void profileChanged(int index);
bool setup();
private:

@ -0,0 +1,476 @@
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#include <stdexcept>
#include <components/esm/esmreader.hpp>
#include "esm/esmfile.hpp"
#include "../utils/naturalsort.hpp"
#include "datafilesmodel.hpp"
DataFilesModel::DataFilesModel(QObject *parent) :
QAbstractTableModel(parent)
{
mEncoding = QString("win1252");
}
DataFilesModel::~DataFilesModel()
{
}
void DataFilesModel::setEncoding(const QString &encoding)
{
mEncoding = encoding;
}
void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state)
{
setData(index, state, Qt::CheckStateRole);
}
Qt::CheckState DataFilesModel::checkState(const QModelIndex &index)
{
EsmFile *file = item(index.row());
return mCheckStates[file->fileName()];
}
int DataFilesModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 9;
}
int DataFilesModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : mFiles.count();
}
bool DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent)
{
if (oldrow < 0 || row < 0 || oldrow == row)
return false;
emit layoutAboutToBeChanged();
//emit beginMoveRows(parent, oldrow, oldrow, parent, row);
mFiles.swap(oldrow, row);
//emit endInsertRows();
emit layoutChanged();
return true;
}
QVariant DataFilesModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
EsmFile *file = item(index.row());
if (!file)
return QVariant();
const int column = index.column();
switch (role) {
case Qt::DisplayRole: {
switch (column) {
case 0:
return file->fileName();
case 1:
return file->author();
case 2:
return QString("%1 kB").arg(int((file->size() + 1023) / 1024));
case 3:
//return file->modified().toString(Qt::TextDate);
return file->modified().toString(Qt::ISODate);
case 4:
return file->accessed().toString(Qt::TextDate);
case 5:
return file->version();
case 6:
return file->path();
case 7:
return file->masters().join(", ");
case 8:
return file->description();
}
}
case Qt::TextAlignmentRole: {
switch (column) {
case 0:
case 1:
return Qt::AlignLeft + Qt::AlignVCenter;
case 2:
case 3:
case 4:
case 5:
return Qt::AlignRight + Qt::AlignVCenter;
default:
return Qt::AlignLeft + Qt::AlignVCenter;
}
}
case Qt::CheckStateRole: {
if (column != 0)
return QVariant();
return mCheckStates[file->fileName()];
}
case Qt::ToolTipRole:
{
if (column != 0)
return QVariant();
if (file->version() == 0.0f)
return QVariant(); // Data not set
QString tooltip =
QString("<b>Author:</b> %1<br/> \
<b>Version:</b> %2<br/> \
<br/><b>Description:</b><br/>%3<br/> \
<br/><b>Dependencies: </b>%4<br/>")
.arg(file->author())
.arg(QString::number(file->version()))
.arg(file->description())
.arg(file->masters().join(", "));
return tooltip;
}
default:
return QVariant();
}
}
Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
EsmFile *file = item(index.row());
if (!file)
return Qt::NoItemFlags;
if (mAvailableFiles.contains(file->fileName())) {
if (index.column() == 0) {
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
} else {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
} else {
if (index.column() == 0) {
return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
} else {
return Qt::NoItemFlags | Qt::ItemIsSelectable;
}
}
}
QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case 0: return tr("Name");
case 1: return tr("Author");
case 2: return tr("Size");
case 3: return tr("Modified");
case 4: return tr("Accessed");
case 5: return tr("Version");
case 6: return tr("Path");
case 7: return tr("Masters");
case 8: return tr("Description");
}
} else {
// Show row numbers
return ++section;
}
return QVariant();
}
bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
if (role == Qt::CheckStateRole) {
emit layoutAboutToBeChanged();
QString name = item(index.row())->fileName();
mCheckStates[name] = static_cast<Qt::CheckState>(value.toInt());
emit checkedItemsChanged(checkedItems(), uncheckedItems());
emit layoutChanged();
return true;
}
return false;
}
void DataFilesModel::sort(int column, Qt::SortOrder order)
{
// TODO: Make this more efficient
emit layoutAboutToBeChanged();
QList<EsmFile *> sortedFiles;
QMultiMap<QString, QString> timestamps;
foreach (EsmFile *file, mFiles)
timestamps.insert(file->modified().toString(Qt::ISODate), file->fileName());
QMapIterator<QString, QString> ti(timestamps);
while (ti.hasNext()) {
ti.next();
QModelIndex index = indexFromItem(findItem(ti.value()));
if (!index.isValid())
continue;
EsmFile *file = item(index.row());
if (!file)
continue;
sortedFiles.append(file);
}
mFiles.clear();
mFiles = sortedFiles;
emit layoutChanged();
}
void DataFilesModel::addFile(EsmFile *file)
{
emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count());
mFiles.append(file);
emit endInsertRows();
}
void DataFilesModel::addMasters(const QString &path)
{
QDir dir(path);
dir.setNameFilters(QStringList(QLatin1String("*.esp")));
// Read the dependencies from the plugins
foreach (const QString &path, dir.entryList()) {
try {
ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString());
fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
for (unsigned int i = 0; i < mlist.size(); ++i) {
QString master = QString::fromStdString(mlist[i].name);
// Add the plugin to the internal dependency map
mDependencies[master].append(path);
// Don't add esps
if (master.endsWith(".esp", Qt::CaseInsensitive))
continue;
QFileInfo info(dir.absoluteFilePath(master));
EsmFile *file = new EsmFile(master);
file->setDates(info.lastModified(), info.lastRead());
// Add the master to the table
if (findItem(master) == 0)
addFile(file);
}
} catch(std::runtime_error &e) {
// An error occurred while reading the .esp
qWarning() << "Error reading esp: " << e.what();
continue;
}
}
// See if the masters actually exist in the filesystem
dir.setNameFilters(QStringList(QLatin1String("*.esm")));
foreach (const QString &path, dir.entryList()) {
QFileInfo info(dir.absoluteFilePath(path));
if (findItem(path) == 0) {
EsmFile *file = new EsmFile(path);
file->setDates(info.lastModified(), info.lastRead());
addFile(file);
}
// Make the master selectable
mAvailableFiles.append(path);
}
}
void DataFilesModel::addPlugins(const QString &path)
{
QDir dir(path);
dir.setNameFilters(QStringList(QLatin1String("*.esp")));
foreach (const QString &path, dir.entryList()) {
QFileInfo info(dir.absoluteFilePath(path));
EsmFile *file = new EsmFile(path);
try {
ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString());
fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
QStringList masters;
for (unsigned int i = 0; i < mlist.size(); ++i) {
QString master = QString::fromStdString(mlist[i].name);
masters.append(master);
// Add the plugin to the internal dependency map
mDependencies[master].append(path);
}
file->setAuthor(QString::fromStdString(fileReader.getAuthor()));
file->setSize(info.size());
file->setDates(info.lastModified(), info.lastRead());
file->setVersion(fileReader.getFVer());
file->setPath(info.absoluteFilePath());
file->setMasters(masters);
file->setDescription(QString::fromStdString(fileReader.getDesc()));
// Put the file in the table
addFile(file);
} catch(std::runtime_error &e) {
// An error occurred while reading the .esp
qWarning() << "Error reading esp: " << e.what();
continue;
}
}
}
QModelIndex DataFilesModel::indexFromItem(EsmFile *item) const
{
if (item)
return createIndex(mFiles.indexOf(item), 0);
return QModelIndex();
}
EsmFile* DataFilesModel::findItem(const QString &name)
{
QList<EsmFile *>::ConstIterator it;
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
int i = 0;
for (it = mFiles.constBegin(); it != itEnd; ++it) {
EsmFile *file = item(i);
++i;
if (name == file->fileName())
return file;
}
// Not found
return 0;
}
EsmFile* DataFilesModel::item(int row) const
{
if (row >= 0 && row < mFiles.count())
return mFiles.at(row);
else
return 0;
}
QStringList DataFilesModel::checkedItems()
{
QStringList list;
QList<EsmFile *>::ConstIterator it;
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
int i = 0;
for (it = mFiles.constBegin(); it != itEnd; ++it) {
EsmFile *file = item(i);
++i;
QString name = file->fileName();
// Only add the items that are in the checked list and available
if (mCheckStates[name] == Qt::Checked && mAvailableFiles.contains(name))
list << name;
}
return list;
}
void DataFilesModel::uncheckAll()
{
emit layoutAboutToBeChanged();
mCheckStates.clear();
emit layoutChanged();
}
QStringList DataFilesModel::uncheckedItems()
{
QStringList list;
QStringList checked = checkedItems();
QList<EsmFile *>::ConstIterator it;
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
int i = 0;
for (it = mFiles.constBegin(); it != itEnd; ++it) {
EsmFile *file = item(i);
++i;
// Add the items that are not in the checked list
if (!checked.contains(file->fileName()))
list << file->fileName();
}
return list;
}
void DataFilesModel::slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems)
{
emit layoutAboutToBeChanged();
QStringList list;
foreach (const QString &file, checkedItems) {
list << mDependencies[file];
}
foreach (const QString &file, unCheckedItems) {
foreach (const QString &remove, mDependencies[file]) {
list.removeAll(remove);
}
}
mAvailableFiles.clear();
mAvailableFiles.append(list);
emit layoutChanged();
}

@ -0,0 +1,71 @@
#ifndef DATAFILESMODEL_HPP
#define DATAFILESMODEL_HPP
#include <QAbstractTableModel>
#include <QStringList>
#include <QString>
#include <QHash>
class EsmFile;
class DataFilesModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit DataFilesModel(QObject *parent = 0);
virtual ~DataFilesModel();
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
bool moveRow(int oldrow, int row, const QModelIndex &parent = QModelIndex());
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
{ return QAbstractTableModel::index(row, column, parent); }
void setEncoding(const QString &encoding);
void addFile(EsmFile *file);
void addMasters(const QString &path);
void addPlugins(const QString &path);
void uncheckAll();
QStringList checkedItems();
QStringList uncheckedItems();
Qt::CheckState checkState(const QModelIndex &index);
void setCheckState(const QModelIndex &index, Qt::CheckState state);
QModelIndex indexFromItem(EsmFile *item) const;
EsmFile* findItem(const QString &name);
EsmFile* item(int row) const;
signals:
void checkedItemsChanged(const QStringList checkedItems, const QStringList unCheckedItems);
public slots:
void slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems);
private:
QList<EsmFile *> mFiles;
QStringList mAvailableFiles;
QHash<QString, QStringList> mDependencies;
QHash<QString, Qt::CheckState> mCheckStates;
QString mEncoding;
};
#endif // DATAFILESMODEL_HPP

@ -0,0 +1,50 @@
#include "esmfile.hpp"
EsmFile::EsmFile(QString fileName, ModelItem *parent)
: ModelItem(parent)
{
mFileName = fileName;
mSize = 0;
mVersion = 0.0f;
}
void EsmFile::setFileName(const QString &fileName)
{
mFileName = fileName;
}
void EsmFile::setAuthor(const QString &author)
{
mAuthor = author;
}
void EsmFile::setSize(const int size)
{
mSize = size;
}
void EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed)
{
mModified = modified;
mAccessed = accessed;
}
void EsmFile::setVersion(float version)
{
mVersion = version;
}
void EsmFile::setPath(const QString &path)
{
mPath = path;
}
void EsmFile::setMasters(const QStringList &masters)
{
mMasters = masters;
}
void EsmFile::setDescription(const QString &description)
{
mDescription = description;
}

@ -0,0 +1,54 @@
#ifndef ESMFILE_HPP
#define ESMFILE_HPP
#include <QDateTime>
#include <QStringList>
#include "../modelitem.hpp"
class EsmFile : public ModelItem
{
Q_OBJECT
Q_PROPERTY(QString filename READ fileName)
public:
EsmFile(QString fileName = QString(), ModelItem *parent = 0);
~EsmFile()
{}
void setFileName(const QString &fileName);
void setAuthor(const QString &author);
void setSize(const int size);
void setDates(const QDateTime &modified, const QDateTime &accessed);
void setVersion(const float version);
void setPath(const QString &path);
void setMasters(const QStringList &masters);
void setDescription(const QString &description);
inline QString fileName() { return mFileName; }
inline QString author() { return mAuthor; }
inline int size() { return mSize; }
inline QDateTime modified() { return mModified; }
inline QDateTime accessed() { return mAccessed; }
inline float version() { return mVersion; }
inline QString path() { return mPath; }
inline QStringList masters() { return mMasters; }
inline QString description() { return mDescription; }
private:
QString mFileName;
QString mAuthor;
int mSize;
QDateTime mModified;
QDateTime mAccessed;
float mVersion;
QString mPath;
QStringList mMasters;
QString mDescription;
};
#endif

@ -0,0 +1,57 @@
#include "modelitem.hpp"
ModelItem::ModelItem(ModelItem *parent)
: mParentItem(parent)
, QObject(parent)
{
}
ModelItem::~ModelItem()
{
qDeleteAll(mChildItems);
}
ModelItem *ModelItem::parent()
{
return mParentItem;
}
int ModelItem::row() const
{
if (mParentItem)
return 1;
//return mParentItem->childRow(const_cast<ModelItem*>(this));
//return mParentItem->mChildItems.indexOf(const_cast<ModelItem*>(this));
return -1;
}
int ModelItem::childCount() const
{
return mChildItems.count();
}
int ModelItem::childRow(ModelItem *child) const
{
Q_ASSERT(child);
return mChildItems.indexOf(child);
}
ModelItem *ModelItem::child(int row)
{
return mChildItems.value(row);
}
void ModelItem::appendChild(ModelItem *item)
{
mChildItems.append(item);
}
void ModelItem::removeChild(int row)
{
mChildItems.removeAt(row);
}

@ -0,0 +1,32 @@
#ifndef MODELITEM_HPP
#define MODELITEM_HPP
#include <QObject>
#include <QList>
class ModelItem : public QObject
{
Q_OBJECT
public:
ModelItem(ModelItem *parent = 0);
~ModelItem();
ModelItem *parent();
int row() const;
int childCount() const;
int childRow(ModelItem *child) const;
ModelItem *child(int row);
void appendChild(ModelItem *child);
void removeChild(int row);
//virtual bool acceptChild(ModelItem *child);
protected:
ModelItem *mParentItem;
QList<ModelItem*> mChildItems;
};
#endif

@ -1,149 +0,0 @@
#include <QMimeData>
#include <QBitArray>
#include <limits>
#include "pluginsmodel.hpp"
PluginsModel::PluginsModel(QObject *parent) : QStandardItemModel(parent)
{
}
void decodeDataRecursive(QDataStream &stream, QStandardItem *item)
{
int colCount, childCount;
stream >> *item;
stream >> colCount >> childCount;
item->setColumnCount(colCount);
int childPos = childCount;
while(childPos > 0) {
childPos--;
QStandardItem *child = new QStandardItem();
decodeDataRecursive(stream, child);
item->setChild( childPos / colCount, childPos % colCount, child);
}
}
bool PluginsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent)
{
// Code largely based on QStandardItemModel::dropMimeData
// check if the action is supported
if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
return false;
// check if the format is supported
QString format = QLatin1String("application/x-qstandarditemmodeldatalist");
if (!data->hasFormat(format))
return QAbstractItemModel::dropMimeData(data, action, row, column, parent);
if (row > rowCount(parent))
row = rowCount(parent);
if (row == -1)
row = rowCount(parent);
if (column == -1)
column = 0;
// decode and insert
QByteArray encoded = data->data(format);
QDataStream stream(&encoded, QIODevice::ReadOnly);
//code based on QAbstractItemModel::decodeData
// adapted to work with QStandardItem
int top = std::numeric_limits<int>::max();
int left = std::numeric_limits<int>::max();
int bottom = 0;
int right = 0;
QVector<int> rows, columns;
QVector<QStandardItem *> items;
while (!stream.atEnd()) {
int r, c;
QStandardItem *item = new QStandardItem();
stream >> r >> c;
decodeDataRecursive(stream, item);
rows.append(r);
columns.append(c);
items.append(item);
top = qMin(r, top);
left = qMin(c, left);
bottom = qMax(r, bottom);
right = qMax(c, right);
}
// insert the dragged items into the table, use a bit array to avoid overwriting items,
// since items from different tables can have the same row and column
int dragRowCount = 0;
int dragColumnCount = right - left + 1;
// Compute the number of continuous rows upon insertion and modify the rows to match
QVector<int> rowsToInsert(bottom + 1);
for (int i = 0; i < rows.count(); ++i)
rowsToInsert[rows.at(i)] = 1;
for (int i = 0; i < rowsToInsert.count(); ++i) {
if (rowsToInsert[i] == 1){
rowsToInsert[i] = dragRowCount;
++dragRowCount;
}
}
for (int i = 0; i < rows.count(); ++i)
rows[i] = top + rowsToInsert[rows[i]];
QBitArray isWrittenTo(dragRowCount * dragColumnCount);
// make space in the table for the dropped data
int colCount = columnCount(parent);
if (colCount < dragColumnCount + column) {
insertColumns(colCount, dragColumnCount + column - colCount, parent);
colCount = columnCount(parent);
}
insertRows(row, dragRowCount, parent);
row = qMax(0, row);
column = qMax(0, column);
QStandardItem *parentItem = itemFromIndex (parent);
if (!parentItem)
parentItem = invisibleRootItem();
QVector<QPersistentModelIndex> newIndexes(items.size());
// set the data in the table
for (int j = 0; j < items.size(); ++j) {
int relativeRow = rows.at(j) - top;
int relativeColumn = columns.at(j) - left;
int destinationRow = relativeRow + row;
int destinationColumn = relativeColumn + column;
int flat = (relativeRow * dragColumnCount) + relativeColumn;
// if the item was already written to, or we just can't fit it in the table, create a new row
if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
destinationColumn = qBound(column, destinationColumn, colCount - 1);
destinationRow = row + dragRowCount;
insertRows(row + dragRowCount, 1, parent);
flat = (dragRowCount * dragColumnCount) + relativeColumn;
isWrittenTo.resize(++dragRowCount * dragColumnCount);
}
if (!isWrittenTo.testBit(flat)) {
newIndexes[j] = index(destinationRow, destinationColumn, parentItem->index());
isWrittenTo.setBit(flat);
}
}
for(int k = 0; k < newIndexes.size(); k++) {
if (newIndexes.at(k).isValid()) {
parentItem->setChild(newIndexes.at(k).row(), newIndexes.at(k).column(), items.at(k));
} else {
delete items.at(k);
}
}
// The important part, tell the view what is dropped
emit indexesDropped(newIndexes);
return true;
}

@ -1,21 +0,0 @@
#ifndef PLUGINSMODEL_H
#define PLUGINSMODEL_H
#include <QStandardItemModel>
class PluginsModel : public QStandardItemModel
{
Q_OBJECT
public:
PluginsModel(QObject *parent = 0);
~PluginsModel() {};
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
signals:
void indexesDropped(QVector<QPersistentModelIndex> indexes);
};
#endif

@ -1,41 +0,0 @@
#include <QSortFilterProxyModel>
#include "pluginsview.hpp"
PluginsView::PluginsView(QWidget *parent) : QTableView(parent)
{
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::ExtendedSelection);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setAlternatingRowColors(true);
setDragEnabled(true);
setDragDropMode(QAbstractItemView::InternalMove);
setDropIndicatorShown(true);
setDragDropOverwriteMode(false);
setContextMenuPolicy(Qt::CustomContextMenu);
}
void PluginsView::startDrag(Qt::DropActions supportedActions)
{
selectionModel()->select( selectionModel()->selection(),
QItemSelectionModel::Select | QItemSelectionModel::Rows );
QAbstractItemView::startDrag( supportedActions );
}
void PluginsView::setModel(QSortFilterProxyModel *model)
{
QTableView::setModel(model);
qRegisterMetaType< QVector<QPersistentModelIndex> >();
connect(model->sourceModel(), SIGNAL(indexesDropped(QVector<QPersistentModelIndex>)),
this, SLOT(selectIndexes(QVector<QPersistentModelIndex>)), Qt::QueuedConnection);
}
void PluginsView::selectIndexes( QVector<QPersistentModelIndex> aIndexes )
{
selectionModel()->clearSelection();
foreach( QPersistentModelIndex pIndex, aIndexes )
selectionModel()->select( pIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows );
}

@ -1,29 +0,0 @@
#ifndef PLUGINSVIEW_H
#define PLUGINSVIEW_H
#include <QTableView>
#include "pluginsmodel.hpp"
class QSortFilterProxyModel;
class PluginsView : public QTableView
{
Q_OBJECT
public:
PluginsView(QWidget *parent = 0);
PluginsModel* model() const
{ return qobject_cast<PluginsModel*>(QAbstractItemView::model()); }
void startDrag(Qt::DropActions supportedActions);
void setModel(QSortFilterProxyModel *model);
public slots:
void selectIndexes(QVector<QPersistentModelIndex> aIndexes);
};
Q_DECLARE_METATYPE(QVector<QPersistentModelIndex>);
#endif

@ -0,0 +1,52 @@
#include <QRegExpValidator>
#include <QLineEdit>
#include <QString>
#include "profilescombobox.hpp"
ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
QComboBox(parent)
{
mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
setEditable(true);
setValidator(mValidator);
setCompleter(0);
connect(this, SIGNAL(currentIndexChanged(int)), this,
SLOT(slotIndexChanged(int)));
connect(lineEdit(), SIGNAL(returnPressed()), this,
SLOT(slotReturnPressed()));
}
void ProfilesComboBox::setEditEnabled(bool editable)
{
if (!editable)
return setEditable(false);
// Reset the completer and validator
setEditable(true);
setValidator(mValidator);
setCompleter(0);
}
void ProfilesComboBox::slotReturnPressed()
{
QString current = currentText();
QString previous = itemText(currentIndex());
if (findText(current) != -1)
return;
setItemText(currentIndex(), current);
emit(profileRenamed(previous, current));
}
void ProfilesComboBox::slotIndexChanged(int index)
{
if (index == -1)
return;
emit(profileChanged(mOldProfile, currentText()));
mOldProfile = itemText(index);
}

@ -0,0 +1,30 @@
#ifndef PROFILESCOMBOBOX_HPP
#define PROFILESCOMBOBOX_HPP
#include <QComboBox>
class QString;
class QRegExpValidator;
class ProfilesComboBox : public QComboBox
{
Q_OBJECT
public:
explicit ProfilesComboBox(QWidget *parent = 0);
void setEditEnabled(bool editable);
signals:
void profileChanged(const QString &previous, const QString &current);
void profileRenamed(const QString &oldName, const QString &newName);
private slots:
void slotReturnPressed();
void slotIndexChanged(int index);
private:
QString mOldProfile;
QRegExpValidator *mValidator;
};
#endif // PROFILESCOMBOBOX_HPP

@ -0,0 +1,61 @@
#include <QDialogButtonBox>
#include <QPushButton>
#include <QDebug>
#include <QLabel>
#include <QVBoxLayout>
#include <QValidator>
#include "lineedit.hpp"
#include "textinputdialog.hpp"
TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) :
QDialog(parent)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
mButtonBox = new QDialogButtonBox(this);
mButtonBox->addButton(QDialogButtonBox::Ok);
mButtonBox->addButton(QDialogButtonBox::Cancel);
setMaximumHeight(height());
setOkButtonEnabled(false);
setModal(true);
// Messageboxes on mac have no title
#ifndef Q_OS_MAC
setWindowTitle(title);
#else
Q_UNUSED(title);
#endif
QLabel *label = new QLabel(this);
label->setText(text);
// Line edit
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
mLineEdit = new LineEdit(this);
mLineEdit->setValidator(validator);
mLineEdit->setCompleter(0);
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
dialogLayout->addWidget(label);
dialogLayout->addWidget(mLineEdit);
dialogLayout->addWidget(mButtonBox);
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
}
int TextInputDialog::exec()
{
mLineEdit->clear();
mLineEdit->setFocus();
return QDialog::exec();
}
void TextInputDialog::setOkButtonEnabled(bool enabled)
{
QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
okButton->setEnabled(enabled);
}

@ -0,0 +1,28 @@
#ifndef TEXTINPUTDIALOG_HPP
#define TEXTINPUTDIALOG_HPP
#include <QDialog>
//#include "lineedit.hpp"
class QDialogButtonBox;
class LineEdit;
class TextInputDialog : public QDialog
{
Q_OBJECT
public:
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
inline LineEdit *lineEdit() { return mLineEdit; }
void setOkButtonEnabled(bool enabled);
LineEdit *mLineEdit;
int exec();
private:
QDialogButtonBox *mButtonBox;
};
#endif // TEXTINPUTDIALOG_HPP

@ -78,7 +78,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) {
multistrmap::iterator it;
if((it = map.find(key)) == map.end()) {
map.insert( std::make_pair<std::string, std::vector<std::string> > (key, std::vector<std::string>() ) );
map.insert( std::make_pair (key, std::vector<std::string>() ) );
}
map[key].push_back(value);
}
@ -115,7 +115,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
multistrmap::iterator it;
if((it = map.find(key)) == map.end()) {
map.insert( std::make_pair<std::string, std::vector<std::string> > (key, std::vector<std::string>() ) );
map.insert( std::make_pair (key, std::vector<std::string>() ) );
}
map[key].push_back(value);
}
@ -152,12 +152,12 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
}
}
}
};
}
void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) {
multistrmap::iterator it = cfg.find(key);
if(it == cfg.end()) {
cfg.insert(std::make_pair<std::string, std::vector<std::string> >(key, std::vector<std::string>() ));
cfg.insert(std::make_pair (key, std::vector<std::string>() ));
}
cfg[key].push_back(value);
}

@ -29,11 +29,12 @@ add_openmw_dir (mwgui
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow
)
add_openmw_dir (mwdialogue
dialoguemanagerimp journalimp journalentry quest topic
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper
)
add_openmw_dir (mwscript
@ -49,9 +50,10 @@ add_openmw_dir (mwsound
add_openmw_dir (mwworld
refdata worldimp physicssystem scene globals class action nullaction actionteleport
containerstore actiontalk actiontake manualref player cellfunctors
containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp
)
add_openmw_dir (mwclass
@ -61,7 +63,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics
mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells
activespells npcstats aipackage aisequence
activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate
)
add_openmw_dir (mwbase

@ -20,6 +20,7 @@
#include "mwscript/scriptmanagerimp.hpp"
#include "mwscript/extensions.hpp"
#include "mwscript/interpretercontext.hpp"
#include "mwsound/soundmanagerimp.hpp"
@ -101,7 +102,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration());
// update world
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame);
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame, MWBase::Environment::get().getWindowManager()->isGuiMode());
// update GUI
Ogre::RenderWindow* window = mOgre->getWindow();
@ -163,9 +164,8 @@ void OMW::Engine::loadBSA()
std::cout << "Data dir " << dataDirectory << std::endl;
Bsa::addDir(dataDirectory, mFSStrict);
// Workaround: Mygui does not find textures in non-BSA subfolders, _unless_ they are explicitely added like this
// For splash screens, this is OK to do, but eventually we will need an investigation why this is necessary
Bsa::addDir(dataDirectory + "/Splash", mFSStrict);
// Workaround until resource listing capabilities are added to DirArchive, we need those to list available splash screens
addResourcesDirectory (dataDirectory);
}
}
@ -356,7 +356,7 @@ void OMW::Engine::go()
// Create dialog system
mEnvironment.setJournal (new MWDialogue::Journal);
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions));
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts));
// Sets up the input system
mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
@ -424,21 +424,10 @@ void OMW::Engine::activate()
if (handle.empty())
return;
// the faced handle is not updated immediately, so on a cell change it might
// point to an object that doesn't exist anymore
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
MWWorld::Ptr ptr;
try
{
ptr = MWBase::Environment::get().getWorld()->getPtrViaHandle (handle);
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaHandle (handle);
if (ptr.isEmpty())
return;
}
catch (std::runtime_error&)
{
if (ptr.isEmpty())
return;
}
MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr);

@ -68,7 +68,7 @@ void validate(boost::any &v, std::vector<std::string> const &tokens, FallbackMap
if((mapIt = map->mMap.find(key)) == map->mMap.end())
{
map->mMap.insert(std::make_pair<std::string,std::string>(key,value));
map->mMap.insert(std::make_pair (key,value));
}
}
}

@ -33,13 +33,17 @@ namespace MWBase
virtual void goodbye() = 0;
///get the faction of the actor you are talking with
virtual std::string getFaction() const = 0;
virtual MWWorld::Ptr getActor() const = 0;
///< Return the actor the player is currently talking to.
//calbacks for the GUI
virtual void keywordSelected (const std::string& keyword) = 0;
virtual void goodbyeSelected() = 0;
virtual void questionAnswered (const std::string& answer) = 0;
virtual void persuade (int type) = 0;
virtual int getTemporaryDispositionChange () const = 0;
virtual void applyTemporaryDispositionChange (int delta) = 0;
};
}

@ -39,6 +39,8 @@ namespace MWBase
virtual void addActor (const MWWorld::Ptr& ptr) = 0;
///< Register an actor for stats management
///
/// \note Dead actors are ignored.
virtual void removeActor (const MWWorld::Ptr& ptr) = 0;
///< Deregister an actor for stats management
@ -60,7 +62,7 @@ namespace MWBase
virtual void setPlayerName (const std::string& name) = 0;
///< Set player name.
virtual void setPlayerRace (const std::string& id, bool male) = 0;
virtual void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) = 0;
///< Set player race.
virtual void setPlayerBirthsign (const std::string& id) = 0;
@ -74,6 +76,28 @@ namespace MWBase
virtual void restoreDynamicStats() = 0;
///< If the player is sleeping, this should be called every hour.
virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0;
///< This is used by every service to determine the price of objects given the trading skills of the player and NPC.
virtual int getDerivedDisposition(const MWWorld::Ptr& ptr) = 0;
///< Calculate the diposition of an NPC toward the player.
virtual int countDeaths (const std::string& id) const = 0;
///< Return the number of deaths for actors with the given ID.
enum PersuasionType
{
PT_Admire,
PT_Intimidate,
PT_Taunt,
PT_Bribe10,
PT_Bribe100,
PT_Bribe1000
};
virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type,
float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
///< Perform a persuasion action on NPC
};
}

@ -37,7 +37,7 @@ namespace MWBase
Play_Normal = 0, /* tracked, non-looping, multi-instance, environment */
Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */
Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */
Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position
Play_NoTrack = 1<<2 /* (3D only) Play the sound at the given object's position
* but do not keep it updated (the sound will not move with
* the object and will not stop when the object is deleted. */
};

@ -42,6 +42,7 @@ namespace MWGui
class Console;
class SpellWindow;
class TradeWindow;
class TravelWindow;
class SpellBuyingWindow;
class ConfirmationDialog;
class CountDialog;
@ -108,6 +109,7 @@ namespace MWBase
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
virtual MWGui::TradeWindow* getTradeWindow() = 0;
virtual MWGui::SpellBuyingWindow* getSpellBuyingWindow() = 0;
virtual MWGui::TravelWindow* getTravelWindow() = 0;
virtual MWGui::SpellWindow* getSpellWindow() = 0;
virtual MWGui::Console* getConsole() = 0;
@ -227,6 +229,10 @@ namespace MWBase
virtual bool getPlayerSleeping() = 0;
virtual void wakeUpPlayer() = 0;
virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
virtual void startEnchanting(MWWorld::Ptr actor) = 0;
virtual void startTraining(MWWorld::Ptr actor) = 0;
};
}

@ -28,11 +28,8 @@ namespace ESM
struct Cell;
struct Class;
struct Potion;
}
namespace ESMS
{
struct ESMStore;
struct Spell;
struct NPC;
}
namespace MWRender
@ -47,6 +44,7 @@ namespace MWWorld
class LocalScripts;
class Ptr;
class TimeStamp;
class ESMStore;
}
namespace MWBase
@ -67,7 +65,8 @@ namespace MWBase
Render_CollisionDebug,
Render_Wireframe,
Render_Pathgrid,
Render_Compositors
Render_Compositors,
Render_BoundingBoxes
};
struct DoorMarker
@ -103,7 +102,7 @@ namespace MWBase
virtual MWWorld::Player& getPlayer() = 0;
virtual const ESMS::ESMStore& getStore() const = 0;
virtual const MWWorld::ESMStore& getStore() const = 0;
virtual ESM::ESMReader& getEsmReader() = 0;
@ -142,6 +141,9 @@ namespace MWBase
virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0;
///< Return a pointer to a liveCellRef with the given Ogre handle.
virtual MWWorld::Ptr searchPtrViaHandle (const std::string& handle) = 0;
///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found
/// \todo enable reference in the OGRE scene
virtual void enable (const MWWorld::Ptr& ptr) = 0;
@ -230,19 +232,28 @@ namespace MWBase
///< Toggle a render mode.
///< \return Resulting mode
virtual std::pair<std::string, const ESM::Potion *> createRecord (const ESM::Potion& record)
virtual const ESM::Potion *createRecord (const ESM::Potion& record)
= 0;
///< Create a new recrod (of type potion) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual std::pair<std::string, const ESM::Class *> createRecord (const ESM::Class& record)
virtual const ESM::Spell *createRecord (const ESM::Spell& record)
= 0;
///< Create a new recrod (of type spell) in the ESM store.
/// \return pointer to created record
virtual const ESM::Class *createRecord (const ESM::Class& record)
= 0;
///< Create a new recrod (of type class) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0;
///< Create a new recrod (of type cell) in the ESM store.
/// \return ID, pointer to created record
/// \return pointer to created record
virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0;
///< Create a new recrod (of type npc) in the ESM store.
/// \return pointer to created record
virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName,
int mode, int number = 1) = 0;
@ -256,7 +267,7 @@ namespace MWBase
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
/// references that are currently not in the rendered scene should be ignored.
virtual void update (float duration) = 0;
virtual void update (float duration, bool paused) = 0;
virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0;
///< place an object into the gameworld at the specified cursor position

@ -30,18 +30,17 @@ namespace MWClass
void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Activator::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -53,7 +52,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return ref->base->mName;
return ref->mBase->mName;
}
std::string Activator::getScript (const MWWorld::Ptr& ptr) const
@ -61,7 +60,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Activator::registerSelf()
@ -76,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -85,22 +84,22 @@ namespace MWClass
ptr.get<ESM::Activator>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
}
MWWorld::Ptr
Activator::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>();
return MWWorld::Ptr(&cell.activators.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mActivators.insert(*ref), &cell);
}
}

@ -33,18 +33,17 @@ namespace MWClass
void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -56,7 +55,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Apparatus::getValue (const MWWorld::Ptr& ptr) const
@ -83,7 +82,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Apparatus::registerSelf()
@ -108,7 +107,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const
@ -116,7 +115,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -125,17 +124,17 @@ namespace MWClass
ptr.get<ESM::Apparatus>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -154,6 +153,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>();
return MWWorld::Ptr(&cell.appas.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
}
}

@ -36,18 +36,17 @@ namespace MWClass
void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Armor::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -59,7 +58,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr,
@ -82,7 +81,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mData.mHealth;
return ref->mBase->mData.mHealth;
}
std::string Armor::getScript (const MWWorld::Ptr& ptr) const
@ -90,7 +89,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Armor::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -118,7 +117,7 @@ namespace MWClass
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType)
if (sMapping[i][0]==ref->mBase->mData.mType)
{
slots.push_back (int (sMapping[i][1]));
break;
@ -134,7 +133,7 @@ namespace MWClass
std::string typeGmst;
switch (ref->base->mData.mType)
switch (ref->mBase->mData.mType)
{
case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break;
case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break;
@ -152,14 +151,17 @@ namespace MWClass
if (typeGmst.empty())
return -1;
float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->getInt();
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
float iWeight = gmst.find (typeGmst)->getInt();
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->getFloat()>=
ref->base->mData.mWeight)
if (iWeight * gmst.find ("fLightMaxMod")->getFloat()>=
ref->mBase->mData.mWeight)
return ESM::Skill::LightArmor;
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->getFloat()>=
ref->base->mData.mWeight)
if (iWeight * gmst.find ("fMedMaxMod")->getFloat()>=
ref->mBase->mData.mWeight)
return ESM::Skill::MediumArmor;
return ESM::Skill::HeavyArmor;
@ -170,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Armor::registerSelf()
@ -207,7 +209,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const
@ -215,7 +217,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -224,8 +226,8 @@ namespace MWClass
ptr.get<ESM::Armor>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
@ -239,20 +241,20 @@ namespace MWClass
else
typeText = "#{sHeavy}";
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->base->mData.mArmor);
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
/// \todo store the current armor health somewhere
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth);
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight) + " (" + typeText + ")";
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")";
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
info.text = text;
@ -264,7 +266,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
@ -282,6 +284,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return MWWorld::Ptr(&cell.armors.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell);
}
}

@ -32,18 +32,17 @@ namespace MWClass
void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Book::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -55,7 +54,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
@ -70,7 +69,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Book::getValue (const MWWorld::Ptr& ptr) const
@ -78,7 +77,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Book::registerSelf()
@ -103,7 +102,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Book::hasToolTip (const MWWorld::Ptr& ptr) const
@ -111,7 +110,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -120,20 +119,20 @@ namespace MWClass
ptr.get<ESM::Book>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
info.text = text;
@ -145,7 +144,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
@ -159,6 +158,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return MWWorld::Ptr(&cell.books.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Clothing::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Clothing::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -85,7 +84,7 @@ namespace MWClass
std::vector<int> slots;
if (ref->base->mData.mType==ESM::Clothing::Ring)
if (ref->mBase->mData.mType==ESM::Clothing::Ring)
{
slots.push_back (int (MWWorld::InventoryStore::Slot_LeftRing));
slots.push_back (int (MWWorld::InventoryStore::Slot_RightRing));
@ -108,7 +107,7 @@ namespace MWClass
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType)
if (sMapping[i][0]==ref->mBase->mData.mType)
{
slots.push_back (int (sMapping[i][1]));
break;
@ -123,7 +122,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
if (ref->base->mData.mType==ESM::Clothing::Shoes)
if (ref->mBase->mData.mType==ESM::Clothing::Shoes)
return ESM::Skill::Unarmored;
return -1;
@ -134,7 +133,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Clothing::registerSelf()
@ -149,7 +148,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
if (ref->base->mData.mType == 8)
if (ref->mBase->mData.mType == 8)
{
return std::string("Item Ring Up");
}
@ -161,7 +160,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
if (ref->base->mData.mType == 8)
if (ref->mBase->mData.mType == 8)
{
return std::string("Item Ring Down");
}
@ -173,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const
@ -181,7 +180,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -190,20 +189,20 @@ namespace MWClass
ptr.get<ESM::Clothing>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
info.text = text;
@ -215,7 +214,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
@ -233,6 +232,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return MWWorld::Ptr(&cell.clothes.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell);
}
}

@ -8,7 +8,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/failedaction.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwworld/cellstore.hpp"
@ -65,18 +65,17 @@ namespace MWClass
void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Container::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -95,9 +94,15 @@ namespace MWClass
bool needKey = ptr.getCellRef().mLockLevel>0;
bool hasKey = false;
std::string keyName;
// make key id lowercase
std::string keyId = ptr.getCellRef().mKey;
std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{
if (it->getCellRef ().mRefID == ptr.getCellRef().mKey)
std::string refId = it->getCellRef().mRefID;
std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower);
if (refId == keyId)
{
hasKey = true;
keyName = MWWorld::Class::get(*it).getName(*it);
@ -124,7 +129,7 @@ namespace MWClass
{
// Trap activation goes here
std::cout << "Activated trap: " << ptr.getCellRef().mTrap << std::endl;
boost::shared_ptr<MWWorld::Action> action(new MWWorld::NullAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::FailedAction);
action->setSound(trapActivationSound);
ptr.getCellRef().mTrap = "";
return action;
@ -132,7 +137,7 @@ namespace MWClass
}
else
{
boost::shared_ptr<MWWorld::Action> action(new MWWorld::NullAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::FailedAction);
action->setSound(lockedSound);
return action;
}
@ -143,7 +148,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return ref->base->mName;
return ref->mBase->mName;
}
MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr)
@ -159,7 +164,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Container::registerSelf()
@ -174,7 +179,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -183,17 +188,17 @@ namespace MWClass
ptr.get<ESM::Container>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
if (ref->ref.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel);
if (ref->ref.mTrap != "")
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -206,7 +211,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return ref->base->mWeight;
return ref->mBase->mWeight;
}
float Container::getEncumbrance (const MWWorld::Ptr& ptr) const
@ -233,6 +238,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>();
return MWWorld::Ptr(&cell.containers.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mContainers.insert(*ref), &cell);
}
}

@ -12,6 +12,7 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
#include "../mwworld/actionopen.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/physicssystem.hpp"
@ -47,28 +48,28 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
// creature stats
data->mCreatureStats.getAttribute(0).set (ref->base->mData.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->base->mData.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->base->mData.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->base->mData.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->base->mData.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck);
data->mCreatureStats.getHealth().set (ref->base->mData.mHealth);
data->mCreatureStats.getMagicka().set (ref->base->mData.mMana);
data->mCreatureStats.getFatigue().set (ref->base->mData.mFatigue);
data->mCreatureStats.setLevel(ref->base->mData.mLevel);
data->mCreatureStats.setHello(ref->base->mAiData.mHello);
data->mCreatureStats.setFight(ref->base->mAiData.mFight);
data->mCreatureStats.setFlee(ref->base->mAiData.mFlee);
data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm);
data->mCreatureStats.getAttribute(0).set (ref->mBase->mData.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->mBase->mData.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->mBase->mData.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->mBase->mData.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->mBase->mData.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->mBase->mData.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->mBase->mData.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->mBase->mData.mLuck);
data->mCreatureStats.setHealth (ref->mBase->mData.mHealth);
data->mCreatureStats.setMagicka (ref->mBase->mData.mMana);
data->mCreatureStats.setFatigue (ref->mBase->mData.mFatigue);
data->mCreatureStats.setLevel(ref->mBase->mData.mLevel);
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
// spells
for (std::vector<std::string>::const_iterator iter (ref->base->mSpells.mList.begin());
iter!=ref->base->mSpells.mList.end(); ++iter)
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter);
// store
@ -81,7 +82,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mId;
return ref->mBase->mId;
}
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -93,9 +94,8 @@ namespace MWClass
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()){
physics.insertActorPhysics(ptr, model);
}
if(!model.empty())
physics.addActor(ptr);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
}
@ -103,9 +103,9 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -117,7 +117,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mName;
return ref->mBase->mName;
}
MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const
@ -130,7 +130,10 @@ namespace MWClass
boost::shared_ptr<MWWorld::Action> Creature::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const
{
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
if (MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead())
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionOpen(ptr));
else
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr)
@ -146,7 +149,15 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->base->mScript;
return ref->mBase->mScript;
}
bool Creature::isEssential (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return ref->mBase->mFlags & ESM::Creature::Essential;
}
void Creature::registerSelf()
@ -169,11 +180,11 @@ namespace MWClass
ptr.get<ESM::Creature>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
@ -207,6 +218,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
return MWWorld::Ptr(&cell.creatures.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
}
}

@ -56,6 +56,9 @@ namespace MWClass
///< Returns total weight of objects inside this object (including modifications from magic
/// effects). Throws an exception, if the object can't hold other objects.
virtual bool isEssential (const MWWorld::Ptr& ptr) const;
///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable)
static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;

@ -10,6 +10,7 @@
#include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/failedaction.hpp"
#include "../mwworld/actionteleport.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp"
@ -35,18 +36,17 @@ namespace MWClass
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Door::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -58,10 +58,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
if (ref->ref.mTeleport && !ref->ref.mDestCell.empty()) // TODO doors that lead to exteriors
return ref->ref.mDestCell;
if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors
return ref->mRef.mDestCell;
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr,
@ -70,8 +70,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
const std::string &openSound = ref->base->mOpenSound;
//const std::string &closeSound = ref->base->closeSound;
const std::string &openSound = ref->mBase->mOpenSound;
//const std::string &closeSound = ref->mBase->closeSound;
const std::string lockedSound = "LockedDoor";
const std::string trapActivationSound = "Disarm Trap Fail";
@ -81,9 +81,15 @@ namespace MWClass
bool needKey = ptr.getCellRef().mLockLevel>0;
bool hasKey = false;
std::string keyName;
// make key id lowercase
std::string keyId = ptr.getCellRef().mKey;
std::transform(keyId.begin(), keyId.end(), keyId.begin(), ::tolower);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{
if (it->getCellRef ().mRefID == ptr.getCellRef().mKey)
std::string refId = it->getCellRef().mRefID;
std::transform(refId.begin(), refId.end(), refId.begin(), ::tolower);
if (refId == keyId)
{
hasKey = true;
keyName = MWWorld::Class::get(*it).getName(*it);
@ -105,21 +111,20 @@ namespace MWClass
// Trap activation
std::cout << "Activated trap: " << ptr.getCellRef().mTrap << std::endl;
boost::shared_ptr<MWWorld::Action> action(new MWWorld::NullAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::FailedAction);
action->setSound(trapActivationSound);
ptr.getCellRef().mTrap = "";
return action;
}
if (ref->ref.mTeleport)
if (ref->mRef.mTeleport)
{
// teleport door
/// \todo remove this if clause once ActionTeleport can also support other actors
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
{
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->ref.mDestCell, ref->ref.mDoorDest));
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest));
action->setSound(openSound);
@ -128,7 +133,7 @@ namespace MWClass
else
{
// another NPC or a creature is using the door
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
return boost::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction);
}
}
else
@ -147,7 +152,7 @@ namespace MWClass
else
{
// locked, and we can't open.
boost::shared_ptr<MWWorld::Action> action(new MWWorld::NullAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::FailedAction);
action->setSound(lockedSound);
return action;
}
@ -171,7 +176,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Door::registerSelf()
@ -186,7 +191,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -195,31 +200,32 @@ namespace MWClass
ptr.get<ESM::Door>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
if (ref->ref.mTeleport)
if (ref->mRef.mTeleport)
{
std::string dest;
if (ref->ref.mDestCell != "")
if (ref->mRef.mDestCell != "")
{
// door leads to an interior, use interior name as tooltip
dest = ref->ref.mDestCell;
dest = ref->mRef.mDestCell;
}
else
{
// door leads to exterior, use cell name (if any), otherwise translated region name
int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (ref->ref.mDoorDest.pos[0], ref->ref.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.cells.findExt(x,y);
MWBase::Environment::get().getWorld()->positionToIndex (ref->mRef.mDoorDest.pos[0], ref->mRef.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "")
dest = cell->mName;
else
{
const ESM::Region* region = store.regions.search(cell->mRegion);
const ESM::Region* region =
store.get<ESM::Region>().find(cell->mRegion);
dest = region->mName;
}
}
@ -227,13 +233,13 @@ namespace MWClass
text += "\n"+dest;
}
if (ref->ref.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel);
if (ref->ref.mTrap != "")
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
@ -246,6 +252,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>();
return MWWorld::Ptr(&cell.doors.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell);
}
}

@ -25,7 +25,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mId;
return ref->mBase->mId;
}
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -41,18 +41,17 @@ namespace MWClass
void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Ingredient::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -64,7 +63,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr,
@ -82,7 +81,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Ingredient::getValue (const MWWorld::Ptr& ptr) const
@ -90,7 +89,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const
@ -133,7 +132,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -142,28 +141,28 @@ namespace MWClass
ptr.get<ESM::Ingredient>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
MWGui::Widgets::SpellEffectList list;
for (int i=0; i<4; ++i)
{
if (ref->base->mData.mEffectID[i] < 0)
if (ref->mBase->mData.mEffectID[i] < 0)
continue;
MWGui::Widgets::SpellEffectParams params;
params.mEffectID = ref->base->mData.mEffectID[i];
params.mAttribute = ref->base->mData.mAttributes[i];
params.mSkill = ref->base->mData.mSkills[i];
params.mEffectID = ref->mBase->mData.mEffectID[i];
params.mAttribute = ref->mBase->mData.mAttributes[i];
params.mSkill = ref->mBase->mData.mSkills[i];
list.push_back(params);
}
info.effects = list;
@ -179,6 +178,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>();
return MWWorld::Ptr(&cell.ingreds.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
}
}

@ -12,6 +12,7 @@
#include "../mwworld/actiontake.hpp"
#include "../mwworld/actionequip.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/failedaction.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp"
@ -27,9 +28,9 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
@ -37,11 +38,11 @@ namespace MWClass
if (!model.empty())
objects.insertMesh(ptr, "meshes\\" + model);
const int color = ref->base->mData.mColor;
const int color = ref->mBase->mData.mColor;
const float r = ((color >> 0) & 0xFF) / 255.0f;
const float g = ((color >> 8) & 0xFF) / 255.0f;
const float b = ((color >> 16) & 0xFF) / 255.0f;
const float radius = float (ref->base->mData.mRadius);
const float radius = float (ref->mBase->mData.mRadius);
objects.insertLight (ptr, r, g, b, radius);
}
@ -49,25 +50,24 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if(!model.empty()) {
physics.insertObjectPhysics(ptr, "meshes\\" + model);
}
if (!ref->base->mSound.empty()) {
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
}
if(!model.empty())
physics.addObject(ptr);
if (!ref->mBase->mSound.empty())
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
}
std::string Light::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
assert (ref->base != NULL);
assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -79,10 +79,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
if (ref->base->mModel.empty())
if (ref->mBase->mModel.empty())
return "";
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr,
@ -91,8 +91,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
if (!(ref->base->mData.mFlags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::NullAction);
if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTake (ptr));
@ -106,7 +106,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Light::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -116,7 +116,7 @@ namespace MWClass
std::vector<int> slots;
if (ref->base->mData.mFlags & ESM::Light::Carry)
if (ref->mBase->mData.mFlags & ESM::Light::Carry)
slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft));
return std::make_pair (slots, false);
@ -127,7 +127,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Light::registerSelf()
@ -153,7 +153,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Light::hasToolTip (const MWWorld::Ptr& ptr) const
@ -161,7 +161,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -170,17 +170,17 @@ namespace MWClass
ptr.get<ESM::Light>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -203,6 +203,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>();
return MWWorld::Ptr(&cell.lights.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Lockpick::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -92,7 +91,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Lockpick::registerSelf()
@ -117,7 +116,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -134,21 +133,21 @@ namespace MWClass
ptr.get<ESM::Tool>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
/// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -171,6 +170,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>();
return MWWorld::Ptr(&cell.lockpicks.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
}
}

@ -37,18 +37,17 @@ namespace MWClass
void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Miscellaneous::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -60,7 +59,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Miscellaneous::activate (const MWWorld::Ptr& ptr,
@ -78,7 +77,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const
@ -86,7 +85,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Miscellaneous::registerSelf()
@ -101,7 +100,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString())
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{
return std::string("Item Gold Up");
}
@ -113,7 +112,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString())
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{
return std::string("Item Gold Down");
}
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const
@ -133,7 +132,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -143,13 +142,13 @@ namespace MWClass
MWGui::ToolTipInfo info;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
int count = ptr.getRefData().getCount();
bool isGold = (ref->base->mName == store.gameSettings.find("sGold")->getString());
bool isGold = (ref->mBase->mName == store.get<ESM::GameSetting>().find("sGold")->getString());
if (isGold && count == 1)
count = ref->base->mData.mValue;
count = ref->mBase->mData.mValue;
std::string countString;
if (!isGold)
@ -157,12 +156,12 @@ namespace MWClass
else // gold displays its count also if it's 1.
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
info.caption = ref->base->mName + countString;
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + countString;
info.icon = ref->mBase->mIcon;
if (ref->ref.mSoul != "")
if (ref->mRef.mSoul != "")
{
const ESM::Creature *creature = store.creatures.search(ref->ref.mSoul);
const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.mSoul);
info.caption += " (" + creature->mName + ")";
}
@ -170,13 +169,13 @@ namespace MWClass
if (!isGold)
{
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
}
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -189,10 +188,10 @@ namespace MWClass
{
MWWorld::Ptr newPtr;
const ESMS::ESMStore &store =
const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore();
if (MWWorld::Class::get(ptr).getName(ptr) == store.gameSettings.find("sGold")->getString()) {
if (MWWorld::Class::get(ptr).getName(ptr) == store.get<ESM::GameSetting>().find("sGold")->getString()) {
int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001";
@ -210,11 +209,11 @@ namespace MWClass
MWWorld::ManualRef newRef(store, base);
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell);
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
} else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell);
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
}
return newPtr;
}

@ -20,6 +20,7 @@
#include "../mwworld/ptr.hpp"
#include "../mwworld/actiontalk.hpp"
#include "../mwworld/actionopen.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwworld/physicssystem.hpp"
@ -61,53 +62,62 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
// NPC stats
if (!ref->base->mFaction.empty())
if (!ref->mBase->mFaction.empty())
{
std::string faction = ref->base->mFaction;
std::string faction = ref->mBase->mFaction;
boost::algorithm::to_lower(faction);
if(ref->base->mNpdt52.mGold != -10)
if(ref->mBase->mNpdt52.mGold != -10)
{
data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt52.mRank;
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank;
}
else
{
data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt12.mRank;
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt12.mRank;
}
}
// creature stats
if(ref->base->mNpdt52.mGold != -10)
if(ref->mBase->mNpdt52.mGold != -10)
{
for (int i=0; i<27; ++i)
data->mNpcStats.getSkill (i).setBase (ref->base->mNpdt52.mSkills[i]);
data->mCreatureStats.getAttribute(0).set (ref->base->mNpdt52.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->base->mNpdt52.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->base->mNpdt52.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->base->mNpdt52.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->base->mNpdt52.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck);
data->mCreatureStats.getHealth().set (ref->base->mNpdt52.mHealth);
data->mCreatureStats.getMagicka().set (ref->base->mNpdt52.mMana);
data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue);
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
data->mCreatureStats.getAttribute(0).set (ref->mBase->mNpdt52.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->mBase->mNpdt52.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->mBase->mNpdt52.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->mBase->mNpdt52.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->mBase->mNpdt52.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->mBase->mNpdt52.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->mBase->mNpdt52.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->mBase->mNpdt52.mLuck);
data->mCreatureStats.setHealth (ref->mBase->mNpdt52.mHealth);
data->mCreatureStats.setMagicka (ref->mBase->mNpdt52.mMana);
data->mCreatureStats.setFatigue (ref->mBase->mNpdt52.mFatigue);
data->mCreatureStats.setLevel(ref->mBase->mNpdt52.mLevel);
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt52.mDisposition);
data->mNpcStats.setReputation(ref->mBase->mNpdt52.mReputation);
}
else
{
/// \todo do something with mNpdt12 maybe:p
for (int i=0; i<8; ++i)
data->mCreatureStats.getAttribute (i).set (10);
for (int i=0; i<3; ++i)
data->mCreatureStats.setDynamic (i, 10);
data->mCreatureStats.setLevel (1);
}
data->mCreatureStats.setHello(ref->base->mAiData.mHello);
data->mCreatureStats.setFight(ref->base->mAiData.mFight);
data->mCreatureStats.setFlee(ref->base->mAiData.mFlee);
data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm);
data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
// spells
for (std::vector<std::string>::const_iterator iter (ref->base->mSpells.mList.begin());
iter!=ref->base->mSpells.mList.end(); ++iter)
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter);
// store
@ -120,7 +130,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mId;
return ref->mBase->mId;
}
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -130,7 +140,7 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
physics.insertActorPhysics(ptr, getModel(ptr));
physics.addActor(ptr);
MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
}
@ -138,9 +148,9 @@ namespace MWClass
{
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
std::string headID = ref->base->mHead;
std::string headID = ref->mBase->mHead;
int end = headID.find_last_of("head_") - 4;
std::string bodyRaceID = headID.substr(0, end);
@ -162,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mName;
return ref->mBase->mName;
}
MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const
@ -182,7 +192,10 @@ namespace MWClass
boost::shared_ptr<MWWorld::Action> Npc::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const
{
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
if (MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead())
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionOpen(ptr));
else
return boost::shared_ptr<MWWorld::Action> (new MWWorld::ActionTalk (ptr));
}
MWWorld::ContainerStore& Npc::getContainerStore (const MWWorld::Ptr& ptr)
@ -206,7 +219,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->base->mScript;
return ref->mBase->mScript;
}
void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const
@ -308,7 +321,15 @@ namespace MWClass
return vector;
}
bool Npc::isEssential (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return ref->mBase->mFlags & ESM::NPC::Essential;
}
void Npc::registerSelf()
{
boost::shared_ptr<Class> instance (new Npc);
@ -328,11 +349,11 @@ namespace MWClass
ptr.get<ESM::NPC>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName;
info.caption = ref->mBase->mName;
std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
@ -376,8 +397,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find (
ref->base->mClass);
const ESM::Class *class_ =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (
ref->mBase->mClass
);
stats.useSkill (skill, *class_, usageType);
}
@ -394,6 +417,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>();
return MWWorld::Ptr(&cell.npcs.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
}
}

@ -90,6 +90,9 @@ namespace MWClass
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
virtual bool isEssential (const MWWorld::Ptr& ptr) const;
///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable)
static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;

@ -34,18 +34,17 @@ namespace MWClass
void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Potion::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr,
@ -76,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Potion::getValue (const MWWorld::Ptr& ptr) const
@ -84,7 +83,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Potion::registerSelf()
@ -109,7 +108,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const
@ -117,7 +116,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -126,20 +125,20 @@ namespace MWClass
ptr.get<ESM::Potion>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->mEffects);
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
info.isPotion = true;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -157,7 +156,7 @@ namespace MWClass
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
boost::shared_ptr<MWWorld::Action> action (
new MWWorld::ActionApply (actor, ref->base->mId));
new MWWorld::ActionApply (actor, ref->mBase->mId));
action->setSound ("Drink");
@ -170,6 +169,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>();
return MWWorld::Ptr(&cell.potions.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Probe::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const
@ -74,7 +73,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Probe::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -91,7 +90,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Probe::registerSelf()
@ -116,7 +115,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const
@ -124,7 +123,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -133,21 +132,21 @@ namespace MWClass
ptr.get<ESM::Probe>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
/// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -170,6 +169,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>();
return MWWorld::Ptr(&cell.probes.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
}
}

@ -32,18 +32,17 @@ namespace MWClass
void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Repair::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -55,7 +54,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr,
@ -73,7 +72,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mScript;
return ref->mBase->mScript;
}
int Repair::getValue (const MWWorld::Ptr& ptr) const
@ -81,7 +80,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Repair::registerSelf()
@ -106,7 +105,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const
@ -114,7 +113,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -123,21 +122,21 @@ namespace MWClass
ptr.get<ESM::Repair>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
std::string text;
/// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -151,6 +150,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>();
return MWWorld::Ptr(&cell.repairs.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell);
}
}

@ -24,18 +24,17 @@ namespace MWClass
void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Static::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -60,6 +59,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>();
return MWWorld::Ptr(&cell.statics.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mStatics.insert(*ref), &cell);
}
}

@ -34,18 +34,17 @@ namespace MWClass
void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{
const std::string model = getModel(ptr);
if(!model.empty()) {
physics.insertObjectPhysics(ptr, model);
}
if(!model.empty())
physics.addObject(ptr);
}
std::string Weapon::getModel(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
assert(ref->base != NULL);
assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel;
const std::string &model = ref->mBase->mModel;
if (!model.empty()) {
return "meshes\\" + model;
}
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mName;
return ref->mBase->mName;
}
boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr,
@ -80,7 +79,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mData.mHealth;
return ref->mBase->mData.mHealth;
}
std::string Weapon::getScript (const MWWorld::Ptr& ptr) const
@ -88,7 +87,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mScript;
return ref->mBase->mScript;
}
std::pair<std::vector<int>, bool> Weapon::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -99,12 +98,12 @@ namespace MWClass
std::vector<int> slots;
bool stack = false;
if (ref->base->mData.mType==ESM::Weapon::Arrow || ref->base->mData.mType==ESM::Weapon::Bolt)
if (ref->mBase->mData.mType==ESM::Weapon::Arrow || ref->mBase->mData.mType==ESM::Weapon::Bolt)
{
slots.push_back (int (MWWorld::InventoryStore::Slot_Ammunition));
stack = true;
}
else if (ref->base->mData.mType==ESM::Weapon::MarksmanThrown)
else if (ref->mBase->mData.mType==ESM::Weapon::MarksmanThrown)
{
slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight));
stack = true;
@ -139,7 +138,7 @@ namespace MWClass
};
for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType)
if (sMapping[i][0]==ref->mBase->mData.mType)
return sMapping[i][1];
return -1;
@ -150,7 +149,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mData.mValue;
return ref->mBase->mData.mValue;
}
void Weapon::registerSelf()
@ -165,7 +164,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
int type = ref->base->mData.mType;
int type = ref->mBase->mData.mType;
// Ammo
if (type == 12 || type == 13)
{
@ -211,7 +210,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
int type = ref->base->mData.mType;
int type = ref->mBase->mData.mType;
// Ammo
if (type == 12 || type == 13)
{
@ -257,7 +256,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mIcon;
return ref->mBase->mIcon;
}
bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const
@ -265,7 +264,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return (ref->base->mName != "");
return (ref->mBase->mName != "");
}
MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -274,15 +273,15 @@ namespace MWClass
ptr.get<ESM::Weapon>();
MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon;
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->mBase->mIcon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string text;
// weapon type & damage. arrows / bolts don't have his info.
if (ref->base->mData.mType < 12)
if (ref->mBase->mData.mType < 12)
{
text += "\n#{sType} ";
@ -300,49 +299,49 @@ namespace MWClass
mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", "");
std::string type = mapping[ref->base->mData.mType].first;
std::string oneOrTwoHanded = mapping[ref->base->mData.mType].second;
std::string type = mapping[ref->mBase->mData.mType].first;
std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second;
text += store.gameSettings.find(type)->getString() +
((oneOrTwoHanded != "") ? ", " + store.gameSettings.find(oneOrTwoHanded)->getString() : "");
text += store.get<ESM::GameSetting>().find(type)->getString() +
((oneOrTwoHanded != "") ? ", " + store.get<ESM::GameSetting>().find(oneOrTwoHanded)->getString() : "");
// weapon damage
if (ref->base->mData.mType >= 9)
if (ref->mBase->mData.mType >= 9)
{
// marksman
text += "\n#{sAttack}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
}
else
{
// Chop
text += "\n#{sChop}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
// Slash
text += "\n#{sSlash}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mSlash[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mSlash[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mSlash[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mSlash[1]));
// Thrust
text += "\n#{sThrust}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mThrust[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mThrust[1]));
+ MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[1]));
}
}
/// \todo store the current weapon health somewhere
if (ref->base->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth);
if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}");
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.enchant = ref->base->mEnchant;
info.enchant = ref->mBase->mEnchant;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
}
info.text = text;
@ -355,7 +354,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->base->mEnchant;
return ref->mBase->mEnchant;
}
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
@ -373,6 +372,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return MWWorld::Ptr(&cell.weapons.insert(*ref), &cell);
return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell);
}
}

File diff suppressed because it is too large Load Diff

@ -3,55 +3,52 @@
#include "../mwbase/dialoguemanager.hpp"
#include <components/esm/loadinfo.hpp>
#include <map>
#include <list>
#include <components/compiler/streamerrorhandler.hpp>
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/output.hpp>
#include "../mwworld/ptr.hpp"
#include <map>
#include "../mwscript/compilercontext.hpp"
namespace MWDialogue
{
class DialogueManager : public MWBase::DialogueManager
{
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const;
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
bool functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice);
void parseText(std::string text);
void updateTopics();
std::map<std::string,ESM::Dialogue> mDialogueMap;
std::map<std::string,bool> mKnownTopics;// Those are the topics the player knows.
std::map<std::string, ESM::Dialogue> mDialogueMap;
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
std::list<std::string> mActorKnownTopics;
MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream;
Compiler::StreamErrorHandler mErrorHandler;
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript(std::string script);
MWWorld::Ptr mActor;
void printError(std::string error);
bool mTalkedTo;
int mChoice;
std::map<std::string,int> mChoiceMap;
std::map<std::string, int> mChoiceMap;
std::string mLastTopic;
ESM::DialInfo mLastDialogue;
bool mIsInChoice;
float mTemporaryDispositionChange;
float mPermanentDispositionChange;
bool mScriptVerbose;
void parseText (const std::string& text);
void updateTopics();
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript (const std::string& script);
void printError (const std::string& error);
public:
DialogueManager (const Compiler::Extensions& extensions);
DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose);
virtual void startDialogue (const MWWorld::Ptr& actor);
@ -61,14 +58,17 @@ namespace MWDialogue
virtual void goodbye();
///get the faction of the actor you are talking with
virtual std::string getFaction() const;
virtual MWWorld::Ptr getActor() const;
///< Return the actor the player is currently talking to.
//calbacks for the GUI
virtual void keywordSelected (const std::string& keyword);
virtual void goodbyeSelected();
virtual void questionAnswered (const std::string& answer);
virtual void persuade (int type);
virtual int getTemporaryDispositionChange () const;
virtual void applyTemporaryDispositionChange (int delta);
};
}

@ -0,0 +1,570 @@
#include "filter.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/magiceffects.hpp"
#include "selectwrapper.hpp"
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
}
bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
{
// actor id
if (!info.mActor.empty())
if (toLower (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor))
return false;
bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
// NPC race
if (!info.mRace.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace))
return false;
}
// NPC class
if (!info.mClass.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass))
return false;
}
// NPC faction
if (!info.mNpcFaction.empty())
{
if (isCreature)
return false;
MWMechanics::NpcStats& stats = MWWorld::Class::get (mActor).getNpcStats (mActor);
std::map<std::string, int>::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction));
if (iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mRank)
return false;
}
// Gender
if (!isCreature)
{
MWWorld::LiveCellRef<ESM::NPC>* npc = mActor.get<ESM::NPC>();
if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1))
return false;
}
return true;
}
bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
{
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// check player faction
if (!info.mPcFaction.empty())
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (player).getNpcStats (player);
std::map<std::string,int>::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction));
if(iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mPCrank)
return false;
}
// check cell
if (!info.mCell.empty())
if (toLower (player.getCell()->mCell->mName) != toLower (info.mCell))
return false;
return true;
}
bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
{
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.mSelects.begin());
iter != info.mSelects.end(); ++iter)
if (!testSelectStruct (*iter))
return false;
return true;
}
bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
{
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
return select.isInverted();
switch (select.getType())
{
case SelectWrapper::Type_None: return true;
case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select));
case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select);
case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select));
}
return true;
}
bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const
{
switch (select.getFunction())
{
case SelectWrapper::Function_Global:
// internally all globals are float :(
return select.selectCompare (
MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat);
case SelectWrapper::Function_Local:
{
std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor);
if (scriptName.empty())
return false; // no script
const ESM::Script *script =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
std::string name = select.getName();
int i = 0;
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
if (script->mVarNames[i]==name)
break;
if (i>=static_cast<int> (script->mVarNames.size()))
return false; // script does not have a variable of this name
const MWScript::Locals& locals = mActor.getRefData().getLocals();
if (i<script->mData.mNumShorts)
return select.selectCompare (static_cast<int> (locals.mShorts[i]));
i -= script->mData.mNumShorts;
if (i<script->mData.mNumLongs)
return select.selectCompare (locals.mLongs[i]);
i -= script->mData.mNumShorts;
return select.selectCompare (locals.mFloats.at (i));
}
case SelectWrapper::Function_PcHealthPercent:
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() /
MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
return select.selectCompare (ratio);
}
case SelectWrapper::Function_PcDynamicStat:
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float value = MWWorld::Class::get (player).getCreatureStats (player).
getDynamic (select.getArgument()).getCurrent();
return select.selectCompare (value);
}
case SelectWrapper::Function_HealthPercent:
{
float ratio = MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getCurrent() /
MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getModified();
return select.selectCompare (ratio);
}
default:
throw std::runtime_error ("unknown numeric select function");
}
}
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
switch (select.getFunction())
{
case SelectWrapper::Function_Journal:
return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName());
case SelectWrapper::Function_Item:
{
MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player);
int sum = 0;
std::string name = select.getName();
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (toLower(iter->getCellRef().mRefID) == name)
sum += iter->getRefData().getCount();
return sum;
}
case SelectWrapper::Function_Dead:
return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName());
case SelectWrapper::Function_Choice:
return mChoice;
case SelectWrapper::Function_AiSetting:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument());
case SelectWrapper::Function_PcAttribute:
return MWWorld::Class::get (player).getCreatureStats (player).
getAttribute (select.getArgument()).getModified();
case SelectWrapper::Function_PcSkill:
return static_cast<int> (MWWorld::Class::get (player).
getNpcStats (player).getSkill (select.getArgument()).getModified());
case SelectWrapper::Function_FriendlyHit:
{
int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits();
return hits>4 ? 4 : hits;
}
case SelectWrapper::Function_PcLevel:
return MWWorld::Class::get (player).getCreatureStats (player).getLevel();
case SelectWrapper::Function_PcGender:
return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1;
case SelectWrapper::Function_PcClothingModifier:
{
MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player);
int value = 0;
for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition
{
MWWorld::ContainerStoreIterator slot = store.getSlot (i);
if (slot!=store.end())
value += MWWorld::Class::get (*slot).getValue (*slot);
}
return value;
}
case SelectWrapper::Function_PcCrimeLevel:
return MWWorld::Class::get (player).getNpcStats (player).getBounty();
case SelectWrapper::Function_RankRequirement:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int rank = getFactionRank (player, faction);
if (rank>=9)
return 0; // max rank
int result = 0;
if (hasFactionRankSkillRequirements (player, faction, rank+1))
result += 1;
if (hasFactionRankReputationRequirements (player, faction, rank+1))
result += 2;
return result;
}
case SelectWrapper::Function_Level:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel();
case SelectWrapper::Function_PCReputation:
return MWWorld::Class::get (player).getNpcStats (player).getReputation();
case SelectWrapper::Function_Weather:
return MWBase::Environment::get().getWorld()->getCurrentWeather();
case SelectWrapper::Function_Reputation:
return MWWorld::Class::get (mActor).getNpcStats (mActor).getReputation();
case SelectWrapper::Function_FactionRankDiff:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::pair<std::string, int> faction =
*MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin();
int rank = getFactionRank (player, faction.first);
return rank-faction.second;
}
case SelectWrapper::Function_WerewolfKills:
return MWWorld::Class::get (player).getNpcStats (player).getWerewolfKills();
case SelectWrapper::Function_RankLow:
case SelectWrapper::Function_RankHigh:
{
bool low = select.getFunction()==SelectWrapper::Function_RankLow;
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string factionId =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int value = 0;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::NpcStats& playerStats = MWWorld::Class::get (player).getNpcStats (player);
for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin());
iter!=faction.mReactions.end(); ++iter)
if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end())
if (low ? iter->mReaction<value : iter->mReaction>value)
value = iter->mReaction;
return value;
}
default:
throw std::runtime_error ("unknown integer select function");
}
}
bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
switch (select.getFunction())
{
case SelectWrapper::Function_False:
return false;
case SelectWrapper::Function_Id:
return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor));
case SelectWrapper::Function_Faction:
return toLower (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName();
case SelectWrapper::Function_Class:
return toLower (mActor.get<ESM::NPC>()->mBase->mClass)==select.getName();
case SelectWrapper::Function_Race:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName();
case SelectWrapper::Function_Cell:
return toLower (mActor.getCell()->mCell->mName)==select.getName();
case SelectWrapper::Function_SameGender:
return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)==
(mActor.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female);
case SelectWrapper::Function_SameRace:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)!=
toLower (player.get<ESM::NPC>()->mBase->mRace);
case SelectWrapper::Function_SameFaction:
return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction (
MWWorld::Class::get (player).getNpcStats (player));
case SelectWrapper::Function_PcCommonDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease();
case SelectWrapper::Function_PcBlightDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease();
case SelectWrapper::Function_PcCorprus:
return MWWorld::Class::get (player).getCreatureStats (player).
getMagicEffects().get (132).mMagnitude!=0;
case SelectWrapper::Function_PcExpelled:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return false;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
std::set<std::string>& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled();
return expelled.find (faction)!=expelled.end();
}
case SelectWrapper::Function_PcVampire:
return MWWorld::Class::get (player).getNpcStats (player).isVampire();
case SelectWrapper::Function_TalkedToPc:
return mTalkedToPlayer;
case SelectWrapper::Function_Alarmed:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).isAlarmed();
case SelectWrapper::Function_Detected:
return MWWorld::Class::get (mActor).hasDetected (mActor, player);
case SelectWrapper::Function_Attacked:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAttacked();
case SelectWrapper::Function_ShouldAttack:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).isHostile();
case SelectWrapper::Function_CreatureTargetted:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getCreatureTargetted();
case SelectWrapper::Function_PCWerewolf:
return MWWorld::Class::get (player).getNpcStats (player).isWerewolf();
default:
throw std::runtime_error ("unknown boolean select function");
}
}
int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId);
if (iter==stats.getFactionRanks().end())
return -1;
return iter->second;
}
bool MWDialogue::Filter::hasFactionRankSkillRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
if (!MWWorld::Class::get (actor).getNpcStats (actor).hasSkillsForRank (factionId, rank))
return false;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::CreatureStats& stats = MWWorld::Class::get (actor).getCreatureStats (actor);
return stats.getAttribute (faction.mData.mAttribute1).getBase()>=faction.mData.mRankData[rank].mAttribute1 &&
stats.getAttribute (faction.mData.mAttribute2).getBase()>=faction.mData.mRankData[rank].mAttribute2;
}
bool MWDialogue::Filter::hasFactionRankReputationRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
return stats.getFactionReputation (factionId)>=faction.mData.mRankData[rank].mFactReaction;
}
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer)
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
{}
bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const
{
return testActor (info) && testPlayer (info) && testSelectStructs (info);
}
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue) const
{
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter)
if ((*this) (*iter))
return &*iter;
return 0;
}

@ -0,0 +1,58 @@
#ifndef GAME_MWDIALOGUE_FILTER_H
#define GAME_MWDIALOGUE_FILTER_H
#include "../mwworld/ptr.hpp"
namespace ESM
{
struct DialInfo;
struct Dialogue;
}
namespace MWDialogue
{
class SelectWrapper;
class Filter
{
MWWorld::Ptr mActor;
int mChoice;
bool mTalkedToPlayer;
bool testActor (const ESM::DialInfo& info) const;
///< Is this the right actor for this \a info?
bool testPlayer (const ESM::DialInfo& info) const;
///< Do the player and the cell the player is currently in match \a info?
bool testSelectStructs (const ESM::DialInfo& info) const;
///< Are all select structs matching?
bool testSelectStruct (const SelectWrapper& select) const;
bool testSelectStructNumeric (const SelectWrapper& select) const;
int getSelectStructInteger (const SelectWrapper& select) const;
bool getSelectStructBoolean (const SelectWrapper& select) const;
int getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const;
bool hasFactionRankSkillRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
int rank) const;
bool hasFactionRankReputationRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
int rank) const;
public:
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
bool operator() (const ESM::DialInfo& info) const;
///< \return does the dialogue match?
const ESM::DialInfo *search (const ESM::Dialogue& dialogue) const;
};
}
#endif

@ -3,11 +3,11 @@
#include <stdexcept>
#include <components/esm_store/store.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp"
namespace MWDialogue
{
JournalEntry::JournalEntry() {}
@ -16,9 +16,10 @@ namespace MWDialogue
: mTopic (topic), mInfoId (infoId)
{}
std::string JournalEntry::getText (const ESMS::ESMStore& store) const
std::string JournalEntry::getText (const MWWorld::ESMStore& store) const
{
const ESM::Dialogue *dialogue = store.dialogs.find (mTopic);
const ESM::Dialogue *dialogue =
store.get<ESM::Dialogue>().find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
@ -35,7 +36,8 @@ namespace MWDialogue
std::string JournalEntry::idFromIndex (const std::string& topic, int index)
{
const ESM::Dialogue *dialogue = MWBase::Environment::get().getWorld()->getStore().dialogs.find (topic);
const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (topic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)

@ -3,7 +3,7 @@
#include <string>
namespace ESMS
namespace MWWorld
{
struct ESMStore;
}
@ -20,7 +20,7 @@ namespace MWDialogue
JournalEntry (const std::string& topic, const std::string& infoId);
std::string getText (const ESMS::ESMStore& store) const;
std::string getText (const MWWorld::ESMStore& store) const;
static JournalEntry makeFromQuest (const std::string& topic, int index);

@ -1,7 +1,7 @@
#include "journalimp.hpp"
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"

@ -1,7 +1,7 @@
#include "quest.hpp"
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -18,7 +18,8 @@ namespace MWDialogue
const std::string Quest::getName() const
{
const ESM::Dialogue *dialogue = MWBase::Environment::get().getWorld()->getStore().dialogs.find (mTopic);
const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
@ -35,7 +36,8 @@ namespace MWDialogue
void Quest::setIndex (int index)
{
const ESM::Dialogue *dialogue = MWBase::Environment::get().getWorld()->getStore().dialogs.find (mTopic);
const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
@ -63,7 +65,8 @@ namespace MWDialogue
{
int index = -1;
const ESM::Dialogue *dialogue = MWBase::Environment::get().getWorld()->getStore().dialogs.find (entry.mTopic);
const ESM::Dialogue *dialogue =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>().find (entry.mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)

@ -0,0 +1,311 @@
#include "selectwrapper.hpp"
#include <cctype>
#include <stdexcept>
#include <algorithm>
#include <sstream>
#include <iterator>
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
template<typename T1, typename T2>
bool selectCompareImp (char comp, T1 value1, T2 value2)
{
switch (comp)
{
case '0': return value1==value2;
case '1': return value1!=value2;
case '2': return value1>value2;
case '3': return value1>=value2;
case '4': return value1<value2;
case '5': return value1<=value2;
}
throw std::runtime_error ("unknown compare type in dialogue info select");
}
template<typename T>
bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1)
{
if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int ||
select.mType==ESM::VT_Long)
{
return selectCompareImp (select.mSelectRule[4], value1, select.mI);
}
else if (select.mType==ESM::VT_Float)
{
return selectCompareImp (select.mSelectRule[4], value1, select.mF);
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
}
}
MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() const
{
int index = 0;
std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index;
switch (index)
{
case 0: return Function_RankLow;
case 1: return Function_RankHigh;
case 2: return Function_RankRequirement;
case 3: return Function_Reputation;
case 4: return Function_HealthPercent;
case 5: return Function_PCReputation;
case 6: return Function_PcLevel;
case 7: return Function_PcHealthPercent;
case 8: case 9: return Function_PcDynamicStat;
case 10: return Function_PcAttribute;
case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20:
case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30:
case 31: case 32: case 33: case 34: case 35: case 36: case 37: return Function_PcSkill;
case 38: return Function_PcGender;
case 39: return Function_PcExpelled;
case 40: return Function_PcCommonDisease;
case 41: return Function_PcBlightDisease;
case 42: return Function_PcClothingModifier;
case 43: return Function_PcCrimeLevel;
case 44: return Function_SameGender;
case 45: return Function_SameRace;
case 46: return Function_SameFaction;
case 47: return Function_FactionRankDiff;
case 48: return Function_Detected;
case 49: return Function_Alarmed;
case 50: return Function_Choice;
case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute;
case 58: return Function_PcCorprus;
case 59: return Function_Weather;
case 60: return Function_PcVampire;
case 61: return Function_Level;
case 62: return Function_Attacked;
case 63: return Function_TalkedToPc;
case 64: return Function_PcDynamicStat;
case 65: return Function_CreatureTargetted;
case 66: return Function_FriendlyHit;
case 67: case 68: case 69: case 70: return Function_AiSetting;
case 71: return Function_ShouldAttack;
case 72: return Function_PCWerewolf;
case 73: return Function_WerewolfKills;
}
return Function_False;
}
MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& select) : mSelect (select) {}
MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() const
{
char type = mSelect.mSelectRule[1];
switch (type)
{
case '1': return decodeFunction();
case '2': return Function_Global;
case '3': return Function_Local;
case '4': return Function_Journal;
case '5': return Function_Item;
case '6': return Function_Dead;
case '7': return Function_Id;
case '8': return Function_Faction;
case '9': return Function_Class;
case 'A': return Function_Race;
case 'B': return Function_Cell;
case 'C': return Function_Local;
}
return Function_None;
}
int MWDialogue::SelectWrapper::getArgument() const
{
if (mSelect.mSelectRule[1]!='1')
return 0;
int index = 0;
std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index;
switch (index)
{
// AI settings
case 67: return 1;
case 68: return 0;
case 69: return 3;
case 70: return 2;
// attributes
case 10: return 0;
case 51: return 1;
case 52: return 2;
case 53: return 3;
case 54: return 4;
case 55: return 5;
case 56: return 6;
case 57: return 7;
// skills
case 11: return 0;
case 12: return 1;
case 13: return 2;
case 14: return 3;
case 15: return 4;
case 16: return 5;
case 17: return 6;
case 18: return 7;
case 19: return 8;
case 20: return 9;
case 21: return 10;
case 22: return 11;
case 23: return 12;
case 24: return 13;
case 25: return 14;
case 26: return 15;
case 27: return 16;
case 28: return 17;
case 29: return 18;
case 30: return 19;
case 31: return 20;
case 32: return 21;
case 33: return 22;
case 34: return 23;
case 35: return 24;
case 36: return 25;
case 37: return 26;
// dynamic stats
case 8: return 1;
case 9: return 2;
case 64: return 0;
}
return 0;
}
MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
{
static const Function integerFunctions[] =
{
Function_Journal, Function_Item, Function_Dead,
Function_Choice,
Function_AiSetting,
Function_PcAttribute, Function_PcSkill,
Function_FriendlyHit,
Function_PcLevel, Function_PcGender, Function_PcClothingModifier,
Function_PcCrimeLevel,
Function_RankRequirement,
Function_Level, Function_PCReputation,
Function_Weather,
Function_Reputation, Function_FactionRankDiff,
Function_WerewolfKills,
Function_RankLow, Function_RankHigh,
Function_None // end marker
};
static const Function numericFunctions[] =
{
Function_Global, Function_Local,
Function_PcDynamicStat, Function_PcHealthPercent,
Function_HealthPercent,
Function_None // end marker
};
static const Function booleanFunctions[] =
{
Function_False,
Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell,
Function_SameGender, Function_SameRace, Function_SameFaction,
Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus,
Function_PcExpelled,
Function_PcVampire, Function_TalkedToPc,
Function_Alarmed, Function_Detected,
Function_Attacked, Function_ShouldAttack,
Function_CreatureTargetted,
Function_PCWerewolf,
Function_None // end marker
};
Function function = getFunction();
for (int i=0; integerFunctions[i]!=Function_None; ++i)
if (integerFunctions[i]==function)
return Type_Integer;
for (int i=0; numericFunctions[i]!=Function_None; ++i)
if (numericFunctions[i]==function)
return Type_Numeric;
for (int i=0; booleanFunctions[i]!=Function_None; ++i)
if (booleanFunctions[i]==function)
return Type_Boolean;
return Type_None;
}
bool MWDialogue::SelectWrapper::isInverted() const
{
char type = mSelect.mSelectRule[1];
return type=='7' || type=='8' || type=='9' || type=='A' || type=='B' || type=='C';
}
bool MWDialogue::SelectWrapper::isNpcOnly() const
{
static const Function functions[] =
{
Function_Faction, SelectWrapper::Function_Class, SelectWrapper::Function_Race,
Function_SameGender, Function_SameRace, Function_SameFaction,
Function_PcSkill,
Function_PcExpelled,
Function_PcVampire,
Function_PcCrimeLevel,
Function_RankRequirement,
Function_Reputation, Function_FactionRankDiff,
Function_PCWerewolf, Function_WerewolfKills,
Function_RankLow, Function_RankHigh,
Function_None // end marker
};
Function function = getFunction();
for (int i=0; functions[i]!=Function_None; ++i)
if (functions[i]==function)
return true;
return false;
}
bool MWDialogue::SelectWrapper::selectCompare (int value) const
{
return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR
}
bool MWDialogue::SelectWrapper::selectCompare (float value) const
{
return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR
}
bool MWDialogue::SelectWrapper::selectCompare (bool value) const
{
return selectCompareImp (mSelect, static_cast<int> (value))!=isInverted(); // logic XOR
}
std::string MWDialogue::SelectWrapper::getName() const
{
return toLower (mSelect.mSelectRule.substr (5));
}

@ -0,0 +1,86 @@
#ifndef GAME_MWDIALOGUE_SELECTWRAPPER_H
#define GAME_MWDIALOGUE_SELECTWRAPPER_H
#include <components/esm/loadinfo.hpp>
namespace MWDialogue
{
class SelectWrapper
{
const ESM::DialInfo::SelectStruct& mSelect;
public:
enum Function
{
Function_None, Function_False,
Function_Journal,
Function_Item,
Function_Dead,
Function_Id,
Function_Faction,
Function_Class,
Function_Race,
Function_Cell,
Function_Local,
Function_Global,
Function_SameGender, Function_SameRace, Function_SameFaction,
Function_Choice,
Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus,
Function_AiSetting,
Function_PcAttribute, Function_PcSkill,
Function_PcExpelled,
Function_PcVampire,
Function_FriendlyHit,
Function_TalkedToPc,
Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat,
Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel,
Function_RankRequirement,
Function_HealthPercent, Function_Level, Function_PCReputation,
Function_Weather,
Function_Reputation, Function_Alarmed, Function_FactionRankDiff, Function_Detected,
Function_Attacked, Function_ShouldAttack,
Function_CreatureTargetted,
Function_PCWerewolf, Function_WerewolfKills,
Function_RankLow, Function_RankHigh
};
enum Type
{
Type_None,
Type_Integer,
Type_Numeric,
Type_Boolean
};
private:
Function decodeFunction() const;
public:
SelectWrapper (const ESM::DialInfo::SelectStruct& select);
Function getFunction() const;
int getArgument() const;
Type getType() const;
bool isInverted() const;
bool isNpcOnly() const;
///< \attention Do not call any of the select functions for this select struct!
bool selectCompare (int value) const;
bool selectCompare (float value) const;
bool selectCompare (bool value) const;
std::string getName() const;
///< Return case-smashed name.
};
}
#endif

@ -1,7 +1,7 @@
#include "topic.hpp"
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
namespace MWDialogue
{

@ -28,25 +28,25 @@ namespace MWGui
{
AlchemyWindow::AlchemyWindow(MWBase::WindowManager& parWindowManager)
: WindowBase("openmw_alchemy_window.layout", parWindowManager)
, ContainerBase(0)
, ContainerBase(0), mApparatus (4), mIngredients (4)
{
getWidget(mCreateButton, "CreateButton");
getWidget(mCancelButton, "CancelButton");
getWidget(mIngredient1, "Ingredient1");
getWidget(mIngredient2, "Ingredient2");
getWidget(mIngredient3, "Ingredient3");
getWidget(mIngredient4, "Ingredient4");
getWidget(mApparatus1, "Apparatus1");
getWidget(mApparatus2, "Apparatus2");
getWidget(mApparatus3, "Apparatus3");
getWidget(mApparatus4, "Apparatus4");
getWidget(mIngredients[0], "Ingredient1");
getWidget(mIngredients[1], "Ingredient2");
getWidget(mIngredients[2], "Ingredient3");
getWidget(mIngredients[3], "Ingredient4");
getWidget(mApparatus[0], "Apparatus1");
getWidget(mApparatus[1], "Apparatus2");
getWidget(mApparatus[2], "Apparatus3");
getWidget(mApparatus[3], "Apparatus4");
getWidget(mEffectsBox, "CreatedEffects");
getWidget(mNameEdit, "NameEdit");
mIngredient1->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredient2->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredient3->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredient4->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredients[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredients[1]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredients[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mIngredients[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected);
mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
@ -62,157 +62,52 @@ namespace MWGui
void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{
mAlchemy.clear();
mWindowManager.removeGuiMode(GM_Alchemy);
mWindowManager.removeGuiMode(GM_Inventory);
}
void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender)
{
// check if mortar & pestle is available (always needed)
/// \todo check albemic, calcinator, retort (sometimes needed)
if (!mApparatus1->isUserString("ToolTipType"))
std::string name = mNameEdit->getCaption();
boost::algorithm::trim(name);
MWMechanics::Alchemy::Result result = mAlchemy.create (mNameEdit->getCaption ());
if (result == MWMechanics::Alchemy::Result_NoName)
{
mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>());
return;
}
// make sure 2 or more ingredients were selected
int numIngreds = 0;
if (mIngredient1->isUserString("ToolTipType"))
++numIngreds;
if (mIngredient2->isUserString("ToolTipType"))
++numIngreds;
if (mIngredient3->isUserString("ToolTipType"))
++numIngreds;
if (mIngredient4->isUserString("ToolTipType"))
++numIngreds;
if (numIngreds < 2)
// check if mortar & pestle is available (always needed)
if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle)
{
mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>());
return;
}
// make sure a name was entered
std::string name = mNameEdit->getCaption();
boost::algorithm::trim(name);
if (name == "")
// make sure 2 or more ingredients were selected
if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients)
{
mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>());
return;
}
// if there are no created effects, the potion will always fail (but the ingredients won't be destroyed)
if (mEffects.empty())
if (result == MWMechanics::Alchemy::Result_NoEffects)
{
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
return;
}
if (rand() % 2 == 0) /// \todo
if (result == MWMechanics::Alchemy::Result_Success)
{
ESM::Potion newPotion;
newPotion.mName = mNameEdit->getCaption();
ESM::EffectList effects;
for (unsigned int i=0; i<4; ++i)
{
if (mEffects.size() >= i+1)
{
ESM::ENAMstruct effect;
effect.mEffectID = mEffects[i].mEffectID;
effect.mArea = 0;
effect.mRange = ESM::RT_Self;
effect.mSkill = mEffects[i].mSkill;
effect.mAttribute = mEffects[i].mAttribute;
effect.mMagnMin = 1; /// \todo
effect.mMagnMax = 10; /// \todo
effect.mDuration = 60; /// \todo
effects.mList.push_back(effect);
}
}
// UESP Wiki / Morrowind:Alchemy
// "The weight of a potion is an average of the weight of the ingredients, rounded down."
// note by scrawl: not rounding down here, I can't imagine a created potion to
// have 0 weight when using ingredients with 0.1 weight respectively
float weight = 0;
if (mIngredient1->isUserString("ToolTipType"))
weight += mIngredient1->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
if (mIngredient2->isUserString("ToolTipType"))
weight += mIngredient2->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
if (mIngredient3->isUserString("ToolTipType"))
weight += mIngredient3->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
if (mIngredient4->isUserString("ToolTipType"))
weight += mIngredient4->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->mData.mWeight;
newPotion.mData.mWeight = weight / float(numIngreds);
newPotion.mData.mValue = 100; /// \todo
newPotion.mEffects = effects;
// pick a random mesh and icon
std::vector<std::string> names;
/// \todo is the mesh/icon dependent on alchemy skill?
names.push_back("standard");
names.push_back("bargain");
names.push_back("cheap");
names.push_back("fresh");
names.push_back("exclusive");
names.push_back("quality");
int random = rand() % names.size();
newPotion.mModel = "m\\misc_potion_" + names[random ] + "_01.nif";
newPotion.mIcon = "m\\tx_potion_" + names[random ] + "_01.dds";
// check if a similiar potion record exists already
bool found = false;
std::string objectId;
typedef std::map<std::string, ESM::Potion> PotionMap;
PotionMap potions = MWBase::Environment::get().getWorld()->getStore().potions.list;
for (PotionMap::const_iterator it = potions.begin(); it != potions.end(); ++it)
{
if (found) break;
if (it->second.mData.mValue == newPotion.mData.mValue
&& it->second.mData.mWeight == newPotion.mData.mWeight
&& it->second.mName == newPotion.mName
&& it->second.mEffects.mList.size() == newPotion.mEffects.mList.size())
{
// check effects
for (unsigned int i=0; i < it->second.mEffects.mList.size(); ++i)
{
const ESM::ENAMstruct& a = it->second.mEffects.mList[i];
const ESM::ENAMstruct& b = newPotion.mEffects.mList[i];
if (a.mEffectID == b.mEffectID
&& a.mArea == b.mArea
&& a.mRange == b.mRange
&& a.mSkill == b.mSkill
&& a.mAttribute == b.mAttribute
&& a.mMagnMin == b.mMagnMin
&& a.mMagnMax == b.mMagnMax
&& a.mDuration == b.mDuration)
{
found = true;
objectId = it->first;
break;
}
}
}
}
if (!found)
{
std::pair<std::string, const ESM::Potion*> result = MWBase::Environment::get().getWorld()->createRecord(newPotion);
objectId = result.first;
}
// create a reference and add it to player inventory
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), objectId);
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
ref.getPtr().getRefData().setCount(1);
store.add(ref.getPtr());
mWindowManager.messageBox("#{sPotionSuccess}", std::vector<std::string>());
MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f);
}
else
else if (result == MWMechanics::Alchemy::Result_RandomFailure)
{
// potion failed
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
@ -220,155 +115,55 @@ namespace MWGui
}
// reduce count of the ingredients
if (mIngredient1->isUserString("ToolTipType"))
{
MWWorld::Ptr ingred = *mIngredient1->getUserData<MWWorld::Ptr>();
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
if (ingred.getRefData().getCount() == 0)
removeIngredient(mIngredient1);
}
if (mIngredient2->isUserString("ToolTipType"))
{
MWWorld::Ptr ingred = *mIngredient2->getUserData<MWWorld::Ptr>();
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
if (ingred.getRefData().getCount() == 0)
removeIngredient(mIngredient2);
}
if (mIngredient3->isUserString("ToolTipType"))
{
MWWorld::Ptr ingred = *mIngredient3->getUserData<MWWorld::Ptr>();
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
if (ingred.getRefData().getCount() == 0)
removeIngredient(mIngredient3);
}
if (mIngredient4->isUserString("ToolTipType"))
{
MWWorld::Ptr ingred = *mIngredient4->getUserData<MWWorld::Ptr>();
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
if (ingred.getRefData().getCount() == 0)
removeIngredient(mIngredient4);
for (int i=0; i<4; ++i)
if (mIngredients[i]->isUserString("ToolTipType"))
{
MWWorld::Ptr ingred = *mIngredients[i]->getUserData<MWWorld::Ptr>();
ingred.getRefData().setCount(ingred.getRefData().getCount()-1);
if (ingred.getRefData().getCount() == 0)
removeIngredient(mIngredients[i]);
}
update();
}
void AlchemyWindow::open()
{
openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
setFilter(ContainerBase::Filter_Ingredients);
openContainer (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); // this sets mPtr
setFilter (ContainerBase::Filter_Ingredients);
// pick the best available apparatus
MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr);
mNameEdit->setCaption("");
MWWorld::Ptr bestAlbemic;
MWWorld::Ptr bestMortarPestle;
MWWorld::Ptr bestCalcinator;
MWWorld::Ptr bestRetort;
mAlchemy.setAlchemist (mPtr);
for (MWWorld::ContainerStoreIterator it(store.begin(MWWorld::ContainerStore::Type_Apparatus));
it != store.end(); ++it)
{
MWWorld::LiveCellRef<ESM::Apparatus>* ref = it->get<ESM::Apparatus>();
if (ref->base->mData.mType == ESM::Apparatus::Albemic
&& (bestAlbemic.isEmpty() || ref->base->mData.mQuality > bestAlbemic.get<ESM::Apparatus>()->base->mData.mQuality))
bestAlbemic = *it;
else if (ref->base->mData.mType == ESM::Apparatus::MortarPestle
&& (bestMortarPestle.isEmpty() || ref->base->mData.mQuality > bestMortarPestle.get<ESM::Apparatus>()->base->mData.mQuality))
bestMortarPestle = *it;
else if (ref->base->mData.mType == ESM::Apparatus::Calcinator
&& (bestCalcinator.isEmpty() || ref->base->mData.mQuality > bestCalcinator.get<ESM::Apparatus>()->base->mData.mQuality))
bestCalcinator = *it;
else if (ref->base->mData.mType == ESM::Apparatus::Retort
&& (bestRetort.isEmpty() || ref->base->mData.mQuality > bestRetort.get<ESM::Apparatus>()->base->mData.mQuality))
bestRetort = *it;
}
int index = 0;
if (!bestMortarPestle.isEmpty())
{
mApparatus1->setUserString("ToolTipType", "ItemPtr");
mApparatus1->setUserData(bestMortarPestle);
mApparatus1->setImageTexture(getIconPath(bestMortarPestle));
}
if (!bestAlbemic.isEmpty())
{
mApparatus2->setUserString("ToolTipType", "ItemPtr");
mApparatus2->setUserData(bestAlbemic);
mApparatus2->setImageTexture(getIconPath(bestAlbemic));
}
if (!bestCalcinator.isEmpty())
for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy.beginTools());
iter!=mAlchemy.endTools() && index<static_cast<int> (mApparatus.size()); ++iter, ++index)
{
mApparatus3->setUserString("ToolTipType", "ItemPtr");
mApparatus3->setUserData(bestCalcinator);
mApparatus3->setImageTexture(getIconPath(bestCalcinator));
}
if (!bestRetort.isEmpty())
{
mApparatus4->setUserString("ToolTipType", "ItemPtr");
mApparatus4->setUserData(bestRetort);
mApparatus4->setImageTexture(getIconPath(bestRetort));
if (!iter->isEmpty())
{
mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr");
mApparatus.at (index)->setUserData (*iter);
mApparatus.at (index)->setImageTexture (getIconPath (*iter));
}
}
update();
}
void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender)
{
removeIngredient(_sender);
drawItems();
update();
}
void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item)
{
MyGUI::ImageBox* add = NULL;
int res = mAlchemy.addIngredient(item);
// don't allow to add an ingredient that is already added
// (which could happen if two similiar ingredients don't stack because of script / owner)
bool alreadyAdded = false;
std::string name = MWWorld::Class::get(item).getName(item);
if (mIngredient1->isUserString("ToolTipType"))
{
MWWorld::Ptr item2 = *mIngredient1->getUserData<MWWorld::Ptr>();
std::string name2 = MWWorld::Class::get(item2).getName(item2);
if (name == name2)
alreadyAdded = true;
}
if (mIngredient2->isUserString("ToolTipType"))
{
MWWorld::Ptr item2 = *mIngredient2->getUserData<MWWorld::Ptr>();
std::string name2 = MWWorld::Class::get(item2).getName(item2);
if (name == name2)
alreadyAdded = true;
}
if (mIngredient3->isUserString("ToolTipType"))
if (res != -1)
{
MWWorld::Ptr item2 = *mIngredient3->getUserData<MWWorld::Ptr>();
std::string name2 = MWWorld::Class::get(item2).getName(item2);
if (name == name2)
alreadyAdded = true;
}
if (mIngredient4->isUserString("ToolTipType"))
{
MWWorld::Ptr item2 = *mIngredient4->getUserData<MWWorld::Ptr>();
std::string name2 = MWWorld::Class::get(item2).getName(item2);
if (name == name2)
alreadyAdded = true;
}
if (alreadyAdded)
return;
if (!mIngredient1->isUserString("ToolTipType"))
add = mIngredient1;
if (add == NULL && !mIngredient2->isUserString("ToolTipType"))
add = mIngredient2;
if (add == NULL && !mIngredient3->isUserString("ToolTipType"))
add = mIngredient3;
if (add == NULL && !mIngredient4->isUserString("ToolTipType"))
add = mIngredient4;
if (add != NULL)
{
add->setUserString("ToolTipType", "ItemPtr");
add->setUserData(item);
add->setImageTexture(getIconPath(item));
drawItems();
update();
std::string sound = MWWorld::Class::get(item).getUpSoundId(item);
@ -380,54 +175,40 @@ namespace MWGui
{
std::vector<MWWorld::Ptr> ignore;
// don't show ingredients that are currently selected in the "available ingredients" box.
if (mIngredient1->isUserString("ToolTipType"))
ignore.push_back(*mIngredient1->getUserData<MWWorld::Ptr>());
if (mIngredient2->isUserString("ToolTipType"))
ignore.push_back(*mIngredient2->getUserData<MWWorld::Ptr>());
if (mIngredient3->isUserString("ToolTipType"))
ignore.push_back(*mIngredient3->getUserData<MWWorld::Ptr>());
if (mIngredient4->isUserString("ToolTipType"))
ignore.push_back(*mIngredient4->getUserData<MWWorld::Ptr>());
for (int i=0; i<4; ++i)
if (mIngredients[i]->isUserString("ToolTipType"))
ignore.push_back(*mIngredients[i]->getUserData<MWWorld::Ptr>());
return ignore;
}
void AlchemyWindow::update()
{
Widgets::SpellEffectList effects;
MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy.beginIngredients ();
for (int i=0; i<4; ++i)
{
MyGUI::ImageBox* ingredient;
if (i==0)
ingredient = mIngredient1;
else if (i==1)
ingredient = mIngredient2;
else if (i==2)
ingredient = mIngredient3;
else if (i==3)
ingredient = mIngredient4;
if (!ingredient->isUserString("ToolTipType"))
continue;
MyGUI::ImageBox* ingredient = mIngredients[i];
// add the effects of this ingredient to list of effects
MWWorld::LiveCellRef<ESM::Ingredient>* ref = ingredient->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>();
for (int i=0; i<4; ++i)
MWWorld::Ptr item;
if (it != mAlchemy.endIngredients ())
{
if (ref->base->mData.mEffectID[i] < 0)
continue;
MWGui::Widgets::SpellEffectParams params;
params.mEffectID = ref->base->mData.mEffectID[i];
params.mAttribute = ref->base->mData.mAttributes[i];
params.mSkill = ref->base->mData.mSkills[i];
effects.push_back(params);
item = *it;
++it;
}
// update ingredient count labels
if (ingredient->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
ingredient->setImageTexture("");
ingredient->clearUserStrings ();
if (item.isEmpty ())
continue;
ingredient->setUserString("ToolTipType", "ItemPtr");
ingredient->setUserData(item);
ingredient->setImageTexture(getIconPath(item));
MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label"));
text->setTextAlign(MyGUI::Align::Right);
text->setNeedMouseFocus(false);
@ -436,49 +217,15 @@ namespace MWGui
text->setCaption(getCountString(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount()));
}
// now remove effects that are only present once
Widgets::SpellEffectList::iterator it = effects.begin();
while (it != effects.end())
{
Widgets::SpellEffectList::iterator next = it;
++next;
bool found = false;
for (; next != effects.end(); ++next)
{
if (*next == *it)
found = true;
}
if (!found)
it = effects.erase(it);
else
++it;
}
drawItems();
// now remove duplicates, and don't allow more than 4 effects
Widgets::SpellEffectList old = effects;
effects.clear();
int i=0;
for (Widgets::SpellEffectList::iterator it = old.begin();
it != old.end(); ++it)
std::vector<ESM::ENAMstruct> effects;
ESM::EffectList list;
list.mList = effects;
for (MWMechanics::Alchemy::TEffectsIterator it = mAlchemy.beginEffects (); it != mAlchemy.endEffects (); ++it)
{
bool found = false;
for (Widgets::SpellEffectList::iterator it2 = effects.begin();
it2 != effects.end(); ++it2)
{
// MW considers all "foritfy attribute" effects as the same effect. See the
// "Can't create multi-state boost potions" discussion on http://www.uesp.net/wiki/Morrowind_talk:Alchemy
// thus, we are only checking effectID here and not attribute or skill
if (it2->mEffectID == it->mEffectID)
found = true;
}
if (!found && i<4)
{
++i;
effects.push_back(*it);
}
list.mList.push_back(*it);
}
mEffects = effects;
while (mEffectsBox->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mEffectsBox->getChildAt(0));
@ -487,7 +234,9 @@ namespace MWGui
Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget<Widgets::MWEffectList>
("MW_StatName", coord, MyGUI::Align::Left | MyGUI::Align::Top);
effectsWidget->setWindowManager(&mWindowManager);
effectsWidget->setEffectList(effects);
Widgets::SpellEffectList _list = Widgets::MWEffectList::effectListFromESM(&list);
effectsWidget->setEffectList(_list);
std::vector<MyGUI::WidgetPtr> effectItems;
effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0);
@ -496,9 +245,10 @@ namespace MWGui
void AlchemyWindow::removeIngredient(MyGUI::Widget* ingredient)
{
ingredient->clearUserStrings();
static_cast<MyGUI::ImageBox*>(ingredient)->setImageTexture("");
if (ingredient->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0));
for (int i=0; i<4; ++i)
if (mIngredients[i] == ingredient)
mAlchemy.removeIngredient (i);
update();
}
}

@ -1,6 +1,10 @@
#ifndef MWGUI_ALCHEMY_H
#define MWGUI_ALCHEMY_H
#include <vector>
#include "../mwmechanics/alchemy.hpp"
#include "window_base.hpp"
#include "container.hpp"
#include "widgets.hpp"
@ -18,22 +22,10 @@ namespace MWGui
MyGUI::Button* mCreateButton;
MyGUI::Button* mCancelButton;
MyGUI::ImageBox* mIngredient1;
MyGUI::ImageBox* mIngredient2;
MyGUI::ImageBox* mIngredient3;
MyGUI::ImageBox* mIngredient4;
MyGUI::ImageBox* mApparatus1;
MyGUI::ImageBox* mApparatus2;
MyGUI::ImageBox* mApparatus3;
MyGUI::ImageBox* mApparatus4;
MyGUI::Widget* mEffectsBox;
MyGUI::EditBox* mNameEdit;
Widgets::SpellEffectList mEffects; // effects of created potion
void onCancelButtonClicked(MyGUI::Widget* _sender);
void onCreateButtonClicked(MyGUI::Widget* _sender);
void onIngredientSelected(MyGUI::Widget* _sender);
@ -46,6 +38,13 @@ namespace MWGui
virtual void onReferenceUnavailable() { ; }
void update();
private:
MWMechanics::Alchemy mAlchemy;
std::vector<MyGUI::ImageBox *> mApparatus;
std::vector<MyGUI::ImageBox *> mIngredients;
};
}

@ -3,7 +3,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "components/esm_store/store.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -14,6 +14,16 @@
using namespace MWGui;
using namespace Widgets;
namespace
{
bool sortBirthSigns(const std::pair<std::string, const ESM::BirthSign*>& left, const std::pair<std::string, const ESM::BirthSign*>& right)
{
return left.second->mName.compare (right.second->mName) < 0;
}
}
BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager)
: WindowBase("openmw_chargen_birth.layout", parWindowManager)
{
@ -38,6 +48,7 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager)
getWidget(okButton, "OKButton");
okButton->setCaption(mWindowManager.getGameSettingString("sOK", ""));
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
okButton->setEnabled(false);
updateBirths();
updateSpells();
@ -72,6 +83,9 @@ void BirthDialog::setBirthId(const std::string &birthId)
if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
{
mBirthList->setIndexSelected(i);
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");
okButton->setEnabled(true);
break;
}
}
@ -83,6 +97,8 @@ void BirthDialog::setBirthId(const std::string &birthId)
void BirthDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE)
return;
eventDone(this);
}
@ -96,6 +112,10 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE)
return;
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");
okButton->setEnabled(true);
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
if (boost::iequals(mCurrentBirthId, *birthId))
return;
@ -110,16 +130,25 @@ void BirthDialog::updateBirths()
{
mBirthList->removeAllItems();
const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::Store<ESM::BirthSign> &signs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>();
ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator it = store.birthSigns.list.begin();
ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator end = store.birthSigns.list.end();
int index = 0;
for (; it != end; ++it)
// sort by name
std::vector < std::pair<std::string, const ESM::BirthSign*> > birthSigns;
MWWorld::Store<ESM::BirthSign>::iterator it = signs.begin();
for (; it != signs.end(); ++it)
{
birthSigns.push_back(std::make_pair(it->mId, &(*it)));
}
std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns);
for (std::vector < std::pair<std::string, const ESM::BirthSign*> >::const_iterator it2 = birthSigns.begin(); it2 != birthSigns.end(); ++it2)
{
const ESM::BirthSign &birth = it->second;
mBirthList->addItem(birth.mName, it->first);
if (boost::iequals(it->first, mCurrentBirthId))
mBirthList->addItem(it2->second->mName, it2->first);
if (boost::iequals(it2->first, mCurrentBirthId))
mBirthList->setIndexSelected(index);
++index;
}
@ -140,8 +169,11 @@ void BirthDialog::updateSpells()
const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, mSpellArea->getWidth(), 18);
const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::BirthSign *birth = store.birthSigns.find(mCurrentBirthId);
const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore();
const ESM::BirthSign *birth =
store.get<ESM::BirthSign>().find(mCurrentBirthId);
std::string texturePath = std::string("textures\\") + birth->mTexture;
fixTexturePath(texturePath);
@ -154,7 +186,7 @@ void BirthDialog::updateSpells()
for (; it != end; ++it)
{
const std::string &spellId = *it;
const ESM::Spell *spell = store.spells.search(spellId);
const ESM::Spell *spell = store.get<ESM::Spell>().search(spellId);
if (!spell)
continue; // Skip spells which cannot be found
ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->mData.mType);
@ -170,11 +202,17 @@ void BirthDialog::updateSpells()
}
int i = 0;
struct{ const std::vector<std::string> &spells; const char *label; } categories[3] = {
struct {
const std::vector<std::string> &spells;
const char *label;
}
categories[3] = {
{abilities, "sBirthsignmenu1"},
{powers, "sPowers"},
{spells, "sBirthsignmenu2"}
};
for (int category = 0; category < 3; ++category)
{
if (!categories[category].spells.empty())

@ -60,7 +60,7 @@ void BookWindow::open (MWWorld::Ptr book)
MWWorld::LiveCellRef<ESM::Book> *ref = mBook.get<ESM::Book>();
BookTextParser parser;
std::vector<std::string> results = parser.split(ref->base->mText, mLeftPage->getSize().width, mLeftPage->getSize().height);
std::vector<std::string> results = parser.split(ref->mBase->mText, mLeftPage->getSize().width, mLeftPage->getSize().height);
int i=0;
for (std::vector<std::string>::iterator it=results.begin();

@ -7,6 +7,7 @@
#include "review.hpp"
#include "dialogue.hpp"
#include "mode.hpp"
#include "inventorywindow.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
@ -232,6 +233,7 @@ void CharacterCreation::spawnDialog(const char id)
mBirthSignDialog = 0;
mBirthSignDialog = new BirthDialog(*mWM);
mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen);
mBirthSignDialog->setBirthId(mPlayerBirthSignId);
mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone);
mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack);
mBirthSignDialog->setVisible(true);
@ -356,7 +358,9 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
const std::string &classId = mPickClassDialog->getClassId();
if (!classId.empty())
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId);
const ESM::Class *klass = MWBase::Environment::get().getWorld()->getStore().classes.find(classId);
const ESM::Class *klass =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(classId);
if (klass)
{
mPlayerClass = *klass;
@ -456,9 +460,16 @@ void CharacterCreation::onRaceDialogBack()
{
if (mRaceDialog)
{
mPlayerRaceId = mRaceDialog->getRaceId();
if (!mPlayerRaceId.empty())
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male);
const ESM::NPC &data = mRaceDialog->getResult();
mPlayerRaceId = data.mRace;
if (!mPlayerRaceId.empty()) {
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(
data.mRace,
data.isMale(),
data.mHead,
data.mHair
);
}
mWM->removeDialog(mRaceDialog);
mRaceDialog = 0;
}
@ -471,10 +482,18 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
{
if (mRaceDialog)
{
mPlayerRaceId = mRaceDialog->getRaceId();
mWM->setValue("race", mPlayerRaceId);
if (!mPlayerRaceId.empty())
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(mPlayerRaceId, mRaceDialog->getGender() == RaceDialog::GM_Male);
const ESM::NPC &data = mRaceDialog->getResult();
mPlayerRaceId = data.mRace;
if (!mPlayerRaceId.empty()) {
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(
data.mRace,
data.isMale(),
data.mHead,
data.mHair
);
}
mWM->getInventoryWindow()->rebuildAvatar();
mWM->removeDialog(mRaceDialog);
mRaceDialog = 0;
}
@ -556,6 +575,7 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
klass.mData.mSkills[i][1] = majorSkills[i];
klass.mData.mSkills[i][0] = minorSkills[i];
}
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass);
mPlayerClass = klass;
mWM->setPlayerClass(klass);
@ -728,7 +748,10 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
mGenerateClassResultDialog = 0;
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
const ESM::Class *klass = MWBase::Environment::get().getWorld()->getStore().classes.find(mGenerateClass);
const ESM::Class *klass =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(mGenerateClass);
mPlayerClass = *klass;
mWM->setPlayerClass(mPlayerClass);

@ -1,7 +1,7 @@
#ifndef CHARACTER_CREATION_HPP
#define CHARACTER_CREATION_HPP
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"

@ -5,7 +5,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -50,7 +50,7 @@ void GenerateClassResultDialog::setClassId(const std::string &classId)
{
mCurrentClassId = classId;
mClassImage->setImageTexture(std::string("textures\\levelup\\") + mCurrentClassId + ".dds");
mClassName->setCaption(MWBase::Environment::get().getWorld()->getStore().classes.find(mCurrentClassId)->mName);
mClassName->setCaption(MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(mCurrentClassId)->mName);
}
// widget controls
@ -104,6 +104,7 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager)
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked);
okButton->setEnabled(false);
updateClasses();
updateStats();
@ -137,6 +138,9 @@ void PickClassDialog::setClassId(const std::string &classId)
if (boost::iequals(*mClassList->getItemDataAt<std::string>(i), classId))
{
mClassList->setIndexSelected(i);
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");
okButton->setEnabled(true);
break;
}
}
@ -148,6 +152,8 @@ void PickClassDialog::setClassId(const std::string &classId)
void PickClassDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(mClassList->getIndexSelected() == MyGUI::ITEM_NONE)
return;
eventDone(this);
}
@ -161,6 +167,10 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index)
if (_index == MyGUI::ITEM_NONE)
return;
MyGUI::ButtonPtr okButton;
getWidget(okButton, "OKButton");
okButton->setEnabled(true);
const std::string *classId = mClassList->getItemDataAt<std::string>(_index);
if (boost::iequals(mCurrentClassId, *classId))
return;
@ -175,20 +185,18 @@ void PickClassDialog::updateClasses()
{
mClassList->removeAllItems();
const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
ESMS::RecListT<ESM::Class>::MapType::const_iterator it = store.classes.list.begin();
ESMS::RecListT<ESM::Class>::MapType::const_iterator end = store.classes.list.end();
int index = 0;
for (; it != end; ++it)
MWWorld::Store<ESM::Class>::iterator it = store.get<ESM::Class>().begin();
for (; it != store.get<ESM::Class>().end(); ++it)
{
const ESM::Class &klass = it->second;
bool playable = (klass.mData.mIsPlayable != 0);
bool playable = (it->mData.mIsPlayable != 0);
if (!playable) // Only display playable classes
continue;
const std::string &id = it->first;
mClassList->addItem(klass.mName, id);
const std::string &id = it->mId;
mClassList->addItem(it->mName, id);
if (boost::iequals(id, mCurrentClassId))
mClassList->setIndexSelected(index);
++index;
@ -199,8 +207,8 @@ void PickClassDialog::updateStats()
{
if (mCurrentClassId.empty())
return;
const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Class *klass = store.classes.search(mCurrentClassId);
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Class *klass = store.get<ESM::Class>().search(mCurrentClassId);
if (!klass)
return;
@ -565,7 +573,7 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
{
delete mAttribDialog;
mAttribDialog = new SelectAttributeDialog(mWindowManager);
mAttribDialog->setAffectedWidget(_sender);
mAffectedAttribute = _sender;
mAttribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
mAttribDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected);
mAttribDialog->setVisible(true);
@ -574,18 +582,17 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender)
void CreateClassDialog::onAttributeSelected()
{
ESM::Attribute::AttributeID id = mAttribDialog->getAttributeId();
Widgets::MWAttributePtr attribute = mAttribDialog->getAffectedWidget();
if (attribute == mFavoriteAttribute0)
if (mAffectedAttribute == mFavoriteAttribute0)
{
if (mFavoriteAttribute1->getAttributeId() == id)
mFavoriteAttribute1->setAttributeId(mFavoriteAttribute0->getAttributeId());
}
else if (attribute == mFavoriteAttribute1)
else if (mAffectedAttribute == mFavoriteAttribute1)
{
if (mFavoriteAttribute0->getAttributeId() == id)
mFavoriteAttribute0->setAttributeId(mFavoriteAttribute1->getAttributeId());
}
attribute->setAttributeId(id);
mAffectedAttribute->setAttributeId(id);
mWindowManager.removeDialog(mAttribDialog);
mAttribDialog = 0;
@ -596,7 +603,7 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
{
delete mSkillDialog;
mSkillDialog = new SelectSkillDialog(mWindowManager);
mSkillDialog->setAffectedWidget(_sender);
mAffectedSkill = _sender;
mSkillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel);
mSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected);
mSkillDialog->setVisible(true);
@ -605,22 +612,21 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender)
void CreateClassDialog::onSkillSelected()
{
ESM::Skill::SkillEnum id = mSkillDialog->getSkillId();
Widgets::MWSkillPtr skill = mSkillDialog->getAffectedWidget();
// Avoid duplicate skills by swapping any skill field that matches the selected one
std::vector<Widgets::MWSkillPtr>::const_iterator end = mSkills.end();
for (std::vector<Widgets::MWSkillPtr>::const_iterator it = mSkills.begin(); it != end; ++it)
{
if (*it == skill)
if (*it == mAffectedSkill)
continue;
if ((*it)->getSkillId() == id)
{
(*it)->setSkillId(skill->getSkillId());
(*it)->setSkillId(mAffectedSkill->getSkillId());
break;
}
}
skill->setSkillId(mSkillDialog->getSkillId());
mAffectedSkill->setSkillId(mSkillDialog->getSkillId());
mWindowManager.removeDialog(mSkillDialog);
mSkillDialog = 0;
update();
@ -643,6 +649,8 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow)
void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender)
{
if(getName().size() <= 0)
return;
eventDone(this);
}

@ -167,8 +167,6 @@ namespace MWGui
~SelectAttributeDialog();
ESM::Attribute::AttributeID getAttributeId() const { return mAttributeId; }
Widgets::MWAttributePtr getAffectedWidget() const { return mAffectedWidget; }
void setAffectedWidget(Widgets::MWAttributePtr widget) { mAffectedWidget = widget; }
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
@ -188,8 +186,6 @@ namespace MWGui
void onCancelClicked(MyGUI::Widget* _sender);
private:
Widgets::MWAttributePtr mAffectedWidget;
ESM::Attribute::AttributeID mAttributeId;
};
@ -200,8 +196,6 @@ namespace MWGui
~SelectSkillDialog();
ESM::Skill::SkillEnum getSkillId() const { return mSkillId; }
Widgets::MWSkillPtr getAffectedWidget() const { return mAffectedWidget; }
void setAffectedWidget(Widgets::MWSkillPtr widget) { mAffectedWidget = widget; }
// Events
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
@ -224,7 +218,6 @@ namespace MWGui
Widgets::MWSkillPtr mCombatSkill[9];
Widgets::MWSkillPtr mMagicSkill[9];
Widgets::MWSkillPtr mStealthSkill[9];
Widgets::MWSkillPtr mAffectedWidget;
ESM::Skill::SkillEnum mSkillId;
};
@ -301,6 +294,9 @@ namespace MWGui
DescriptionDialog *mDescDialog;
ESM::Class::Specialization mSpecializationId;
Widgets::MWAttributePtr mAffectedAttribute;
Widgets::MWSkillPtr mAffectedSkill;
};
}
#endif

@ -4,11 +4,10 @@
#include <algorithm>
#include <fstream>
#include <components/esm_store/reclists.hpp>
#include <components/esm_store/store.hpp>
#include <components/compiler/exception.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwscript/extensions.hpp"
#include "../mwbase/environment.hpp"
@ -93,12 +92,12 @@ namespace MWGui
scanner.listKeywords (mNames);
// identifier
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::ESMStore& store =
MWBase::Environment::get().getWorld()->getStore();
for (ESMS::RecListList::const_iterator iter (store.recLists.begin());
iter!=store.recLists.end(); ++iter)
for (MWWorld::ESMStore::iterator it = store.begin(); it != store.end(); ++it)
{
iter->second->listIdentifier (mNames);
it->second->listIdentifier (mNames);
}
// sort

@ -127,10 +127,13 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
if (isInventory())
{
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
// the player is trying to sell an item, check if the merchant accepts it
// also, don't allow selling gold (let's be better than Morrowind at this, can we?)
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object) ||
MWWorld::Class::get(object).getName(object) == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString())
MWWorld::Class::get(object).getName(object) == gmst.find("sGold")->getString())
{
// user notification "i don't buy this item"
MWBase::Environment::get().getWindowManager()->
@ -274,7 +277,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
if (mPtr.getTypeName() == typeid(ESM::Container).name())
{
MWWorld::LiveCellRef<ESM::Container>* ref = mPtr.get<ESM::Container>();
if (ref->base->mFlags & ESM::Container::Organic)
if (ref->mBase->mFlags & ESM::Container::Organic)
{
// user notification
MWBase::Environment::get().getWindowManager()->

@ -1,7 +1,7 @@
#ifndef MGUI_CONTAINER_H
#define MGUI_CONTAINER_H
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
#include "window_base.hpp"
#include "referenceinterface.hpp"

@ -6,12 +6,15 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <components/esm_store/store.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/dialoguemanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "dialogue_history.hpp"
#include "widgets.hpp"
@ -19,6 +22,7 @@
#include "tradewindow.hpp"
#include "spellbuyingwindow.hpp"
#include "inventorywindow.hpp"
#include "travelwindow.hpp"
using namespace MWGui;
using namespace Widgets;
@ -27,6 +31,8 @@ using namespace Widgets;
*Copied from the internet.
*/
namespace {
std::string lower_string(const std::string& str)
{
std::string lowerCase;
@ -42,16 +48,90 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
return lower_string(str).find(lower_string(substr),pos);
}
}
PersuasionDialog::PersuasionDialog(MWBase::WindowManager &parWindowManager)
: WindowModal("openmw_persuasion_dialog.layout", parWindowManager)
{
getWidget(mCancelButton, "CancelButton");
getWidget(mAdmireButton, "AdmireButton");
getWidget(mIntimidateButton, "IntimidateButton");
getWidget(mTauntButton, "TauntButton");
getWidget(mBribe10Button, "Bribe10Button");
getWidget(mBribe100Button, "Bribe100Button");
getWidget(mBribe1000Button, "Bribe1000Button");
getWidget(mGoldLabel, "GoldLabel");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onCancel);
mAdmireButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mIntimidateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mTauntButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe10Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe100Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
mBribe1000Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
}
void PersuasionDialog::onCancel(MyGUI::Widget *sender)
{
setVisible(false);
}
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
{
MWBase::MechanicsManager::PersuasionType type;
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
else if (sender == mBribe10Button)
{
mWindowManager.getTradeWindow()->addOrRemoveGold(-10);
type = MWBase::MechanicsManager::PT_Bribe10;
}
else if (sender == mBribe100Button)
{
mWindowManager.getTradeWindow()->addOrRemoveGold(-100);
type = MWBase::MechanicsManager::PT_Bribe100;
}
else /*if (sender == mBribe1000Button)*/
{
mWindowManager.getTradeWindow()->addOrRemoveGold(-1000);
type = MWBase::MechanicsManager::PT_Bribe1000;
}
MWBase::Environment::get().getDialogueManager()->persuade(type);
setVisible(false);
}
void PersuasionDialog::open()
{
WindowModal::open();
center();
int playerGold = mWindowManager.getInventoryWindow()->getPlayerGold();
mBribe10Button->setEnabled (playerGold >= 10);
mBribe100Button->setEnabled (playerGold >= 100);
mBribe1000Button->setEnabled (playerGold >= 1000);
mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
}
// --------------------------------------------------------------------------------------------------
DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window.layout", parWindowManager)
, mEnabled(true)
, mShowTrade(false)
, mShowSpells(false)
, mPersuasionDialog(parWindowManager)
, mEnabled(false)
, mServices(0)
{
// Centre dialog
center();
mPersuasionDialog.setVisible(false);
//History view
getWidget(mHistory, "History");
mHistory->setOverflowToTheLeft(true);
@ -123,18 +203,44 @@ void DialogueWindow::onSelectTopic(std::string topic)
{
if (!mEnabled) return;
if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sBarter")->getString())
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
if (topic == gmst.find("sBarter")->getString())
{
/// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
mWindowManager.pushGuiMode(GM_Barter);
mWindowManager.getTradeWindow()->startTrade(mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString())
if (topic == gmst.find("sPersuasion")->getString())
{
mPersuasionDialog.setVisible(true);
}
else if (topic == gmst.find("sSpells")->getString())
{
mWindowManager.pushGuiMode(GM_SpellBuying);
mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr);
}
else if (topic == gmst.find("sTravel")->getString())
{
mWindowManager.pushGuiMode(GM_Travel);
mWindowManager.getTravelWindow()->startTravel(mPtr);
}
else if (topic == gmst.find("sSpellMakingMenuTitle")->getString())
{
mWindowManager.pushGuiMode(GM_SpellCreation);
mWindowManager.startSpellMaking (mPtr);
}
else if (topic == gmst.find("sEnchanting")->getString())
{
mWindowManager.pushGuiMode(GM_Enchanting);
mWindowManager.startEnchanting (mPtr);
}
else if (topic == gmst.find("sServiceTrainingTitle")->getString())
{
mWindowManager.pushGuiMode(GM_Training);
mWindowManager.startTraining (mPtr);
}
else
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
}
@ -147,7 +253,7 @@ void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
setTitle(npcName);
mTopicsList->clear();
mHistory->eraseText(0,mHistory->getTextLength());
mHistory->setCaption("");
updateOptions();
}
@ -155,13 +261,31 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
mTopicsList->clear();
bool anyService = mShowTrade||mShowSpells;
bool anyService = mServices > 0;
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
mTopicsList->addItem(gmst.find("sPersuasion")->getString());
if (mServices & Service_Trade)
mTopicsList->addItem(gmst.find("sBarter")->getString());
if (mServices & Service_BuySpells)
mTopicsList->addItem(gmst.find("sSpells")->getString());
if (mServices & Service_Travel)
mTopicsList->addItem(gmst.find("sTravel")->getString());
if (mServices & Service_CreateSpells)
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
if (mShowTrade)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sBarter")->getString());
// if (mServices & Service_Enchant)
// mTopicsList->addItem(gmst.find("sEnchanting")->getString());
if (mShowSpells)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString());
if (mServices & Service_Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
if (anyService)
mTopicsList->addSeparator();
@ -258,15 +382,18 @@ void DialogueWindow::updateOptions()
mTopicsList->clear();
mHistory->eraseText(0, mHistory->getTextLength());
mDispositionBar->setProgressRange(100);
mDispositionBar->setProgressPosition(40);
mDispositionText->eraseText(0, mDispositionText->getTextLength());
mDispositionText->addText("#B29154"+std::string("40/100")+"#B29154");
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
mDispositionBar->setProgressRange(100);
mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr));
mDispositionText->eraseText(0, mDispositionText->getTextLength());
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")+"#B29154");
}
}
void DialogueWindow::goodbye()
{
mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGoodbye")->getString());
mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString());
mTopicsList->setEnabled(false);
mEnabled = false;
}
@ -275,3 +402,17 @@ void DialogueWindow::onReferenceUnavailable()
{
mWindowManager.removeGuiMode(GM_Dialogue);
}
void DialogueWindow::onFrame()
{
if(mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name())
{
int disp = std::max(0, std::min(100,
MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()));
mDispositionBar->setProgressRange(100);
mDispositionBar->setProgressPosition(disp);
mDispositionText->eraseText(0, mDispositionText->getTextLength());
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(disp)+std::string("/100")+"#B29154");
}
}

@ -26,6 +26,27 @@ namespace MWGui
{
class DialogueHistory;
class PersuasionDialog : public WindowModal
{
public:
PersuasionDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
private:
MyGUI::Button* mCancelButton;
MyGUI::Button* mAdmireButton;
MyGUI::Button* mIntimidateButton;
MyGUI::Button* mTauntButton;
MyGUI::Button* mBribe10Button;
MyGUI::Button* mBribe100Button;
MyGUI::Button* mBribe1000Button;
MyGUI::TextBox* mGoldLabel;
void onCancel (MyGUI::Widget* sender);
void onPersuade (MyGUI::Widget* sender);
};
class DialogueWindow: public WindowBase, public ReferenceInterface
{
public:
@ -47,11 +68,20 @@ namespace MWGui
void addTitle(std::string text);
void askQuestion(std::string question);
void goodbye();
void onFrame();
// various service button visibilities, depending if the npc/creature talked to has these services
// make sure to call these before setKeywords()
void setShowTrade(bool show) { mShowTrade = show; }
void setShowSpells(bool show) { mShowSpells = show; }
void setServices(int services) { mServices = services; }
enum Services
{
Service_Trade = 0x01,
Service_BuySpells = 0x02,
Service_CreateSpells = 0x04,
Service_Enchant = 0x08,
Service_Training = 0x10,
Service_Travel = 0x20
};
protected:
void onSelectTopic(std::string topic);
@ -69,9 +99,7 @@ namespace MWGui
*/
std::string parseText(std::string text);
// various service button visibilities, depending if the npc/creature talked to has these services
bool mShowTrade;
bool mShowSpells;
int mServices;
bool mEnabled;
@ -79,6 +107,8 @@ namespace MWGui
Widgets::MWList* mTopicsList;
MyGUI::ProgressPtr mDispositionBar;
MyGUI::EditPtr mDispositionText;
PersuasionDialog mPersuasionDialog;
};
}
#endif

@ -3,7 +3,8 @@
#include "../mwbase/windowmanager.hpp"
#include "widgets.hpp"
#include "components/esm_store/store.hpp"
#include "../mwworld/esmstore.hpp"
#include <iostream>
#include <iterator>

@ -0,0 +1,43 @@
#include "enchantingdialog.hpp"
namespace MWGui
{
EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_enchanting_dialog.layout", parWindowManager)
, EffectEditorBase(parWindowManager)
{
getWidget(mCancelButton, "CancelButton");
getWidget(mAvailableEffectsList, "AvailableEffects");
getWidget(mUsedEffectsView, "UsedEffects");
setWidgets(mAvailableEffectsList, mUsedEffectsView);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked);
}
void EnchantingDialog::open()
{
center();
}
void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
{
mPtr = actor;
startEditing ();
}
void EnchantingDialog::onReferenceUnavailable ()
{
mWindowManager.removeGuiMode (GM_Dialogue);
mWindowManager.removeGuiMode (GM_Enchanting);
}
void EnchantingDialog::onCancelButtonClicked(MyGUI::Widget* sender)
{
mWindowManager.removeGuiMode (GM_Enchanting);
}
}

@ -0,0 +1,31 @@
#ifndef MWGUI_ENCHANTINGDIALOG_H
#define MWGUI_ENCHANTINGDIALOG_H
#include "window_base.hpp"
#include "referenceinterface.hpp"
#include "spellcreationdialog.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWGui
{
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{
public:
EnchantingDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
void startEnchanting(MWWorld::Ptr actor);
protected:
virtual void onReferenceUnavailable();
void onCancelButtonClicked(MyGUI::Widget* sender);
MyGUI::Button* mCancelButton;
};
}
#endif

@ -245,15 +245,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
return;
std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle();
MWWorld::Ptr object;
try
{
object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle);
}
catch (std::exception& /* e */)
{
return;
}
MWWorld::Ptr object = MWBase::Environment::get().getWorld()->searchPtrViaHandle(handle);
if (mode == GM_Console)
MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object);
@ -349,7 +341,9 @@ void HUD::onResChange(int width, int height)
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId);
const ESM::Spell* spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
std::string spellName = spell->mName;
if (spellName != mSpellName && mSpellVisible)
{
@ -369,7 +363,9 @@ void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
mSpellBox->setUserString("Spell", spellId);
// use the icon of the first effect
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->mEffects.mList.front().mEffectID);
const ESM::MagicEffect* effect =
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(spell->mEffects.mList.front().mEffectID);
std::string icon = effect->mIcon;
int slashPos = icon.find("\\");
icon.insert(slashPos+1, "b_");

@ -28,6 +28,10 @@ namespace MWGui
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
void rebuildAvatar() {
mPreview.rebuild();
}
protected:
MyGUI::Widget* mAvatar;
MyGUI::ImageBox* mAvatarImage;

@ -85,6 +85,7 @@ MWGui::JournalWindow::JournalWindow (MWBase::WindowManager& parWindowManager)
: WindowBase("openmw_journal.layout", parWindowManager)
, mLastPos(0)
, mVisible(false)
, mPageNumber(0)
{
//setCoord(0,0,498, 342);
center();

@ -8,14 +8,12 @@
#include "../mwworld/player.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/stat.hpp"
#include <components/esm_store/reclists.hpp>
#include <components/esm_store/store.hpp>
namespace MWGui
{
@ -110,7 +108,8 @@ namespace MWGui
void LevelupDialog::open()
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayer().getPlayer();
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player);
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
@ -121,17 +120,13 @@ namespace MWGui
setAttributeValues();
const ESM::NPC *playerData = player.get<ESM::NPC>()->mBase;
// set class image
const ESM::Class& playerClass = MWBase::Environment::get().getWorld ()->getPlayer ().getClass ();
// retrieve the ID to this class
std::string classId;
std::map<std::string, ESM::Class> list = MWBase::Environment::get().getWorld()->getStore ().classes.list;
for (std::map<std::string, ESM::Class>::iterator it = list.begin(); it != list.end(); ++it)
{
if (playerClass.mName == it->second.mName)
classId = it->first;
}
mClassImage->setImageTexture ("textures\\levelup\\" + classId + ".dds");
const ESM::Class *cls =
world->getStore().get<ESM::Class>().find(playerData->mClass);
mClassImage->setImageTexture ("textures\\levelup\\" + cls->mId + ".dds");
/// \todo replace this with INI-imported texts
int level = creatureStats.getLevel ()+1;

@ -128,4 +128,10 @@ void MWList::onItemSelected(MyGUI::Widget* _sender)
std::string name = static_cast<MyGUI::Button*>(_sender)->getCaption();
eventItemSelected(name);
eventWidgetSelected(_sender);
}
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
{
return mScrollView->findWidget (getName() + "_item_" + name);
}

@ -18,6 +18,7 @@ namespace MWGui
MWList();
typedef MyGUI::delegates::CMultiDelegate1<std::string> EventHandle_String;
typedef MyGUI::delegates::CMultiDelegate1<MyGUI::Widget*> EventHandle_Widget;
/**
* Event: Item selected with the mouse.
@ -25,6 +26,13 @@ namespace MWGui
*/
EventHandle_String eventItemSelected;
/**
* Event: Item selected with the mouse.
* signature: void method(MyGUI::Widget* sender)
*/
EventHandle_Widget eventWidgetSelected;
/**
* Call after the size of the list changed, or items were inserted/removed
*/
@ -38,6 +46,9 @@ namespace MWGui
std::string getItemNameAt(unsigned int at); ///< \attention if there are separators, this method will return "" at the place where the separator is
void clear();
MyGUI::Widget* getItemWidget(const std::string& name);
///< get widget for an item name, useful to set up tooltip
protected:
void initialiseOverride();

@ -6,10 +6,13 @@
#include <OgreCompositorChain.h>
#include <OgreMaterial.h>
#include <boost/algorithm/string.hpp>
#include <openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
@ -106,6 +109,7 @@ namespace MWGui
if (mTimer.getMilliseconds () > mLastRenderTime + (1.f/loadingScreenFps) * 1000.f)
{
float dt = mTimer.getMilliseconds () - mLastRenderTime;
mLastRenderTime = mTimer.getMilliseconds ();
if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 3000*1)
@ -151,6 +155,8 @@ namespace MWGui
}
}
MWBase::Environment::get().getWorld ()->getFader ()->update (dt);
mWindow->update();
if (!hasCompositor)
@ -207,20 +213,22 @@ namespace MWGui
void LoadingScreen::changeWallpaper ()
{
/// \todo use a directory listing here
std::vector<std::string> splash;
splash.push_back ("Splash_Bonelord.tga");
splash.push_back ("Splash_ClannDaddy.tga");
splash.push_back ("Splash_Clannfear.tga");
splash.push_back ("Splash_Daedroth.tga");
splash.push_back ("Splash_Hunger.tga");
splash.push_back ("Splash_KwamaWarrior.tga");
splash.push_back ("Splash_Netch.tga");
splash.push_back ("Splash_NixHound.tga");
splash.push_back ("Splash_Siltstriker.tga");
splash.push_back ("Splash_Skeleton.tga");
splash.push_back ("Splash_SphereCenturion.tga");
mBackgroundImage->setImageTexture (splash[rand() % splash.size()]);
Ogre::StringVectorPtr resources = Ogre::ResourceGroupManager::getSingleton ().listResourceNames ("General", false);
for (Ogre::StringVector::const_iterator it = resources->begin(); it != resources->end(); ++it)
{
if (it->size() < 6)
continue;
std::string start = it->substr(0, 6);
boost::to_lower(start);
if (start == "splash")
splash.push_back (*it);
}
std::string randomSplash = splash[rand() % splash.size()];
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton ().load (randomSplash, "General");
mBackgroundImage->setImageTexture (randomSplash);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save