Merge branch 'master' into alchemy

Conflicts:
	components/esm/loadmgef.hpp
actorid
Marc Zinnschlag 12 years ago
commit 510674aa5e

@ -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)

@ -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>

@ -24,6 +24,6 @@ public slots:
};
Q_DECLARE_METATYPE(QVector<QPersistentModelIndex>);
Q_DECLARE_METATYPE(QVector<QPersistentModelIndex>)
#endif
#endif

@ -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,7 +29,8 @@ 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

@ -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));
}
}
}

@ -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;
};
}

@ -145,16 +145,17 @@ namespace
return false;
}
}
namespace MWDialogue
{
//helper function
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
return toLower(str).find(toLower(substr),pos);
}
}
namespace MWDialogue
{
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
{
@ -779,6 +780,8 @@ namespace MWDialogue
services = ref->base->mAiData.mServices;
}
int windowServices = 0;
if (services & ESM::NPC::Weapon
|| services & ESM::NPC::Armor
|| services & ESM::NPC::Clothing
@ -790,14 +793,24 @@ namespace MWDialogue
|| services & ESM::NPC::Apparatus
|| services & ESM::NPC::RepairItem
|| services & ESM::NPC::Misc)
win->setShowTrade(true);
else
win->setShowTrade(false);
windowServices |= MWGui::DialogueWindow::Service_Trade;
if( !mActor.get<ESM::NPC>()->base->mTransport.empty())
windowServices |= MWGui::DialogueWindow::Service_Travel;
if (services & ESM::NPC::Spells)
win->setShowSpells(true);
else
win->setShowSpells(false);
windowServices |= MWGui::DialogueWindow::Service_BuySpells;
if (services & ESM::NPC::Spellmaking)
windowServices |= MWGui::DialogueWindow::Service_CreateSpells;
if (services & ESM::NPC::Training)
windowServices |= MWGui::DialogueWindow::Service_Training;
if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant;
win->setServices (windowServices);
// sort again, because the previous sort was case-sensitive
keywordList.sort(stringCompareNoCase);

@ -565,7 +565,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 +574,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 +595,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 +604,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();

@ -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

@ -19,6 +19,7 @@
#include "tradewindow.hpp"
#include "spellbuyingwindow.hpp"
#include "inventorywindow.hpp"
#include "travelwindow.hpp"
using namespace MWGui;
using namespace Widgets;
@ -27,6 +28,8 @@ using namespace Widgets;
*Copied from the internet.
*/
namespace {
std::string lower_string(const std::string& str)
{
std::string lowerCase;
@ -42,12 +45,13 @@ std::string::size_type find_str_ci(const std::string& str, const std::string& su
return lower_string(str).find(lower_string(substr),pos);
}
}
DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager)
: WindowBase("openmw_dialogue_window.layout", parWindowManager)
, mEnabled(true)
, mShowTrade(false)
, mShowSpells(false)
, mServices(0)
{
// Centre dialog
center();
@ -134,7 +138,26 @@ void DialogueWindow::onSelectTopic(std::string topic)
mWindowManager.pushGuiMode(GM_SpellBuying);
mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString())
{
mWindowManager.pushGuiMode(GM_Travel);
mWindowManager.getTravelWindow()->startTravel(mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellMakingMenuTitle")->getString())
{
mWindowManager.pushGuiMode(GM_SpellCreation);
mWindowManager.startSpellMaking (mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString())
{
mWindowManager.pushGuiMode(GM_Enchanting);
mWindowManager.startEnchanting (mPtr);
}
else if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString())
{
mWindowManager.pushGuiMode(GM_Training);
mWindowManager.startTraining (mPtr);
}
else
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
}
@ -155,14 +178,26 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
mTopicsList->clear();
bool anyService = mShowTrade||mShowSpells;
bool anyService = mServices > 0;
if (mShowTrade)
if (mServices & Service_Trade)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sBarter")->getString());
if (mShowSpells)
if (mServices & Service_BuySpells)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpells")->getString());
if (mServices & Service_Travel)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sTravel")->getString());
if (mServices & Service_CreateSpells)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sSpellmakingMenuTitle")->getString());
if (mServices & Service_Enchant)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sEnchanting")->getString());
if (mServices & Service_Training)
mTopicsList->addItem(MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sServiceTrainingTitle")->getString());
if (anyService)
mTopicsList->addSeparator();

@ -48,10 +48,18 @@ namespace MWGui
void askQuestion(std::string question);
void goodbye();
// 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 +77,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;

@ -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

@ -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,12 @@
#include <OgreCompositorChain.h>
#include <OgreMaterial.h>
#include <openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
@ -106,6 +108,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 +154,8 @@ namespace MWGui
}
}
MWBase::Environment::get().getWorld ()->getFader ()->update (dt);
mWindow->update();
if (!hasCompositor)

@ -22,6 +22,10 @@ namespace MWGui
GM_Rest,
GM_RestBed,
GM_SpellBuying,
GM_Travel,
GM_SpellCreation,
GM_Enchanting,
GM_Training,
GM_Levelup,

@ -24,7 +24,6 @@ namespace MWGui
SpellBuyingWindow::SpellBuyingWindow(MWBase::WindowManager& parWindowManager) :
WindowBase("openmw_spell_buying_window.layout", parWindowManager)
, ContainerBase(NULL) // no drag&drop
, mCurrentY(0)
, mLastPos(0)
{
@ -55,7 +54,7 @@ namespace MWGui
MyGUI::Button* toAdd =
mSpellsView->createWidget<MyGUI::Button>(
(price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SpellText",
(price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
0,
mCurrentY,
200,
@ -88,7 +87,7 @@ namespace MWGui
void SpellBuyingWindow::startSpellBuying(const MWWorld::Ptr& actor)
{
center();
mActor = actor;
mPtr = actor;
clearSpells();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
@ -125,7 +124,7 @@ namespace MWGui
MWMechanics::Spells& spells = stats.getSpells();
spells.add (mSpellsWidgetMap.find(_sender)->second);
mWindowManager.getTradeWindow()->addOrRemoveGold(-price);
startSpellBuying(mActor);
startSpellBuying(mPtr);
MWBase::Environment::get().getSoundManager()->playSound ("Item Gold Up", 1.0, 1.0);
}

@ -1,10 +1,8 @@
#ifndef MWGUI_SpellBuyingWINDOW_H
#define MWGUI_SpellBuyingWINDOW_H
#include "container.hpp"
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
#include "referenceinterface.hpp"
namespace MyGUI
{
@ -20,7 +18,7 @@ namespace MWGui
namespace MWGui
{
class SpellBuyingWindow : public ContainerBase, public WindowBase
class SpellBuyingWindow : public ReferenceInterface, public WindowBase
{
public:
SpellBuyingWindow(MWBase::WindowManager& parWindowManager);
@ -35,8 +33,6 @@ namespace MWGui
MyGUI::ScrollView* mSpellsView;
MWWorld::Ptr mActor;
std::map<MyGUI::Widget*, std::string> mSpellsWidgetMap;
void onCancelButtonClicked(MyGUI::Widget* _sender);

@ -0,0 +1,513 @@
#include "spellcreationdialog.hpp"
#include <boost/lexical_cast.hpp>
#include <components/esm_store/store.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "tooltips.hpp"
#include "widgets.hpp"
#include "class.hpp"
namespace
{
bool sortMagicEffects (short id1, short id2)
{
return MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(ESM::MagicEffect::effectIdToString (id1))->getString()
< MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(ESM::MagicEffect::effectIdToString (id2))->getString();
}
}
namespace MWGui
{
EditEffectDialog::EditEffectDialog(MWBase::WindowManager &parWindowManager)
: WindowModal("openmw_edit_effect.layout", parWindowManager)
, mEditing(false)
{
getWidget(mCancelButton, "CancelButton");
getWidget(mOkButton, "OkButton");
getWidget(mDeleteButton, "DeleteButton");
getWidget(mRangeButton, "RangeButton");
getWidget(mMagnitudeMinValue, "MagnitudeMinValue");
getWidget(mMagnitudeMaxValue, "MagnitudeMaxValue");
getWidget(mDurationValue, "DurationValue");
getWidget(mAreaValue, "AreaValue");
getWidget(mMagnitudeMinSlider, "MagnitudeMinSlider");
getWidget(mMagnitudeMaxSlider, "MagnitudeMaxSlider");
getWidget(mDurationSlider, "DurationSlider");
getWidget(mAreaSlider, "AreaSlider");
getWidget(mEffectImage, "EffectImage");
getWidget(mEffectName, "EffectName");
getWidget(mAreaText, "AreaText");
getWidget(mDurationBox, "DurationBox");
getWidget(mAreaBox, "AreaBox");
getWidget(mMagnitudeBox, "MagnitudeBox");
mRangeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onRangeButtonClicked);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onOkButtonClicked);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onCancelButtonClicked);
mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onDeleteButtonClicked);
mMagnitudeMinSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMinChanged);
mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged);
mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged);
mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged);
}
void EditEffectDialog::open()
{
WindowModal::open();
center();
}
void EditEffectDialog::newEffect (const ESM::MagicEffect *effect)
{
setMagicEffect(effect);
mEditing = false;
mDeleteButton->setVisible (false);
mEffect.mRange = ESM::RT_Self;
onRangeButtonClicked(mRangeButton);
mMagnitudeMinSlider->setScrollPosition (0);
mMagnitudeMaxSlider->setScrollPosition (0);
mAreaSlider->setScrollPosition (0);
mDurationSlider->setScrollPosition (0);
mDurationValue->setCaption("1");
mMagnitudeMinValue->setCaption("1");
mMagnitudeMaxValue->setCaption("- 1");
mAreaValue->setCaption("0");
mEffect.mMagnMin = 1;
mEffect.mMagnMax = 1;
mEffect.mDuration = 1;
mEffect.mArea = 0;
}
void EditEffectDialog::editEffect (ESM::ENAMstruct effect)
{
const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effect.mEffectID);
setMagicEffect(magicEffect);
mEffect = effect;
mEditing = true;
mDeleteButton->setVisible (true);
mMagnitudeMinSlider->setScrollPosition (effect.mMagnMin-1);
mMagnitudeMaxSlider->setScrollPosition (effect.mMagnMax-1);
mAreaSlider->setScrollPosition (effect.mArea);
mDurationSlider->setScrollPosition (effect.mDuration-1);
onMagnitudeMinChanged (mMagnitudeMinSlider, effect.mMagnMin-1);
onMagnitudeMaxChanged (mMagnitudeMinSlider, effect.mMagnMax-1);
onAreaChanged (mAreaSlider, effect.mArea);
onDurationChanged (mDurationSlider, effect.mDuration-1);
}
void EditEffectDialog::setMagicEffect (const ESM::MagicEffect *effect)
{
std::string icon = effect->mIcon;
icon[icon.size()-3] = 'd';
icon[icon.size()-2] = 'd';
icon[icon.size()-1] = 's';
icon = "icons\\" + icon;
mEffectImage->setImageTexture (icon);
mEffectName->setCaptionWithReplacing("#{"+ESM::MagicEffect::effectIdToString (effect->mIndex)+"}");
mEffect.mEffectID = effect->mIndex;
mMagicEffect = effect;
updateBoxes();
}
void EditEffectDialog::updateBoxes()
{
static int startY = mMagnitudeBox->getPosition().top;
int curY = startY;
mMagnitudeBox->setVisible (false);
mDurationBox->setVisible (false);
mAreaBox->setVisible (false);
if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
{
mMagnitudeBox->setPosition(mMagnitudeBox->getPosition().left, curY);
mMagnitudeBox->setVisible (true);
curY += mMagnitudeBox->getSize().height;
}
if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
{
mDurationBox->setPosition(mDurationBox->getPosition().left, curY);
mDurationBox->setVisible (true);
curY += mDurationBox->getSize().height;
}
if (mEffect.mRange == ESM::RT_Target)
{
mAreaBox->setPosition(mAreaBox->getPosition().left, curY);
mAreaBox->setVisible (true);
curY += mAreaBox->getSize().height;
}
}
void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender)
{
mEffect.mRange = (mEffect.mRange+1)%3;
if (mEffect.mRange == ESM::RT_Self)
mRangeButton->setCaptionWithReplacing ("#{sRangeSelf}");
else if (mEffect.mRange == ESM::RT_Target)
mRangeButton->setCaptionWithReplacing ("#{sRangeTarget}");
else if (mEffect.mRange == ESM::RT_Touch)
mRangeButton->setCaptionWithReplacing ("#{sRangeTouch}");
mAreaSlider->setVisible (mEffect.mRange != ESM::RT_Self);
mAreaText->setVisible (mEffect.mRange != ESM::RT_Self);
// cycle through range types until we find something that's allowed
if (mEffect.mRange == ESM::RT_Target && !(mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTarget))
onRangeButtonClicked(sender);
if (mEffect.mRange == ESM::RT_Self && !(mMagicEffect->mData.mFlags & ESM::MagicEffect::CastSelf))
onRangeButtonClicked(sender);
if (mEffect.mRange == ESM::RT_Touch && !(mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTouch))
onRangeButtonClicked(sender);
updateBoxes();
}
void EditEffectDialog::onDeleteButtonClicked (MyGUI::Widget* sender)
{
setVisible(false);
eventEffectRemoved(mEffect);
}
void EditEffectDialog::onOkButtonClicked (MyGUI::Widget* sender)
{
setVisible(false);
if (mEditing)
eventEffectModified(mEffect);
else
eventEffectAdded(mEffect);
}
void EditEffectDialog::onCancelButtonClicked (MyGUI::Widget* sender)
{
setVisible(false);
}
void EditEffectDialog::setSkill (int skill)
{
mEffect.mSkill = skill;
}
void EditEffectDialog::setAttribute (int attribute)
{
mEffect.mAttribute = attribute;
}
void EditEffectDialog::onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos)
{
mMagnitudeMinValue->setCaption(boost::lexical_cast<std::string>(pos+1));
mEffect.mMagnMin = pos+1;
// trigger the check again (see below)
onMagnitudeMaxChanged(mMagnitudeMaxSlider, mMagnitudeMaxSlider->getScrollPosition ());
}
void EditEffectDialog::onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos)
{
// make sure the max value is actually larger or equal than the min value
size_t magnMin = std::abs(mEffect.mMagnMin); // should never be < 0, this is just here to avoid the compiler warning
if (pos+1 < magnMin)
{
pos = mEffect.mMagnMin-1;
sender->setScrollPosition (pos);
}
mEffect.mMagnMax = pos+1;
mMagnitudeMaxValue->setCaption("- " + boost::lexical_cast<std::string>(pos+1));
}
void EditEffectDialog::onDurationChanged (MyGUI::ScrollBar* sender, size_t pos)
{
mDurationValue->setCaption(boost::lexical_cast<std::string>(pos+1));
mEffect.mDuration = pos+1;
}
void EditEffectDialog::onAreaChanged (MyGUI::ScrollBar* sender, size_t pos)
{
mAreaValue->setCaption(boost::lexical_cast<std::string>(pos));
mEffect.mArea = pos;
}
// ------------------------------------------------------------------------------------------------
SpellCreationDialog::SpellCreationDialog(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_spellcreation_dialog.layout", parWindowManager)
, EffectEditorBase(parWindowManager)
{
getWidget(mNameEdit, "NameEdit");
getWidget(mMagickaCost, "MagickaCost");
getWidget(mSuccessChance, "SuccessChance");
getWidget(mAvailableEffectsList, "AvailableEffects");
getWidget(mUsedEffectsView, "UsedEffects");
getWidget(mPriceLabel, "PriceLabel");
getWidget(mBuyButton, "BuyButton");
getWidget(mCancelButton, "CancelButton");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onCancelButtonClicked);
mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onBuyButtonClicked);
setWidgets(mAvailableEffectsList, mUsedEffectsView);
}
void SpellCreationDialog::startSpellMaking (MWWorld::Ptr actor)
{
mPtr = actor;
startEditing();
}
void SpellCreationDialog::onCancelButtonClicked (MyGUI::Widget* sender)
{
mWindowManager.removeGuiMode (MWGui::GM_SpellCreation);
}
void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender)
{
}
void SpellCreationDialog::open()
{
center();
}
void SpellCreationDialog::onReferenceUnavailable ()
{
mWindowManager.removeGuiMode (GM_Dialogue);
mWindowManager.removeGuiMode (GM_SpellCreation);
}
// ------------------------------------------------------------------------------------------------
EffectEditorBase::EffectEditorBase(MWBase::WindowManager& parWindowManager)
: mAddEffectDialog(parWindowManager)
, mSelectAttributeDialog(NULL)
, mSelectSkillDialog(NULL)
{
mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded);
mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified);
mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &EffectEditorBase::onEffectRemoved);
mAddEffectDialog.setVisible (false);
}
void EffectEditorBase::startEditing ()
{
// get the list of magic effects that are known to the player
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
MWMechanics::Spells& spells = stats.getSpells();
std::vector<short> knownEffects;
for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it);
// only normal spells count
if (spell->mData.mType != ESM::Spell::ST_Spell)
continue;
const std::vector<ESM::ENAMstruct>& list = spell->mEffects.mList;
for (std::vector<ESM::ENAMstruct>::const_iterator it2 = list.begin(); it2 != list.end(); ++it2)
{
if (std::find(knownEffects.begin(), knownEffects.end(), it2->mEffectID) == knownEffects.end())
knownEffects.push_back(it2->mEffectID);
}
}
std::sort(knownEffects.begin(), knownEffects.end(), sortMagicEffects);
mAvailableEffectsList->clear ();
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{
mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(
ESM::MagicEffect::effectIdToString (*it))->getString());
}
mAvailableEffectsList->adjustSize ();
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{
std::string name = MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find(
ESM::MagicEffect::effectIdToString (*it))->getString();
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
w->setUserData(*it);
ToolTips::createMagicEffectToolTip (w, *it);
}
}
void EffectEditorBase::setWidgets (Widgets::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView)
{
mAvailableEffectsList = availableEffectsList;
mUsedEffectsView = usedEffectsView;
mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked);
}
void EffectEditorBase::onSelectAttribute ()
{
mAddEffectDialog.setVisible(true);
mAddEffectDialog.setAttribute (mSelectAttributeDialog->getAttributeId());
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog);
mSelectAttributeDialog = 0;
}
void EffectEditorBase::onSelectSkill ()
{
mAddEffectDialog.setVisible(true);
mAddEffectDialog.setSkill (mSelectSkillDialog->getSkillId ());
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog);
mSelectSkillDialog = 0;
}
void EffectEditorBase::onAttributeOrSkillCancel ()
{
if (mSelectSkillDialog)
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectSkillDialog);
if (mSelectAttributeDialog)
MWBase::Environment::get().getWindowManager ()->removeDialog (mSelectAttributeDialog);
mSelectSkillDialog = 0;
mSelectAttributeDialog = 0;
}
void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender)
{
short effectId = *sender->getUserData<short>();
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(effectId);
mAddEffectDialog.newEffect (effect);
if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill)
{
delete mSelectSkillDialog;
mSelectSkillDialog = new SelectSkillDialog(*MWBase::Environment::get().getWindowManager ());
mSelectSkillDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel);
mSelectSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectSkill);
mSelectSkillDialog->setVisible (true);
}
else if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
{
delete mSelectAttributeDialog;
mSelectAttributeDialog = new SelectAttributeDialog(*MWBase::Environment::get().getWindowManager ());
mSelectAttributeDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel);
mSelectAttributeDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute);
mSelectAttributeDialog->setVisible (true);
}
else
{
mAddEffectDialog.setVisible(true);
}
}
void EffectEditorBase::onEffectModified (ESM::ENAMstruct effect)
{
mEffects[mSelectedEffect] = effect;
updateEffectsView();
}
void EffectEditorBase::onEffectRemoved (ESM::ENAMstruct effect)
{
mEffects.erase(mEffects.begin() + mSelectedEffect);
updateEffectsView();
}
void EffectEditorBase::updateEffectsView ()
{
MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator ();
MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets);
MyGUI::IntSize size(0,0);
int i = 0;
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{
Widgets::SpellEffectParams params;
params.mEffectID = it->mEffectID;
params.mSkill = it->mSkill;
params.mAttribute = it->mAttribute;
params.mDuration = it->mDuration;
params.mMagnMin = it->mMagnMin;
params.mMagnMax = it->mMagnMax;
params.mRange = it->mRange;
params.mArea = it->mArea;
MyGUI::Button* button = mUsedEffectsView->createWidget<MyGUI::Button>("", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default);
button->setUserData(i);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onEditEffect);
button->setNeedMouseFocus (true);
Widgets::MWSpellEffectPtr effect = button->createWidget<Widgets::MWSpellEffect>("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default);
effect->setNeedMouseFocus (false);
effect->setWindowManager (MWBase::Environment::get().getWindowManager ());
effect->setSpellEffect (params);
effect->setSize(effect->getRequestedWidth (), 24);
button->setSize(effect->getRequestedWidth (), 24);
size.width = std::max(size.width, effect->getRequestedWidth ());
size.height += 24;
++i;
}
mUsedEffectsView->setCanvasSize(size);
}
void EffectEditorBase::onEffectAdded (ESM::ENAMstruct effect)
{
mEffects.push_back(effect);
updateEffectsView();
}
void EffectEditorBase::onEditEffect (MyGUI::Widget *sender)
{
int id = *sender->getUserData<int>();
mSelectedEffect = id;
mAddEffectDialog.editEffect (mEffects[id]);
mAddEffectDialog.setVisible (true);
}
}

@ -0,0 +1,150 @@
#ifndef MWGUI_SPELLCREATION_H
#define MWGUI_SPELLCREATION_H
#include "window_base.hpp"
#include "referenceinterface.hpp"
#include "list.hpp"
#include "widgets.hpp"
namespace MWGui
{
class SelectSkillDialog;
class SelectAttributeDialog;
class EditEffectDialog : public WindowModal
{
public:
EditEffectDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
void setSkill(int skill);
void setAttribute(int attribute);
void newEffect (const ESM::MagicEffect* effect);
void editEffect (ESM::ENAMstruct effect);
typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect;
EventHandle_Effect eventEffectAdded;
EventHandle_Effect eventEffectModified;
EventHandle_Effect eventEffectRemoved;
protected:
MyGUI::Button* mCancelButton;
MyGUI::Button* mOkButton;
MyGUI::Button* mDeleteButton;
MyGUI::Button* mRangeButton;
MyGUI::Widget* mDurationBox;
MyGUI::Widget* mMagnitudeBox;
MyGUI::Widget* mAreaBox;
MyGUI::TextBox* mMagnitudeMinValue;
MyGUI::TextBox* mMagnitudeMaxValue;
MyGUI::TextBox* mDurationValue;
MyGUI::TextBox* mAreaValue;
MyGUI::ScrollBar* mMagnitudeMinSlider;
MyGUI::ScrollBar* mMagnitudeMaxSlider;
MyGUI::ScrollBar* mDurationSlider;
MyGUI::ScrollBar* mAreaSlider;
MyGUI::TextBox* mAreaText;
MyGUI::ImageBox* mEffectImage;
MyGUI::TextBox* mEffectName;
bool mEditing;
protected:
void onRangeButtonClicked (MyGUI::Widget* sender);
void onDeleteButtonClicked (MyGUI::Widget* sender);
void onOkButtonClicked (MyGUI::Widget* sender);
void onCancelButtonClicked (MyGUI::Widget* sender);
void onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos);
void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos);
void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos);
void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos);
void setMagicEffect(const ESM::MagicEffect* effect);
void updateBoxes();
protected:
ESM::ENAMstruct mEffect;
const ESM::MagicEffect* mMagicEffect;
};
class EffectEditorBase
{
public:
EffectEditorBase(MWBase::WindowManager& parWindowManager);
protected:
Widgets::MWList* mAvailableEffectsList;
MyGUI::ScrollView* mUsedEffectsView;
EditEffectDialog mAddEffectDialog;
SelectAttributeDialog* mSelectAttributeDialog;
SelectSkillDialog* mSelectSkillDialog;
int mSelectedEffect;
std::vector<ESM::ENAMstruct> mEffects;
void onEffectAdded(ESM::ENAMstruct effect);
void onEffectModified(ESM::ENAMstruct effect);
void onEffectRemoved(ESM::ENAMstruct effect);
void onAvailableEffectClicked (MyGUI::Widget* sender);
void onAttributeOrSkillCancel();
void onSelectAttribute();
void onSelectSkill();
void onEditEffect(MyGUI::Widget* sender);
void updateEffectsView();
void startEditing();
void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView);
};
class SpellCreationDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{
public:
SpellCreationDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
void startSpellMaking(MWWorld::Ptr actor);
protected:
virtual void onReferenceUnavailable ();
void onCancelButtonClicked (MyGUI::Widget* sender);
void onBuyButtonClicked (MyGUI::Widget* sender);
MyGUI::EditBox* mNameEdit;
MyGUI::TextBox* mMagickaCost;
MyGUI::TextBox* mSuccessChance;
MyGUI::Button* mBuyButton;
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPriceLabel;
Widgets::MWEffectList* mUsedEffectsList;
};
}
#endif

@ -588,8 +588,6 @@ void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId)
widget->setUserString("Caption_SkillNoProgressDescription", skill->mDescription);
widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}");
widget->setUserString("ImageTexture_SkillNoProgressImage", icon);
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip");
}
void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId)
@ -715,6 +713,38 @@ void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playe
widget->setUserString("ToolTipLayout", "ClassToolTip");
}
void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id)
{
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld ()->getStore ().magicEffects.find(id);
const std::string &name = ESM::MagicEffect::effectIdToString (id);
std::string icon = effect->mIcon;
int slashPos = icon.find("\\");
icon.insert(slashPos+1, "b_");
icon[icon.size()-3] = 'd';
icon[icon.size()-2] = 'd';
icon[icon.size()-1] = 's';
icon = "icons\\" + icon;
std::vector<std::string> schools;
schools.push_back ("#{sSchoolAlteration}");
schools.push_back ("#{sSchoolConjuration}");
schools.push_back ("#{sSchoolDestruction}");
schools.push_back ("#{sSchoolIllusion}");
schools.push_back ("#{sSchoolMysticism}");
schools.push_back ("#{sSchoolRestoration}");
widget->setUserString("ToolTipType", "Layout");
widget->setUserString("ToolTipLayout", "MagicEffectToolTip");
widget->setUserString("Caption_MagicEffectName", "#{" + name + "}");
widget->setUserString("Caption_MagicEffectDescription", effect->mDescription);
widget->setUserString("Caption_MagicEffectSchool", "#{sSchool}: " + schools[effect->mData.mSchool]);
widget->setUserString("ImageTexture_MagicEffectImage", icon);
}
void ToolTips::setDelay(float delay)
{
mDelay = delay;

@ -71,6 +71,7 @@ namespace MWGui
static void createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId);
static void createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace);
static void createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass);
static void createMagicEffectToolTip(MyGUI::Widget* widget, short id);
private:
MyGUI::Widget* mDynamicToolTipBox;

@ -0,0 +1,159 @@
#include "trainingwindow.hpp"
#include <boost/lexical_cast.hpp>
#include <openengine/ogre/fader.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"
#include "tooltips.hpp"
namespace MWGui
{
TrainingWindow::TrainingWindow(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_trainingwindow.layout", parWindowManager)
, mFadeTimeRemaining(0)
{
getWidget(mTrainingOptions, "TrainingOptions");
getWidget(mCancelButton, "CancelButton");
getWidget(mPlayerGold, "PlayerGold");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked);
}
void TrainingWindow::open()
{
center();
}
void TrainingWindow::startTraining (MWWorld::Ptr actor)
{
mPtr = actor;
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats (actor);
// NPC can train you in his best 3 skills
std::vector< std::pair<int, int> > bestSkills;
bestSkills.push_back (std::make_pair(-1, -1));
bestSkills.push_back (std::make_pair(-1, -1));
bestSkills.push_back (std::make_pair(-1, -1));
for (int i=0; i<ESM::Skill::Length; ++i)
{
int value = npcStats.getSkill (i).getBase ();
for (int j=0; j<3; ++j)
{
if (value > bestSkills[j].second)
{
if (j<2)
{
bestSkills[j+1] = bestSkills[j];
}
bestSkills[j] = std::make_pair(i, value);
break;
}
}
}
MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator ();
MyGUI::Gui::getInstance ().destroyWidgets (widgets);
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
for (int i=0; i<3; ++i)
{
/// \todo mercantile skill
int price = pcStats.getSkill (bestSkills[i].first).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt ();
std::string skin = (price > mWindowManager.getInventoryWindow ()->getPlayerGold ()) ? "SandTextGreyedOut" : "SandTextButton";
MyGUI::Button* button = mTrainingOptions->createWidget<MyGUI::Button>(skin,
MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default);
button->setUserData(bestSkills[i].first);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected);
button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[bestSkills[i].first] + "} - " + boost::lexical_cast<std::string>(price));
button->setSize(button->getTextSize ().width+12, button->getSize().height);
ToolTips::createSkillToolTip (button, bestSkills[i].first);
}
center();
}
void TrainingWindow::onReferenceUnavailable ()
{
mWindowManager.removeGuiMode(GM_Training);
}
void TrainingWindow::onCancelButtonClicked (MyGUI::Widget *sender)
{
mWindowManager.removeGuiMode (GM_Training);
}
void TrainingWindow::onTrainingSelected (MyGUI::Widget *sender)
{
int skillId = *sender->getUserData<int>();
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ();
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
/// \todo mercantile skill
int price = pcStats.getSkill (skillId).getBase() * MWBase::Environment::get().getWorld ()->getStore ().gameSettings.find("iTrainingMod")->getInt ();
if (mWindowManager.getInventoryWindow()->getPlayerGold()<price)
return;
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mPtr).getNpcStats (mPtr);
if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ())
{
mWindowManager.messageBox ("#{sServiceTrainingWords}", std::vector<std::string>());
return;
}
// increase skill
MWWorld::LiveCellRef<ESM::NPC> *playerRef = player.get<ESM::NPC>();
const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find (
playerRef->base->mClass);
pcStats.increaseSkill (skillId, *class_, true);
// remove gold
mWindowManager.getTradeWindow()->addOrRemoveGold(-price);
// go back to game mode
mWindowManager.removeGuiMode (GM_Training);
mWindowManager.removeGuiMode (GM_Dialogue);
// advance time
MWBase::Environment::get().getWorld ()->advanceTime (2);
MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25);
mFadeTimeRemaining = 0.5;
}
void TrainingWindow::onFrame(float dt)
{
if (mFadeTimeRemaining <= 0)
return;
mFadeTimeRemaining -= dt;
if (mFadeTimeRemaining <= 0)
MWBase::Environment::get().getWorld ()->getFader()->fadeIn(0.25);
}
}

@ -0,0 +1,36 @@
#ifndef MWGUI_TRAININGWINDOW_H
#define MWGUI_TRAININGWINDOW_H
#include "window_base.hpp"
#include "referenceinterface.hpp"
namespace MWGui
{
class TrainingWindow : public WindowBase, public ReferenceInterface
{
public:
TrainingWindow(MWBase::WindowManager& parWindowManager);
virtual void open();
void startTraining(MWWorld::Ptr actor);
void onFrame(float dt);
protected:
virtual void onReferenceUnavailable ();
void onCancelButtonClicked (MyGUI::Widget* sender);
void onTrainingSelected(MyGUI::Widget* sender);
MyGUI::Widget* mTrainingOptions;
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold;
float mFadeTimeRemaining;
};
}
#endif

@ -0,0 +1,187 @@
#include "travelwindow.hpp"
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace MWGui
{
const int TravelWindow::sLineHeight = 18;
TravelWindow::TravelWindow(MWBase::WindowManager& parWindowManager) :
WindowBase("openmw_travel_window.layout", parWindowManager)
, mCurrentY(0)
, mLastPos(0)
{
setCoord(0, 0, 450, 300);
getWidget(mCancelButton, "CancelButton");
getWidget(mPlayerGold, "PlayerGold");
getWidget(mSelect, "Select");
getWidget(mDestinations, "Travel");
getWidget(mDestinationsView, "DestinationsView");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked);
mDestinations->setCoord(450/2-mDestinations->getTextSize().width/2,
mDestinations->getTop(),
mDestinations->getTextSize().width,
mDestinations->getHeight());
mSelect->setCoord(8,
mSelect->getTop(),
mSelect->getTextSize().width,
mSelect->getHeight());
}
void TravelWindow::addDestination(const std::string& travelId,ESM::Position pos,bool interior)
{
int price = 0;
if(interior)
{
price = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fMagesGuildTravel")->getFloat();
}
else
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
ESM::Position PlayerPos = player.getRefData().getPosition();
float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) );
price = d/MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelMult")->getFloat();
}
MyGUI::Button* toAdd = mDestinationsView->createWidget<MyGUI::Button>((price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton", 0, mCurrentY, 200, sLineHeight, MyGUI::Align::Default);
mCurrentY += sLineHeight;
/// \todo price adjustment depending on merchantile skill
if(interior)
toAdd->setUserString("interior","y");
else
toAdd->setUserString("interior","n");
std::ostringstream oss;
oss << price;
toAdd->setUserString("price",oss.str());
toAdd->setCaptionWithReplacing(travelId+" - "+boost::lexical_cast<std::string>(price)+"#{sgp}");
toAdd->setSize(toAdd->getTextSize().width,sLineHeight);
toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel);
toAdd->setUserString("Destination", travelId);
toAdd->setUserData(pos);
toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onTravelButtonClick);
mDestinationsWidgetMap.insert(std::make_pair (toAdd, travelId));
}
void TravelWindow::clearDestinations()
{
mDestinationsView->setViewOffset(MyGUI::IntPoint(0,0));
mCurrentY = 0;
while (mDestinationsView->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mDestinationsView->getChildAt(0));
mDestinationsWidgetMap.clear();
}
void TravelWindow::startTravel(const MWWorld::Ptr& actor)
{
center();
mPtr = actor;
clearDestinations();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
for(unsigned int i = 0;i<mPtr.get<ESM::NPC>()->base->mTransport.size();i++)
{
std::string cellname = mPtr.get<ESM::NPC>()->base->mTransport[i].mCellName;
bool interior = true;
int x,y;
MWBase::Environment::get().getWorld()->positionToIndex(mPtr.get<ESM::NPC>()->base->mTransport[i].mPos.pos[0],
mPtr.get<ESM::NPC>()->base->mTransport[i].mPos.pos[1],x,y);
if(cellname == "") {cellname = MWBase::Environment::get().getWorld()->getExterior(x,y)->cell->mName; interior= false;}
addDestination(cellname,mPtr.get<ESM::NPC>()->base->mTransport[i].mPos,interior);
}
updateLabels();
mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY)));
}
void TravelWindow::onTravelButtonClick(MyGUI::Widget* _sender)
{
std::istringstream iss(_sender->getUserString("price"));
int price;
iss >> price;
if (mWindowManager.getInventoryWindow()->getPlayerGold()<price)
return;
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
ESM::Position pos = *_sender->getUserData<ESM::Position>();
std::string cellname = _sender->getUserString("Destination");
int x,y;
bool interior = _sender->getUserString("interior") == "y";
MWBase::Environment::get().getWorld()->positionToIndex(pos.pos[0],pos.pos[1],x,y);
MWWorld::CellStore* cell;
if(interior) cell = MWBase::Environment::get().getWorld()->getInterior(cellname);
else
{
cell = MWBase::Environment::get().getWorld()->getExterior(x,y);
ESM::Position PlayerPos = player.getRefData().getPosition();
float d = sqrt( pow(pos.pos[0] - PlayerPos.pos[0],2) + pow(pos.pos[1] - PlayerPos.pos[1],2) + pow(pos.pos[2] - PlayerPos.pos[2],2) );
int time = int(d /MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fTravelTimeMult")->getFloat());
for(int i = 0;i < time;i++)
{
MWBase::Environment::get().getMechanicsManager ()->restoreDynamicStats ();
}
MWBase::Environment::get().getWorld()->advanceTime(time);
}
MWBase::Environment::get().getWorld()->moveObject(player,*cell,pos.pos[0],pos.pos[1],pos.pos[2]);
mWindowManager.removeGuiMode(GM_Travel);
mWindowManager.removeGuiMode(GM_Dialogue);
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0);
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1);
}
void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender)
{
mWindowManager.removeGuiMode(GM_Travel);
}
void TravelWindow::updateLabels()
{
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
mPlayerGold->setCoord(8,
mPlayerGold->getTop(),
mPlayerGold->getTextSize().width,
mPlayerGold->getHeight());
}
void TravelWindow::onReferenceUnavailable()
{
mWindowManager.removeGuiMode(GM_Travel);
mWindowManager.removeGuiMode(GM_Dialogue);
}
void TravelWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mDestinationsView->getViewOffset().top + _rel*0.3 > 0)
mDestinationsView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mDestinationsView->setViewOffset(MyGUI::IntPoint(0, mDestinationsView->getViewOffset().top + _rel*0.3));
}
}

@ -0,0 +1,55 @@
#ifndef MWGUI_TravelWINDOW_H
#define MWGUI_TravelWINDOW_H
#include "container.hpp"
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
namespace MyGUI
{
class Gui;
class Widget;
}
namespace MWGui
{
class WindowManager;
}
namespace MWGui
{
class TravelWindow : public ReferenceInterface, public WindowBase
{
public:
TravelWindow(MWBase::WindowManager& parWindowManager);
void startTravel(const MWWorld::Ptr& actor);
protected:
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold;
MyGUI::TextBox* mDestinations;
MyGUI::TextBox* mSelect;
MyGUI::ScrollView* mDestinationsView;
std::map<MyGUI::Widget*, std::string> mDestinationsWidgetMap;
void onCancelButtonClicked(MyGUI::Widget* _sender);
void onTravelButtonClick(MyGUI::Widget* _sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void addDestination(const std::string& destinationID,ESM::Position pos,bool interior);
void clearDestinations();
int mLastPos,mCurrentY;
static const int sLineHeight;
void updateLabels();
virtual void onReferenceUnavailable();
};
}
#endif

@ -362,6 +362,7 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects)
params.mMagnMin = it->mMagnMin;
params.mMagnMax = it->mMagnMax;
params.mRange = it->mRange;
params.mArea = it->mArea;
result.push_back(params);
}
return result;
@ -385,343 +386,82 @@ void MWSpellEffect::setSpellEffect(const SpellEffectParams& params)
void MWSpellEffect::updateWidgets()
{
if (!mWindowManager)
return;
const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::MagicEffect *magicEffect = store.magicEffects.search(mEffectParams.mEffectID);
if (!magicEffect)
return;
if (mTextWidget)
assert(magicEffect);
assert(mWindowManager);
std::string pt = mWindowManager->getGameSettingString("spoint", "");
std::string pts = mWindowManager->getGameSettingString("spoints", "");
std::string to = " " + mWindowManager->getGameSettingString("sTo", "") + " ";
std::string sec = " " + mWindowManager->getGameSettingString("ssecond", "");
std::string secs = " " + mWindowManager->getGameSettingString("sseconds", "");
std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID);
std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, "");
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)
{
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], "");
}
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
}
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude))
{
std::string pt = mWindowManager->getGameSettingString("spoint", "");
std::string pts = mWindowManager->getGameSettingString("spoints", "");
std::string to = " " + mWindowManager->getGameSettingString("sTo", "") + " ";
std::string sec = " " + mWindowManager->getGameSettingString("ssecond", "");
std::string secs = " " + mWindowManager->getGameSettingString("sseconds", "");
std::string effectIDStr = effectIDToString(mEffectParams.mEffectID);
std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, "");
if (effectInvolvesSkill(effectIDStr) && mEffectParams.mSkill >= 0 && mEffectParams.mSkill < ESM::Skill::Length)
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
else
{
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], "");
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
}
if (effectInvolvesAttribute(effectIDStr) && mEffectParams.mAttribute >= 0 && mEffectParams.mAttribute < 8)
}
// constant effects have no duration and no target
if (!mEffectParams.mIsConstant)
{
if (mEffectParams.mDuration >= 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], "");
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs);
}
if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && effectHasMagnitude(effectIDStr))
if (mEffectParams.mArea > 0)
{
if (mEffectParams.mMagnMin == mEffectParams.mMagnMax)
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts);
else
{
spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts;
}
spellLine += " #{sin} " + boost::lexical_cast<std::string>(mEffectParams.mArea) + " #{sfootarea}";
}
// constant effects have no duration and no target
if (!mEffectParams.mIsConstant)
// potions have no target
if (!mEffectParams.mNoTarget)
{
if (mEffectParams.mDuration >= 0 && effectHasDuration(effectIDStr))
{
spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs);
}
// potions have no target
if (!mEffectParams.mNoTarget)
{
std::string on = mWindowManager->getGameSettingString("sonword", "");
if (mEffectParams.mRange == ESM::RT_Self)
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", "");
else if (mEffectParams.mRange == ESM::RT_Touch)
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", "");
else if (mEffectParams.mRange == ESM::RT_Target)
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", "");
}
std::string on = mWindowManager->getGameSettingString("sonword", "");
if (mEffectParams.mRange == ESM::RT_Self)
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", "");
else if (mEffectParams.mRange == ESM::RT_Touch)
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", "");
else if (mEffectParams.mRange == ESM::RT_Target)
spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", "");
}
static_cast<MyGUI::TextBox*>(mTextWidget)->setCaption(spellLine);
mRequestedWidth = mTextWidget->getTextSize().width + 24;
}
if (mImageWidget)
{
std::string path = std::string("icons\\") + magicEffect->mIcon;
fixTexturePath(path);
mImageWidget->setImageTexture(path);
}
}
std::string MWSpellEffect::effectIDToString(const short effectID)
{
// Map effect ID to GMST name
// http://www.uesp.net/morrow/hints/mweffects.shtml
std::map<short, std::string> names;
names[85] ="sEffectAbsorbAttribute";
names[88] ="sEffectAbsorbFatigue";
names[86] ="sEffectAbsorbHealth";
names[87] ="sEffectAbsorbSpellPoints";
names[89] ="sEffectAbsorbSkill";
names[63] ="sEffectAlmsiviIntervention";
names[47] ="sEffectBlind";
names[123] ="sEffectBoundBattleAxe";
names[129] ="sEffectBoundBoots";
names[127] ="sEffectBoundCuirass";
names[120] ="sEffectBoundDagger";
names[131] ="sEffectBoundGloves";
names[128] ="sEffectBoundHelm";
names[125] ="sEffectBoundLongbow";
names[121] ="sEffectBoundLongsword";
names[122] ="sEffectBoundMace";
names[130] ="sEffectBoundShield";
names[124] ="sEffectBoundSpear";
names[7] ="sEffectBurden";
names[50] ="sEffectCalmCreature";
names[49] ="sEffectCalmHumanoid";
names[40] ="sEffectChameleon";
names[44] ="sEffectCharm";
names[118] ="sEffectCommandCreatures";
names[119] ="sEffectCommandHumanoids";
names[132] ="sEffectCorpus"; // NB this typo. (bethesda made it)
names[70] ="sEffectCureBlightDisease";
names[69] ="sEffectCureCommonDisease";
names[71] ="sEffectCureCorprusDisease";
names[73] ="sEffectCureParalyzation";
names[72] ="sEffectCurePoison";
names[22] ="sEffectDamageAttribute";
names[25] ="sEffectDamageFatigue";
names[23] ="sEffectDamageHealth";
names[24] ="sEffectDamageMagicka";
names[26] ="sEffectDamageSkill";
names[54] ="sEffectDemoralizeCreature";
names[53] ="sEffectDemoralizeHumanoid";
names[64] ="sEffectDetectAnimal";
names[65] ="sEffectDetectEnchantment";
names[66] ="sEffectDetectKey";
names[38] ="sEffectDisintegrateArmor";
names[37] ="sEffectDisintegrateWeapon";
names[57] ="sEffectDispel";
names[62] ="sEffectDivineIntervention";
names[17] ="sEffectDrainAttribute";
names[20] ="sEffectDrainFatigue";
names[18] ="sEffectDrainHealth";
names[19] ="sEffectDrainSpellpoints";
names[21] ="sEffectDrainSkill";
names[8] ="sEffectFeather";
names[14] ="sEffectFireDamage";
names[4] ="sEffectFireShield";
names[117] ="sEffectFortifyAttackBonus";
names[79] ="sEffectFortifyAttribute";
names[82] ="sEffectFortifyFatigue";
names[80] ="sEffectFortifyHealth";
names[81] ="sEffectFortifySpellpoints";
names[84] ="sEffectFortifyMagickaMultiplier";
names[83] ="sEffectFortifySkill";
names[52] ="sEffectFrenzyCreature";
names[51] ="sEffectFrenzyHumanoid";
names[16] ="sEffectFrostDamage";
names[6] ="sEffectFrostShield";
names[39] ="sEffectInvisibility";
names[9] ="sEffectJump";
names[10] ="sEffectLevitate";
names[41] ="sEffectLight";
names[5] ="sEffectLightningShield";
names[12] ="sEffectLock";
names[60] ="sEffectMark";
names[43] ="sEffectNightEye";
names[13] ="sEffectOpen";
names[45] ="sEffectParalyze";
names[27] ="sEffectPoison";
names[56] ="sEffectRallyCreature";
names[55] ="sEffectRallyHumanoid";
names[61] ="sEffectRecall";
names[68] ="sEffectReflect";
names[100] ="sEffectRemoveCurse";
names[95] ="sEffectResistBlightDisease";
names[94] ="sEffectResistCommonDisease";
names[96] ="sEffectResistCorprusDisease";
names[90] ="sEffectResistFire";
names[91] ="sEffectResistFrost";
names[93] ="sEffectResistMagicka";
names[98] ="sEffectResistNormalWeapons";
names[99] ="sEffectResistParalysis";
names[97] ="sEffectResistPoison";
names[92] ="sEffectResistShock";
names[74] ="sEffectRestoreAttribute";
names[77] ="sEffectRestoreFatigue";
names[75] ="sEffectRestoreHealth";
names[76] ="sEffectRestoreSpellPoints";
names[78] ="sEffectRestoreSkill";
names[42] ="sEffectSanctuary";
names[3] ="sEffectShield";
names[15] ="sEffectShockDamage";
names[46] ="sEffectSilence";
names[11] ="sEffectSlowFall";
names[58] ="sEffectSoultrap";
names[48] ="sEffectSound";
names[67] ="sEffectSpellAbsorption";
names[136] ="sEffectStuntedMagicka";
names[106] ="sEffectSummonAncestralGhost";
names[110] ="sEffectSummonBonelord";
names[108] ="sEffectSummonLeastBonewalker";
names[134] ="sEffectSummonCenturionSphere";
names[103] ="sEffectSummonClannfear";
names[104] ="sEffectSummonDaedroth";
names[105] ="sEffectSummonDremora";
names[114] ="sEffectSummonFlameAtronach";
names[115] ="sEffectSummonFrostAtronach";
names[113] ="sEffectSummonGoldenSaint";
names[109] ="sEffectSummonGreaterBonewalker";
names[112] ="sEffectSummonHunger";
names[102] ="sEffectSummonScamp";
names[107] ="sEffectSummonSkeletalMinion";
names[116] ="sEffectSummonStormAtronach";
names[111] ="sEffectSummonWingedTwilight";
names[135] ="sEffectSunDamage";
names[1] ="sEffectSwiftSwim";
names[59] ="sEffectTelekinesis";
names[101] ="sEffectTurnUndead";
names[133] ="sEffectVampirism";
names[0] ="sEffectWaterBreathing";
names[2] ="sEffectWaterWalking";
names[33] ="sEffectWeaknesstoBlightDisease";
names[32] ="sEffectWeaknesstoCommonDisease";
names[34] ="sEffectWeaknesstoCorprusDisease";
names[28] ="sEffectWeaknesstoFire";
names[29] ="sEffectWeaknesstoFrost";
names[31] ="sEffectWeaknesstoMagicka";
names[36] ="sEffectWeaknesstoNormalWeapons";
names[35] ="sEffectWeaknesstoPoison";
names[30] ="sEffectWeaknesstoShock";
// bloodmoon
names[138] ="sEffectSummonCreature01";
names[139] ="sEffectSummonCreature02";
names[140] ="sEffectSummonCreature03";
names[141] ="sEffectSummonCreature04";
names[142] ="sEffectSummonCreature05";
// tribunal
names[137] ="sEffectSummonFabricant";
assert(names.find(effectID) != names.end() && "Unimplemented effect type");
return names[effectID];
}
bool MWSpellEffect::effectHasDuration(const std::string& effect)
{
// lists effects that have no duration (e.g. open lock)
std::vector<std::string> effectsWithoutDuration;
effectsWithoutDuration.push_back("sEffectOpen");
effectsWithoutDuration.push_back("sEffectLock");
effectsWithoutDuration.push_back("sEffectDispel");
effectsWithoutDuration.push_back("sEffectSunDamage");
effectsWithoutDuration.push_back("sEffectCorpus");
effectsWithoutDuration.push_back("sEffectVampirism");
effectsWithoutDuration.push_back("sEffectMark");
effectsWithoutDuration.push_back("sEffectRecall");
effectsWithoutDuration.push_back("sEffectDivineIntervention");
effectsWithoutDuration.push_back("sEffectAlmsiviIntervention");
effectsWithoutDuration.push_back("sEffectCureCommonDisease");
effectsWithoutDuration.push_back("sEffectCureBlightDisease");
effectsWithoutDuration.push_back("sEffectCureCorprusDisease");
effectsWithoutDuration.push_back("sEffectCurePoison");
effectsWithoutDuration.push_back("sEffectCureParalyzation");
effectsWithoutDuration.push_back("sEffectRemoveCurse");
effectsWithoutDuration.push_back("sEffectRestoreAttribute");
return (std::find(effectsWithoutDuration.begin(), effectsWithoutDuration.end(), effect) == effectsWithoutDuration.end());
}
bool MWSpellEffect::effectHasMagnitude(const std::string& effect)
{
// lists effects that have no magnitude (e.g. invisiblity)
std::vector<std::string> effectsWithoutMagnitude;
effectsWithoutMagnitude.push_back("sEffectInvisibility");
effectsWithoutMagnitude.push_back("sEffectStuntedMagicka");
effectsWithoutMagnitude.push_back("sEffectParalyze");
effectsWithoutMagnitude.push_back("sEffectSoultrap");
effectsWithoutMagnitude.push_back("sEffectSilence");
effectsWithoutMagnitude.push_back("sEffectParalyze");
effectsWithoutMagnitude.push_back("sEffectInvisibility");
effectsWithoutMagnitude.push_back("sEffectWaterWalking");
effectsWithoutMagnitude.push_back("sEffectWaterBreathing");
effectsWithoutMagnitude.push_back("sEffectSummonScamp");
effectsWithoutMagnitude.push_back("sEffectSummonClannfear");
effectsWithoutMagnitude.push_back("sEffectSummonDaedroth");
effectsWithoutMagnitude.push_back("sEffectSummonDremora");
effectsWithoutMagnitude.push_back("sEffectSummonAncestralGhost");
effectsWithoutMagnitude.push_back("sEffectSummonSkeletalMinion");
effectsWithoutMagnitude.push_back("sEffectSummonBonewalker");
effectsWithoutMagnitude.push_back("sEffectSummonGreaterBonewalker");
effectsWithoutMagnitude.push_back("sEffectSummonBonelord");
effectsWithoutMagnitude.push_back("sEffectSummonWingedTwilight");
effectsWithoutMagnitude.push_back("sEffectSummonHunger");
effectsWithoutMagnitude.push_back("sEffectSummonGoldenSaint");
effectsWithoutMagnitude.push_back("sEffectSummonFlameAtronach");
effectsWithoutMagnitude.push_back("sEffectSummonFrostAtronach");
effectsWithoutMagnitude.push_back("sEffectSummonStormAtronach");
effectsWithoutMagnitude.push_back("sEffectSummonCenturionSphere");
effectsWithoutMagnitude.push_back("sEffectBoundDagger");
effectsWithoutMagnitude.push_back("sEffectBoundLongsword");
effectsWithoutMagnitude.push_back("sEffectBoundMace");
effectsWithoutMagnitude.push_back("sEffectBoundBattleAxe");
effectsWithoutMagnitude.push_back("sEffectBoundSpear");
effectsWithoutMagnitude.push_back("sEffectBoundLongbow");
effectsWithoutMagnitude.push_back("sEffectBoundCuirass");
effectsWithoutMagnitude.push_back("sEffectBoundHelm");
effectsWithoutMagnitude.push_back("sEffectBoundBoots");
effectsWithoutMagnitude.push_back("sEffectBoundShield");
effectsWithoutMagnitude.push_back("sEffectBoundGloves");
effectsWithoutMagnitude.push_back("sEffectStuntedMagicka");
effectsWithoutMagnitude.push_back("sEffectMark");
effectsWithoutMagnitude.push_back("sEffectRecall");
effectsWithoutMagnitude.push_back("sEffectDivineIntervention");
effectsWithoutMagnitude.push_back("sEffectAlmsiviIntervention");
effectsWithoutMagnitude.push_back("sEffectCureCommonDisease");
effectsWithoutMagnitude.push_back("sEffectCureBlightDisease");
effectsWithoutMagnitude.push_back("sEffectCureCorprusDisease");
effectsWithoutMagnitude.push_back("sEffectCurePoison");
effectsWithoutMagnitude.push_back("sEffectCureParalyzation");
effectsWithoutMagnitude.push_back("sEffectRemoveCurse");
effectsWithoutMagnitude.push_back("sEffectSummonCreature01");
effectsWithoutMagnitude.push_back("sEffectSummonCreature02");
effectsWithoutMagnitude.push_back("sEffectSummonCreature03");
effectsWithoutMagnitude.push_back("sEffectSummonCreature04");
effectsWithoutMagnitude.push_back("sEffectSummonCreature05");
effectsWithoutMagnitude.push_back("sEffectSummonFabricant");
return (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effect) == effectsWithoutMagnitude.end());
}
bool MWSpellEffect::effectInvolvesAttribute (const std::string& effect)
{
return (effect == "sEffectRestoreAttribute"
|| effect == "sEffectAbsorbAttribute"
|| effect == "sEffectDrainAttribute"
|| effect == "sEffectFortifyAttribute"
|| effect == "sEffectDamageAttribute");
}
static_cast<MyGUI::TextBox*>(mTextWidget)->setCaptionWithReplacing(spellLine);
mRequestedWidth = mTextWidget->getTextSize().width + 24;
bool MWSpellEffect::effectInvolvesSkill (const std::string& effect)
{
return (effect == "sEffectRestoreSkill"
|| effect == "sEffectAbsorbSkill"
|| effect == "sEffectDrainSkill"
|| effect == "sEffectFortifySkill"
|| effect == "sEffectDamageSkill");
std::string path = std::string("icons\\") + magicEffect->mIcon;
fixTexturePath(path);
mImageWidget->setImageTexture(path);
}
MWSpellEffect::~MWSpellEffect()

@ -32,6 +32,7 @@ namespace MWGui
, mRange(-1)
, mDuration(-1)
, mSkill(-1)
, mArea(0)
, mAttribute(-1)
, mEffectID(-1)
, mNoTarget(false)
@ -51,6 +52,9 @@ namespace MWGui
// value of -1 here means the value is unavailable
int mMagnMin, mMagnMax, mRange, mDuration;
// value of 0 -> no area effect
int mArea;
bool operator==(const SpellEffectParams& other) const
{
if (mEffectID != other.mEffectID)
@ -66,7 +70,7 @@ namespace MWGui
|| mEffectID == 21 // drain skill
|| mEffectID == 83 // fortify skill
|| mEffectID == 26); // damage skill
return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute);
return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute) && (other.mArea == mArea);
}
};
@ -249,12 +253,6 @@ namespace MWGui
void setWindowManager(MWBase::WindowManager* parWindowManager) { mWindowManager = parWindowManager; }
void setSpellEffect(const SpellEffectParams& params);
std::string effectIDToString(const short effectID);
bool effectHasMagnitude (const std::string& effect);
bool effectHasDuration (const std::string& effect);
bool effectInvolvesAttribute (const std::string& effect);
bool effectInvolvesSkill (const std::string& effect);
int getRequestedWidth() const { return mRequestedWidth; }
protected:

@ -38,6 +38,7 @@
#include "countdialog.hpp"
#include "tradewindow.hpp"
#include "spellbuyingwindow.hpp"
#include "travelwindow.hpp"
#include "settingswindow.hpp"
#include "confirmationdialog.hpp"
#include "alchemywindow.hpp"
@ -46,6 +47,9 @@
#include "loadingscreen.hpp"
#include "levelupdialog.hpp"
#include "waitdialog.hpp"
#include "spellcreationdialog.hpp"
#include "enchantingdialog.hpp"
#include "trainingwindow.hpp"
using namespace MWGui;
@ -67,6 +71,7 @@ WindowManager::WindowManager(
, mCountDialog(NULL)
, mTradeWindow(NULL)
, mSpellBuyingWindow(NULL)
, mTravelWindow(NULL)
, mSettingsWindow(NULL)
, mConfirmationDialog(NULL)
, mAlchemyWindow(NULL)
@ -75,6 +80,9 @@ WindowManager::WindowManager(
, mCharGen(NULL)
, mLevelupDialog(NULL)
, mWaitDialog(NULL)
, mSpellCreationDialog(NULL)
, mEnchantingDialog(NULL)
, mTrainingWindow(NULL)
, mPlayerClass()
, mPlayerName()
, mPlayerRaceId()
@ -141,6 +149,7 @@ WindowManager::WindowManager(
mInventoryWindow = new InventoryWindow(*this,mDragAndDrop);
mTradeWindow = new TradeWindow(*this);
mSpellBuyingWindow = new SpellBuyingWindow(*this);
mTravelWindow = new TravelWindow(*this);
mDialogueWindow = new DialogueWindow(*this);
mContainerWindow = new ContainerWindow(*this,mDragAndDrop);
mHud = new HUD(w,h, mShowFPSLevel, mDragAndDrop);
@ -155,6 +164,9 @@ WindowManager::WindowManager(
mQuickKeysMenu = new QuickKeysMenu(*this);
mLevelupDialog = new LevelupDialog(*this);
mWaitDialog = new WaitDialog(*this);
mSpellCreationDialog = new SpellCreationDialog(*this);
mEnchantingDialog = new EnchantingDialog(*this);
mTrainingWindow = new TrainingWindow(*this);
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this);
mLoadingScreen->onResChange (w,h);
@ -203,6 +215,7 @@ WindowManager::~WindowManager()
delete mScrollWindow;
delete mTradeWindow;
delete mSpellBuyingWindow;
delete mTravelWindow;
delete mSettingsWindow;
delete mConfirmationDialog;
delete mAlchemyWindow;
@ -210,6 +223,9 @@ WindowManager::~WindowManager()
delete mLoadingScreen;
delete mLevelupDialog;
delete mWaitDialog;
delete mSpellCreationDialog;
delete mEnchantingDialog;
delete mTrainingWindow;
cleanupGarbage();
@ -253,12 +269,16 @@ void WindowManager::updateVisible()
mBookWindow->setVisible(false);
mTradeWindow->setVisible(false);
mSpellBuyingWindow->setVisible(false);
mTravelWindow->setVisible(false);
mSettingsWindow->setVisible(false);
mAlchemyWindow->setVisible(false);
mSpellWindow->setVisible(false);
mQuickKeysMenu->setVisible(false);
mLevelupDialog->setVisible(false);
mWaitDialog->setVisible(false);
mSpellCreationDialog->setVisible(false);
mEnchantingDialog->setVisible(false);
mTrainingWindow->setVisible(false);
mHud->setVisible(true);
@ -359,6 +379,18 @@ void WindowManager::updateVisible()
case GM_SpellBuying:
mSpellBuyingWindow->setVisible(true);
break;
case GM_Travel:
mTravelWindow->setVisible(true);
break;
case GM_SpellCreation:
mSpellCreationDialog->setVisible(true);
break;
case GM_Enchanting:
mEnchantingDialog->setVisible(true);
break;
case GM_Training:
mTrainingWindow->setVisible(true);
break;
case GM_InterMessageBox:
break;
case GM_Journal:
@ -558,9 +590,14 @@ void WindowManager::onFrame (float frameDuration)
mHud->onFrame(frameDuration);
mTrainingWindow->onFrame (frameDuration);
mTrainingWindow->checkReferenceAvailable();
mDialogueWindow->checkReferenceAvailable();
mTradeWindow->checkReferenceAvailable();
mSpellBuyingWindow->checkReferenceAvailable();
mSpellCreationDialog->checkReferenceAvailable();
mEnchantingDialog->checkReferenceAvailable();
mContainerWindow->checkReferenceAvailable();
mConsole->checkReferenceAvailable();
}
@ -844,6 +881,7 @@ MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; }
MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; }
MWGui::TradeWindow* WindowManager::getTradeWindow() { return mTradeWindow; }
MWGui::SpellBuyingWindow* WindowManager::getSpellBuyingWindow() { return mSpellBuyingWindow; }
MWGui::TravelWindow* WindowManager::getTravelWindow() { return mTravelWindow; }
MWGui::SpellWindow* WindowManager::getSpellWindow() { return mSpellWindow; }
MWGui::Console* WindowManager::getConsole() { return mConsole; }
@ -965,3 +1003,18 @@ void WindowManager::addVisitedLocation(const std::string& name, int x, int y)
{
mMap->addVisitedLocation (name, x, y);
}
void WindowManager::startSpellMaking(MWWorld::Ptr actor)
{
mSpellCreationDialog->startSpellMaking (actor);
}
void WindowManager::startEnchanting (MWWorld::Ptr actor)
{
mEnchantingDialog->startEnchanting (actor);
}
void WindowManager::startTraining(MWWorld::Ptr actor)
{
mTrainingWindow->startTraining(actor);
}

@ -64,6 +64,9 @@ namespace MWGui
class LoadingScreen;
class LevelupDialog;
class WaitDialog;
class SpellCreationDialog;
class EnchantingDialog;
class TrainingWindow;
class WindowManager : public MWBase::WindowManager
{
@ -111,6 +114,7 @@ namespace MWGui
virtual MWGui::ConfirmationDialog* getConfirmationDialog();
virtual MWGui::TradeWindow* getTradeWindow();
virtual MWGui::SpellBuyingWindow* getSpellBuyingWindow();
virtual MWGui::TravelWindow* getTravelWindow();
virtual MWGui::SpellWindow* getSpellWindow();
virtual MWGui::Console* getConsole();
@ -211,6 +215,10 @@ namespace MWGui
virtual bool getPlayerSleeping();
virtual void wakeUpPlayer();
virtual void startSpellMaking(MWWorld::Ptr actor);
virtual void startEnchanting(MWWorld::Ptr actor);
virtual void startTraining(MWWorld::Ptr actor);
private:
OEngine::GUI::MyGUIManager *mGuiManager;
HUD *mHud;
@ -230,6 +238,7 @@ namespace MWGui
CountDialog* mCountDialog;
TradeWindow* mTradeWindow;
SpellBuyingWindow* mSpellBuyingWindow;
TravelWindow* mTravelWindow;
SettingsWindow* mSettingsWindow;
ConfirmationDialog* mConfirmationDialog;
AlchemyWindow* mAlchemyWindow;
@ -238,6 +247,9 @@ namespace MWGui
LoadingScreen* mLoadingScreen;
LevelupDialog* mLevelupDialog;
WaitDialog* mWaitDialog;
SpellCreationDialog* mSpellCreationDialog;
EnchantingDialog* mEnchantingDialog;
TrainingWindow* mTrainingWindow;
CharacterCreation* mCharGen;

@ -90,7 +90,7 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const
{
bool magnitude = !(flags & ESM::MagicEffect::NoMagnitude);
bool duration = !(flags & ESM::MagicEffect::NoDuration);
bool negative = flags & (ESM::MagicEffect::Negative | ESM::MagicEffect::Negative2);
bool negative = flags & (ESM::MagicEffect::Negative | ESM::MagicEffect::Harmful);
int tool = negative ? ESM::Apparatus::Retort : ESM::Apparatus::Albemic;

@ -8,7 +8,7 @@ namespace MWMechanics
{
DrawState_Weapon = 0,
DrawState_Spell = 1,
DrawState_Nothing = 2,
DrawState_Nothing = 2
};
}

@ -53,7 +53,7 @@ namespace MWRender
{
Ogre::Image image;
Ogre::uchar data[mWidth * mHeight * 3];
std::vector<Ogre::uchar> data (mWidth * mHeight * 3);
for (int x = mMinX; x <= mMaxX; ++x)
{
@ -150,7 +150,7 @@ namespace MWRender
}
}
image.loadDynamicImage (data, mWidth, mHeight, Ogre::PF_B8G8R8);
image.loadDynamicImage (&data[0], mWidth, mHeight, Ogre::PF_B8G8R8);
//image.save (mCacheDir + "/GlobalMap.png");

@ -180,6 +180,8 @@ RenderingManager::~RenderingManager ()
delete mOcclusionQuery;
delete mCompositors;
delete mWater;
delete mFactory;
}
MWRender::SkyManager* RenderingManager::getSkyManager()

@ -23,7 +23,7 @@ namespace Ogre
class Entity;
class Vector3;
struct RenderTargetEvent;
};
}
namespace MWRender {

@ -74,6 +74,6 @@ namespace MWScript
///< Return index of the variable of the given name and type in the given script. Will
/// throw an exception, if there is no such script or variable or the type does not match.
};
};
}
#endif

@ -54,6 +54,6 @@ namespace MWSound
#ifndef DEFAULT_DECODER
#define DEFAULT_DECODER (::MWSound::FFmpeg_Decoder)
#endif
};
}
#endif

@ -52,6 +52,6 @@ namespace MWSound
#ifndef DEFAULT_DECODER
#define DEFAULT_DECODER (::MWSound::MpgSnd_Decoder)
#endif
};
}
#endif

@ -66,6 +66,6 @@ namespace MWSound
#ifndef DEFAULT_OUTPUT
#define DEFAULT_OUTPUT (::MWSound::OpenAL_Output)
#endif
};
}
#endif

@ -26,7 +26,7 @@ namespace MWSound
enum Environment {
Env_Normal,
Env_Underwater,
Env_Underwater
};
class SoundManager : public MWBase::SoundManager

@ -18,8 +18,6 @@ namespace ESM
{
// These are probabilities
char mHello, mU1, mFight, mFlee, mAlarm, mU2, mU3, mU4;
// The last u's might be the skills that this NPC can train you
// in?
int mServices; // See the Services enum
}; // 12 bytes
@ -60,7 +58,7 @@ namespace ESM
AI_Travel = 0x545f4941,
AI_Follow = 0x465f4941,
AI_Escort = 0x455f4941,
AI_Activate = 0x415f4941,
AI_Activate = 0x415f4941
};
/// \note Used for storaging packages in a single container

@ -138,11 +138,11 @@ void ESMWriter::writeHNString(const std::string& name, const std::string& data)
void ESMWriter::writeHNString(const std::string& name, const std::string& data, int size)
{
assert(data.size() <= size);
assert(static_cast<int> (data.size()) <= size);
startSubRecord(name);
writeHString(data);
if (data.size() < size)
if (static_cast<int> (data.size()) < size)
{
for (int i = data.size(); i < size; ++i)
write("\0",1);

@ -1,5 +1,7 @@
#include "loadmgef.hpp"
#include <boost/lexical_cast.hpp>
#include "esmreader.hpp"
#include "esmwriter.hpp"
@ -79,4 +81,162 @@ void MagicEffect::save(ESMWriter &esm)
esm.writeHNOString("DESC", mDescription);
}
std::string MagicEffect::effectIdToString(short effectID)
{
// Map effect ID to GMST name
// http://www.uesp.net/morrow/hints/mweffects.shtml
std::map<short, std::string> names;
names[85] ="sEffectAbsorbAttribute";
names[88] ="sEffectAbsorbFatigue";
names[86] ="sEffectAbsorbHealth";
names[87] ="sEffectAbsorbSpellPoints";
names[89] ="sEffectAbsorbSkill";
names[63] ="sEffectAlmsiviIntervention";
names[47] ="sEffectBlind";
names[123] ="sEffectBoundBattleAxe";
names[129] ="sEffectBoundBoots";
names[127] ="sEffectBoundCuirass";
names[120] ="sEffectBoundDagger";
names[131] ="sEffectBoundGloves";
names[128] ="sEffectBoundHelm";
names[125] ="sEffectBoundLongbow";
names[121] ="sEffectBoundLongsword";
names[122] ="sEffectBoundMace";
names[130] ="sEffectBoundShield";
names[124] ="sEffectBoundSpear";
names[7] ="sEffectBurden";
names[50] ="sEffectCalmCreature";
names[49] ="sEffectCalmHumanoid";
names[40] ="sEffectChameleon";
names[44] ="sEffectCharm";
names[118] ="sEffectCommandCreatures";
names[119] ="sEffectCommandHumanoids";
names[132] ="sEffectCorpus"; // NB this typo. (bethesda made it)
names[70] ="sEffectCureBlightDisease";
names[69] ="sEffectCureCommonDisease";
names[71] ="sEffectCureCorprusDisease";
names[73] ="sEffectCureParalyzation";
names[72] ="sEffectCurePoison";
names[22] ="sEffectDamageAttribute";
names[25] ="sEffectDamageFatigue";
names[23] ="sEffectDamageHealth";
names[24] ="sEffectDamageMagicka";
names[26] ="sEffectDamageSkill";
names[54] ="sEffectDemoralizeCreature";
names[53] ="sEffectDemoralizeHumanoid";
names[64] ="sEffectDetectAnimal";
names[65] ="sEffectDetectEnchantment";
names[66] ="sEffectDetectKey";
names[38] ="sEffectDisintegrateArmor";
names[37] ="sEffectDisintegrateWeapon";
names[57] ="sEffectDispel";
names[62] ="sEffectDivineIntervention";
names[17] ="sEffectDrainAttribute";
names[20] ="sEffectDrainFatigue";
names[18] ="sEffectDrainHealth";
names[19] ="sEffectDrainSpellpoints";
names[21] ="sEffectDrainSkill";
names[8] ="sEffectFeather";
names[14] ="sEffectFireDamage";
names[4] ="sEffectFireShield";
names[117] ="sEffectFortifyAttackBonus";
names[79] ="sEffectFortifyAttribute";
names[82] ="sEffectFortifyFatigue";
names[80] ="sEffectFortifyHealth";
names[81] ="sEffectFortifySpellpoints";
names[84] ="sEffectFortifyMagickaMultiplier";
names[83] ="sEffectFortifySkill";
names[52] ="sEffectFrenzyCreature";
names[51] ="sEffectFrenzyHumanoid";
names[16] ="sEffectFrostDamage";
names[6] ="sEffectFrostShield";
names[39] ="sEffectInvisibility";
names[9] ="sEffectJump";
names[10] ="sEffectLevitate";
names[41] ="sEffectLight";
names[5] ="sEffectLightningShield";
names[12] ="sEffectLock";
names[60] ="sEffectMark";
names[43] ="sEffectNightEye";
names[13] ="sEffectOpen";
names[45] ="sEffectParalyze";
names[27] ="sEffectPoison";
names[56] ="sEffectRallyCreature";
names[55] ="sEffectRallyHumanoid";
names[61] ="sEffectRecall";
names[68] ="sEffectReflect";
names[100] ="sEffectRemoveCurse";
names[95] ="sEffectResistBlightDisease";
names[94] ="sEffectResistCommonDisease";
names[96] ="sEffectResistCorprusDisease";
names[90] ="sEffectResistFire";
names[91] ="sEffectResistFrost";
names[93] ="sEffectResistMagicka";
names[98] ="sEffectResistNormalWeapons";
names[99] ="sEffectResistParalysis";
names[97] ="sEffectResistPoison";
names[92] ="sEffectResistShock";
names[74] ="sEffectRestoreAttribute";
names[77] ="sEffectRestoreFatigue";
names[75] ="sEffectRestoreHealth";
names[76] ="sEffectRestoreSpellPoints";
names[78] ="sEffectRestoreSkill";
names[42] ="sEffectSanctuary";
names[3] ="sEffectShield";
names[15] ="sEffectShockDamage";
names[46] ="sEffectSilence";
names[11] ="sEffectSlowFall";
names[58] ="sEffectSoultrap";
names[48] ="sEffectSound";
names[67] ="sEffectSpellAbsorption";
names[136] ="sEffectStuntedMagicka";
names[106] ="sEffectSummonAncestralGhost";
names[110] ="sEffectSummonBonelord";
names[108] ="sEffectSummonLeastBonewalker";
names[134] ="sEffectSummonCenturionSphere";
names[103] ="sEffectSummonClannfear";
names[104] ="sEffectSummonDaedroth";
names[105] ="sEffectSummonDremora";
names[114] ="sEffectSummonFlameAtronach";
names[115] ="sEffectSummonFrostAtronach";
names[113] ="sEffectSummonGoldenSaint";
names[109] ="sEffectSummonGreaterBonewalker";
names[112] ="sEffectSummonHunger";
names[102] ="sEffectSummonScamp";
names[107] ="sEffectSummonSkeletalMinion";
names[116] ="sEffectSummonStormAtronach";
names[111] ="sEffectSummonWingedTwilight";
names[135] ="sEffectSunDamage";
names[1] ="sEffectSwiftSwim";
names[59] ="sEffectTelekinesis";
names[101] ="sEffectTurnUndead";
names[133] ="sEffectVampirism";
names[0] ="sEffectWaterBreathing";
names[2] ="sEffectWaterWalking";
names[33] ="sEffectWeaknesstoBlightDisease";
names[32] ="sEffectWeaknesstoCommonDisease";
names[34] ="sEffectWeaknesstoCorprusDisease";
names[28] ="sEffectWeaknesstoFire";
names[29] ="sEffectWeaknesstoFrost";
names[31] ="sEffectWeaknesstoMagicka";
names[36] ="sEffectWeaknesstoNormalWeapons";
names[35] ="sEffectWeaknesstoPoison";
names[30] ="sEffectWeaknesstoShock";
// bloodmoon
names[138] ="sEffectSummonCreature01";
names[139] ="sEffectSummonCreature02";
names[140] ="sEffectSummonCreature03";
names[141] ="sEffectSummonCreature04";
names[142] ="sEffectSummonCreature05";
// tribunal
names[137] ="sEffectSummonFabricant";
if (names.find(effectID) == names.end())
throw std::runtime_error( std::string("Unimplemented effect ID ") + boost::lexical_cast<std::string>(effectID));
return names[effectID];
}
}

@ -13,13 +13,23 @@ struct MagicEffect
{
enum Flags
{
NoDuration = 0x4,
NoMagnitude = 0x8,
Negative2 = 0x10,
TargetSkill = 0x1, // Affects a specific skill, which is specified elsewhere in the effect structure.
TargetAttribute = 0x2, // Affects a specific attribute, which is specified elsewhere in the effect structure.
NoDuration = 0x4, // Has no duration. Only runs effect once on cast.
NoMagnitude = 0x8, // Has no magnitude.
Harmful = 0x10, // Counts as a negative effect. Interpreted as useful for attack, and is treated as a bad effect in alchemy.
ContinuousVfx = 0x20, // The effect's hit particle VFX repeats for the full duration of the spell, rather than occuring once on hit.
CastSelf = 0x40, // Allows range - cast on self.
CastTouch = 0x80, // Allows range - cast on touch.
CastTarget = 0x100, // Allows range - cast on target.
UncappedDamage = 0x1000, // Negates multiple cap behaviours. Allows an effect to reduce an attribute below zero; removes the normal minimum effect duration of 1 second.
NonRecastable = 0x4000, // Does not land if parent spell is already affecting target. Shows "you cannot re-cast" message for self target.
Unreflectable = 0x10000, // Cannot be reflected, the effect always lands normally.
CasterLinked = 0x20000, // Must quench if caster is dead, or not an NPC/creature. Not allowed in containter/door trap spells.
SpellMaking = 0x0200,
Enchanting = 0x0400,
Negative = 0x0800 // A harmful effect. Will determine whether
// eg. NPCs regard this spell as an attack.
// eg. NPCs regard this spell as an attack. (same as 0x10?)
};
struct MEDTstruct
@ -32,6 +42,9 @@ struct MagicEffect
float mSpeed, mSize, mSizeCap;
}; // 36 bytes
static std::string effectIdToString(short effectID);
MEDTstruct mData;
std::string mIcon, mParticle; // Textures

@ -331,7 +331,7 @@ namespace ESMS
// Find land for the given coordinates. Return null if no mData.
Land *search(int x, int y) const
{
LandMap::const_iterator itr = lands.find(std::make_pair<int, int>(x, y));
LandMap::const_iterator itr = lands.find(std::make_pair (x, y));
if ( itr == lands.end() )
{
return NULL;
@ -350,7 +350,7 @@ namespace ESMS
land->load(esm);
// Store the structure
lands[std::make_pair<int, int>(land->mX, land->mY)] = land;
lands[std::make_pair (land->mX, land->mY)] = land;
}
};

@ -16,6 +16,7 @@ Alexander Olofsson (Ace)
Artem Kotsynyak (greye)
athile
BrotherBrick
Cory F. Cohen (cfcohen)
Cris Mihalache (Mirceam)
Douglas Diniz (Dgdiniz)
Eli2

2
extern/shiny vendored

@ -1 +1 @@
Subproject commit ffd078843c11586107024ccbc2493d0ec2df896c
Subproject commit f17c4ebab0e7a1f3bbb25fd9b3dbef2bd742536a

@ -256,7 +256,7 @@
#endif
#if FOG
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
float fogValue = shSaturate((length(cameraPos.xyz-worldPos) - fogParams.y) * fogParams.w);
#if UNDERWATER
// regular fog only if fragment is above water

@ -1,6 +1,5 @@
configuration water_reflection
{
fog false
shadows false
shadows_pssm false
mrt_output false

@ -332,7 +332,7 @@
#if FOG
float fogValue = shSaturate((depth - fogParams.y) * fogParams.w);
float fogValue = shSaturate((length(cameraPos.xyz-worldPos) - fogParams.y) * fogParams.w);
#if UNDERWATER
// regular fog only if fragment is above water

@ -298,7 +298,7 @@
}
else
{
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
float fogValue = shSaturate((length(cameraPos.xyz-position.xyz) - fogParams.y) * fogParams.w);
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColor), fogValue);
}

@ -75,6 +75,11 @@ set(MYGUI_FILES
openmw_levelup_dialog.layout
openmw_wait_dialog.layout
openmw_wait_dialog_progressbar.layout
openmw_spellcreation_dialog.layout
openmw_edit_effect.layout
openmw_enchanting_dialog.layout
openmw_trainingwindow.layout
openmw_travel_window.layout
smallbars.png
VeraMono.ttf
markers.png

@ -3,7 +3,7 @@
<MyGUI type="List">
<List file="core.skin" />
<List file="openmw_resources.xml" />
<List file="openmw.font.xml" />
<List file="openmw_font.xml"/>
<List file="openmw_text.skin.xml" />
<List file="openmw_windows.skin.xml" />
<List file="openmw_button.skin.xml" />

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 362 310" name="_Main">
<Widget type="ImageBox" skin="ImageBox" position="8 12 16 16" name="EffectImage">
</Widget>
<Widget type="TextBox" skin="NormalText" position="36 8 400 24" name="EffectName">
<Property key="TextAlign" value="Left HCenter"/>
</Widget>
<!-- Range -->
<Widget type="TextBox" skin="NormalText" position="8 36 400 24">
<Property key="Caption" value="#{sRange}"/>
<Property key="TextAlign" value="Left HCenter"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="130 36 0 24" name="RangeButton">
<Property key="Caption" value="#{sRangeTouch}"/>
</Widget>
<!-- Magnitude -->
<Widget type="Widget" position="8 80 400 70" name="MagnitudeBox">
<Widget type="TextBox" skin="NormalText" position="0 0 400 24">
<Property key="Caption" value="#{sMagnitude}"/>
<Property key="TextAlign" value="Left HCenter"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 0 210 20" name="MagnitudeMinValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="MagnitudeMinSlider">
<Property key="Range" value="100"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 32 210 20" name="MagnitudeMaxValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 52 210 13" name="MagnitudeMaxSlider">
<Property key="Range" value="100"/>
</Widget>
</Widget>
<!-- Duration -->
<Widget type="Widget" position="8 153 400 40" name="DurationBox">
<Widget type="TextBox" skin="NormalText" position="0 20 400 24">
<Property key="Caption" value="#{sDuration}"/>
<Property key="TextAlign" value="Left Top"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 0 210 20" name="DurationValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="DurationSlider">
<Property key="Range" value="1440"/>
</Widget>
</Widget>
<!-- Area -->
<Widget type="Widget" position="8 197 400 40" name="AreaBox">
<Widget type="TextBox" skin="NormalText" position="0 20 400 24" name="AreaText">
<Property key="Caption" value="#{sArea}"/>
<Property key="TextAlign" value="Left Top"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="122 0 210 20" name="AreaValue">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="AreaSlider">
<Property key="Range" value="51"/>
</Widget>
</Widget>
<Widget type="HBox" position="8 266 336 24">
<Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="DeleteButton">
<Property key="Caption" value="#{sDelete}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="OkButton">
<Property key="Caption" value="#{sOk}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 560 400" name="_Main">
<Widget type="HBox" position="12 12 250 30">
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sName}"/>
</Widget>
<Widget type="EditBox" skin="MW_TextEdit" position="0 0 30 30" name="NameEdit">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="Widget">
</Widget>
</Widget>
<!-- Item -->
<Widget type="HBox" position="12 48 400 59">
<Property key="Spacing" value="8"/>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sItem}"/>
</Widget>
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="ItemBox"/>
<Widget type="Widget" position="0 0 8 0"/>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sSoulGem}"/>
</Widget>
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="SoulBox"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="320 0 300 24">
<Property key="Caption" value="#{sEnchantmentMenu3}:"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 0 258 24" name="Enchantment">
<Property key="Caption" value="1"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="320 24 300 24">
<Property key="Caption" value="#{sCastCost}:"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 24 258 24" name="CastCost">
<Property key="Caption" value="39"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="320 48 300 24">
<Property key="Caption" value="#{sCharges}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 48 258 24" name="Charge">
<Property key="Caption" value="39"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<!-- Available effects -->
<Widget type="TextBox" skin="NormalText" position="12 148 300 24">
<Property key="Caption" value="#{sMagicEffects}"/>
</Widget>
<Widget type="MWList" skin="MW_SimpleList" position="12 176 202 169" name="AvailableEffects">
</Widget>
<!-- Used effects -->
<Widget type="TextBox" skin="NormalText" position="226 148 300 24">
<Property key="Caption" value="#{sEffects}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="226 176 316 169">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 308 161" name="UsedEffects">
<Property key="CanvasAlign" value="Left Top"/>
</Widget>
</Widget>
<Widget type="HBox" position="0 340 560 60">
<Property key="Padding" value="16"/>
<Widget type="Widget" position="0 0 0 0">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sBarterDialog7}"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="PriceLabel">
<Property key="Caption" value="30"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BuyButton">
<Property key="Caption" value="#{sBuy}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 560 400" name="_Main">
<Widget type="HBox" position="12 12 250 30">
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sName}"/>
</Widget>
<Widget type="EditBox" skin="MW_TextEdit" position="0 0 30 30" name="NameEdit">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="Widget">
</Widget>
</Widget>
<Widget type="TextBox" skin="NormalText" position="280 0 300 24">
<Property key="Caption" value="#{sEnchantmentMenu4}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 0 258 24" name="MagickaCost">
<Property key="Caption" value="1"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="280 24 300 24">
<Property key="Caption" value="#{sSpellmakingMenu1}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="280 24 258 24" name="SuccessChance">
<Property key="Caption" value="39"/>
<Property key="TextAlign" value="Right HCenter"/>
</Widget>
<!-- Available effects -->
<Widget type="TextBox" skin="NormalText" position="12 48 300 24">
<Property key="Caption" value="#{sMagicEffects}"/>
</Widget>
<Widget type="MWList" skin="MW_SimpleList" position="12 76 202 269" name="AvailableEffects">
</Widget>
<!-- Used effects -->
<Widget type="TextBox" skin="NormalText" position="226 48 300 24">
<Property key="Caption" value="#{sEffects}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="226 76 316 269">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 308 261" name="UsedEffects">
<Property key="CanvasAlign" value="Left Top"/>
</Widget>
</Widget>
<Widget type="HBox" position="0 340 560 60">
<Property key="Padding" value="16"/>
<Widget type="Widget" position="0 0 0 0">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sBarterDialog7}"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="PriceLabel">
<Property key="Caption" value="30"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BuyButton">
<Property key="Caption" value="#{sBuy}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -196,6 +196,31 @@
</Widget>
</Widget>
<!-- Magic effect tooltip -->
<Widget type="Widget" skin="HUD_Box_NoTransp" position="0 0 300 52" align="Stretch" name="MagicEffectToolTip">
<Property key="Visible" value="false"/>
<Widget type="ImageBox" skin="ImageBox" position="8 8 32 32" align="Left Top" name="MagicEffectImage"/>
<Widget type="TextBox" skin="NormalText" position="44 8 252 16" align="Left Top HStretch" name="MagicEffectName">
<Property key="TextAlign" value="Left"/>
<UserString key="AutoResizeHorizontal" value="true"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="44 24 252 16" align="Left Top HStretch" name="MagicEffectSchool">
<Property key="TextAlign" value="Left"/>
<UserString key="AutoResizeHorizontal" value="true"/>
</Widget>
<Widget type="EditBox" skin="SandText" position="8 44 284 0" align="Left Top Stretch" name="MagicEffectDescription">
<Property key="MultiLine" value="true"/>
<Property key="WordWrap" value="true"/>
<Property key="TextAlign" value="Left Top"/>
<UserString key="AutoResizeHorizontal" value="true"/>
<UserString key="AutoResizeVertical" value="true"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 319 200" name="_Main">
<Widget type="TextBox" skin="NormalText" position="0 5 319 24" name="Select" align="Right Top">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="#{sServiceTrainingTitle}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="5 30 319 24" name="Travel" align="Right Top">
<Property key="TextAlign" value="Left"/>
<Property key="Caption" value="#{sTrainingServiceTitle}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="6 54 299 100" align="Left Top" name="TrainingOptions">
</Widget>
<Widget type="TextBox" skin="SandText" position="8 161 200 24" name="PlayerGold" align="Right Top">
<Property key="TextAlign" value="Left"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="244 161 60 24" name="CancelButton" align="Right Top">
<Property key="ExpandDirection" value="Left"/>
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</MyGUI>

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 450 300" name="_Main">
<Property key="Visible" value="false"/>
<Widget type="TextBox" skin="SandText" position="8 10 24 24" name="Select" align="Right Top">
<Property key="TextAlign" value="Right"/>
<Property key="Caption" value="#{sTravelServiceTitle}"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="0 0 24 24" name="Travel" align="Right Top">
<Property key="TextAlign" value="Right"/>
<Property key="Caption" value="#D8C09A#{sTravel}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="6 31 430 225" align="ALIGN_LEFT ALIGN_STRETCH">
<Widget type="ScrollView" skin="MW_ScrollView" position="4 4 422 217" align="ALIGN_LEFT ALIGN_TOP ALIGN_STRETCH" name="DestinationsView">
<Property key="CanvasAlign" value="Left"/>
</Widget>
</Widget>
<Widget type="TextBox" skin="SandText" position="8 255 24 24" name="PlayerGold" align="Right Top">
<Property key="TextAlign" value="Right"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="375 260 60 24" name="CancelButton" align="Right Top">
<Property key="ExpandDirection" value="Left"/>
<Property key="Caption" value="#{sOK}"/>
</Widget>
</Widget>
</MyGUI>

@ -1,5 +1,4 @@
[Desktop Entry]
Version=${OPENMW_VERSION}
Type=Application
Name=OpenMW Launcher
GenericName=Role Playing Game

@ -16,7 +16,7 @@ namespace Physic
pEng = eng;
tr.setIdentity();
pName = name;
};
}
void CMotionState::getWorldTransform(btTransform &worldTrans) const
{

@ -626,4 +626,4 @@ namespace Physic
shape->Shape->getAabb(trans, min, max);
}
}};
}}

@ -40,7 +40,7 @@ Fader::Fader(Ogre::SceneManager* sceneMgr)
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(mRectangle);
mRectangle->setVisible(false);
mRectangle->setVisibilityFlags (0x01);
mRectangle->setVisibilityFlags (2048);
}
Fader::~Fader()

Loading…
Cancel
Save