1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 20:23:51 +00:00

Merge branch 'master' into tables

This commit is contained in:
Marc Zinnschlag 2014-10-02 15:49:36 +02:00
commit f4c9897bbd
215 changed files with 2879 additions and 3158 deletions

View file

@ -607,8 +607,8 @@ if (WIN32)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(SolutionDir)$(Configuration)\" ) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(SolutionDir)$(Configuration)" )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)\" ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)" )
endforeach( OUTPUTCONFIG ) endforeach( OUTPUTCONFIG )
if (USE_DEBUG_CONSOLE) if (USE_DEBUG_CONSOLE)

View file

@ -18,6 +18,8 @@
std::string bodyPartLabel(int idx) std::string bodyPartLabel(int idx)
{ {
if (idx >= 0 && idx <= 26)
{
const char *bodyPartLabels[] = { const char *bodyPartLabels[] = {
"Head", "Head",
"Hair", "Hair",
@ -47,15 +49,16 @@ std::string bodyPartLabel(int idx)
"Weapon", "Weapon",
"Tail" "Tail"
}; };
if (idx >= 0 && idx <= 26)
return bodyPartLabels[idx]; return bodyPartLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string meshPartLabel(int idx) std::string meshPartLabel(int idx)
{ {
if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail)
{
const char *meshPartLabels[] = { const char *meshPartLabels[] = {
"Head", "Head",
"Hair", "Hair",
@ -73,29 +76,31 @@ std::string meshPartLabel(int idx)
"Clavicle", "Clavicle",
"Tail" "Tail"
}; };
if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail)
return meshPartLabels[idx]; return meshPartLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string meshTypeLabel(int idx) std::string meshTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor)
{
const char *meshTypeLabels[] = { const char *meshTypeLabels[] = {
"Skin", "Skin",
"Clothing", "Clothing",
"Armor" "Armor"
}; };
if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor)
return meshTypeLabels[idx]; return meshTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string clothingTypeLabel(int idx) std::string clothingTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 9)
{
const char *clothingTypeLabels[] = { const char *clothingTypeLabels[] = {
"Pants", "Pants",
"Shoes", "Shoes",
@ -108,15 +113,16 @@ std::string clothingTypeLabel(int idx)
"Ring", "Ring",
"Amulet" "Amulet"
}; };
if (idx >= 0 && idx <= 9)
return clothingTypeLabels[idx]; return clothingTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string armorTypeLabel(int idx) std::string armorTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 10)
{
const char *armorTypeLabels[] = { const char *armorTypeLabels[] = {
"Helmet", "Helmet",
"Cuirass", "Cuirass",
@ -130,15 +136,16 @@ std::string armorTypeLabel(int idx)
"Left Bracer", "Left Bracer",
"Right Bracer" "Right Bracer"
}; };
if (idx >= 0 && idx <= 10)
return armorTypeLabels[idx]; return armorTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string dialogTypeLabel(int idx) std::string dialogTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 4)
{
const char *dialogTypeLabels[] = { const char *dialogTypeLabels[] = {
"Topic", "Topic",
"Voice", "Voice",
@ -146,9 +153,8 @@ std::string dialogTypeLabel(int idx)
"Persuasion", "Persuasion",
"Journal" "Journal"
}; };
if (idx >= 0 && idx <= 4)
return dialogTypeLabels[idx]; return dialogTypeLabels[idx];
}
else if (idx == -1) else if (idx == -1)
return "Deleted"; return "Deleted";
else else
@ -157,6 +163,8 @@ std::string dialogTypeLabel(int idx)
std::string questStatusLabel(int idx) std::string questStatusLabel(int idx)
{ {
if (idx >= 0 && idx <= 4)
{
const char *questStatusLabels[] = { const char *questStatusLabels[] = {
"None", "None",
"Name", "Name",
@ -164,30 +172,32 @@ std::string questStatusLabel(int idx)
"Restart", "Restart",
"Deleted" "Deleted"
}; };
if (idx >= 0 && idx <= 4)
return questStatusLabels[idx]; return questStatusLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string creatureTypeLabel(int idx) std::string creatureTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 3)
{
const char *creatureTypeLabels[] = { const char *creatureTypeLabels[] = {
"Creature", "Creature",
"Daedra", "Daedra",
"Undead", "Undead",
"Humanoid", "Humanoid",
}; };
if (idx >= 0 && idx <= 3)
return creatureTypeLabels[idx]; return creatureTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string soundTypeLabel(int idx) std::string soundTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 7)
{
const char *soundTypeLabels[] = { const char *soundTypeLabels[] = {
"Left Foot", "Left Foot",
"Right Foot", "Right Foot",
@ -198,15 +208,16 @@ std::string soundTypeLabel(int idx)
"Scream", "Scream",
"Land" "Land"
}; };
if (idx >= 0 && idx <= 7)
return soundTypeLabels[idx]; return soundTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string weaponTypeLabel(int idx) std::string weaponTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 13)
{
const char *weaponTypeLabels[] = { const char *weaponTypeLabels[] = {
"Short Blade One Hand", "Short Blade One Hand",
"Long Blade One Hand", "Long Blade One Hand",
@ -223,9 +234,8 @@ std::string weaponTypeLabel(int idx)
"Arrow", "Arrow",
"Bolt" "Bolt"
}; };
if (idx >= 0 && idx <= 13)
return weaponTypeLabels[idx]; return weaponTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
@ -242,6 +252,8 @@ std::string aiTypeLabel(int type)
std::string magicEffectLabel(int idx) std::string magicEffectLabel(int idx)
{ {
if (idx >= 0 && idx <= 142)
{
const char* magicEffectLabels [] = { const char* magicEffectLabels [] = {
"Water Breathing", "Water Breathing",
"Swift Swim", "Swift Swim",
@ -387,14 +399,16 @@ std::string magicEffectLabel(int idx)
"sEffectSummonCreature04", "sEffectSummonCreature04",
"sEffectSummonCreature05" "sEffectSummonCreature05"
}; };
if (idx >= 0 && idx <= 142)
return magicEffectLabels[idx]; return magicEffectLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string attributeLabel(int idx) std::string attributeLabel(int idx)
{ {
if (idx >= 0 && idx <= 7)
{
const char* attributeLabels [] = { const char* attributeLabels [] = {
"Strength", "Strength",
"Intelligence", "Intelligence",
@ -405,14 +419,16 @@ std::string attributeLabel(int idx)
"Personality", "Personality",
"Luck" "Luck"
}; };
if (idx >= 0 && idx <= 7)
return attributeLabels[idx]; return attributeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string spellTypeLabel(int idx) std::string spellTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 5)
{
const char* spellTypeLabels [] = { const char* spellTypeLabels [] = {
"Spells", "Spells",
"Abilities", "Abilities",
@ -421,27 +437,31 @@ std::string spellTypeLabel(int idx)
"Curse", "Curse",
"Powers" "Powers"
}; };
if (idx >= 0 && idx <= 5)
return spellTypeLabels[idx]; return spellTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string specializationLabel(int idx) std::string specializationLabel(int idx)
{ {
if (idx >= 0 && idx <= 2)
{
const char* specializationLabels [] = { const char* specializationLabels [] = {
"Combat", "Combat",
"Magic", "Magic",
"Stealth" "Stealth"
}; };
if (idx >= 0 && idx <= 2)
return specializationLabels[idx]; return specializationLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string skillLabel(int idx) std::string skillLabel(int idx)
{ {
if (idx >= 0 && idx <= 26)
{
const char* skillLabels [] = { const char* skillLabels [] = {
"Block", "Block",
"Armorer", "Armorer",
@ -471,41 +491,47 @@ std::string skillLabel(int idx)
"Speechcraft", "Speechcraft",
"Hand-to-hand" "Hand-to-hand"
}; };
if (idx >= 0 && idx <= 26)
return skillLabels[idx]; return skillLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string apparatusTypeLabel(int idx) std::string apparatusTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 3)
{
const char* apparatusTypeLabels [] = { const char* apparatusTypeLabels [] = {
"Mortar", "Mortar",
"Alembic", "Alembic",
"Calcinator", "Calcinator",
"Retort", "Retort",
}; };
if (idx >= 0 && idx <= 3)
return apparatusTypeLabels[idx]; return apparatusTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string rangeTypeLabel(int idx) std::string rangeTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 2)
{
const char* rangeTypeLabels [] = { const char* rangeTypeLabels [] = {
"Self", "Self",
"Touch", "Touch",
"Target" "Target"
}; };
if (idx >= 0 && idx <= 2)
return rangeTypeLabels[idx]; return rangeTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string schoolLabel(int idx) std::string schoolLabel(int idx)
{ {
if (idx >= 0 && idx <= 5)
{
const char* schoolLabels [] = { const char* schoolLabels [] = {
"Alteration", "Alteration",
"Conjuration", "Conjuration",
@ -514,28 +540,32 @@ std::string schoolLabel(int idx)
"Mysticism", "Mysticism",
"Restoration" "Restoration"
}; };
if (idx >= 0 && idx <= 5)
return schoolLabels[idx]; return schoolLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string enchantTypeLabel(int idx) std::string enchantTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 3)
{
const char* enchantTypeLabels [] = { const char* enchantTypeLabels [] = {
"Cast Once", "Cast Once",
"Cast When Strikes", "Cast When Strikes",
"Cast When Used", "Cast When Used",
"Constant Effect" "Constant Effect"
}; };
if (idx >= 0 && idx <= 3)
return enchantTypeLabels[idx]; return enchantTypeLabels[idx];
}
else else
return "Invalid"; return "Invalid";
} }
std::string ruleFunction(int idx) std::string ruleFunction(int idx)
{ {
if (idx >= 0 && idx <= 72)
{
std::string ruleFunctions[] = { std::string ruleFunctions[] = {
"Reaction Low", "Reaction Low",
"Reaction High", "Reaction High",
@ -611,8 +641,8 @@ std::string ruleFunction(int idx)
"Should Attack", "Should Attack",
"Werewolf" "Werewolf"
}; };
if (idx >= 0 && idx <= 72)
return ruleFunctions[idx]; return ruleFunctions[idx];
}
else else
return "Invalid"; return "Invalid";
} }

View file

@ -412,7 +412,7 @@ void Record<ESM::Armor>::print()
std::cout << " Armor: " << mData.mData.mArmor << std::endl; std::cout << " Armor: " << mData.mData.mArmor << std::endl;
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
std::vector<ESM::PartReference>::iterator pit; std::vector<ESM::PartReference>::iterator pit;
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit)
{ {
std::cout << " Body Part: " << bodyPartLabel(pit->mPart) std::cout << " Body Part: " << bodyPartLabel(pit->mPart)
<< " (" << (int)(pit->mPart) << ")" << std::endl; << " (" << (int)(pit->mPart) << ")" << std::endl;
@ -484,7 +484,7 @@ void Record<ESM::BirthSign>::print()
std::cout << " Texture: " << mData.mTexture << std::endl; std::cout << " Texture: " << mData.mTexture << std::endl;
std::cout << " Description: " << mData.mDescription << std::endl; std::cout << " Description: " << mData.mDescription << std::endl;
std::vector<std::string>::iterator pit; std::vector<std::string>::iterator pit;
for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); pit++) for (pit = mData.mPowers.mList.begin(); pit != mData.mPowers.mList.end(); ++pit)
std::cout << " Power: " << *pit << std::endl; std::cout << " Power: " << *pit << std::endl;
} }
@ -554,7 +554,7 @@ void Record<ESM::Clothing>::print()
std::cout << " Value: " << mData.mData.mValue << std::endl; std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl;
std::vector<ESM::PartReference>::iterator pit; std::vector<ESM::PartReference>::iterator pit;
for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); pit++) for (pit = mData.mParts.mParts.begin(); pit != mData.mParts.mParts.end(); ++pit)
{ {
std::cout << " Body Part: " << bodyPartLabel(pit->mPart) std::cout << " Body Part: " << bodyPartLabel(pit->mPart)
<< " (" << (int)(pit->mPart) << ")" << std::endl; << " (" << (int)(pit->mPart) << ")" << std::endl;
@ -574,7 +574,7 @@ void Record<ESM::Container>::print()
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
std::cout << " Weight: " << mData.mWeight << std::endl; std::cout << " Weight: " << mData.mWeight << std::endl;
std::vector<ESM::ContItem>::iterator cit; std::vector<ESM::ContItem>::iterator cit;
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
<< " Item: " << cit->mItem.toString() << std::endl; << " Item: " << cit->mItem.toString() << std::endl;
} }
@ -619,12 +619,12 @@ void Record<ESM::Creature>::print()
std::cout << " Gold: " << mData.mData.mGold << std::endl; std::cout << " Gold: " << mData.mData.mGold << std::endl;
std::vector<ESM::ContItem>::iterator cit; std::vector<ESM::ContItem>::iterator cit;
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
<< " Item: " << cit->mItem.toString() << std::endl; << " Item: " << cit->mItem.toString() << std::endl;
std::vector<std::string>::iterator sit; std::vector<std::string>::iterator sit;
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
std::cout << " Spell: " << *sit << std::endl; std::cout << " Spell: " << *sit << std::endl;
std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl; std::cout << " Artifical Intelligence: " << mData.mHasAI << std::endl;
@ -639,7 +639,7 @@ void Record<ESM::Creature>::print()
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
std::vector<ESM::AIPackage>::iterator pit; std::vector<ESM::AIPackage>::iterator pit;
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
printAIPackage(*pit); printAIPackage(*pit);
} }
@ -706,7 +706,7 @@ void Record<ESM::Faction>::print()
<< mData.mData.mRankData[i].mFactReaction << std::endl; << mData.mData.mRankData[i].mFactReaction << std::endl;
} }
std::map<std::string, int>::iterator rit; std::map<std::string, int>::iterator rit;
for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); rit++) for (rit = mData.mReactions.begin(); rit != mData.mReactions.end(); ++rit)
std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl; std::cout << " Reaction: " << rit->second << " = " << rit->first << std::endl;
} }
@ -763,7 +763,7 @@ void Record<ESM::DialInfo>::print()
std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl;
std::vector<ESM::DialInfo::SelectStruct>::iterator sit; std::vector<ESM::DialInfo::SelectStruct>::iterator sit;
for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); sit++) for (sit = mData.mSelects.begin(); sit != mData.mSelects.end(); ++sit)
std::cout << " Select Rule: " << ruleString(*sit) << std::endl; std::cout << " Select Rule: " << ruleString(*sit) << std::endl;
if (mData.mResultScript != "") if (mData.mResultScript != "")
@ -835,7 +835,7 @@ void Record<ESM::CreatureLevList>::print()
std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl;
std::cout << " Number of items: " << mData.mList.size() << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl;
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit; std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
std::cout << " Creature: Level: " << iit->mLevel std::cout << " Creature: Level: " << iit->mLevel
<< " Creature: " << iit->mId << std::endl; << " Creature: " << iit->mId << std::endl;
} }
@ -847,7 +847,7 @@ void Record<ESM::ItemLevList>::print()
std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl;
std::cout << " Number of items: " << mData.mList.size() << std::endl; std::cout << " Number of items: " << mData.mList.size() << std::endl;
std::vector<ESM::LeveledListBase::LevelItem>::iterator iit; std::vector<ESM::LeveledListBase::LevelItem>::iterator iit;
for (iit = mData.mList.begin(); iit != mData.mList.end(); iit++) for (iit = mData.mList.begin(); iit != mData.mList.end(); ++iit)
std::cout << " Inventory: Level: " << iit->mLevel std::cout << " Inventory: Level: " << iit->mLevel
<< " Item: " << iit->mId << std::endl; << " Item: " << iit->mId << std::endl;
} }
@ -1031,16 +1031,16 @@ void Record<ESM::NPC>::print()
} }
std::vector<ESM::ContItem>::iterator cit; std::vector<ESM::ContItem>::iterator cit;
for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); cit++) for (cit = mData.mInventory.mList.begin(); cit != mData.mInventory.mList.end(); ++cit)
std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount std::cout << " Inventory: Count: " << boost::format("%4d") % cit->mCount
<< " Item: " << cit->mItem.toString() << std::endl; << " Item: " << cit->mItem.toString() << std::endl;
std::vector<std::string>::iterator sit; std::vector<std::string>::iterator sit;
for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); sit++) for (sit = mData.mSpells.mList.begin(); sit != mData.mSpells.mList.end(); ++sit)
std::cout << " Spell: " << *sit << std::endl; std::cout << " Spell: " << *sit << std::endl;
std::vector<ESM::NPC::Dest>::iterator dit; std::vector<ESM::NPC::Dest>::iterator dit;
for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); dit++) for (dit = mData.mTransport.begin(); dit != mData.mTransport.end(); ++dit)
{ {
std::cout << " Destination Position: " std::cout << " Destination Position: "
<< boost::format("%12.3f") % dit->mPos.pos[0] << "," << boost::format("%12.3f") % dit->mPos.pos[0] << ","
@ -1066,7 +1066,7 @@ void Record<ESM::NPC>::print()
std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl; std::cout << " AI Services:" << boost::format("0x%08X") % mData.mAiData.mServices << std::endl;
std::vector<ESM::AIPackage>::iterator pit; std::vector<ESM::AIPackage>::iterator pit;
for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); pit++) for (pit = mData.mAiPackage.mList.begin(); pit != mData.mAiPackage.mList.end(); ++pit)
printAIPackage(*pit); printAIPackage(*pit);
} }
@ -1140,7 +1140,7 @@ void Record<ESM::Race>::print()
<< mData.mData.mBonus[i].mBonus << std::endl; << mData.mData.mBonus[i].mBonus << std::endl;
std::vector<std::string>::iterator sit; std::vector<std::string>::iterator sit;
for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); sit++) for (sit = mData.mPowers.mList.begin(); sit != mData.mPowers.mList.end(); ++sit)
std::cout << " Power: " << *sit << std::endl; std::cout << " Power: " << *sit << std::endl;
} }
@ -1164,7 +1164,7 @@ void Record<ESM::Region>::print()
if (mData.mSleepList != "") if (mData.mSleepList != "")
std::cout << " Sleep List: " << mData.mSleepList << std::endl; std::cout << " Sleep List: " << mData.mSleepList << std::endl;
std::vector<ESM::Region::SoundRef>::iterator sit; std::vector<ESM::Region::SoundRef>::iterator sit;
for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); sit++) for (sit = mData.mSoundList.begin(); sit != mData.mSoundList.end(); ++sit)
std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl; std::cout << " Sound: " << (int)sit->mChance << " = " << sit->mSound.toString() << std::endl;
} }
@ -1181,12 +1181,12 @@ void Record<ESM::Script>::print()
std::vector<std::string>::iterator vit; std::vector<std::string>::iterator vit;
for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); vit++) for (vit = mData.mVarNames.begin(); vit != mData.mVarNames.end(); ++vit)
std::cout << " Variable: " << *vit << std::endl; std::cout << " Variable: " << *vit << std::endl;
std::cout << " ByteCode: "; std::cout << " ByteCode: ";
std::vector<unsigned char>::iterator cit; std::vector<unsigned char>::iterator cit;
for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); cit++) for (cit = mData.mScriptData.begin(); cit != mData.mScriptData.end(); ++cit)
std::cout << boost::format("%02X") % (int)(*cit); std::cout << boost::format("%02X") % (int)(*cit);
std::cout << std::endl; std::cout << std::endl;

View file

@ -15,6 +15,7 @@ namespace bfs = boost::filesystem;
MwIniImporter::MwIniImporter() MwIniImporter::MwIniImporter()
: mVerbose(false) : mVerbose(false)
, mEncoding(ToUTF8::WINDOWS_1250)
{ {
const char *map[][2] = const char *map[][2] =
{ {
@ -709,8 +710,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filenam
continue; continue;
} }
multistrmap::iterator it; if(map.find(key) == map.end()) {
if((it = map.find(key)) == map.end()) {
map.insert( std::make_pair (key, std::vector<std::string>() ) ); map.insert( std::make_pair (key, std::vector<std::string>() ) );
} }
map[key].push_back(value); map[key].push_back(value);
@ -746,8 +746,7 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filenam
std::string key(line.substr(0,pos)); std::string key(line.substr(0,pos));
std::string value(line.substr(pos+1)); std::string value(line.substr(pos+1));
multistrmap::iterator it; if(map.find(key) == map.end()) {
if((it = map.find(key)) == map.end()) {
map.insert( std::make_pair (key, std::vector<std::string>() ) ); map.insert( std::make_pair (key, std::vector<std::string>() ) );
} }
map[key].push_back(value); map[key].push_back(value);

View file

@ -37,6 +37,8 @@ public:
char **get() const { return const_cast<char **>(argv); } char **get() const { return const_cast<char **>(argv); }
private: private:
utf8argv(const utf8argv&);
utf8argv& operator=(const utf8argv&);
const char **argv; const char **argv;
std::vector<std::string> args; std::vector<std::string> args;

View file

@ -103,11 +103,6 @@ namespace CSMDoc
if (state==CSMWorld::RecordBase::State_Modified || if (state==CSMWorld::RecordBase::State_Modified ||
state==CSMWorld::RecordBase::State_ModifiedOnly) state==CSMWorld::RecordBase::State_ModifiedOnly)
{ {
std::string type;
for (int i=0; i<4; ++i)
/// \todo make endianess agnostic (change ESMWriter interface?)
type += reinterpret_cast<const char *> (&mCollection.getRecord (stage).mModified.sRecordId)[i];
mState.getWriter().startRecord (mCollection.getRecord (stage).mModified.sRecordId); mState.getWriter().startRecord (mCollection.getRecord (stage).mModified.sRecordId);
mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage)); mState.getWriter().writeHNCString ("NAME", mCollection.getId (stage));
mCollection.getRecord (stage).mModified.save (mState.getWriter()); mCollection.getRecord (stage).mModified.save (mState.getWriter());

View file

@ -71,6 +71,14 @@ namespace CSMWorld
record.load (reader); record.load (reader);
if (index==-1)
{
std::string newId = IdAccessorT().getId(record);
int newIndex = this->searchId(newId);
if (newIndex != -1 && id != newId)
index = newIndex;
}
load (record, base, index); load (record, base, index);
} }
} }

View file

@ -6,18 +6,20 @@
void CSMWorld::ResourcesManager::addResources (const Resources& resources) void CSMWorld::ResourcesManager::addResources (const Resources& resources)
{ {
mResources.insert (std::make_pair (resources.getType(), resources)); mResources.insert (std::make_pair (resources.getType(), resources));
mResources.insert (std::make_pair (UniversalId::getParentType (resources.getType()),
resources));
} }
void CSMWorld::ResourcesManager::listResources() void CSMWorld::ResourcesManager::listResources()
{ {
static const char * const sMeshTypes[] = { "nif", 0 }; static const char * const sMeshTypes[] = { "nif", 0 };
addResources (Resources ("meshes", UniversalId::Type_Meshes, sMeshTypes)); addResources (Resources ("meshes", UniversalId::Type_Mesh, sMeshTypes));
addResources (Resources ("icons", UniversalId::Type_Icons)); addResources (Resources ("icons", UniversalId::Type_Icon));
addResources (Resources ("music", UniversalId::Type_Musics)); addResources (Resources ("music", UniversalId::Type_Music));
addResources (Resources ("sound", UniversalId::Type_SoundsRes)); addResources (Resources ("sound", UniversalId::Type_SoundRes));
addResources (Resources ("textures", UniversalId::Type_Textures)); addResources (Resources ("textures", UniversalId::Type_Texture));
addResources (Resources ("videos", UniversalId::Type_Videos)); addResources (Resources ("videos", UniversalId::Type_Video));
} }
const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const

View file

@ -11,6 +11,11 @@ float CSVRender::Navigation::getFactor (bool mouse) const
return factor; return factor;
} }
CSVRender::Navigation::Navigation()
: mFastModeFactor(1)
{
}
CSVRender::Navigation::~Navigation() {} CSVRender::Navigation::~Navigation() {}
void CSVRender::Navigation::setFastModeFactor (float factor) void CSVRender::Navigation::setFastModeFactor (float factor)

View file

@ -20,6 +20,7 @@ namespace CSVRender
public: public:
Navigation();
virtual ~Navigation(); virtual ~Navigation();
void setFastModeFactor (float factor); void setFastModeFactor (float factor);

View file

@ -361,11 +361,6 @@ namespace CSVRender
} }
} }
int SceneWidget::getFastFactor() const
{
return mFast ? mFastFactor : 1;
}
void SceneWidget::setLighting (Lighting *lighting) void SceneWidget::setLighting (Lighting *lighting)
{ {
if (mLighting) if (mLighting)

View file

@ -80,8 +80,6 @@ namespace CSVRender
void updateOgreWindow(); void updateOgreWindow();
int getFastFactor() const;
void setLighting (Lighting *lighting); void setLighting (Lighting *lighting);
///< \attention The ownership of \a lighting is not transferred to *this. ///< \attention The ownership of \a lighting is not transferred to *this.

View file

@ -38,7 +38,7 @@ void CSVWorld::DataDisplayDelegate::buildPixmaps ()
} }
} }
void CSVWorld::DataDisplayDelegate::setIconSize(const QSize size) void CSVWorld::DataDisplayDelegate::setIconSize(const QSize& size)
{ {
mIconSize = size; mIconSize = size;
buildPixmaps(); buildPixmaps();

View file

@ -50,7 +50,7 @@ namespace CSVWorld
virtual void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; virtual void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
/// pass a QSize defining height / width of icon. Default is QSize (16,16). /// pass a QSize defining height / width of icon. Default is QSize (16,16).
void setIconSize (const QSize icon); void setIconSize (const QSize& icon);
/// offset the horizontal position of the icon from the left edge of the cell. Default is 3 pixels. /// offset the horizontal position of the icon from the left edge of the cell. Default is 3 pixels.
void setIconLeftOffset (int offset); void setIconLeftOffset (int offset);

View file

@ -32,7 +32,7 @@ add_openmw_dir (mwinput
add_openmw_dir (mwgui add_openmw_dir (mwgui
textinput widgets race class birth review windowmanagerimp console dialogue textinput widgets race class birth review windowmanagerimp console dialogue
windowbase statswindow messagebox journalwindow charactercreation windowbase statswindow messagebox journalwindow charactercreation
mapwindow windowpinnablebase tooltips scrollwindow bookwindow list mapwindow windowpinnablebase tooltips scrollwindow bookwindow
formatting inventorywindow container hud countdialog tradewindow settingswindow formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
@ -40,7 +40,7 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
recharge mode videowidget backgroundimage itemwidget screenfader recharge mode videowidget backgroundimage itemwidget screenfader debugwindow
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

View file

@ -127,7 +127,6 @@ static int (*cc_user_info)(char*, char*);
static void gdb_info(pid_t pid) static void gdb_info(pid_t pid)
{ {
char respfile[64]; char respfile[64];
char cmd_buf[128];
FILE *f; FILE *f;
int fd; int fd;
@ -156,6 +155,7 @@ static void gdb_info(pid_t pid)
fclose(f); fclose(f);
/* Run gdb and print process info. */ /* Run gdb and print process info. */
char cmd_buf[128];
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile); snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
printf("Executing: %s\n", cmd_buf); printf("Executing: %s\n", cmd_buf);
fflush(stdout); fflush(stdout);

View file

@ -62,7 +62,6 @@ void validate(boost::any &v, std::vector<std::string> const &tokens, FallbackMap
FallbackMap *map = boost::any_cast<FallbackMap>(&v); FallbackMap *map = boost::any_cast<FallbackMap>(&v);
std::map<std::string,std::string>::iterator mapIt;
for(std::vector<std::string>::const_iterator it=tokens.begin(); it != tokens.end(); ++it) for(std::vector<std::string>::const_iterator it=tokens.begin(); it != tokens.end(); ++it)
{ {
int sep = it->find(","); int sep = it->find(",");
@ -76,7 +75,7 @@ void validate(boost::any &v, std::vector<std::string> const &tokens, FallbackMap
std::string key(it->substr(0,sep)); std::string key(it->substr(0,sep));
std::string value(it->substr(sep+1)); std::string value(it->substr(sep+1));
if((mapIt = map->mMap.find(key)) == map->mMap.end()) if(map->mMap.find(key) == map->mMap.end())
{ {
map->mMap.insert(std::make_pair (key,value)); map->mMap.insert(std::make_pair (key,value));
} }

View file

@ -128,7 +128,8 @@ namespace MWBase
OffenseType type, int arg=0) = 0; OffenseType type, int arg=0) = 0;
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
OffenseType type, int arg=0) = 0; OffenseType type, int arg=0) = 0;
virtual void actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; /// @return false if the attack was considered a "friendly hit" and forgiven
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;
/// Utility to check if taking this item is illegal and calling commitCrime if so /// Utility to check if taking this item is illegal and calling commitCrime if so
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0; virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0;
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so

View file

@ -225,7 +225,6 @@ namespace MWBase
virtual void showCrosshair(bool show) = 0; virtual void showCrosshair(bool show) = 0;
virtual bool getSubtitlesEnabled() = 0; virtual bool getSubtitlesEnabled() = 0;
virtual void toggleHud() = 0;
virtual bool toggleGui() = 0; virtual bool toggleGui() = 0;
virtual void disallowMouse() = 0; virtual void disallowMouse() = 0;
@ -338,6 +337,8 @@ namespace MWBase
virtual void fadeScreenTo(const int percent, const float time) = 0; virtual void fadeScreenTo(const int percent, const float time) = 0;
/// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading. /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
virtual void setScreenFactor (float factor) = 0; virtual void setScreenFactor (float factor) = 0;
virtual void toggleDebugWindow() = 0;
}; };
} }

View file

@ -338,11 +338,12 @@ namespace MWClass
getCreatureStats(ptr).setAttacked(true); getCreatureStats(ptr).setAttacked(true);
// Self defense // Self defense
bool setOnPcHitMe = true; // Note OnPcHitMe is not set for friendly hits.
if ((canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures if ((canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
// (they have no movement or attacks anyway) // (they have no movement or attacks anyway)
&& !attacker.isEmpty()) && !attacker.isEmpty())
{ {
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
if(!successful) if(!successful)
@ -357,7 +358,7 @@ namespace MWClass
if(!object.isEmpty()) if(!object.isEmpty())
getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object)); getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object));
if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player") if(setOnPcHitMe && !attacker.isEmpty() && attacker.getRefData().getHandle() == "player")
{ {
const std::string &script = ptr.get<ESM::Creature>()->mBase->mScript; const std::string &script = ptr.get<ESM::Creature>()->mBase->mScript;
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */

View file

@ -644,11 +644,13 @@ namespace MWClass
bool wasDead = getCreatureStats(ptr).isDead(); bool wasDead = getCreatureStats(ptr).isDead();
// Note OnPcHitMe is not set for friendly hits.
bool setOnPcHitMe = true;
if (!attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)) if (!attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker))
{ {
getCreatureStats(ptr).setAttacked(true); getCreatureStats(ptr).setAttacked(true);
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
if(!successful) if(!successful)
@ -663,7 +665,7 @@ namespace MWClass
if(!object.isEmpty()) if(!object.isEmpty())
getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object)); getCreatureStats(ptr).setLastHitObject(object.getClass().getId(object));
if(!attacker.isEmpty() && attacker.getRefData().getHandle() == "player") if(setOnPcHitMe && !attacker.isEmpty() && attacker.getRefData().getHandle() == "player")
{ {
const std::string &script = ptr.getClass().getScript(ptr); const std::string &script = ptr.getClass().getScript(ptr);
/* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */
@ -1123,10 +1125,13 @@ namespace MWClass
return cast.cast(id); return cast.cast(id);
} }
void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const
{ {
MWMechanics::NpcStats& stats = getNpcStats (ptr); MWMechanics::NpcStats& stats = getNpcStats (ptr);
if (stats.isWerewolf())
return;
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
const ESM::Class *class_ = const ESM::Class *class_ =
@ -1134,7 +1139,7 @@ namespace MWClass
ref->mBase->mClass ref->mBase->mClass
); );
stats.useSkill (skill, *class_, usageType); stats.useSkill (skill, *class_, usageType, extraFactor);
} }
float Npc::getArmorRating (const MWWorld::Ptr& ptr) const float Npc::getArmorRating (const MWWorld::Ptr& ptr) const
@ -1185,13 +1190,6 @@ namespace MWClass
+ shield; + shield;
} }
void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{
y = 0;
x = 0;
}
void Npc::adjustScale(const MWWorld::Ptr &ptr, float &scale) const void Npc::adjustScale(const MWWorld::Ptr &ptr, float &scale) const
{ {
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =

View file

@ -136,11 +136,9 @@ namespace MWClass
virtual void adjustScale (const MWWorld::Ptr &ptr, float &scale) const; virtual void adjustScale (const MWWorld::Ptr &ptr, float &scale) const;
virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const; virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const;
///< Inform actor \a ptr that a skill use has succeeded. ///< Inform actor \a ptr that a skill use has succeeded.
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
virtual bool isEssential (const MWWorld::Ptr& ptr) const; virtual bool isEssential (const MWWorld::Ptr& ptr) const;
///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable)

View file

@ -729,10 +729,10 @@ namespace MWDialogue
{ {
std::vector<HyperTextToken> result; std::vector<HyperTextToken> result;
MyGUI::UString utext(text); MyGUI::UString utext(text);
size_t pos_begin, pos_end, iteration_pos = 0; size_t pos_end, iteration_pos = 0;
for(;;) for(;;)
{ {
pos_begin = utext.find('@', iteration_pos); size_t pos_begin = utext.find('@', iteration_pos);
if (pos_begin != std::string::npos) if (pos_begin != std::string::npos)
pos_end = utext.find('#', pos_begin); pos_end = utext.find('#', pos_begin);
@ -758,12 +758,12 @@ namespace MWDialogue
size_t RemovePseudoAsterisks(std::string& phrase) size_t RemovePseudoAsterisks(std::string& phrase)
{ {
size_t pseudoAsterisksCount = 0; size_t pseudoAsterisksCount = 0;
const char specialPseudoAsteriskCharacter = 127;
if( !phrase.empty() ) if( !phrase.empty() )
{ {
std::string::reverse_iterator rit = phrase.rbegin(); std::string::reverse_iterator rit = phrase.rbegin();
const char specialPseudoAsteriskCharacter = 127;
while( rit != phrase.rend() && *rit == specialPseudoAsteriskCharacter ) while( rit != phrase.rend() && *rit == specialPseudoAsteriskCharacter )
{ {
pseudoAsterisksCount++; pseudoAsterisksCount++;

View file

@ -70,11 +70,6 @@ namespace MWGui
void BookWindow::clearPages() void BookWindow::clearPages()
{ {
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
it!=mPages.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
mPages.clear(); mPages.clear();
} }
@ -89,25 +84,9 @@ namespace MWGui
MWWorld::LiveCellRef<ESM::Book> *ref = mBook.get<ESM::Book>(); MWWorld::LiveCellRef<ESM::Book> *ref = mBook.get<ESM::Book>();
BookTextParser parser; Formatting::BookFormatter formatter;
std::vector<std::string> results = parser.split(ref->mBase->mText, mLeftPage->getSize().width, mLeftPage->getSize().height); mPages = formatter.markupToWidget(mLeftPage, ref->mBase->mText);
formatter.markupToWidget(mRightPage, ref->mBase->mText);
int i=0;
for (std::vector<std::string>::iterator it=results.begin();
it!=results.end(); ++it)
{
MyGUI::Widget* parent;
if (i%2 == 0)
parent = mLeftPage;
else
parent = mRightPage;
MyGUI::Widget* pageWidget = parent->createWidgetReal<MyGUI::Widget>("", MyGUI::FloatCoord(0.0,0.0,1.0,1.0), MyGUI::Align::Default, "BookPage" + boost::lexical_cast<std::string>(i));
pageWidget->setNeedMouseFocus(false);
parser.parsePage(*it, pageWidget, mLeftPage->getSize().width);
mPages.push_back(pageWidget);
++i;
}
updatePages(); updatePages();
@ -164,19 +143,6 @@ namespace MWGui
mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) ); mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) );
mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) ); mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) );
unsigned int i=0;
for (std::vector<MyGUI::Widget*>::iterator it = mPages.begin();
it != mPages.end(); ++it)
{
if (mCurrentPage*2 == i || mCurrentPage*2+1 == i)
(*it)->setVisible(true);
else
{
(*it)->setVisible(false);
}
++i;
}
//If it is the last page, hide the button "Next Page" //If it is the last page, hide the button "Next Page"
if ( (mCurrentPage+1)*2 == mPages.size() if ( (mCurrentPage+1)*2 == mPages.size()
|| (mCurrentPage+1)*2 == mPages.size() + 1) || (mCurrentPage+1)*2 == mPages.size() + 1)
@ -191,6 +157,27 @@ namespace MWGui
} else { } else {
mPrevPageButton->setVisible(true); mPrevPageButton->setVisible(true);
} }
if (mPages.empty())
return;
MyGUI::Widget * paper;
paper = mLeftPage->getChildAt(0);
paper->setCoord(paper->getPosition().left, -mPages[mCurrentPage*2].first,
paper->getWidth(), mPages[mCurrentPage*2].second);
paper = mRightPage->getChildAt(0);
if ((mCurrentPage+1)*2 <= mPages.size())
{
paper->setCoord(paper->getPosition().left, -mPages[mCurrentPage*2+1].first,
paper->getWidth(), mPages[mCurrentPage*2+1].second);
paper->setVisible(true);
}
else
{
paper->setVisible(false);
}
} }
void BookWindow::adjustButton (Gui::ImageButton* button) void BookWindow::adjustButton (Gui::ImageButton* button)

View file

@ -34,17 +34,21 @@ namespace MWGui
void adjustButton(Gui::ImageButton* button); void adjustButton(Gui::ImageButton* button);
private: private:
typedef std::pair<int, int> Page;
typedef std::vector<Page> Pages;
Gui::ImageButton* mCloseButton; Gui::ImageButton* mCloseButton;
Gui::ImageButton* mTakeButton; Gui::ImageButton* mTakeButton;
Gui::ImageButton* mNextPageButton; Gui::ImageButton* mNextPageButton;
Gui::ImageButton* mPrevPageButton; Gui::ImageButton* mPrevPageButton;
MyGUI::TextBox* mLeftPageNumber; MyGUI::TextBox* mLeftPageNumber;
MyGUI::TextBox* mRightPageNumber; MyGUI::TextBox* mRightPageNumber;
MyGUI::Widget* mLeftPage; MyGUI::Widget* mLeftPage;
MyGUI::Widget* mRightPage; MyGUI::Widget* mRightPage;
unsigned int mCurrentPage; // 0 is first page unsigned int mCurrentPage; // 0 is first page
std::vector<MyGUI::Widget*> mPages; Pages mPages;
MWWorld::Ptr mBook; MWWorld::Ptr mBook;

View file

@ -277,7 +277,6 @@ namespace MWGui
InfoBoxDialog::InfoBoxDialog() InfoBoxDialog::InfoBoxDialog()
: WindowModal("openmw_infobox.layout") : WindowModal("openmw_infobox.layout")
, mCurrentButton(-1)
{ {
getWidget(mTextBox, "TextBox"); getWidget(mTextBox, "TextBox");
getWidget(mText, "Text"); getWidget(mText, "Text");
@ -306,7 +305,6 @@ namespace MWGui
MyGUI::Gui::getInstance().destroyWidget(*it); MyGUI::Gui::getInstance().destroyWidget(*it);
} }
this->mButtons.clear(); this->mButtons.clear();
mCurrentButton = -1;
// TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget // TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget
MyGUI::Button* button; MyGUI::Button* button;
@ -336,11 +334,6 @@ namespace MWGui
center(); center();
} }
int InfoBoxDialog::getChosenButton() const
{
return mCurrentButton;
}
void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender) void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender)
{ {
std::vector<MyGUI::Button*>::const_iterator end = mButtons.end(); std::vector<MyGUI::Button*>::const_iterator end = mButtons.end();
@ -349,7 +342,6 @@ namespace MWGui
{ {
if (*it == _sender) if (*it == _sender)
{ {
mCurrentButton = i;
eventButtonSelected(i); eventButtonSelected(i);
return; return;
} }
@ -671,8 +663,6 @@ namespace MWGui
// Centre dialog // Centre dialog
center(); center();
setText("LabelT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSpecializationMenu1", ""));
getWidget(mSpecialization0, "Specialization0"); getWidget(mSpecialization0, "Specialization0");
getWidget(mSpecialization1, "Specialization1"); getWidget(mSpecialization1, "Specialization1");
getWidget(mSpecialization2, "Specialization2"); getWidget(mSpecialization2, "Specialization2");
@ -694,7 +684,6 @@ namespace MWGui
MyGUI::Button* cancelButton; MyGUI::Button* cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked);
} }
@ -737,8 +726,6 @@ namespace MWGui
// Centre dialog // Centre dialog
center(); center();
setText("LabelT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sAttributesMenu1", ""));
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
Widgets::MWAttributePtr attribute; Widgets::MWAttributePtr attribute;
@ -752,7 +739,6 @@ namespace MWGui
MyGUI::Button* cancelButton; MyGUI::Button* cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked);
} }
@ -788,11 +774,6 @@ namespace MWGui
// Centre dialog // Centre dialog
center(); center();
setText("LabelT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillsMenu1", ""));
setText("CombatLabelT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSpecializationCombat", ""));
setText("MagicLabelT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSpecializationMagic", ""));
setText("StealthLabelT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSpecializationStealth", ""));
for(int i = 0; i < 9; i++) for(int i = 0; i < 9; i++)
{ {
char theIndex = '0'+i; char theIndex = '0'+i;
@ -849,7 +830,6 @@ namespace MWGui
MyGUI::Button* cancelButton; MyGUI::Button* cancelButton;
getWidget(cancelButton, "CancelButton"); getWidget(cancelButton, "CancelButton");
cancelButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sCancel", ""));
cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked);
} }

View file

@ -24,7 +24,6 @@ namespace MWGui
void setButtons(ButtonList &buttons); void setButtons(ButtonList &buttons);
virtual void open(); virtual void open();
int getChosenButton() const;
// Events // Events
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int; typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
@ -41,7 +40,6 @@ namespace MWGui
void fitToText(MyGUI::TextBox* widget); void fitToText(MyGUI::TextBox* widget);
void layoutVertically(MyGUI::Widget* widget, int margin); void layoutVertically(MyGUI::Widget* widget, int margin);
int mCurrentButton;
MyGUI::Widget* mTextBox; MyGUI::Widget* mTextBox;
MyGUI::TextBox* mText; MyGUI::TextBox* mText;
MyGUI::Widget* mButtonBar; MyGUI::Widget* mButtonBar;

View file

@ -155,11 +155,6 @@ namespace MWGui
mCommandLine->setFontName(fntName); mCommandLine->setFontName(fntName);
} }
void Console::clearHistory()
{
mHistory->setCaption("");
}
void Console::print(const std::string &msg) void Console::print(const std::string &msg)
{ {
mHistory->addText(msg); mHistory->addText(msg);

View file

@ -48,8 +48,6 @@ namespace MWGui
void onResChange(int width, int height); void onResChange(int width, int height);
void clearHistory();
// Print a message to the console. Messages may contain color // Print a message to the console. Messages may contain color
// code, eg. "#FFFFFF this is white". // code, eg. "#FFFFFF this is white".
void print(const std::string &msg); void print(const std::string &msg);

View file

@ -2,6 +2,8 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/widgets/numericeditbox.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
@ -19,7 +21,7 @@ namespace MWGui
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked);
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked);
mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange); mItemEdit->eventValueChanged += MyGUI::newDelegate(this, &CountDialog::onEditValueChanged);
mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved); mSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &CountDialog::onSliderMoved);
// make sure we read the enter key being pressed to accept multiple items // make sure we read the enter key being pressed to accept multiple items
mItemEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &CountDialog::onEnterKeyPressed); mItemEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &CountDialog::onEnterKeyPressed);
@ -46,7 +48,10 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit);
mSlider->setScrollPosition(maxCount-1); mSlider->setScrollPosition(maxCount-1);
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
mItemEdit->setMinValue(1);
mItemEdit->setMaxValue(maxCount);
mItemEdit->setValue(maxCount);
} }
void CountDialog::cancel() //Keeping this here as I don't know if anything else relies on it. void CountDialog::cancel() //Keeping this here as I don't know if anything else relies on it.
@ -80,30 +85,13 @@ namespace MWGui
setVisible(false); setVisible(false);
} }
void CountDialog::onEditTextChange(MyGUI::EditBox* _sender) void CountDialog::onEditValueChanged(int value)
{ {
if (_sender->getCaption() == "") mSlider->setScrollPosition(value-1);
return;
unsigned int count;
try
{
count = boost::lexical_cast<unsigned int>(_sender->getCaption());
}
catch (std::bad_cast&)
{
count = 1;
}
if (count > mSlider->getScrollRange())
{
count = mSlider->getScrollRange();
}
mSlider->setScrollPosition(count-1);
onSliderMoved(mSlider, count-1);
} }
void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position) void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position)
{ {
mItemEdit->setCaption(boost::lexical_cast<std::string>(_position+1)); mItemEdit->setValue(_position+1);
} }
} }

View file

@ -3,6 +3,11 @@
#include "windowbase.hpp" #include "windowbase.hpp"
namespace Gui
{
class NumericEditBox;
}
namespace MWGui namespace MWGui
{ {
class CountDialog : public WindowModal class CountDialog : public WindowModal
@ -22,7 +27,7 @@ namespace MWGui
private: private:
MyGUI::ScrollBar* mSlider; MyGUI::ScrollBar* mSlider;
MyGUI::EditBox* mItemEdit; Gui::NumericEditBox* mItemEdit;
MyGUI::TextBox* mItemText; MyGUI::TextBox* mItemText;
MyGUI::TextBox* mLabelText; MyGUI::TextBox* mLabelText;
MyGUI::Button* mOkButton; MyGUI::Button* mOkButton;
@ -30,7 +35,7 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* _sender); void onCancelButtonClicked(MyGUI::Widget* _sender);
void onOkButtonClicked(MyGUI::Widget* _sender); void onOkButtonClicked(MyGUI::Widget* _sender);
void onEditTextChange(MyGUI::EditBox* _sender); void onEditValueChanged(int value);
void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position); void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position);
void onEnterKeyPressed(MyGUI::EditBox* _sender); void onEnterKeyPressed(MyGUI::EditBox* _sender);
}; };

View file

@ -0,0 +1,116 @@
#include "debugwindow.hpp"
#include <LinearMath/btQuickprof.h>
namespace
{
void bulletDumpRecursive(CProfileIterator* pit, int spacing, std::stringstream& os)
{
pit->First();
if (pit->Is_Done())
return;
float accumulated_time=0,parent_time = pit->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : pit->Get_Current_Parent_Total_Time();
int i,j;
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
for (i=0;i<spacing;i++) os << ".";
os << "----------------------------------\n";
for (i=0;i<spacing;i++) os << ".";
std::string s = "Profiling: "+
std::string(pit->Get_Current_Parent_Name())+" (total running time: "+MyGUI::utility::toString(parent_time,3)+" ms) ---\n";
os << s;
//float totalTime = 0.f;
int numChildren = 0;
for (i = 0; !pit->Is_Done(); i++,pit->Next())
{
numChildren++;
float current_total_time = pit->Get_Current_Total_Time();
accumulated_time += current_total_time;
float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
for (j=0;j<spacing;j++) os << ".";
double ms = (current_total_time / (double)frames_since_reset);
s = MyGUI::utility::toString(i)+" -- "+pit->Get_Current_Name()+" ("+MyGUI::utility::toString(fraction,2)+" %) :: "+MyGUI::utility::toString(ms,3)+" ms / frame ("+MyGUI::utility::toString(pit->Get_Current_Total_Calls())+" calls)\n";
os << s;
//totalTime += current_total_time;
//recurse into children
}
if (parent_time < accumulated_time)
{
os << "what's wrong\n";
}
for (i=0;i<spacing;i++) os << ".";
double unaccounted= parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f;
s = "Unaccounted: ("+MyGUI::utility::toString(unaccounted,3)+" %) :: "+MyGUI::utility::toString(parent_time - accumulated_time,3)+" ms\n";
os << s;
for (i=0;i<numChildren;i++)
{
pit->Enter_Child(i);
bulletDumpRecursive(pit, spacing+3, os);
pit->Enter_Parent();
}
}
void bulletDumpAll(std::stringstream& os)
{
CProfileIterator* profileIterator = 0;
profileIterator = CProfileManager::Get_Iterator();
bulletDumpRecursive(profileIterator, 0, os);
CProfileManager::Release_Iterator(profileIterator);
}
}
namespace MWGui
{
DebugWindow::DebugWindow()
: WindowBase("openmw_debug_window.layout")
{
getWidget(mTabControl, "TabControl");
// Ideas for other tabs:
// - Texture / compositor texture viewer
// - Log viewer
// - Material editor
// - Shader editor
MyGUI::TabItem* item = mTabControl->addItem("Physics Profiler");
mBulletProfilerEdit = item->createWidgetReal<MyGUI::EditBox>
("LogEdit", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Stretch);
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
mMainWidget->setSize(viewSize);
}
void DebugWindow::onFrame(float dt)
{
if (!isVisible())
return;
static float timer = 0;
timer -= dt;
if (timer > 0)
return;
timer = 1;
std::stringstream stream;
bulletDumpAll(stream);
if (mBulletProfilerEdit->isTextSelection()) // pause updating while user is trying to copy text
return;
size_t previousPos = mBulletProfilerEdit->getVScrollPosition();
mBulletProfilerEdit->setCaption(stream.str());
mBulletProfilerEdit->setVScrollPosition(std::min(previousPos, mBulletProfilerEdit->getVScrollRange()-1));
}
}

View file

@ -0,0 +1,24 @@
#ifndef OPENMW_MWGUI_DEBUGWINDOW_H
#define OPENMW_MWGUI_DEBUGWINDOW_H
#include "windowbase.hpp"
namespace MWGui
{
class DebugWindow : public WindowBase
{
public:
DebugWindow();
void onFrame(float dt);
private:
MyGUI::TabControl* mTabControl;
MyGUI::EditBox* mBulletProfilerEdit;
};
}
#endif

View file

@ -3,6 +3,8 @@
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/widgets/list.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
@ -17,7 +19,6 @@
#include "../mwdialogue/dialoguemanagerimp.hpp" #include "../mwdialogue/dialoguemanagerimp.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "list.hpp"
#include "tradewindow.hpp" #include "tradewindow.hpp"
#include "spellbuyingwindow.hpp" #include "spellbuyingwindow.hpp"
#include "travelwindow.hpp" #include "travelwindow.hpp"
@ -124,10 +125,10 @@ namespace MWGui
// We need this copy for when @# hyperlinks are replaced // We need this copy for when @# hyperlinks are replaced
std::string text = mText; std::string text = mText;
size_t pos_begin, pos_end; size_t pos_end;
for(;;) for(;;)
{ {
pos_begin = text.find('@'); size_t pos_begin = text.find('@');
if (pos_begin != std::string::npos) if (pos_begin != std::string::npos)
pos_end = text.find('#', pos_begin); pos_end = text.find('#', pos_begin);
@ -561,12 +562,11 @@ namespace MWGui
MyGUI::Button* byeButton; MyGUI::Button* byeButton;
getWidget(byeButton, "ByeButton"); getWidget(byeButton, "ByeButton");
if(MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye) { bool goodbyeEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() || mGoodbye;
byeButton->setEnabled(false); byeButton->setEnabled(goodbyeEnabled);
}
else { bool topicsEnabled = !MWBase::Environment::get().getDialogueManager()->isInChoice() && !mGoodbye;
byeButton->setEnabled(true); mTopicsList->setEnabled(topicsEnabled);
}
} }
void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link) void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link)
@ -656,7 +656,6 @@ namespace MWGui
{ {
mLinks.push_back(new Goodbye()); mLinks.push_back(new Goodbye());
mGoodbye = true; mGoodbye = true;
mTopicsList->setEnabled(false);
mEnabled = false; mEnabled = false;
updateHistory(); updateHistory();
} }

View file

@ -8,14 +8,14 @@
#include "keywordsearch.hpp" #include "keywordsearch.hpp"
namespace Gui
{
class MWList;
}
namespace MWGui namespace MWGui
{ {
class WindowManager; class WindowManager;
namespace Widgets
{
class MWList;
}
} }
/* /*
@ -169,7 +169,7 @@ namespace MWGui
KeywordSearchT mKeywordSearch; KeywordSearchT mKeywordSearch;
BookPage* mHistory; BookPage* mHistory;
Widgets::MWList* mTopicsList; Gui::MWList* mTopicsList;
MyGUI::ScrollBar* mScrollBar; MyGUI::ScrollBar* mScrollBar;
MyGUI::Progress* mDispositionBar; MyGUI::Progress* mDispositionBar;
MyGUI::EditBox* mDispositionText; MyGUI::EditBox* mDispositionText;

View file

@ -2,401 +2,404 @@
#include <components/interpreter/defines.hpp> #include <components/interpreter/defines.hpp>
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
#include <components/misc/stringops.hpp>
#include "../mwscript/interpretercontext.hpp" #include "../mwscript/interpretercontext.hpp"
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <OgreUTFString.h>
#include <OgreUTFString.h>
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
namespace #include <MyGUI_EditText.h>
{
int convertFromHex(std::string hex)
{
int value = 0;
int a = 0;
int b = hex.length() - 1;
for (; b >= 0; a++, b--)
{
if (hex[b] >= '0' && hex[b] <= '9')
{
value += (hex[b] - '0') * (1 << (a * 4));
}
else
{
switch (hex[b])
{
case 'A':
case 'a':
value += 10 * (1 << (a * 4));
break;
case 'B':
case 'b':
value += 11 * (1 << (a * 4));
break;
case 'C':
case 'c':
value += 12 * (1 << (a * 4));
break;
case 'D':
case 'd':
value += 13 * (1 << (a * 4));
break;
case 'E':
case 'e':
value += 14 * (1 << (a * 4));
break;
case 'F':
case 'f':
value += 15 * (1 << (a * 4));
break;
default:
throw std::runtime_error("invalid character in hex number");
break;
}
}
}
return value;
}
Ogre::UTFString::unicode_char unicodeCharFromChar(char ch)
{
std::string s;
s += ch;
Ogre::UTFString string(s);
return string.getChar(0);
}
bool is_not_empty(const std::string& s) {
std::string temp = s;
boost::algorithm::trim(temp);
return !temp.empty();
}
}
namespace MWGui namespace MWGui
{ {
namespace Formatting
std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height) {
/* BookTextParser */
BookTextParser::BookTextParser(const std::string & text)
: mIndex(0), mText(text), mIgnoreNewlineTags(true), mIgnoreLineEndings(true)
{ {
using Ogre::UTFString;
std::vector<std::string> result;
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext); mText = Interpreter::fixDefinesBook(mText, interpreterContext);
boost::algorithm::replace_all(utf8Text, "\n", ""); boost::algorithm::replace_all(mText, "\r", "");
boost::algorithm::replace_all(utf8Text, "\r", "");
boost::algorithm::replace_all(utf8Text, "<BR>", "\n");
boost::algorithm::replace_all(utf8Text, "<P>", "\n\n");
UTFString text(utf8Text); registerTag("br", Event_BrTag);
const int spacing = 48; registerTag("p", Event_PTag);
registerTag("img", Event_ImgTag);
const UTFString::unicode_char LEFT_ANGLE = unicodeCharFromChar('<'); registerTag("div", Event_DivTag);
const UTFString::unicode_char NEWLINE = unicodeCharFromChar('\n'); registerTag("font", Event_FontTag);
const UTFString::unicode_char SPACE = unicodeCharFromChar(' ');
while (!text.empty())
{
// read in characters until we have exceeded the size, or run out of text
int currentWidth = 0;
int currentHeight = 0;
size_t currentWordStart = 0;
size_t index = 0;
{
std::string texToTrim = text.asUTF8();
boost::algorithm::trim( texToTrim );
text = UTFString(texToTrim);
} }
void BookTextParser::registerTag(const std::string & tag, BookTextParser::Events type)
{
mTagTypes[tag] = type;
}
while (currentHeight <= height - spacing && index < text.size()) std::string BookTextParser::getReadyText()
{ {
const UTFString::unicode_char ch = text.getChar(index); return mReadyText;
if (ch == LEFT_ANGLE) }
BookTextParser::Events BookTextParser::next()
{ {
const size_t tagStart = index + 1; while (mIndex < mText.size())
const size_t tagEnd = text.find('>', tagStart); {
if (tagEnd == UTFString::npos) char ch = mText[mIndex];
if (ch == '<')
{
const size_t tagStart = mIndex + 1;
const size_t tagEnd = mText.find('>', tagStart);
if (tagEnd == std::string::npos)
throw std::runtime_error("BookTextParser Error: Tag is not terminated"); throw std::runtime_error("BookTextParser Error: Tag is not terminated");
const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8(); parseTag(mText.substr(tagStart, tagEnd - tagStart));
mIndex = tagEnd;
if (boost::algorithm::starts_with(tag, "IMG")) if (mTagTypes.find(mTag) != mTagTypes.end())
{ {
const int h = mHeight; Events type = mTagTypes.at(mTag);
parseImage(tag, false);
currentHeight += (mHeight - h); if (type == Event_BrTag || type == Event_PTag)
currentWidth = 0;
}
else if (boost::algorithm::starts_with(tag, "FONT"))
{ {
parseFont(tag); if (!mIgnoreNewlineTags)
if (currentWidth != 0) {
currentHeight += currentFontHeight();
}
currentWidth = 0;
}
else if (boost::algorithm::starts_with(tag, "DIV"))
{ {
parseDiv(tag); if (type == Event_BrTag)
if (currentWidth != 0) { mBuffer.push_back('\n');
currentHeight += currentFontHeight(); else
currentWidth = 0;
}
}
index = tagEnd;
}
else if (ch == NEWLINE)
{ {
currentHeight += currentFontHeight(); mBuffer.append("\n\n");
currentWidth = 0;
currentWordStart = index;
} }
else if (ch == SPACE) }
mIgnoreLineEndings = true;
}
else
flushBuffer();
if (type == Event_ImgTag)
{ {
currentWidth += 3; // keep this in sync with the font's SpaceWidth property mIgnoreLineEndings = false;
currentWordStart = index; mIgnoreNewlineTags = false;
}
++mIndex;
return type;
}
} }
else else
{ {
currentWidth += widthForCharGlyph(ch); if (!mIgnoreLineEndings || ch != '\n')
}
if (currentWidth > width)
{ {
currentHeight += currentFontHeight(); mBuffer.push_back(ch);
currentWidth = 0; mIgnoreLineEndings = false;
// add size of the current word mIgnoreNewlineTags = false;
UTFString word = text.substr(currentWordStart, index - currentWordStart);
for (UTFString::const_iterator it = word.begin(), end = word.end(); it != end; ++it)
currentWidth += widthForCharGlyph(it.getCharacter());
} }
index += UTFString::_utf16_char_length(ch);
}
const size_t pageEnd = (currentHeight > height - spacing && currentWordStart != 0)
? currentWordStart : index;
result.push_back(text.substr(0, pageEnd).asUTF8());
text.erase(0, pageEnd);
} }
std::vector<std::string> nonEmptyPages; ++mIndex;
boost::copy(result | boost::adaptors::filtered(is_not_empty), std::back_inserter(nonEmptyPages));
return nonEmptyPages;
} }
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const flushBuffer();
return Event_EOF;
}
void BookTextParser::flushBuffer()
{ {
std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont); mReadyText = mBuffer;
return MyGUI::FontManager::getInstance().getByName(fontName) mBuffer.clear();
->getGlyphInfo(unicodeChar)->width;
} }
float BookTextParser::currentFontHeight() const const BookTextParser::Attributes & BookTextParser::getAttributes() const
{ {
std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont); return mAttributes;
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
} }
MyGUI::IntSize BookTextParser::parsePage(std::string text, MyGUI::Widget* parent, const int width) void BookTextParser::parseTag(std::string tag)
{ {
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor size_t tagNameEndPos = tag.find(' ');
text = Interpreter::fixDefinesBook(text, interpreterContext); mTag = tag.substr(0, tagNameEndPos);
Misc::StringUtils::toLower(mTag);
mAttributes.clear();
if (tagNameEndPos == std::string::npos)
return;
tag.erase(0, tagNameEndPos+1);
mParent = parent; while (!tag.empty())
mWidth = width;
mHeight = 0;
assert(mParent);
while (mParent->getChildCount())
{ {
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0)); size_t sepPos = tag.find('=');
} if (sepPos == std::string::npos)
// remove trailing "
if (text[text.size()-1] == '\"')
text.erase(text.size()-1);
parseSubText(text);
return MyGUI::IntSize(mWidth, mHeight);
}
MyGUI::IntSize BookTextParser::parseScroll(std::string text, MyGUI::Widget* parent, const int width)
{
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
text = Interpreter::fixDefinesBook(text, interpreterContext);
mParent = parent;
mWidth = width;
mHeight = 0;
assert(mParent);
while (mParent->getChildCount())
{
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
}
boost::algorithm::replace_all(text, "<BR>", "\n");
boost::algorithm::replace_all(text, "<P>", "\n\n");
boost::algorithm::trim_left(text);
// remove trailing "
if (text[text.size()-1] == '\"')
text.erase(text.size()-1);
parseSubText(text);
return MyGUI::IntSize(mWidth, mHeight);
}
void BookTextParser::parseImage(std::string tag, bool createWidget)
{
int src_start = tag.find("SRC=")+5;
int width_start = tag.find("WIDTH=")+7;
int width = boost::lexical_cast<int>(tag.substr(width_start, tag.find('"', width_start)-width_start));
int height_start = tag.find("HEIGHT=")+8;
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
if (createWidget)
{
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
std::string image = Misc::ResourceHelpers::correctBookartPath(tag.substr(src_start, tag.find('"', src_start)-src_start), width, height);
box->setImageTexture(image);
box->setProperty("NeedMouse", "false");
}
mWidth = std::max(mWidth, width);
mHeight += height;
}
void BookTextParser::parseDiv(std::string tag)
{
if (tag.find("ALIGN=") == std::string::npos)
return; return;
int align_start = tag.find("ALIGN=")+7; std::string key = tag.substr(0, sepPos);
std::string align = tag.substr(align_start, tag.find('"', align_start)-align_start); Misc::StringUtils::toLower(key);
if (align == "CENTER") tag.erase(0, sepPos+1);
std::string value;
if (tag.empty())
return;
if (tag[0] == '"')
{
size_t quoteEndPos = tag.find('"', 1);
if (quoteEndPos == std::string::npos)
throw std::runtime_error("BookTextParser Error: Missing end quote in tag");
value = tag.substr(1, quoteEndPos-1);
tag.erase(0, quoteEndPos+2);
}
else
{
size_t valEndPos = tag.find(' ');
if (valEndPos == std::string::npos)
{
value = tag;
tag.erase();
}
else
{
value = tag.substr(0, valEndPos);
tag.erase(0, valEndPos+1);
}
}
mAttributes[key] = value;
}
}
/* BookFormatter */
Paginator::Pages BookFormatter::markupToWidget(MyGUI::Widget * parent, const std::string & markup, const int pageWidth, const int pageHeight)
{
Paginator pag(pageWidth, pageHeight);
while (parent->getChildCount())
{
MyGUI::Gui::getInstance().destroyWidget(parent->getChildAt(0));
}
MyGUI::Widget * paper = parent->createWidget<MyGUI::Widget>("Widget", MyGUI::IntCoord(0, 0, pag.getPageWidth(), pag.getPageHeight()), MyGUI::Align::Left | MyGUI::Align::Top);
paper->setNeedMouseFocus(false);
BookTextParser parser(markup);
for (;;)
{
BookTextParser::Events event = parser.next();
if (event == BookTextParser::Event_BrTag || event == BookTextParser::Event_PTag)
continue;
std::string plainText = parser.getReadyText();
if (!plainText.empty())
{
// if there's a newline at the end of the box caption, remove it
if (plainText[plainText.size()-1] == '\n')
plainText.erase(plainText.end()-1);
#if (MYGUI_VERSION < MYGUI_DEFINE_VERSION(3, 2, 2))
// splitting won't be fully functional until 3.2.2 (see TextElement::pageSplit())
// hack: prevent newlines at the end of the book possibly creating unnecessary pages
if (event == BookTextParser::Event_EOF)
{
while (plainText.size() && plainText[plainText.size()-1] == '\n')
plainText.erase(plainText.end()-1);
}
#endif
TextElement elem(paper, pag, mTextStyle, plainText);
elem.paginate();
}
if (event == BookTextParser::Event_EOF)
break;
switch (event)
{
case BookTextParser::Event_ImgTag:
{
const BookTextParser::Attributes & attr = parser.getAttributes();
if (attr.find("src") == attr.end() || attr.find("width") == attr.end() || attr.find("height") == attr.end())
continue;
std::string src = attr.at("src");
int width = boost::lexical_cast<int>(attr.at("width"));
int height = boost::lexical_cast<int>(attr.at("height"));
ImageElement elem(paper, pag, src, width, height);
elem.paginate();
break;
}
case BookTextParser::Event_FontTag:
handleFont(parser.getAttributes());
break;
case BookTextParser::Event_DivTag:
handleDiv(parser.getAttributes());
break;
default:
break;
}
}
// insert last page
if (pag.getStartTop() != pag.getCurrentTop())
pag << Paginator::Page(pag.getStartTop(), pag.getStartTop() + pag.getPageHeight());
paper->setSize(paper->getWidth(), pag.getCurrentTop());
return pag.getPages();
}
Paginator::Pages BookFormatter::markupToWidget(MyGUI::Widget * parent, const std::string & markup)
{
return markupToWidget(parent, markup, parent->getWidth(), parent->getHeight());
}
void BookFormatter::handleDiv(const BookTextParser::Attributes & attr)
{
if (attr.find("align") == attr.end())
return;
std::string align = attr.at("align");
if (Misc::StringUtils::ciEqual(align, "center"))
mTextStyle.mTextAlign = MyGUI::Align::HCenter; mTextStyle.mTextAlign = MyGUI::Align::HCenter;
else if (align == "LEFT") else if (Misc::StringUtils::ciEqual(align, "left"))
mTextStyle.mTextAlign = MyGUI::Align::Left; mTextStyle.mTextAlign = MyGUI::Align::Left;
} }
void BookTextParser::parseFont(std::string tag) void BookFormatter::handleFont(const BookTextParser::Attributes & attr)
{ {
if (tag.find("COLOR=") != std::string::npos) if (attr.find("color") != attr.end())
{ {
int color_start = tag.find("COLOR=")+7; int color;
std::string color = tag.substr(color_start, tag.find('"', color_start)-color_start); std::stringstream ss;
ss << attr.at("color");
ss >> std::hex >> color;
mTextStyle.mColour = MyGUI::Colour( mTextStyle.mColour = MyGUI::Colour(
convertFromHex(color.substr(0, 2))/255.0, (color>>16 & 0xFF) / 255.f,
convertFromHex(color.substr(2, 2))/255.0, (color>>8 & 0xFF) / 255.f,
convertFromHex(color.substr(4, 2))/255.0); (color & 0xFF) / 255.f);
} }
if (tag.find("FACE=") != std::string::npos) if (attr.find("face") != attr.end())
{ {
int face_start = tag.find("FACE=")+6; std::string face = attr.at("face");
std::string face = tag.substr(face_start, tag.find('"', face_start)-face_start);
if (face != "Magic Cards") if (face != "Magic Cards")
mTextStyle.mFont = face; mTextStyle.mFont = face;
} }
if (tag.find("SIZE=") != std::string::npos) if (attr.find("size") != attr.end())
{ {
/// \todo /// \todo
} }
} }
void BookTextParser::parseSubText(std::string text) /* GraphicElement */
GraphicElement::GraphicElement(MyGUI::Widget * parent, Paginator & pag)
: mParent(parent), mPaginator(pag)
{ {
if (text[0] == '<')
{
const size_t tagStart = 1;
const size_t tagEnd = text.find('>', tagStart);
if (tagEnd == std::string::npos)
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
const std::string tag = text.substr(tagStart, tagEnd - tagStart);
if (boost::algorithm::starts_with(tag, "IMG"))
parseImage(tag);
if (boost::algorithm::starts_with(tag, "FONT"))
parseFont(tag);
if (boost::algorithm::starts_with(tag, "DIV"))
parseDiv(tag);
text.erase(0, tagEnd + 1);
} }
size_t tagStart = std::string::npos; void GraphicElement::paginate()
std::string realText; // real text, without tags
for (size_t i = 0; i<text.size(); ++i)
{ {
char c = text[i]; int newTop = mPaginator.getCurrentTop() + getHeight();
if (c == '<') while (newTop-mPaginator.getStartTop() > mPaginator.getPageHeight())
{ {
if ((i + 1 < text.size()) && text[i+1] == '/') // ignore closing tags int newStartTop = pageSplit();
{ mPaginator << Paginator::Page(mPaginator.getStartTop(), newStartTop);
while (c != '>') mPaginator.setStartTop(newStartTop);
{
if (i >= text.size())
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
++i;
c = text[i];
}
continue;
}
else
{
tagStart = i;
break;
}
}
else
realText += c;
} }
MyGUI::EditBox* box = mParent->createWidget<MyGUI::EditBox>("NormalText", mPaginator.setCurrentTop(newTop);
MyGUI::IntCoord(0, mHeight, mWidth, 24), MyGUI::Align::Left | MyGUI::Align::Top, }
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
int GraphicElement::pageSplit()
{
return mPaginator.getStartTop() + mPaginator.getPageHeight();
}
/* TextElement */
TextElement::TextElement(MyGUI::Widget * parent, Paginator & pag,
const TextStyle & style, const std::string & text)
: GraphicElement(parent, pag),
mStyle(style)
{
MyGUI::EditBox* box = parent->createWidget<MyGUI::EditBox>("NormalText",
MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top,
parent->getName() + boost::lexical_cast<std::string>(parent->getChildCount()));
box->setProperty("Static", "true"); box->setProperty("Static", "true");
box->setProperty("MultiLine", "true"); box->setProperty("MultiLine", "true");
box->setProperty("WordWrap", "true"); box->setProperty("WordWrap", "true");
box->setProperty("NeedMouse", "false"); box->setProperty("NeedMouse", "false");
box->setMaxTextLength(realText.size()); box->setMaxTextLength(text.size());
box->setTextAlign(mTextStyle.mTextAlign); box->setTextAlign(mStyle.mTextAlign);
box->setTextColour(mTextStyle.mColour); box->setTextColour(mStyle.mColour);
box->setFontName(mTextStyle.mFont); box->setFontName(mStyle.mFont);
box->setCaption(MyGUI::TextIterator::toTagsString(realText)); box->setCaption(MyGUI::TextIterator::toTagsString(text));
box->setSize(box->getSize().width, box->getTextSize().height); box->setSize(box->getSize().width, box->getTextSize().height);
mHeight += box->getTextSize().height; mEditBox = box;
}
if (tagStart != std::string::npos) int TextElement::currentFontHeight() const
{ {
parseSubText(text.substr(tagStart, text.size())); std::string fontName(mStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mStyle.mFont);
} return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
} }
int TextElement::getHeight()
{
return mEditBox->getTextSize().height;
}
int TextElement::pageSplit()
{
// split lines
const int lineHeight = currentFontHeight();
unsigned int lastLine = (mPaginator.getStartTop() + mPaginator.getPageHeight() - mPaginator.getCurrentTop()) / lineHeight;
int ret = mPaginator.getCurrentTop() + lastLine * lineHeight;
// first empty lines that would go to the next page should be ignored
// unfortunately, getLineInfo method won't be available until 3.2.2
#if (MYGUI_VERSION >= MYGUI_DEFINE_VERSION(3, 2, 2))
const MyGUI::VectorLineInfo & lines = mEditBox->getSubWidgetText()->castType<MyGUI::EditText>()->getLineInfo();
for (unsigned int i = lastLine; i < lines.size(); ++i)
{
if (lines[i].width == 0)
ret += lineHeight;
else
break;
}
#endif
return ret;
}
/* ImageElement */
ImageElement::ImageElement(MyGUI::Widget * parent, Paginator & pag,
const std::string & src, int width, int height)
: GraphicElement(parent, pag),
mImageHeight(height)
{
mImageBox = parent->createWidget<MyGUI::ImageBox> ("ImageBox",
MyGUI::IntCoord(0, pag.getCurrentTop(), width, mImageHeight), MyGUI::Align::Left | MyGUI::Align::Top,
parent->getName() + boost::lexical_cast<std::string>(parent->getChildCount()));
std::string image = Misc::ResourceHelpers::correctBookartPath(src, width, mImageHeight);
mImageBox->setImageTexture(image);
mImageBox->setProperty("NeedMouse", "false");
}
int ImageElement::getHeight()
{
return mImageHeight;
}
int ImageElement::pageSplit()
{
// if the image is larger than the page, fall back to the default pageSplit implementation
if (mImageHeight > mPaginator.getPageHeight())
return GraphicElement::pageSplit();
return mPaginator.getCurrentTop();
}
}
} }

View file

@ -2,9 +2,12 @@
#define MWGUI_FORMATTING_H #define MWGUI_FORMATTING_H
#include <MyGUI.h> #include <MyGUI.h>
#include <map>
namespace MWGui namespace MWGui
{ {
namespace Formatting
{
struct TextStyle struct TextStyle
{ {
TextStyle() : TextStyle() :
@ -21,47 +24,128 @@ namespace MWGui
MyGUI::Align mTextAlign; MyGUI::Align mTextAlign;
}; };
/// \brief utilities for parsing book/scroll text as mygui widgets
class BookTextParser class BookTextParser
{ {
public: public:
/** typedef std::map<std::string, std::string> Attributes;
* Parse markup as MyGUI widgets enum Events
* @param markup to parse {
* @param parent for the created widgets Event_None = -2,
* @param maximum width Event_EOF = -1,
* @return size of the created widgets Event_BrTag,
*/ Event_PTag,
MyGUI::IntSize parsePage(std::string text, MyGUI::Widget* parent, const int width); Event_ImgTag,
Event_DivTag,
Event_FontTag
};
/** BookTextParser(const std::string & text);
* Parse markup as MyGUI widgets void registerTag(const std::string & tag, Events type);
* @param markup to parse std::string getReadyText();
* @param parent for the created widgets
* @param maximum width
* @return size of the created widgets
*/
MyGUI::IntSize parseScroll(std::string text, MyGUI::Widget* parent, const int width);
/** Events next();
* Split the specified text into pieces that fit in the area specified by width and height parameters void flushBuffer();
*/ const Attributes & getAttributes() const;
std::vector<std::string> split(std::string text, const int width, const int height); void parseTag(std::string tag);
private:
size_t mIndex;
std::string mText;
std::string mReadyText;
bool mIgnoreNewlineTags;
bool mIgnoreLineEndings;
Attributes mAttributes;
std::string mTag;
std::map<std::string, Events> mTagTypes;
std::string mBuffer;
};
class Paginator
{
public:
typedef std::pair<int, int> Page;
typedef std::vector<Page> Pages;
Paginator(int pageWidth, int pageHeight)
: mStartTop(0), mCurrentTop(0),
mPageWidth(pageWidth), mPageHeight(pageHeight)
{
}
int getStartTop() const { return mStartTop; }
int getCurrentTop() const { return mCurrentTop; }
int getPageWidth() const { return mPageWidth; }
int getPageHeight() const { return mPageHeight; }
Pages getPages() const { return mPages; }
void setStartTop(int top) { mStartTop = top; }
void setCurrentTop(int top) { mCurrentTop = top; }
Paginator & operator<<(const Page & page)
{
mPages.push_back(page);
return *this;
}
private:
int mStartTop, mCurrentTop;
int mPageWidth, mPageHeight;
Pages mPages;
};
/// \brief utilities for parsing book/scroll text as mygui widgets
class BookFormatter
{
public:
Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup, const int pageWidth, const int pageHeight);
Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup);
protected: protected:
float widthForCharGlyph(unsigned unicodeChar) const; void handleImg(const BookTextParser::Attributes & attr);
float currentFontHeight() const; void handleDiv(const BookTextParser::Attributes & attr);
void parseSubText(std::string text); void handleFont(const BookTextParser::Attributes & attr);
void parseImage(std::string tag, bool createWidget=true);
void parseDiv(std::string tag);
void parseFont(std::string tag);
private: private:
MyGUI::Widget* mParent;
int mWidth; // maximum width
int mHeight; // current height
TextStyle mTextStyle; TextStyle mTextStyle;
}; };
class GraphicElement
{
public:
GraphicElement(MyGUI::Widget * parent, Paginator & pag);
virtual int getHeight() = 0;
virtual void paginate();
virtual int pageSplit();
protected:
MyGUI::Widget * mParent;
Paginator & mPaginator;
};
class TextElement : public GraphicElement
{
public:
TextElement(MyGUI::Widget * parent, Paginator & pag, const TextStyle & style, const std::string & text);
virtual int getHeight();
virtual int pageSplit();
private:
int currentFontHeight() const;
TextStyle mStyle;
MyGUI::EditBox * mEditBox;
};
class ImageElement : public GraphicElement
{
public:
ImageElement(MyGUI::Widget * parent, Paginator & pag, const std::string & src, int width, int height);
virtual int getHeight();
virtual int pageSplit();
private:
int mImageHeight;
MyGUI::ImageBox * mImageBox;
};
}
} }
#endif #endif

View file

@ -278,14 +278,14 @@ namespace MWGui
if (item.mType == ItemStack::Type_Barter) if (item.mType == ItemStack::Type_Barter)
{ {
// this was an item borrowed to us by the merchant // this was an item borrowed to us by the merchant
MWBase::Environment::get().getWindowManager()->getTradeWindow()->returnItem(mSelectedItem, count);
mTradeModel->returnItemBorrowedToUs(mSelectedItem, count); mTradeModel->returnItemBorrowedToUs(mSelectedItem, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->returnItem(mSelectedItem, count);
} }
else else
{ {
// borrow item to the merchant // borrow item to the merchant
MWBase::Environment::get().getWindowManager()->getTradeWindow()->borrowItem(mSelectedItem, count);
mTradeModel->borrowItemFromUs(mSelectedItem, count); mTradeModel->borrowItemFromUs(mSelectedItem, count);
MWBase::Environment::get().getWindowManager()->getTradeWindow()->borrowItem(mSelectedItem, count);
} }
mItemView->update(); mItemView->update();

View file

@ -36,7 +36,8 @@ namespace MWGui
Misc::StringUtils::toLower(currentGMSTID); Misc::StringUtils::toLower(currentGMSTID);
// Don't bother checking this GMST if it's not a sMagicBound* one. // Don't bother checking this GMST if it's not a sMagicBound* one.
if (currentGMSTID.find("smagicbound") != 0) const std::string& toFind = "smagicbound";
if (currentGMSTID.compare(0, toFind.length(), toFind) != 0)
continue; continue;
// All sMagicBound* GMST's should be of type string // All sMagicBound* GMST's should be of type string

View file

@ -113,10 +113,10 @@ struct JournalViewModelImpl : JournalViewModel
utf8text = getText (); utf8text = getText ();
size_t pos_begin, pos_end; size_t pos_end = 0;
for(;;) for(;;)
{ {
pos_begin = utf8text.find('@'); size_t pos_begin = utf8text.find('@');
if (pos_begin != std::string::npos) if (pos_begin != std::string::npos)
pos_end = utf8text.find('#', pos_begin); pos_end = utf8text.find('#', pos_begin);
@ -223,15 +223,6 @@ struct JournalViewModelImpl : JournalViewModel
} }
} }
void visitQuestName (QuestId questId, boost::function <void (Utf8Span)> visitor) const
{
MWDialogue::Quest const * quest = reinterpret_cast <MWDialogue::Quest const *> (questId);
std::string name = quest->getName ();
visitor (toUtf8Span (name));
}
template <typename iterator_t> template <typename iterator_t>
struct JournalEntryImpl : BaseEntry <iterator_t, JournalEntry> struct JournalEntryImpl : BaseEntry <iterator_t, JournalEntry>
{ {
@ -301,11 +292,6 @@ struct JournalViewModelImpl : JournalViewModel
} }
} }
void visitTopics (boost::function <void (TopicId, Utf8Span)> visitor) const
{
throw std::runtime_error ("not implemented");
}
void visitTopicName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const void visitTopicName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const
{ {
MWDialogue::Topic const & topic = * reinterpret_cast <MWDialogue::Topic const *> (topicId); MWDialogue::Topic const & topic = * reinterpret_cast <MWDialogue::Topic const *> (topicId);

View file

@ -67,9 +67,6 @@ namespace MWGui
/// returns true if their are no journal entries to display /// returns true if their are no journal entries to display
virtual bool isEmpty () const = 0; virtual bool isEmpty () const = 0;
/// provides access to the name of the quest with the specified identifier
virtual void visitQuestName (TopicId topicId, boost::function <void (Utf8Span)> visitor) const = 0;
/// walks the active and optionally completed, quests providing the name /// walks the active and optionally completed, quests providing the name
virtual void visitQuestNames (bool active_only, boost::function <void (const std::string&)> visitor) const = 0; virtual void visitQuestNames (bool active_only, boost::function <void (const std::string&)> visitor) const = 0;

View file

@ -4,7 +4,6 @@
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/journal.hpp" #include "../mwbase/journal.hpp"
#include "list.hpp"
#include <sstream> #include <sstream>
#include <set> #include <set>
@ -16,12 +15,12 @@
#include "boost/lexical_cast.hpp" #include "boost/lexical_cast.hpp"
#include <components/widgets/imagebutton.hpp> #include <components/widgets/imagebutton.hpp>
#include <components/widgets/list.hpp>
#include "bookpage.hpp" #include "bookpage.hpp"
#include "windowbase.hpp" #include "windowbase.hpp"
#include "journalviewmodel.hpp" #include "journalviewmodel.hpp"
#include "journalbooks.hpp" #include "journalbooks.hpp"
#include "list.hpp"
namespace namespace
{ {
@ -111,10 +110,10 @@ namespace
adviseButtonClick (ShowAllBTN, &JournalWindowImpl::notifyShowAll ); adviseButtonClick (ShowAllBTN, &JournalWindowImpl::notifyShowAll );
adviseButtonClick (ShowActiveBTN, &JournalWindowImpl::notifyShowActive); adviseButtonClick (ShowActiveBTN, &JournalWindowImpl::notifyShowActive);
MWGui::Widgets::MWList* list = getWidget<MWGui::Widgets::MWList>(QuestsList); Gui::MWList* list = getWidget<Gui::MWList>(QuestsList);
list->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyQuestClicked); list->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyQuestClicked);
MWGui::Widgets::MWList* topicsList = getWidget<MWGui::Widgets::MWList>(TopicsList); Gui::MWList* topicsList = getWidget<Gui::MWList>(TopicsList);
topicsList->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyTopicSelected); topicsList->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyTopicSelected);
{ {
@ -394,25 +393,13 @@ namespace
popBook (); popBook ();
} }
void showList (char const * listId, char const * pageId, Book book)
{
std::pair <int, int> size = book->getSize ();
getPage (pageId)->showPage (book, 0);
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
getWidget <MyGUI::ScrollView> (listId)->setVisibleVScroll(false);
getWidget <MyGUI::ScrollView> (listId)->setCanvasSize (size.first, size.second);
getWidget <MyGUI::ScrollView> (listId)->setVisibleVScroll(true);
}
void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId character) void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId character)
{ {
setVisible (LeftTopicIndex, false); setVisible (LeftTopicIndex, false);
setVisible (RightTopicIndex, false); setVisible (RightTopicIndex, false);
setVisible (TopicsList, true); setVisible (TopicsList, true);
MWGui::Widgets::MWList* list = getWidget<MWGui::Widgets::MWList>(TopicsList); Gui::MWList* list = getWidget<Gui::MWList>(TopicsList);
list->clear(); list->clear();
AddNamesToList add(list); AddNamesToList add(list);
@ -435,9 +422,9 @@ namespace
struct AddNamesToList struct AddNamesToList
{ {
AddNamesToList(MWGui::Widgets::MWList* list) : mList(list) {} AddNamesToList(Gui::MWList* list) : mList(list) {}
MWGui::Widgets::MWList* mList; Gui::MWList* mList;
void operator () (const std::string& name) void operator () (const std::string& name)
{ {
mList->addItem(name); mList->addItem(name);
@ -455,7 +442,7 @@ namespace
setVisible (ShowAllBTN, !mAllQuests); setVisible (ShowAllBTN, !mAllQuests);
setVisible (ShowActiveBTN, mAllQuests); setVisible (ShowActiveBTN, mAllQuests);
MWGui::Widgets::MWList* list = getWidget<MWGui::Widgets::MWList>(QuestsList); Gui::MWList* list = getWidget<Gui::MWList>(QuestsList);
list->clear(); list->clear();
AddNamesToList add(list); AddNamesToList add(list);

View file

@ -5,6 +5,7 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp" #include "../mwworld/fallback.hpp"
@ -139,7 +140,7 @@ namespace MWGui
// Vanilla uses thief.dds for custom classes. // Vanilla uses thief.dds for custom classes.
// Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found. // Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found.
MWWorld::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin(); MWWorld::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin();
for(; it != world->getStore().get<ESM::Class>().end(); it++) for(; it != world->getStore().get<ESM::Class>().end(); ++it)
{ {
if(it->mData.mIsPlayable && it->mData.mSpecialization == 2 && it->mData.mAttribute[0] == 4 && it->mData.mAttribute[1] == 3) if(it->mData.mIsPlayable && it->mData.mSpecialization == 2 && it->mData.mAttribute[0] == 4 && it->mData.mAttribute[1] == 3)
break; break;
@ -191,6 +192,9 @@ namespace MWGui
setAttributeValues(); setAttributeValues();
center(); center();
// Play LevelUp Music
MWBase::Environment::get().getSoundManager()->streamMusic("Special/MW_Triumph.mp3");
} }
void LevelupDialog::onOkButtonClicked(MyGUI::Widget* sender) void LevelupDialog::onOkButtonClicked(MyGUI::Widget* sender)

View file

@ -1,169 +0,0 @@
#include "list.hpp"
#include <MyGUI_Gui.h>
#include <MyGUI_Button.h>
#include <MyGUI_ImageBox.h>
#include <MyGUI_ScrollBar.h>
namespace MWGui
{
namespace Widgets
{
MWList::MWList() :
mClient(0)
, mScrollView(0)
, mItemHeight(0)
{
}
void MWList::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(mClient, "Client");
if (mClient == 0)
mClient = this;
mScrollView = mClient->createWidgetReal<MyGUI::ScrollView>(
"MW_ScrollView", MyGUI::FloatCoord(0.0, 0.0, 1.0, 1.0),
MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView");
}
void MWList::addItem(const std::string& name)
{
mItems.push_back(name);
}
void MWList::addSeparator()
{
mItems.push_back("");
}
void MWList::adjustSize()
{
redraw();
}
void MWList::redraw(bool scrollbarShown)
{
const int _scrollBarWidth = 20; // fetch this from skin?
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
const int spacing = 3;
size_t viewPosition = -mScrollView->getViewOffset().top;
while (mScrollView->getChildCount())
{
MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
}
mItemHeight = 0;
int i=0;
for (std::vector<std::string>::const_iterator it=mItems.begin();
it!=mItems.end(); ++it)
{
if (*it != "")
{
if (mListItemSkin.empty())
throw std::runtime_error("MWList needs a ListItemSkin property");
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
mListItemSkin, MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24),
MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it));
button->setCaption((*it));
button->getSubWidgetText()->setWordWrap(true);
button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left);
button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected);
int height = button->getTextSize().height;
button->setSize(MyGUI::IntSize(button->getSize().width, height));
button->setUserData(i);
mItemHeight += height + spacing;
}
else
{
MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth() - scrollBarWidth - 4, 18),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
separator->setNeedMouseFocus(false);
mItemHeight += 18 + spacing;
}
++i;
}
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mScrollView->setVisibleVScroll(false);
mScrollView->setCanvasSize(mClient->getSize().width, std::max(mItemHeight, mClient->getSize().height));
mScrollView->setVisibleVScroll(true);
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
redraw(true);
size_t viewRange = mScrollView->getCanvasSize().height;
if(viewPosition > viewRange)
viewPosition = viewRange;
mScrollView->setViewOffset(MyGUI::IntPoint(0, viewPosition * -1));
}
void MWList::setPropertyOverride(const std::string &_key, const std::string &_value)
{
if (_key == "ListItemSkin")
mListItemSkin = _value;
else
Base::setPropertyOverride(_key, _value);
}
bool MWList::hasItem(const std::string& name)
{
return (std::find(mItems.begin(), mItems.end(), name) != mItems.end());
}
unsigned int MWList::getItemCount()
{
return mItems.size();
}
std::string MWList::getItemNameAt(unsigned int at)
{
assert(at < mItems.size() && "List item out of bounds");
return mItems[at];
}
void MWList::removeItem(const std::string& name)
{
assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() );
mItems.erase( std::find(mItems.begin(), mItems.end(), name) );
}
void MWList::clear()
{
mItems.clear();
}
void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
//NB view offset is negative
if (mScrollView->getViewOffset().top + _rel*0.3 > 0)
mScrollView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mScrollView->setViewOffset(MyGUI::IntPoint(0, mScrollView->getViewOffset().top + _rel*0.3));
}
void MWList::onItemSelected(MyGUI::Widget* _sender)
{
std::string name = _sender->castType<MyGUI::Button>()->getCaption();
int id = *_sender->getUserData<int>();
eventItemSelected(name, id);
eventWidgetSelected(_sender);
}
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
{
return mScrollView->findWidget (getName() + "_item_" + name);
}
}
}

View file

@ -1,74 +0,0 @@
#ifndef MWGUI_LIST_HPP
#define MWGUI_LIST_HPP
#include <MyGUI_ScrollView.h>
namespace MWGui
{
namespace Widgets
{
/**
* \brief a very simple list widget that supports word-wrapping entries
* \note if the width or height of the list changes, you must call adjustSize() method
*/
class MWList : public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(MWList)
public:
MWList();
typedef MyGUI::delegates::CMultiDelegate2<const std::string&, int> EventHandle_StringInt;
typedef MyGUI::delegates::CMultiDelegate1<MyGUI::Widget*> EventHandle_Widget;
/**
* Event: Item selected with the mouse.
* signature: void method(std::string itemName, int index)
*/
EventHandle_StringInt 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
*/
void adjustSize();
void addItem(const std::string& name);
void addSeparator(); ///< add a seperator between the current and the next item.
void removeItem(const std::string& name);
bool hasItem(const std::string& name);
unsigned int getItemCount();
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
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
protected:
void initialiseOverride();
void redraw(bool scrollbarShown = false);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onItemSelected(MyGUI::Widget* _sender);
private:
MyGUI::ScrollView* mScrollView;
MyGUI::Widget* mClient;
std::string mListItemSkin;
std::vector<std::string> mItems;
int mItemHeight; // height of all items
};
}
}
#endif

View file

@ -26,15 +26,55 @@ namespace
const int cellSize = 8192; const int cellSize = 8192;
enum WidgetDepth enum LocalMapWidgetDepth
{ {
CompassLayer = 0, Local_CompassLayer = 0,
MarkerAboveFogLayer = 1, Local_MarkerAboveFogLayer = 1,
FogLayer = 2, Local_FogLayer = 2,
MarkerLayer = 3, Local_MarkerLayer = 3,
MapLayer = 4 Local_MapLayer = 4
}; };
enum GlobalMapWidgetDepth
{
Global_CompassLayer = 0,
Global_MarkerLayer = 1,
Global_ExploreOverlayLayer = 2,
Global_MapLayer = 3
};
/// @brief A widget that changes its color when hovered.
class MarkerWidget: public MyGUI::Widget
{
MYGUI_RTTI_DERIVED(MarkerWidget)
public:
void setNormalColour(const MyGUI::Colour& colour)
{
mNormalColour = colour;
setColour(colour);
}
void setHoverColour(const MyGUI::Colour& colour)
{
mHoverColour = colour;
}
private:
MyGUI::Colour mNormalColour;
MyGUI::Colour mHoverColour;
void onMouseLostFocus(MyGUI::Widget* _new)
{
setColour(mNormalColour);
}
void onMouseSetFocus(MyGUI::Widget* _old)
{
setColour(mHoverColour);
}
};
} }
namespace MWGui namespace MWGui
@ -140,7 +180,7 @@ namespace MWGui
mLocalMap = widget; mLocalMap = widget;
mCompass = compass; mCompass = compass;
mCompass->setDepth(CompassLayer); mCompass->setDepth(Local_CompassLayer);
mCompass->setNeedMouseFocus(false); mCompass->setNeedMouseFocus(false);
// create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each // create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each
@ -151,12 +191,12 @@ namespace MWGui
MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize), MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize),
MyGUI::Align::Top | MyGUI::Align::Left); MyGUI::Align::Top | MyGUI::Align::Left);
map->setDepth(MapLayer); map->setDepth(Local_MapLayer);
MyGUI::ImageBox* fog = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::ImageBox* fog = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize), MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize),
MyGUI::Align::Top | MyGUI::Align::Left); MyGUI::Align::Top | MyGUI::Align::Left);
fog->setDepth(FogLayer); fog->setDepth(Local_FogLayer);
map->setNeedMouseFocus(false); map->setNeedMouseFocus(false);
fog->setNeedMouseFocus(false); fog->setNeedMouseFocus(false);
@ -273,16 +313,17 @@ namespace MWGui
MyGUI::IntCoord widgetCoord(widgetPos.left - 4, MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
widgetPos.top - 4, widgetPos.top - 4,
8, 8); 8, 8);
MyGUI::Button* markerWidget = mLocalMap->createWidget<MyGUI::Button>("ButtonImage", MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>("MarkerButton",
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(MarkerAboveFogLayer); markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote)); markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote));
markerWidget->setColour(MyGUI::Colour(1.0,0.3,0.3)); markerWidget->setNormalColour(MyGUI::Colour(1.0,0.3,0.3));
markerWidget->setHoverColour(MyGUI::Colour(1.0,0.5,0.5));
markerWidget->setUserData(marker); markerWidget->setUserData(marker);
markerWidget->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &LocalMapBase::onCustomMarkerDoubleClicked); markerWidget->setNeedMouseFocus(true);
customMarkerCreated(markerWidget);
mCustomMarkerWidgets.push_back(markerWidget); mCustomMarkerWidgets.push_back(markerWidget);
} }
redraw(); redraw();
@ -357,16 +398,19 @@ namespace MWGui
widgetPos.top - 4, widgetPos.top - 4,
8, 8); 8, 8);
++counter; ++counter;
MyGUI::Button* markerWidget = mLocalMap->createWidget<MyGUI::Button>("ButtonImage", MarkerWidget* markerWidget = mLocalMap->createWidget<MarkerWidget>("MarkerButton",
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(MarkerLayer); markerWidget->setNormalColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}")));
markerWidget->setImageResource("DoorMarker"); markerWidget->setHoverColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal_over}")));
markerWidget->setDepth(Local_MarkerLayer);
markerWidget->setNeedMouseFocus(true);
markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", marker.name); markerWidget->setUserString("Caption_TextOneLine", marker.name);
// Used by tooltips to not show the tooltip if marker is hidden by fog of war // Used by tooltips to not show the tooltip if marker is hidden by fog of war
markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserString("IsMarker", "true");
markerWidget->setUserData(markerPos); markerWidget->setUserData(markerPos);
doorMarkerCreated(markerWidget);
mDoorMarkerWidgets.push_back(markerWidget); mDoorMarkerWidgets.push_back(markerWidget);
} }
@ -458,7 +502,7 @@ namespace MWGui
++counter; ++counter;
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(MarkerAboveFogLayer); markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setImageTexture(markerTexture); markerWidget->setImageTexture(markerTexture);
markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserString("IsMarker", "true");
markerWidget->setUserData(markerPos); markerWidget->setUserData(markerPos);
@ -503,7 +547,7 @@ namespace MWGui
8, 8); 8, 8);
MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::ImageBox* markerWidget = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
widgetCoord, MyGUI::Align::Default); widgetCoord, MyGUI::Align::Default);
markerWidget->setDepth(MarkerAboveFogLayer); markerWidget->setDepth(Local_MarkerAboveFogLayer);
markerWidget->setImageTexture("textures\\menu_map_smark.dds"); markerWidget->setImageTexture("textures\\menu_map_smark.dds");
markerWidget->setUserString("IsMarker", "true"); markerWidget->setUserString("IsMarker", "true");
markerWidget->setUserData(markerPos); markerWidget->setUserData(markerPos);
@ -523,7 +567,18 @@ namespace MWGui
, mGlobalMap(0) , mGlobalMap(0)
, mGlobalMapRender(0) , mGlobalMapRender(0)
, mEditNoteDialog() , mEditNoteDialog()
, mEventBoxGlobal(NULL)
, mEventBoxLocal(NULL)
, mGlobalMapImage(NULL)
, mGlobalMapOverlay(NULL)
{ {
static bool registered = false;
if (!registered)
{
MyGUI::FactoryManager::getInstance().registerFactory<MarkerWidget>("Widget");
registered = true;
}
mEditNoteDialog.setVisible(false); mEditNoteDialog.setVisible(false);
mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk); mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk);
mEditNoteDialog.eventDeleteClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditDelete); mEditNoteDialog.eventDeleteClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditDelete);
@ -537,6 +592,11 @@ namespace MWGui
getWidget(mPlayerArrowLocal, "CompassLocal"); getWidget(mPlayerArrowLocal, "CompassLocal");
getWidget(mPlayerArrowGlobal, "CompassGlobal"); getWidget(mPlayerArrowGlobal, "CompassGlobal");
mPlayerArrowGlobal->setDepth(Global_CompassLayer);
mPlayerArrowGlobal->setNeedMouseFocus(false);
mGlobalMapImage->setDepth(Global_MapLayer);
mGlobalMapOverlay->setDepth(Global_ExploreOverlayLayer);
mLastScrollWindowCoordinates = mLocalMap->getCoord(); mLastScrollWindowCoordinates = mLocalMap->getCoord();
mLocalMap->eventChangeCoord += MyGUI::newDelegate(this, &MapWindow::onChangeScrollWindowCoord); mLocalMap->eventChangeCoord += MyGUI::newDelegate(this, &MapWindow::onChangeScrollWindowCoord);
@ -549,6 +609,8 @@ namespace MWGui
getWidget(mEventBoxGlobal, "EventBoxGlobal"); getWidget(mEventBoxGlobal, "EventBoxGlobal");
mEventBoxGlobal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); mEventBoxGlobal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
mEventBoxGlobal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); mEventBoxGlobal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
mEventBoxGlobal->setDepth(Global_ExploreOverlayLayer);
getWidget(mEventBoxLocal, "EventBoxLocal"); getWidget(mEventBoxLocal, "EventBoxLocal");
mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
@ -672,34 +734,32 @@ namespace MWGui
void MapWindow::addVisitedLocation(const std::string& name, int x, int y) void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
{ {
float worldX, worldY;
mGlobalMapRender->cellTopLeftCornerToImageSpace (x, y, worldX, worldY);
MyGUI::IntCoord widgetCoord(
worldX * mGlobalMapRender->getWidth()+6,
worldY * mGlobalMapRender->getHeight()+6,
12, 12);
static int _counter=0;
MyGUI::Button* markerWidget = mGlobalMapOverlay->createWidget<MyGUI::Button>("ButtonImage",
widgetCoord, MyGUI::Align::Default);
markerWidget->setImageResource("DoorMarker");
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", name);
++_counter;
markerWidget = mEventBoxGlobal->createWidget<MyGUI::Button>("",
widgetCoord, MyGUI::Align::Default);
markerWidget->setNeedMouseFocus (true);
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", name);
CellId cell; CellId cell;
cell.first = x; cell.first = x;
cell.second = y; cell.second = y;
mMarkers.push_back(cell); if (mMarkers.insert(cell).second)
{
float worldX, worldY;
mGlobalMapRender->cellTopLeftCornerToImageSpace (x, y, worldX, worldY);
int markerSize = 12;
int offset = mGlobalMapRender->getCellSize()/2 - markerSize/2;
MyGUI::IntCoord widgetCoord(
worldX * mGlobalMapRender->getWidth()+offset,
worldY * mGlobalMapRender->getHeight()+offset,
markerSize, markerSize);
MyGUI::Widget* markerWidget = mGlobalMap->createWidget<MyGUI::Widget>("MarkerButton",
widgetCoord, MyGUI::Align::Default);
markerWidget->setNeedMouseFocus(true);
markerWidget->setColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}")));
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", name);
markerWidget->setDepth(Global_MarkerLayer);
markerWidget->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
markerWidget->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
}
} }
void MapWindow::cellExplored(int x, int y) void MapWindow::cellExplored(int x, int y)
@ -827,8 +887,6 @@ namespace MWGui
while (mEventBoxGlobal->getChildCount()) while (mEventBoxGlobal->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mEventBoxGlobal->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(mEventBoxGlobal->getChildAt(0));
while (mGlobalMapOverlay->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mGlobalMapOverlay->getChildAt(0));
} }
void MapWindow::write(ESM::ESMWriter &writer, Loading::Listener& progress) void MapWindow::write(ESM::ESMWriter &writer, Loading::Listener& progress)
@ -853,7 +911,7 @@ namespace MWGui
mGlobalMapRender->read(map); mGlobalMapRender->read(map);
for (std::vector<ESM::GlobalMap::CellId>::iterator it = map.mMarkers.begin(); it != map.mMarkers.end(); ++it) for (std::set<ESM::GlobalMap::CellId>::iterator it = map.mMarkers.begin(); it != map.mMarkers.end(); ++it)
{ {
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>().search(it->first, it->second); const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>().search(it->first, it->second);
if (cell && !cell->mName.empty()) if (cell && !cell->mName.empty())
@ -871,6 +929,19 @@ namespace MWGui
(*it)->setVisible(alpha == 1); (*it)->setVisible(alpha == 1);
} }
void MapWindow::customMarkerCreated(MyGUI::Widget *marker)
{
marker->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
marker->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
marker->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &MapWindow::onCustomMarkerDoubleClicked);
}
void MapWindow::doorMarkerCreated(MyGUI::Widget *marker)
{
marker->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
marker->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
EditNoteDialog::EditNoteDialog() EditNoteDialog::EditNoteDialog()

View file

@ -119,7 +119,8 @@ namespace MWGui
virtual void notifyPlayerUpdate() {} virtual void notifyPlayerUpdate() {}
virtual void notifyMapChanged() {} virtual void notifyMapChanged() {}
virtual void onCustomMarkerDoubleClicked(MyGUI::Widget* sender) {} virtual void customMarkerCreated(MyGUI::Widget* marker) {}
virtual void doorMarkerCreated(MyGUI::Widget* marker) {}
void updateMagicMarkers(); void updateMagicMarkers();
void addDetectionMarkers(int type); void addDetectionMarkers(int type);
@ -199,6 +200,7 @@ namespace MWGui
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onWorldButtonClicked(MyGUI::Widget* _sender); void onWorldButtonClicked(MyGUI::Widget* _sender);
void onMapDoubleClicked(MyGUI::Widget* sender); void onMapDoubleClicked(MyGUI::Widget* sender);
void onCustomMarkerDoubleClicked(MyGUI::Widget* sender);
void onNoteEditOk(); void onNoteEditOk();
void onNoteEditDelete(); void onNoteEditDelete();
void onNoteEditDeleteConfirm(); void onNoteEditDeleteConfirm();
@ -219,7 +221,7 @@ namespace MWGui
// Markers on global map // Markers on global map
typedef std::pair<int, int> CellId; typedef std::pair<int, int> CellId;
std::vector<CellId> mMarkers; std::set<CellId> mMarkers;
// Cells that should be explored in the next frame (i.e. their map revealed on the global map) // Cells that should be explored in the next frame (i.e. their map revealed on the global map)
// We can't do this immediately, because the map update is not immediate either (see mNeedMapUpdate in scene.cpp) // We can't do this immediately, because the map update is not immediate either (see mNeedMapUpdate in scene.cpp)
@ -235,7 +237,9 @@ namespace MWGui
virtual void onPinToggled(); virtual void onPinToggled();
virtual void onTitleDoubleClicked(); virtual void onTitleDoubleClicked();
virtual void onCustomMarkerDoubleClicked(MyGUI::Widget* sender);
virtual void doorMarkerCreated(MyGUI::Widget* marker);
virtual void customMarkerCreated(MyGUI::Widget *marker);
virtual void notifyPlayerUpdate(); virtual void notifyPlayerUpdate();

View file

@ -139,11 +139,6 @@ namespace MWGui
return false; return false;
} }
void MessageBoxManager::setMessageBoxSpeed (int speed)
{
mMessageBoxSpeed = speed;
}
int MessageBoxManager::readPressedButton () int MessageBoxManager::readPressedButton ()
{ {
int pressed = mLastButtonPressed; int pressed = mLastButtonPressed;
@ -218,7 +213,6 @@ namespace MWGui
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
int biggestButtonWidth = 0; int biggestButtonWidth = 0;
int buttonWidth = 0;
int buttonsWidth = 0; int buttonsWidth = 0;
int buttonsHeight = 0; int buttonsHeight = 0;
int buttonHeight = 0; int buttonHeight = 0;
@ -241,7 +235,7 @@ namespace MWGui
if (buttonsWidth != 0) if (buttonsWidth != 0)
buttonsWidth += buttonLeftPadding; buttonsWidth += buttonLeftPadding;
buttonWidth = button->getTextSize().width + 2*buttonPadding; int buttonWidth = button->getTextSize().width + 2*buttonPadding;
buttonsWidth += buttonWidth; buttonsWidth += buttonWidth;
buttonHeight = button->getTextSize().height + 2*buttonPadding; buttonHeight = button->getTextSize().height + 2*buttonPadding;

View file

@ -34,7 +34,6 @@ namespace MWGui
void clear(); void clear();
bool removeMessageBox (MessageBox *msgbox); bool removeMessageBox (MessageBox *msgbox);
void setMessageBoxSpeed (int speed);
int readPressedButton (); int readPressedButton ();

View file

@ -393,7 +393,6 @@ namespace MWGui
if (mCurrentRaceId.empty()) if (mCurrentRaceId.empty())
return; return;
Widgets::MWSpellPtr spellPowerWidget;
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), 18); MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), 18);
@ -405,7 +404,7 @@ namespace MWGui
for (int i = 0; it != end; ++it) for (int i = 0; it != end; ++it)
{ {
const std::string &spellpower = *it; const std::string &spellpower = *it;
spellPowerWidget = mSpellPowerList->createWidget<Widgets::MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i)); Widgets::MWSpellPtr spellPowerWidget = mSpellPowerList->createWidget<Widgets::MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
spellPowerWidget->setSpellId(spellpower); spellPowerWidget->setSpellId(spellpower);
spellPowerWidget->setUserString("ToolTipType", "Spell"); spellPowerWidget->setUserString("ToolTipType", "Spell");
spellPowerWidget->setUserString("Spell", spellpower); spellPowerWidget->setUserString("Spell", spellpower);

View file

@ -322,7 +322,8 @@ namespace MWGui
if (i == pos) if (i == pos)
mCurrentSlot = &*it; mCurrentSlot = &*it;
} }
assert(mCurrentSlot && "Can't find selected slot"); if (!mCurrentSlot)
throw std::runtime_error("Can't find selected slot");
std::stringstream text; std::stringstream text;
time_t time = mCurrentSlot->mTimeStamp; time_t time = mCurrentSlot->mTimeStamp;

View file

@ -54,8 +54,9 @@ namespace MWGui
MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>(); MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>();
BookTextParser parser; Formatting::BookFormatter formatter;
MyGUI::IntSize size = parser.parseScroll(ref->mBase->mText, mTextView, 390); formatter.markupToWidget(mTextView, ref->mBase->mText, 390, mTextView->getHeight());
MyGUI::IntSize size = mTextView->getChildAt(0)->getSize();
// Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden
mTextView->setVisibleVScroll(false); mTextView->setVisibleVScroll(false);

View file

@ -362,8 +362,7 @@ namespace MWGui
void SettingsWindow::onShaderModeToggled(MyGUI::Widget* _sender) void SettingsWindow::onShaderModeToggled(MyGUI::Widget* _sender)
{ {
std::string val = _sender->castType<MyGUI::Button>()->getCaption(); std::string val = hlslGlsl();
val = hlslGlsl();
_sender->castType<MyGUI::Button>()->setCaption(val); _sender->castType<MyGUI::Button>()->setCaption(val);

View file

@ -39,6 +39,7 @@ namespace MWGui
EditEffectDialog::EditEffectDialog() EditEffectDialog::EditEffectDialog()
: WindowModal("openmw_edit_effect.layout") : WindowModal("openmw_edit_effect.layout")
, mEditing(false) , mEditing(false)
, mMagicEffect(NULL)
{ {
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");
getWidget(mOkButton, "OkButton"); getWidget(mOkButton, "OkButton");
@ -181,7 +182,7 @@ namespace MWGui
{ {
mAreaBox->setPosition(mAreaBox->getPosition().left, curY); mAreaBox->setPosition(mAreaBox->getPosition().left, curY);
mAreaBox->setVisible (true); mAreaBox->setVisible (true);
curY += mAreaBox->getSize().height; //curY += mAreaBox->getSize().height;
} }
} }
@ -522,7 +523,7 @@ namespace MWGui
updateEffectsView (); updateEffectsView ();
} }
void EffectEditorBase::setWidgets (Widgets::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView) void EffectEditorBase::setWidgets (Gui::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView)
{ {
mAvailableEffectsList = availableEffectsList; mAvailableEffectsList = availableEffectsList;
mUsedEffectsView = usedEffectsView; mUsedEffectsView = usedEffectsView;

View file

@ -1,9 +1,10 @@
#ifndef MWGUI_SPELLCREATION_H #ifndef MWGUI_SPELLCREATION_H
#define MWGUI_SPELLCREATION_H #define MWGUI_SPELLCREATION_H
#include <components/widgets/list.hpp>
#include "windowbase.hpp" #include "windowbase.hpp"
#include "referenceinterface.hpp" #include "referenceinterface.hpp"
#include "list.hpp"
#include "widgets.hpp" #include "widgets.hpp"
namespace MWGui namespace MWGui
@ -97,7 +98,7 @@ namespace MWGui
protected: protected:
std::map<int, short> mButtonMapping; // maps button ID to effect ID std::map<int, short> mButtonMapping; // maps button ID to effect ID
Widgets::MWList* mAvailableEffectsList; Gui::MWList* mAvailableEffectsList;
MyGUI::ScrollView* mUsedEffectsView; MyGUI::ScrollView* mUsedEffectsView;
EditEffectDialog mAddEffectDialog; EditEffectDialog mAddEffectDialog;
@ -124,7 +125,7 @@ namespace MWGui
void updateEffectsView(); void updateEffectsView();
void startEditing(); void startEditing();
void setWidgets (Widgets::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); void setWidgets (Gui::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView);
virtual void notifyEffectsChanged () {} virtual void notifyEffectsChanged () {}
@ -157,8 +158,6 @@ namespace MWGui
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPriceLabel; MyGUI::TextBox* mPriceLabel;
Widgets::MWEffectList* mUsedEffectsList;
ESM::Spell mSpell; ESM::Spell mSpell;
}; };

View file

@ -2,6 +2,8 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/widgets/numericeditbox.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
@ -86,7 +88,7 @@ namespace MWGui
mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed); mDecreaseButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonPressed);
mDecreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased); mDecreaseButton->eventMouseButtonReleased += MyGUI::newDelegate(this, &TradeWindow::onBalanceButtonReleased);
mTotalBalance->eventEditTextChange += MyGUI::newDelegate(this, &TradeWindow::onBalanceEdited); mTotalBalance->eventValueChanged += MyGUI::newDelegate(this, &TradeWindow::onBalanceValueChanged);
setCoord(400, 0, 400, 300); setCoord(400, 0, 400, 300);
} }
@ -324,12 +326,12 @@ namespace MWGui
const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player); const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player);
float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100); float a1 = player.getClass().getSkill(player, ESM::Skill::Mercantile);
float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified();
float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); float c1 = 0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified();
float d1 = std::min(mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile), 100); float d1 = mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile);
float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); float e1 = 0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified();
float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f); float f1 = 0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified();
float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm(); float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm(); float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
@ -352,7 +354,15 @@ namespace MWGui
} }
//skill use! //skill use!
player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0); float skillGain = 0.f;
int finalPrice = std::abs(mCurrentBalance);
int initialMerchantOffer = std::abs(mCurrentMerchantOffer);
if (!buying && (finalPrice > initialMerchantOffer) && finalPrice > 0)
skillGain = int(100 * (finalPrice - initialMerchantOffer) / float(finalPrice));
else if (buying && (finalPrice < initialMerchantOffer) && initialMerchantOffer > 0)
skillGain = int(100 * (initialMerchantOffer - finalPrice) / float(initialMerchantOffer));
player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0, skillGain);
} }
int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt(); int iBarterSuccessDisposition = gmst.find("iBarterSuccessDisposition")->getInt();
@ -425,21 +435,14 @@ namespace MWGui
MyGUI::ControllerManager::getInstance().removeItem(_sender); MyGUI::ControllerManager::getInstance().removeItem(_sender);
} }
void TradeWindow::onBalanceEdited(MyGUI::EditBox *_sender) void TradeWindow::onBalanceValueChanged(int value)
{ {
try // Entering a "-" sign inverts the buying/selling state
{ mCurrentBalance = (mCurrentBalance >= 0 ? 1 : -1) * value;
unsigned int count = boost::lexical_cast<unsigned int>(_sender->getCaption());
mCurrentBalance = count * (mCurrentBalance >= 0 ? 1 : -1);
updateLabels(); updateLabels();
}
catch (std::bad_cast&) if (value != std::abs(value))
{ mTotalBalance->setValue(std::abs(value));
if (_sender->getCaption().empty())
mTotalBalance->setCaption("0");
else
mTotalBalance->setCaption(boost::lexical_cast<std::string>(std::abs(mCurrentBalance)));
}
} }
void TradeWindow::onIncreaseButtonTriggered() void TradeWindow::onIncreaseButtonTriggered()
@ -463,41 +466,52 @@ namespace MWGui
mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(playerGold)); mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(playerGold));
std::string balanceCaption;
if (mCurrentBalance > 0) if (mCurrentBalance > 0)
{ {
mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}"); mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}");
balanceCaption = boost::lexical_cast<std::string>(mCurrentBalance);
} }
else else
{ {
mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}"); mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}");
balanceCaption = boost::lexical_cast<std::string>(-mCurrentBalance);
} }
if (balanceCaption != mTotalBalance->getCaption().asUTF8()) // Don't reset text cursor if text doesn't need to be changed
mTotalBalance->setCaption(balanceCaption); mTotalBalance->setValue(std::abs(mCurrentBalance));
mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(getMerchantGold())); mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(getMerchantGold()));
} }
void TradeWindow::updateOffer()
{
TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel();
int merchantOffer = 0;
std::vector<ItemStack> playerBorrowed = playerTradeModel->getItemsBorrowedToUs();
for (std::vector<ItemStack>::const_iterator it = playerBorrowed.begin(); it != playerBorrowed.end(); ++it)
{
merchantOffer -= MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(it->mBase, it->mCount), true);
}
std::vector<ItemStack> merchantBorrowed = mTradeModel->getItemsBorrowedToUs();
for (std::vector<ItemStack>::const_iterator it = merchantBorrowed.begin(); it != merchantBorrowed.end(); ++it)
{
merchantOffer += MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(it->mBase, it->mCount), false);
}
int diff = merchantOffer - mCurrentMerchantOffer;
mCurrentMerchantOffer = merchantOffer;
mCurrentBalance += diff;
updateLabels();
}
void TradeWindow::sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem) void TradeWindow::sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem)
{ {
int diff = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(item, count), boughtItem); updateOffer();
mCurrentBalance += diff;
mCurrentMerchantOffer += diff;
updateLabels();
} }
void TradeWindow::buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem) void TradeWindow::buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem)
{ {
int diff = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, getEffectiveValue(item, count), !soldItem); updateOffer();
mCurrentBalance -= diff;
mCurrentMerchantOffer -= diff;
updateLabels();
} }
void TradeWindow::onReferenceUnavailable() void TradeWindow::onReferenceUnavailable()

View file

@ -3,10 +3,9 @@
#include "container.hpp" #include "container.hpp"
namespace MyGUI namespace Gui
{ {
class Gui; class NumericEditBox;
class Widget;
} }
namespace MWGui namespace MWGui
@ -54,7 +53,7 @@ namespace MWGui
MyGUI::Button* mIncreaseButton; MyGUI::Button* mIncreaseButton;
MyGUI::Button* mDecreaseButton; MyGUI::Button* mDecreaseButton;
MyGUI::TextBox* mTotalBalanceLabel; MyGUI::TextBox* mTotalBalanceLabel;
MyGUI::EditBox* mTotalBalance; Gui::NumericEditBox* mTotalBalance;
MyGUI::Widget* mBottomPane; MyGUI::Widget* mBottomPane;
@ -72,6 +71,8 @@ namespace MWGui
void sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance void sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance
void buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance void buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance
void updateOffer();
void onItemSelected (int index); void onItemSelected (int index);
void sellItem (MyGUI::Widget* sender, int count); void sellItem (MyGUI::Widget* sender, int count);
@ -82,7 +83,7 @@ namespace MWGui
void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onBalanceEdited(MyGUI::EditBox* _sender); void onBalanceValueChanged(int value);
void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller); void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller);
void addRepeatController(MyGUI::Widget* widget); void addRepeatController(MyGUI::Widget* widget);

View file

@ -225,11 +225,10 @@ namespace MWGui
const ESM::Spell *spell = store.get<ESM::Spell>().search(mId); const ESM::Spell *spell = store.get<ESM::Spell>().search(mId);
MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found"); MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found");
MWSpellEffectPtr effect = NULL;
std::vector<ESM::ENAMstruct>::const_iterator end = spell->mEffects.mList.end(); std::vector<ESM::ENAMstruct>::const_iterator end = spell->mEffects.mList.end();
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != end; ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != end; ++it)
{ {
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default); MWSpellEffectPtr effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
SpellEffectParams params; SpellEffectParams params;
params.mEffectID = it->mEffectID; params.mEffectID = it->mEffectID;
params.mSkill = it->mSkill; params.mSkill = it->mSkill;
@ -565,22 +564,6 @@ namespace MWGui
} }
} }
void MWScrollBar::setEnableRepeat(bool enable)
{
mEnableRepeat = enable;
}
bool MWScrollBar::getEnableRepeat()
{
return mEnableRepeat;
}
void MWScrollBar::getRepeat(float &trigger, float &step)
{
trigger = mRepeatTriggerTime;
step = mRepeatStepTime;
}
void MWScrollBar::setRepeat(float trigger, float step) void MWScrollBar::setRepeat(float trigger, float step)
{ {
mRepeatTriggerTime = trigger; mRepeatTriggerTime = trigger;

View file

@ -307,9 +307,6 @@ namespace MWGui
MWScrollBar(); MWScrollBar();
virtual ~MWScrollBar(); virtual ~MWScrollBar();
void setEnableRepeat(bool enable);
bool getEnableRepeat();
void getRepeat(float &trigger, float &step);
void setRepeat(float trigger, float step); void setRepeat(float trigger, float step);
protected: protected:

View file

@ -76,6 +76,8 @@ void WindowModal::close()
NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget) NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget)
: mDrag(drag), mWidget(widget), mTransparent(false) : mDrag(drag), mWidget(widget), mTransparent(false)
{ {
if (!mWidget)
throw std::runtime_error("NoDrop needs a non-NULL widget!");
} }
void NoDrop::onFrame(float dt) void NoDrop::onFrame(float dt)

View file

@ -18,7 +18,8 @@
#include <components/fontloader/fontloader.hpp> #include <components/fontloader/fontloader.hpp>
#include <components/widgets/box.hpp> #include <components/widgets/widgets.hpp>
#include <components/widgets/tags.hpp>
#include "../mwbase/inputmanager.hpp" #include "../mwbase/inputmanager.hpp"
#include "../mwbase/statemanager.hpp" #include "../mwbase/statemanager.hpp"
@ -71,6 +72,7 @@
#include "backgroundimage.hpp" #include "backgroundimage.hpp"
#include "itemwidget.hpp" #include "itemwidget.hpp"
#include "screenfader.hpp" #include "screenfader.hpp"
#include "debugwindow.hpp"
namespace MWGui namespace MWGui
{ {
@ -119,6 +121,7 @@ namespace MWGui
, mVideoBackground(NULL) , mVideoBackground(NULL)
, mVideoWidget(NULL) , mVideoWidget(NULL)
, mScreenFader(NULL) , mScreenFader(NULL)
, mDebugWindow(NULL)
, mTranslationDataStorage (translationDataStorage) , mTranslationDataStorage (translationDataStorage)
, mCharGen(NULL) , mCharGen(NULL)
, mInputBlocker(NULL) , mInputBlocker(NULL)
@ -164,13 +167,6 @@ namespace MWGui
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWEffectList>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWEffectList>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpellEffect>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWSpellEffect>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWDynamicStat>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWList>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<Gui::HBox>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<Gui::VBox>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<Gui::AutoSizedTextBox>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<Gui::AutoSizedEditBox>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<Gui::AutoSizedButton>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<Gui::ImageButton>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollBar>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollBar>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<VideoWidget>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<VideoWidget>("Widget");
@ -178,6 +174,7 @@ namespace MWGui
BookPage::registerMyGUIComponents (); BookPage::registerMyGUIComponents ();
ItemView::registerComponents(); ItemView::registerComponents();
ItemWidget::registerComponents(); ItemWidget::registerComponents();
Gui::registerAllWidgets();
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatEvent>("Controller"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatEvent>("Controller");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerFollowMouse>("Controller"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerFollowMouse>("Controller");
@ -271,6 +268,7 @@ namespace MWGui
mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager); mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
trackWindow(mCompanionWindow, "companion"); trackWindow(mCompanionWindow, "companion");
mScreenFader = new ScreenFader(); mScreenFader = new ScreenFader();
mDebugWindow = new DebugWindow();
mInputBlocker = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Stretch,"Overlay"); mInputBlocker = MyGUI::Gui::getInstance().createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Stretch,"Overlay");
@ -362,6 +360,7 @@ namespace MWGui
delete mRecharge; delete mRecharge;
delete mCompanionWindow; delete mCompanionWindow;
delete mScreenFader; delete mScreenFader;
delete mDebugWindow;
cleanupGarbage(); cleanupGarbage();
@ -864,6 +863,8 @@ namespace MWGui
mCompanionWindow->onFrame(); mCompanionWindow->onFrame();
mScreenFader->update(frameDuration); mScreenFader->update(frameDuration);
mDebugWindow->onFrame(frameDuration);
} }
void WindowManager::changeCell(MWWorld::CellStore* cell) void WindowManager::changeCell(MWWorld::CellStore* cell)
@ -991,50 +992,13 @@ namespace MWGui
std::string tokenToFind = "sCell="; std::string tokenToFind = "sCell=";
size_t tokenLength = tokenToFind.length(); size_t tokenLength = tokenToFind.length();
std::string fontcolour = "fontcolour=";
size_t fontcolourLength = fontcolour.length();
std::string fontcolourhtml = "fontcolourhtml=";
size_t fontcolourhtmlLength = fontcolourhtml.length();
if (tag.compare(0, tokenLength, tokenToFind) == 0) if (tag.compare(0, tokenLength, tokenToFind) == 0)
{ {
_result = mTranslationDataStorage.translateCellName(tag.substr(tokenLength)); _result = mTranslationDataStorage.translateCellName(tag.substr(tokenLength));
} }
else if (tag.compare(0, fontcolourLength, fontcolour) == 0) else if (Gui::replaceTag(tag, _result, mFallbackMap))
{ {
std::string fallbackName = "FontColor_color_" + tag.substr(fontcolourLength); return;
std::map<std::string, std::string>::const_iterator it = mFallbackMap.find(fallbackName);
if (it == mFallbackMap.end())
throw std::runtime_error("Unknown fallback name: " + fallbackName);
std::string str = it->second;
std::string ret[3];
unsigned int j=0;
for(unsigned int i=0;i<str.length();++i){
if(str[i]==',') j++;
else if (str[i] != ' ') ret[j]+=str[i];
}
MyGUI::Colour col (MyGUI::utility::parseInt(ret[0])/255.f,MyGUI::utility::parseInt(ret[1])/255.f,MyGUI::utility::parseInt(ret[2])/255.f);
_result = col.print();
}
else if (tag.compare(0, fontcolourhtmlLength, fontcolourhtml) == 0)
{
std::string fallbackName = "FontColor_color_" + tag.substr(fontcolourhtmlLength);
std::map<std::string, std::string>::const_iterator it = mFallbackMap.find(fallbackName);
if (it == mFallbackMap.end())
throw std::runtime_error("Unknown fallback name: " + fallbackName);
std::string str = it->second;
std::string ret[3];
unsigned int j=0;
for(unsigned int i=0;i<str.length();++i){
if(str[i]==',') j++;
else if (str[i] != ' ') ret[j]+=str[i];
}
std::stringstream html;
html << "#" << std::hex << MyGUI::utility::parseInt(ret[0]) << MyGUI::utility::parseInt(ret[1]) << MyGUI::utility::parseInt(ret[2]);
_result = html.str();
} }
else else
{ {
@ -1390,12 +1354,6 @@ namespace MWGui
return mSubtitlesEnabled; return mSubtitlesEnabled;
} }
void WindowManager::toggleHud ()
{
mHudEnabled = !mHudEnabled;
mHud->setVisible (mHudEnabled);
}
bool WindowManager::toggleGui() bool WindowManager::toggleGui()
{ {
mGuiEnabled = !mGuiEnabled; mGuiEnabled = !mGuiEnabled;
@ -1711,7 +1669,7 @@ namespace MWGui
WindowModal* WindowManager::getCurrentModal() const WindowModal* WindowManager::getCurrentModal() const
{ {
if(mCurrentModals.size() > 0) if(!mCurrentModals.empty())
return mCurrentModals.top(); return mCurrentModals.top();
else else
return NULL; return NULL;
@ -1721,7 +1679,7 @@ namespace MWGui
{ {
// Only remove the top if it matches the current pointer. A lot of things hide their visibility before showing it, // Only remove the top if it matches the current pointer. A lot of things hide their visibility before showing it,
//so just popping the top would cause massive issues. //so just popping the top would cause massive issues.
if(mCurrentModals.size() > 0) if(!mCurrentModals.empty())
if(input == mCurrentModals.top()) if(input == mCurrentModals.top())
mCurrentModals.pop(); mCurrentModals.pop();
} }
@ -1797,4 +1755,9 @@ namespace MWGui
SDL_free(text); SDL_free(text);
} }
void WindowManager::toggleDebugWindow()
{
mDebugWindow->setVisible(!mDebugWindow->isVisible());
}
} }

View file

@ -89,6 +89,7 @@ namespace MWGui
class VideoWidget; class VideoWidget;
class WindowModal; class WindowModal;
class ScreenFader; class ScreenFader;
class DebugWindow;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -222,7 +223,6 @@ namespace MWGui
virtual void showCrosshair(bool show); virtual void showCrosshair(bool show);
virtual bool getSubtitlesEnabled(); virtual bool getSubtitlesEnabled();
virtual void toggleHud();
/// Turn visibility of *all* GUI elements on or off (HUD and all windows, except the console) /// Turn visibility of *all* GUI elements on or off (HUD and all windows, except the console)
virtual bool toggleGui(); virtual bool toggleGui();
@ -334,6 +334,8 @@ namespace MWGui
/// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading. /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
virtual void setScreenFactor (float factor); virtual void setScreenFactor (float factor);
virtual void toggleDebugWindow();
private: private:
bool mConsoleOnlyScripts; bool mConsoleOnlyScripts;
@ -387,6 +389,7 @@ namespace MWGui
MyGUI::ImageBox* mVideoBackground; MyGUI::ImageBox* mVideoBackground;
VideoWidget* mVideoWidget; VideoWidget* mVideoWidget;
ScreenFader* mScreenFader; ScreenFader* mScreenFader;
DebugWindow* mDebugWindow;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;
Cursor* mSoftwareCursor; Cursor* mSoftwareCursor;

View file

@ -279,6 +279,9 @@ namespace MWInput
case A_ToggleHUD: case A_ToggleHUD:
MWBase::Environment::get().getWindowManager()->toggleGui(); MWBase::Environment::get().getWindowManager()->toggleGui();
break; break;
case A_ToggleDebug:
MWBase::Environment::get().getWindowManager()->toggleDebugWindow();
break;
case A_QuickSave: case A_QuickSave:
quickSave(); quickSave();
break; break;
@ -902,6 +905,7 @@ namespace MWInput
defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0; defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0;
defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12; defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12;
defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11; defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11;
defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10;
defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK; defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK;
defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5; defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5;
defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9; defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9;

View file

@ -259,6 +259,8 @@ namespace MWInput
A_ToggleHUD, A_ToggleHUD,
A_ToggleDebug,
A_Last // Marker for the last item A_Last // Marker for the last item
}; };
}; };

View file

@ -323,8 +323,9 @@ namespace MWMechanics
for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it) for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it)
{ {
// need to check both ways since player doesn't use AI packages // need to check both ways since player doesn't use AI packages
if (creatureStats2.getAiSequence().isInCombat(*it) if ((creatureStats2.getAiSequence().isInCombat(*it)
|| it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2)) || it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2))
&& !creatureStats.getAiSequence().isInCombat(*it))
aggressive = true; aggressive = true;
} }
@ -337,6 +338,9 @@ namespace MWMechanics
if (followTarget.isEmpty()) if (followTarget.isEmpty())
continue; continue;
if (creatureStats.getAiSequence().isInCombat(followTarget))
continue;
// need to check both ways since player doesn't use AI packages // need to check both ways since player doesn't use AI packages
if (creatureStats2.getAiSequence().isInCombat(followTarget) if (creatureStats2.getAiSequence().isInCombat(followTarget)
|| followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2)) || followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2))
@ -466,13 +470,13 @@ namespace MWMechanics
return; return;
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
// restore fatigue // restore fatigue
float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat (); const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat (); static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->getFloat ();
static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->getFloat ();
float x = fFatigueReturnBase + fFatigueReturnMult * endurance; float x = fFatigueReturnBase + fFatigueReturnMult * endurance;
@ -1175,14 +1179,26 @@ namespace MWMechanics
iter->second->updateContinuousVfx(); iter->second->updateContinuousVfx();
// Animation/movement update // Animation/movement update
CharacterController* playerCharacter = NULL;
for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{ {
if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get( if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get(
ESM::MagicEffect::Paralyze).getMagnitude() > 0) ESM::MagicEffect::Paralyze).getMagnitude() > 0)
iter->second->skipAnim(); iter->second->skipAnim();
// Handle player last, in case a cell transition occurs by casting a teleportation spell
// (would invalidate the iterator)
if (iter->first.getCellRef().getRefId() == "player")
{
playerCharacter = iter->second;
continue;
}
iter->second->update(duration); iter->second->update(duration);
} }
if (playerCharacter)
playerCharacter->update(duration);
for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) for(PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{ {
const MWWorld::Class &cls = iter->first.getClass(); const MWWorld::Class &cls = iter->first.getClass();
@ -1207,7 +1223,8 @@ namespace MWMechanics
// check if we still have any player enemies to switch music // check if we still have any player enemies to switch music
static bool isBattleMusic = false; static bool isBattleMusic = false;
if (isBattleMusic && hostilesCount == 0) if (isBattleMusic && hostilesCount == 0 && !(player.getClass().getCreatureStats(player).isDead() &&
MWBase::Environment::get().getSoundManager()->isMusicPlaying()))
{ {
MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore"));
isBattleMusic = false; isBattleMusic = false;
@ -1219,14 +1236,14 @@ namespace MWMechanics
} }
static float sneakTimer = 0.f; // times update of sneak icon static float sneakTimer = 0.f; // times update of sneak icon
static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice"
// if player is in sneak state see if anyone detects him // if player is in sneak state see if anyone detects him
if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)) if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak))
{ {
static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice"
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
const int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt(); const int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt();
bool detected = false;
static float fSneakUseDelay = esmStore.get<ESM::GameSetting>().find("fSneakUseDelay")->getFloat(); static float fSneakUseDelay = esmStore.get<ESM::GameSetting>().find("fSneakUseDelay")->getFloat();
@ -1238,6 +1255,8 @@ namespace MWMechanics
// Set when an NPC is within line of sight and distance, but is still unaware. Used for skill progress. // Set when an NPC is within line of sight and distance, but is still unaware. Used for skill progress.
bool avoidedNotice = false; bool avoidedNotice = false;
bool detected = false;
for (PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) for (PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{ {
if (iter->first == player) // not the player if (iter->first == player) // not the player
@ -1405,7 +1424,7 @@ namespace MWMechanics
std::list<MWWorld::Ptr> Actors::getActorsFollowing(const MWWorld::Ptr& actor) std::list<MWWorld::Ptr> Actors::getActorsFollowing(const MWWorld::Ptr& actor)
{ {
std::list<MWWorld::Ptr> list; std::list<MWWorld::Ptr> list;
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++) for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
{ {
const MWWorld::Class &cls = iter->first.getClass(); const MWWorld::Class &cls = iter->first.getClass();
CreatureStats &stats = cls.getCreatureStats(iter->first); CreatureStats &stats = cls.getCreatureStats(iter->first);
@ -1437,7 +1456,7 @@ namespace MWMechanics
getObjectsInRange(position, getObjectsInRange(position,
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(), MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(),
neighbors); //only care about those within the alarm disance neighbors); //only care about those within the alarm disance
for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();iter++) for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();++iter)
{ {
const MWWorld::Class &cls = iter->getClass(); const MWWorld::Class &cls = iter->getClass();
CreatureStats &stats = cls.getCreatureStats(*iter); CreatureStats &stats = cls.getCreatureStats(*iter);

View file

@ -35,8 +35,6 @@ namespace MWMechanics
private: private:
std::string mObjectId; std::string mObjectId;
int mCellX;
int mCellY;
}; };
} }
#endif // GAME_MWMECHANICS_AIACTIVATE_H #endif // GAME_MWMECHANICS_AIACTIVATE_H

View file

@ -64,7 +64,7 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor,float duration
// Make all nearby actors also avoid the door // Make all nearby actors also avoid the door
std::vector<MWWorld::Ptr> actors; std::vector<MWWorld::Ptr> actors;
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(pos.pos[0],pos.pos[1],pos.pos[2]),100,actors); MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(pos.pos[0],pos.pos[1],pos.pos[2]),100,actors);
for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); it++) { for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it) {
if(*it != MWBase::Environment::get().getWorld()->getPlayerPtr()) { //Not the player if(*it != MWBase::Environment::get().getWorld()->getPlayerPtr()) { //Not the player
MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence(); MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence();
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) { //Only add it once if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) { //Only add it once

View file

@ -300,6 +300,8 @@ namespace MWMechanics
case ESM::MagicEffect::DrainAttribute: case ESM::MagicEffect::DrainAttribute:
if (!target.isEmpty() && target.getClass().getCreatureStats(target).getAttribute(effect.mAttribute).getModified() <= 0) if (!target.isEmpty() && target.getClass().getCreatureStats(target).getAttribute(effect.mAttribute).getModified() <= 0)
return 0.f; return 0.f;
{
if (effect.mAttribute >= 0 && effect.mAttribute < ESM::Attribute::Length)
{ {
const float attributePriorities[ESM::Attribute::Length] = { const float attributePriorities[ESM::Attribute::Length] = {
1.f, // Strength 1.f, // Strength
@ -311,9 +313,9 @@ namespace MWMechanics
0.7, // Personality 0.7, // Personality
0.3 // Luck 0.3 // Luck
}; };
if (effect.mAttribute >= 0 && effect.mAttribute < ESM::Attribute::Length)
rating *= attributePriorities[effect.mAttribute]; rating *= attributePriorities[effect.mAttribute];
} }
}
break; break;
case ESM::MagicEffect::DamageSkill: case ESM::MagicEffect::DamageSkill:

View file

@ -54,6 +54,7 @@ namespace MWMechanics
, mCellY(std::numeric_limits<int>::max()) , mCellY(std::numeric_limits<int>::max())
, mCellId(escort->mCellId) , mCellId(escort->mCellId)
, mRemainingDuration(escort->mRemainingDuration) , mRemainingDuration(escort->mRemainingDuration)
, mMaxDist(450)
{ {
} }
@ -91,7 +92,11 @@ namespace MWMechanics
if(distanceBetweenResult <= mMaxDist * mMaxDist) if(distanceBetweenResult <= mMaxDist * mMaxDist)
{ {
if(pathTo(actor,ESM::Pathgrid::Point(mX,mY,mZ),duration)) //Returns true on path complete ESM::Pathgrid::Point point(mX,mY,mZ);
point.mAutogenerated = 0;
point.mConnectionNum = 0;
point.mUnknown = 0;
if(pathTo(actor,point,duration)) //Returns true on path complete
return true; return true;
mMaxDist = 450; mMaxDist = 450;
} }

View file

@ -50,11 +50,6 @@ bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
) )
return true; //Target doesn't exist return true; //Target doesn't exist
// Only the player can be actively followed. AiFollow packages with targets other than the player
// are only used for defining combat alliances, since NPCs will defend whoever they are following or being followed by.
if (target != MWBase::Environment::get().getWorld()->getPlayerPtr())
return false;
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor ESM::Position pos = actor.getRefData().getPosition(); //position of the actor

View file

@ -69,7 +69,6 @@ namespace MWMechanics
PathFinder mPathFinder; PathFinder mPathFinder;
ObstacleCheck mObstacleCheck; ObstacleCheck mObstacleCheck;
float mDoorCheckDuration;
float mTimer; float mTimer;
float mStuckTimer; float mStuckTimer;

View file

@ -41,8 +41,6 @@ namespace MWMechanics
private: private:
int mTargetActorId; // The actor to pursue int mTargetActorId; // The actor to pursue
int mCellX;
int mCellY;
}; };
} }
#endif #endif

View file

@ -31,9 +31,11 @@ void AiSequence::copy (const AiSequence& sequence)
AiSequence::AiSequence() : mDone (false), mLastAiPackage(-1) {} AiSequence::AiSequence() : mDone (false), mLastAiPackage(-1) {}
AiSequence::AiSequence (const AiSequence& sequence) : mDone (false) AiSequence::AiSequence (const AiSequence& sequence)
{ {
copy (sequence); copy (sequence);
mDone = sequence.mDone;
mLastAiPackage = sequence.mLastAiPackage;
} }
AiSequence& AiSequence::operator= (const AiSequence& sequence) AiSequence& AiSequence::operator= (const AiSequence& sequence)
@ -43,6 +45,7 @@ AiSequence& AiSequence::operator= (const AiSequence& sequence)
clear(); clear();
copy (sequence); copy (sequence);
mDone = sequence.mDone; mDone = sequence.mDone;
mLastAiPackage = sequence.mLastAiPackage;
} }
return *this; return *this;
@ -120,33 +123,6 @@ bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const
return false; return false;
} }
bool AiSequence::canAddTarget(const ESM::Position& actorPos, float distToTarget) const
{
bool firstCombatFound = false;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
for(std::list<AiPackage*>::const_iterator it = mPackages.begin(); it != mPackages.end(); ++it)
{
if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
{
firstCombatFound = true;
const AiCombat *combat = static_cast<const AiCombat *>(*it);
if (combat->getTarget() != player ) return false; // only 1 non-player target allowed
else
{
// add new target only if current target (player) is farther
const ESM::Position &targetPos = combat->getTarget().getRefData().getPosition();
float distToCurrTarget = (Ogre::Vector3(targetPos.pos) - Ogre::Vector3(actorPos.pos)).length();
return (distToCurrTarget > distToTarget);
}
}
else if (firstCombatFound) break; // assumes combat packages go one-by-one in packages list
}
return true;
}
void AiSequence::stopCombat() void AiSequence::stopCombat()
{ {
while (getTypeId() == AiPackage::TypeIdCombat) while (getTypeId() == AiPackage::TypeIdCombat)
@ -295,11 +271,6 @@ void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
mPackages.push_front (package.clone()); mPackages.push_front (package.clone());
} }
void AiSequence::queue (const AiPackage& package)
{
mPackages.push_back (package.clone());
}
AiPackage* MWMechanics::AiSequence::getActivePackage() AiPackage* MWMechanics::AiSequence::getActivePackage()
{ {
if(mPackages.empty()) if(mPackages.empty())

View file

@ -98,10 +98,6 @@ namespace MWMechanics
@param actor The actor that owns this AiSequence **/ @param actor The actor that owns this AiSequence **/
void stack (const AiPackage& package, const MWWorld::Ptr& actor); void stack (const AiPackage& package, const MWWorld::Ptr& actor);
/// Add \a package to the end of the sequence
/** Executed after all other packages have been completed **/
void queue (const AiPackage& package);
/// Return the current active package. /// Return the current active package.
/** If there is no active package, it will throw an exception **/ /** If there is no active package, it will throw an exception **/
AiPackage* getActivePackage(); AiPackage* getActivePackage();

View file

@ -686,16 +686,15 @@ namespace MWMechanics
} }
AiWander::AiWander (const ESM::AiSequence::AiWander* wander) AiWander::AiWander (const ESM::AiSequence::AiWander* wander)
: mDistance(wander->mData.mDistance)
, mDuration(wander->mData.mDuration)
, mStartTime(MWWorld::TimeStamp(wander->mStartTime))
, mTimeOfDay(wander->mData.mTimeOfDay)
, mRepeat(wander->mData.mShouldRepeat)
{ {
mDistance = wander->mData.mDistance;
mDuration = wander->mData.mDuration;
mStartTime = MWWorld::TimeStamp(wander->mStartTime);
mTimeOfDay = wander->mData.mTimeOfDay;
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
mIdle.push_back(wander->mData.mIdle[i]); mIdle.push_back(wander->mData.mIdle[i]);
mRepeat = wander->mData.mShouldRepeat;
init(); init();
} }
} }

View file

@ -27,6 +27,11 @@
#include "creaturestats.hpp" #include "creaturestats.hpp"
#include "npcstats.hpp" #include "npcstats.hpp"
MWMechanics::Alchemy::Alchemy()
: mValue(0)
{
}
std::set<MWMechanics::EffectKey> MWMechanics::Alchemy::listEffects() const std::set<MWMechanics::EffectKey> MWMechanics::Alchemy::listEffects() const
{ {
std::map<EffectKey, int> effects; std::map<EffectKey, int> effects;

View file

@ -22,6 +22,8 @@ namespace MWMechanics
{ {
public: public:
Alchemy();
typedef std::vector<MWWorld::Ptr> TToolsContainer; typedef std::vector<MWWorld::Ptr> TToolsContainer;
typedef TToolsContainer::const_iterator TToolsIterator; typedef TToolsContainer::const_iterator TToolsIterator;

View file

@ -220,7 +220,7 @@ namespace MWMechanics
if (spell->mData.mFlags & ESM::Spell::F_Always) if (spell->mData.mFlags & ESM::Spell::F_Always)
return 100.f; return 100.f;
float skillTerm; float skillTerm = 0;
if (effectiveSchool != -1) if (effectiveSchool != -1)
skillTerm = 2.f * actorSkills[mapSchoolToSkill(effectiveSchool)]; skillTerm = 2.f * actorSkills[mapSchoolToSkill(effectiveSchool)];
else else

View file

@ -1611,7 +1611,7 @@ void CharacterController::update(float duration)
if(mMovementAnimationControlled && mPtr.getClass().isActor()) if(mMovementAnimationControlled && mPtr.getClass().isActor())
world->queueMovement(mPtr, moved); world->queueMovement(mPtr, moved);
} }
else if (mAnimation) else
mAnimation->updateEffects(duration); mAnimation->updateEffects(duration);
mSkipAnim = false; mSkipAnim = false;
@ -1703,6 +1703,10 @@ bool CharacterController::kill()
mIdleState = CharState_None; mIdleState = CharState_None;
mCurrentIdle.clear(); mCurrentIdle.clear();
// Play Death Music if it was the player dying
if(mPtr.getRefData().getHandle()=="player")
MWBase::Environment::get().getSoundManager()->streamMusic("Special/MW_Death.mp3");
return true; return true;
} }

View file

@ -193,13 +193,11 @@ namespace MWMechanics
return; return;
} }
float damage = 0.0f;
float fDamageStrengthBase = gmst.find("fDamageStrengthBase")->getFloat(); float fDamageStrengthBase = gmst.find("fDamageStrengthBase")->getFloat();
float fDamageStrengthMult = gmst.find("fDamageStrengthMult")->getFloat(); float fDamageStrengthMult = gmst.find("fDamageStrengthMult")->getFloat();
const unsigned char* attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop; const unsigned char* attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
damage = attack[0] + ((attack[1]-attack[0])*attackerStats.getAttackStrength()); // Bow/crossbow damage float damage = attack[0] + ((attack[1]-attack[0])*attackerStats.getAttackStrength()); // Bow/crossbow damage
if (weapon != projectile) if (weapon != projectile)
{ {
// Arrow/bolt damage // Arrow/bolt damage

View file

@ -120,11 +120,6 @@ namespace MWMechanics
return mSpells; return mSpells;
} }
void CreatureStats::setSpells(const Spells &spells)
{
mSpells = spells;
}
ActiveSpells &CreatureStats::getActiveSpells() ActiveSpells &CreatureStats::getActiveSpells()
{ {
return mActiveSpells; return mActiveSpells;
@ -200,11 +195,6 @@ namespace MWMechanics
mLevel = level; mLevel = level;
} }
void CreatureStats::setActiveSpells(const ActiveSpells &active)
{
mActiveSpells = active;
}
void CreatureStats::modifyMagicEffects(const MagicEffects &effects) void CreatureStats::modifyMagicEffects(const MagicEffects &effects)
{ {
if (effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier() if (effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier()
@ -536,7 +526,6 @@ namespace MWMechanics
mLastRestock = MWWorld::TimeStamp(state.mTradeTime); mLastRestock = MWWorld::TimeStamp(state.mTradeTime);
mGoldPool = state.mGoldPool; mGoldPool = state.mGoldPool;
mFallHeight = state.mFallHeight;
mDead = state.mDead; mDead = state.mDead;
mDied = state.mDied; mDied = state.mDied;

View file

@ -40,7 +40,6 @@ namespace MWMechanics
bool mTalkedTo; bool mTalkedTo;
bool mAlarmed; bool mAlarmed;
bool mAttacked; bool mAttacked;
bool mHostile;
bool mAttackingOrSpell; bool mAttackingOrSpell;
bool mKnockdown; bool mKnockdown;
bool mKnockdownOneFrame; bool mKnockdownOneFrame;
@ -138,10 +137,6 @@ namespace MWMechanics
void setDynamic (int index, const DynamicStat<float> &value); void setDynamic (int index, const DynamicStat<float> &value);
void setSpells(const Spells &spells);
void setActiveSpells(const ActiveSpells &active);
/// Set Modifier for each magic effect according to \a effects. Does not touch Base values. /// Set Modifier for each magic effect according to \a effects. Does not touch Base values.
void modifyMagicEffects(const MagicEffects &effects); void modifyMagicEffects(const MagicEffects &effects);

View file

@ -166,16 +166,15 @@ namespace MWMechanics
float enchantmentCost = 0; float enchantmentCost = 0;
int effectsLeftCnt = mEffects.size(); int effectsLeftCnt = mEffects.size();
float baseCost, magnitudeCost, areaCost;
int magMin, magMax, area;
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{ {
baseCost = (store.get<ESM::MagicEffect>().find(it->mEffectID))->mData.mBaseCost; float baseCost = (store.get<ESM::MagicEffect>().find(it->mEffectID))->mData.mBaseCost;
// To reflect vanilla behavior // To reflect vanilla behavior
magMin = (it->mMagnMin == 0) ? 1 : it->mMagnMin; int magMin = (it->mMagnMin == 0) ? 1 : it->mMagnMin;
magMax = (it->mMagnMax == 0) ? 1 : it->mMagnMax; int magMax = (it->mMagnMax == 0) ? 1 : it->mMagnMax;
area = (it->mArea == 0) ? 1 : it->mArea; int area = (it->mArea == 0) ? 1 : it->mArea;
float magnitudeCost = 0;
if (mCastStyle == ESM::Enchantment::ConstantEffect) if (mCastStyle == ESM::Enchantment::ConstantEffect)
{ {
magnitudeCost = (magMin + magMax) * baseCost * 2.5; magnitudeCost = (magMin + magMax) * baseCost * 2.5;
@ -187,7 +186,7 @@ namespace MWMechanics
magnitudeCost *= 1.5; magnitudeCost *= 1.5;
} }
areaCost = area * 0.025 * baseCost; float areaCost = area * 0.025 * baseCost;
if (it->mRange == ESM::RT_Target) if (it->mRange == ESM::RT_Target)
areaCost *= 1.5; areaCost *= 1.5;

View file

@ -566,11 +566,14 @@ namespace MWMechanics
MWWorld::LiveCellRef<ESM::NPC>* player = playerPtr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC>* player = playerPtr.get<ESM::NPC>();
const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr); const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr);
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
static const float fDispRaceMod = gmst.find("fDispRaceMod")->getFloat();
if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace)) if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace))
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispRaceMod")->getFloat(); x += fDispRaceMod;
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityMult")->getFloat() static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->getFloat();
* (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispPersonalityBase")->getFloat()); static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->getFloat();
x += fDispPersonalityMult * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase);
float reaction = 0; float reaction = 0;
int rank = 0; int rank = 0;
@ -606,16 +609,23 @@ namespace MWMechanics
reaction = 0; reaction = 0;
rank = 0; rank = 0;
} }
x += (MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispFactionRankMult")->getFloat() * rank
+ MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispFactionRankBase")->getFloat())
* MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispFactionMod")->getFloat() * reaction;
x -= MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispCrimeMod")->getFloat() * playerStats.getBounty(); static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->getFloat();
static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->getFloat();
static const float fDispFactionMod = gmst.find("fDispFactionMod")->getFloat();
x += (fDispFactionRankMult * rank
+ fDispFactionRankBase)
* fDispFactionMod * reaction;
static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->getFloat();
static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->getFloat();
x -= fDispCrimeMod * playerStats.getBounty();
if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease()) if (playerStats.hasCommonDisease() || playerStats.hasBlightDisease())
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispDiseaseMod")->getFloat(); x += fDispDiseaseMod;
static const float fDispWeaponDrawn = gmst.find("fDispWeaponDrawn")->getFloat();
if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon) if (playerStats.getDrawState() == MWMechanics::DrawState_Weapon)
x += MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fDispWeaponDrawn")->getFloat(); x += fDispWeaponDrawn;
x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude(); x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude();
@ -1111,10 +1121,10 @@ namespace MWMechanics
} }
} }
void MechanicsManager::actorAttacked(const MWWorld::Ptr &ptr, const MWWorld::Ptr &attacker) bool MechanicsManager::actorAttacked(const MWWorld::Ptr &ptr, const MWWorld::Ptr &attacker)
{ {
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
return; return false;
std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker); std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker);
if (std::find(followers.begin(), followers.end(), ptr) != followers.end()) if (std::find(followers.begin(), followers.end(), ptr) != followers.end())
@ -1124,13 +1134,25 @@ namespace MWMechanics
if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4) if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4)
{ {
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
return; return false;
}
}
// Attacking an NPC that is already in combat with any other NPC is not a crime
AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
bool isFightingNpc = false;
for (std::list<AiPackage*>::const_iterator it = seq.begin(); it != seq.end(); ++it)
{
if ((*it)->getTypeId() == AiPackage::TypeIdCombat)
{
MWWorld::Ptr target = static_cast<AiCombat*>(*it)->getTarget();
if (!target.isEmpty() && target.getClass().isNpc())
isFightingNpc = true;
} }
} }
// Attacking peaceful NPCs is a crime
if (ptr.getClass().isNpc() && !attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker) if (ptr.getClass().isNpc() && !attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
&& !isAggressive(ptr, attacker)) && !isAggressive(ptr, attacker) && !isFightingNpc)
commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
if (!attacker.isEmpty() && (attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr) if (!attacker.isEmpty() && (attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr)
@ -1141,6 +1163,8 @@ namespace MWMechanics
// Note: accidental or collateral damage attacks are ignored. // Note: accidental or collateral damage attacks are ignored.
startCombat(ptr, attacker); startCombat(ptr, attacker);
} }
return true;
} }
bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer)

View file

@ -120,7 +120,8 @@ namespace MWMechanics
OffenseType type, int arg=0); OffenseType type, int arg=0);
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
OffenseType type, int arg=0); OffenseType type, int arg=0);
virtual void actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); /// @return false if the attack was considered a "friendly hit" and forgiven
virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
/// Utility to check if taking this item is illegal and calling commitCrime if so /// Utility to check if taking this item is illegal and calling commitCrime if so
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count); virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count);
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so

View file

@ -107,7 +107,7 @@ bool MWMechanics::NpcStats::isSameFaction (const NpcStats& npcStats) const
} }
float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType, float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType,
int level) const int level, float extraFactor) const
{ {
if (level<0) if (level<0)
level = static_cast<int> (getSkill (skillIndex).getBase()); level = static_cast<int> (getSkill (skillIndex).getBase());
@ -131,6 +131,8 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
return 0; return 0;
} }
skillFactor *= extraFactor;
const MWWorld::Store<ESM::GameSetting> &gmst = const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -167,7 +169,7 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla
return 1.0 / ((level+1) * (1.0/skillFactor) * typeFactor * specialisationFactor); return 1.0 / ((level+1) * (1.0/skillFactor) * typeFactor * specialisationFactor);
} }
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType) void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
{ {
// Don't increase skills as a werewolf // Don't increase skills as a werewolf
if(mIsWerewolf) if(mIsWerewolf)
@ -175,7 +177,7 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_,
MWMechanics::SkillValue& value = getSkill (skillIndex); MWMechanics::SkillValue& value = getSkill (skillIndex);
value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType)); value.setProgress(value.getProgress() + getSkillGain (skillIndex, class_, usageType, -1, extraFactor));
if (value.getProgress()>=1) if (value.getProgress()>=1)
{ {

View file

@ -81,12 +81,12 @@ namespace MWMechanics
///< Do *this and \a npcStats share a faction? ///< Do *this and \a npcStats share a faction?
float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1, float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1,
int level = -1) const; int level = -1, float extraFactor=1.f) const;
///< \param usageType: Usage specific factor, specified in the respective skill record; ///< \param usageType: Usage specific factor, specified in the respective skill record;
/// -1: use a factor of 1.0 instead. /// -1: use a factor of 1.0 instead.
/// \param level Level to base calculation on; -1: use current level. /// \param level Level to base calculation on; -1: use current level.
void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1); void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor=1.f);
///< Increase skill by usage. ///< Increase skill by usage.
void increaseSkill (int skillIndex, const ESM::Class& class_, bool preserveProgress); void increaseSkill (int skillIndex, const ESM::Class& class_, bool preserveProgress);

View file

@ -283,13 +283,6 @@ namespace MWMechanics
return Ogre::Radian(Ogre::Math::ACos(directionY / directionResult) * sgn(Ogre::Math::ASin(directionX / directionResult))).valueDegrees(); return Ogre::Radian(Ogre::Math::ACos(directionY / directionResult) * sgn(Ogre::Math::ASin(directionX / directionResult))).valueDegrees();
} }
// Used by AiCombat, use Euclidean distance
float PathFinder::getDistToNext(float x, float y, float z)
{
ESM::Pathgrid::Point nextPoint = *mPath.begin();
return distance(nextPoint, x, y, z);
}
bool PathFinder::checkWaypoint(float x, float y, float z) bool PathFinder::checkWaypoint(float x, float y, float z)
{ {
if(mPath.empty()) if(mPath.empty())

View file

@ -47,8 +47,6 @@ namespace MWMechanics
float getZAngleToNext(float x, float y) const; float getZAngleToNext(float x, float y) const;
float getDistToNext(float x, float y, float z);
bool isPathConstructed() const bool isPathConstructed() const
{ {
return mIsPathConstructed; return mIsPathConstructed;

View file

@ -521,7 +521,7 @@ float Animation::getVelocity(const std::string &groupname) const
{ {
/* Look in reverse; last-inserted source has priority. */ /* Look in reverse; last-inserted source has priority. */
AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin()); AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin());
for(;animsrc != mAnimSources.rend();animsrc++) for(;animsrc != mAnimSources.rend();++animsrc)
{ {
const NifOgre::TextKeyMap &keys = (*animsrc)->mTextKeys; const NifOgre::TextKeyMap &keys = (*animsrc)->mTextKeys;
if(findGroupStart(keys, groupname) != keys.end()) if(findGroupStart(keys, groupname) != keys.end())
@ -831,8 +831,7 @@ void Animation::handleTextKey(AnimState &state, const std::string &groupname, co
void Animation::changeGroups(const std::string &groupname, int groups) void Animation::changeGroups(const std::string &groupname, int groups)
{ {
AnimStateMap::iterator stateiter = mStates.begin(); AnimStateMap::iterator stateiter = mStates.find(groupname);
stateiter = mStates.find(groupname);
if(stateiter != mStates.end()) if(stateiter != mStates.end())
{ {
if(stateiter->second.mGroups != groups) if(stateiter->second.mGroups != groups)

View file

@ -26,7 +26,6 @@ namespace MWRender
mNearest(30.f), mNearest(30.f),
mFurthest(800.f), mFurthest(800.f),
mIsNearest(false), mIsNearest(false),
mIsFurthest(false),
mHeight(128.f), mHeight(128.f),
mCameraDistance(300.f), mCameraDistance(300.f),
mDistanceAdjusted(false), mDistanceAdjusted(false),
@ -292,7 +291,6 @@ namespace MWRender
if(mFirstPersonView && !mPreviewMode && !mVanity.enabled) if(mFirstPersonView && !mPreviewMode && !mVanity.enabled)
return; return;
mIsFurthest = false;
mIsNearest = false; mIsNearest = false;
Ogre::Vector3 v(0.f, 0.f, dist); Ogre::Vector3 v(0.f, 0.f, dist);
@ -301,7 +299,6 @@ namespace MWRender
} }
if (v.z >= mFurthest) { if (v.z >= mFurthest) {
v.z = mFurthest; v.z = mFurthest;
mIsFurthest = true;
} else if (!override && v.z < 10.f) { } else if (!override && v.z < 10.f) {
v.z = 10.f; v.z = 10.f;
} else if (override && v.z <= mNearest) { } else if (override && v.z <= mNearest) {
@ -389,9 +386,4 @@ namespace MWRender
{ {
return mIsNearest; return mIsNearest;
} }
bool Camera::isFurthest()
{
return mIsFurthest;
}
} }

View file

@ -36,7 +36,6 @@ namespace MWRender
float mNearest; float mNearest;
float mFurthest; float mFurthest;
bool mIsNearest; bool mIsNearest;
bool mIsFurthest;
struct { struct {
bool enabled, allowed; bool enabled, allowed;
@ -118,8 +117,6 @@ namespace MWRender
bool isVanityOrPreviewModeEnabled(); bool isVanityOrPreviewModeEnabled();
bool isNearest(); bool isNearest();
bool isFurthest();
}; };
} }

View file

@ -281,9 +281,9 @@ namespace MWRender
RaceSelectionPreview::RaceSelectionPreview() RaceSelectionPreview::RaceSelectionPreview()
: CharacterPreview(MWBase::Environment::get().getWorld()->getPlayerPtr(), : CharacterPreview(MWBase::Environment::get().getWorld()->getPlayerPtr(),
512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 6, -35), Ogre::Vector3(0,125,0)) 512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 6, -35), Ogre::Vector3(0,125,0))
, mBase (*mCharacter.get<ESM::NPC>()->mBase)
, mRef(&mBase) , mRef(&mBase)
{ {
mBase = *mCharacter.get<ESM::NPC>()->mBase;
mCharacter = MWWorld::Ptr(&mRef, NULL); mCharacter = MWWorld::Ptr(&mRef, NULL);
} }

View file

@ -150,7 +150,7 @@ void CreatureWeaponAnimation::updatePart(NifOgre::ObjectScenePtr& scene, int slo
} }
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(scene->mControllers.begin()); std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(scene->mControllers.begin());
for(;ctrl != scene->mControllers.end();ctrl++) for(;ctrl != scene->mControllers.end();++ctrl)
{ {
if(ctrl->getSource().isNull()) if(ctrl->getSource().isNull())
{ {

View file

@ -29,6 +29,7 @@ namespace MWRender
, mWidth(0) , mWidth(0)
, mHeight(0) , mHeight(0)
{ {
mCellSize = Settings::Manager::getInt("global map cell size", "Map");
} }
GlobalMap::~GlobalMap() GlobalMap::~GlobalMap()
@ -57,9 +58,8 @@ namespace MWRender
mMaxY = it->getGridY(); mMaxY = it->getGridY();
} }
int cellSize = 24; mWidth = mCellSize*(mMaxX-mMinX+1);
mWidth = cellSize*(mMaxX-mMinX+1); mHeight = mCellSize*(mMaxY-mMinY+1);
mHeight = cellSize*(mMaxY-mMinY+1);
loadingListener->loadingOn(); loadingListener->loadingOn();
loadingListener->setLabel("Creating map"); loadingListener->setLabel("Creating map");
@ -90,29 +90,29 @@ namespace MWRender
land->loadData(mask); land->loadData(mask);
} }
for (int cellY=0; cellY<cellSize; ++cellY) for (int cellY=0; cellY<mCellSize; ++cellY)
{ {
for (int cellX=0; cellX<cellSize; ++cellX) for (int cellX=0; cellX<mCellSize; ++cellX)
{ {
int vertexX = float(cellX)/float(cellSize) * ESM::Land::LAND_SIZE; int vertexX = float(cellX)/float(mCellSize) * ESM::Land::LAND_SIZE;
int vertexY = float(cellY)/float(cellSize) * ESM::Land::LAND_SIZE; int vertexY = float(cellY)/float(mCellSize) * ESM::Land::LAND_SIZE;
int texelX = (x-mMinX) * cellSize + cellX; int texelX = (x-mMinX) * mCellSize + cellX;
int texelY = (mHeight-1) - ((y-mMinY) * cellSize + cellY); int texelY = (mHeight-1) - ((y-mMinY) * mCellSize + cellY);
unsigned char r,g,b; unsigned char r,g,b;
if (land) if (land)
{ {
const float landHeight = land->mLandData->mHeights[vertexY * ESM::Land::LAND_SIZE + vertexX]; const float landHeight = land->mLandData->mHeights[vertexY * ESM::Land::LAND_SIZE + vertexX];
const float mountainHeight = 15000.f;
const float hillHeight = 2500.f;
if (landHeight >= 0) if (landHeight >= 0)
{ {
const float hillHeight = 2500.f;
if (landHeight >= hillHeight) if (landHeight >= hillHeight)
{ {
const float mountainHeight = 15000.f;
float factor = std::min(1.f, float(landHeight-hillHeight)/mountainHeight); float factor = std::min(1.f, float(landHeight-hillHeight)/mountainHeight);
r = (hillColour.r * (1-factor) + mountainColour.r * factor) * 255; r = (hillColour.r * (1-factor) + mountainColour.r * factor) * 255;
g = (hillColour.g * (1-factor) + mountainColour.g * factor) * 255; g = (hillColour.g * (1-factor) + mountainColour.g * factor) * 255;
@ -197,11 +197,9 @@ namespace MWRender
void GlobalMap::exploreCell(int cellX, int cellY) void GlobalMap::exploreCell(int cellX, int cellY)
{ {
const int size = 24; float originX = (cellX - mMinX) * mCellSize;
float originX = (cellX - mMinX) * size;
// NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is // NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is
float originY = mHeight - (cellY+1 - mMinY) * size; float originY = mHeight - (cellY+1 - mMinY) * mCellSize;
if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY) if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY)
return; return;
@ -213,17 +211,17 @@ namespace MWRender
{ {
mOverlayTexture->load(); mOverlayTexture->load();
mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(), Ogre::Image::Box(0,0,512,512), mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(), Ogre::Image::Box(0,0,512,512),
Ogre::Image::Box(originX,originY,originX+size,originY+size)); Ogre::Image::Box(originX,originY,originX+mCellSize,originY+mCellSize));
Ogre::Image backup; Ogre::Image backup;
std::vector<Ogre::uchar> data; std::vector<Ogre::uchar> data;
data.resize(size*size*4, 0); data.resize(mCellSize*mCellSize*4, 0);
backup.loadDynamicImage(&data[0], size, size, Ogre::PF_A8B8G8R8); backup.loadDynamicImage(&data[0], mCellSize, mCellSize, Ogre::PF_A8B8G8R8);
localMapTexture->getBuffer()->blitToMemory(Ogre::Image::Box(0,0,512,512), backup.getPixelBox()); localMapTexture->getBuffer()->blitToMemory(Ogre::Image::Box(0,0,512,512), backup.getPixelBox());
for (int x=0; x<size; ++x) for (int x=0; x<mCellSize; ++x)
for (int y=0; y<size; ++y) for (int y=0; y<mCellSize; ++y)
{ {
assert (originX+x < mOverlayImage.getWidth()); assert (originX+x < mOverlayImage.getWidth());
assert (originY+y < mOverlayImage.getHeight()); assert (originY+y < mOverlayImage.getHeight());
@ -292,7 +290,7 @@ namespace MWRender
// If cell bounds of the currently loaded content and the loaded savegame do not match, // If cell bounds of the currently loaded content and the loaded savegame do not match,
// we need to resize source/dest boxes to accommodate // we need to resize source/dest boxes to accommodate
// This means nonexisting cells will be dropped silently // This means nonexisting cells will be dropped silently
int cellImageSizeDst = 24; int cellImageSizeDst = mCellSize;
// Completely off-screen? -> no need to blit anything // Completely off-screen? -> no need to blit anything
if (bounds.mMaxX < mMinX if (bounds.mMaxX < mMinX
@ -326,7 +324,8 @@ namespace MWRender
mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox); mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox);
if (srcBox.left == destBox.left && srcBox.right == destBox.right if (srcBox.left == destBox.left && srcBox.right == destBox.right
&& srcBox.top == destBox.top && srcBox.bottom == destBox.bottom) && srcBox.top == destBox.top && srcBox.bottom == destBox.bottom
&& int(image.getWidth()) == mWidth && int(image.getHeight()) == mHeight)
mOverlayImage = image; mOverlayImage = image;
else else
mOverlayTexture->convertToImage(mOverlayImage); mOverlayTexture->convertToImage(mOverlayImage);

View file

@ -26,8 +26,10 @@ namespace MWRender
void render(Loading::Listener* loadingListener); void render(Loading::Listener* loadingListener);
int getWidth() { return mWidth; } int getWidth() const { return mWidth; }
int getHeight() { return mHeight; } int getHeight() const { return mHeight; }
int getCellSize() const { return mCellSize; }
void worldPosToImageSpace(float x, float z, float& imageX, float& imageY); void worldPosToImageSpace(float x, float z, float& imageX, float& imageY);
@ -46,6 +48,8 @@ namespace MWRender
private: private:
std::string mCacheDir; std::string mCacheDir;
int mCellSize;
std::vector< std::pair<int,int> > mExploredCells; std::vector< std::pair<int,int> > mExploredCells;
Ogre::TexturePtr mOverlayTexture; Ogre::TexturePtr mOverlayTexture;

View file

@ -410,15 +410,18 @@ void NpcAnimation::updateParts()
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination // Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping; static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping;
static const int Flag_Female = 1<<0;
static const int Flag_FirstPerson = 1<<1;
bool isWerewolf = (mNpcType == Type_Werewolf); bool isWerewolf = (mNpcType == Type_Werewolf);
int flags = (isWerewolf ? -1 : 0); int flags = (isWerewolf ? -1 : 0);
if(!mNpc->isMale()) if(!mNpc->isMale())
{
static const int Flag_Female = 1<<0;
flags |= Flag_Female; flags |= Flag_Female;
}
if(mViewMode == VM_FirstPerson) if(mViewMode == VM_FirstPerson)
{
static const int Flag_FirstPerson = 1<<1;
flags |= Flag_FirstPerson; flags |= Flag_FirstPerson;
}
std::string race = (isWerewolf ? "werewolf" : Misc::StringUtils::lowerCase(mNpc->mRace)); std::string race = (isWerewolf ? "werewolf" : Misc::StringUtils::lowerCase(mNpc->mRace));
std::pair<std::string, int> thisCombination = std::make_pair(race, flags); std::pair<std::string, int> thisCombination = std::make_pair(race, flags);
@ -604,7 +607,7 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
if (mObjectParts[i].isNull()) if (mObjectParts[i].isNull())
continue; continue;
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[i]->mControllers.begin()); std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[i]->mControllers.begin());
for(;ctrl != mObjectParts[i]->mControllers.end();ctrl++) for(;ctrl != mObjectParts[i]->mControllers.end();++ctrl)
ctrl->update(); ctrl->update();
Ogre::Entity *ent = mObjectParts[i]->mSkelBase; Ogre::Entity *ent = mObjectParts[i]->mSkelBase;
@ -678,7 +681,7 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
} }
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[type]->mControllers.begin()); std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[type]->mControllers.begin());
for(;ctrl != mObjectParts[type]->mControllers.end();ctrl++) for(;ctrl != mObjectParts[type]->mControllers.end();++ctrl)
{ {
if(ctrl->getSource().isNull()) if(ctrl->getSource().isNull())
{ {
@ -715,7 +718,7 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::
const char *ext = (mViewMode == VM_FirstPerson) ? ".1st" : ""; const char *ext = (mViewMode == VM_FirstPerson) ? ".1st" : "";
std::vector<ESM::PartReference>::const_iterator part(parts.begin()); std::vector<ESM::PartReference>::const_iterator part(parts.begin());
for(;part != parts.end();part++) for(;part != parts.end();++part)
{ {
const ESM::BodyPart *bodypart = 0; const ESM::BodyPart *bodypart = 0;
if(!mNpc->isMale() && !part->mFemale.empty()) if(!mNpc->isMale() && !part->mFemale.empty())

View file

@ -574,24 +574,6 @@ void RenderingManager::configureAmbient(MWWorld::CellStore &mCell)
sunEnable(false); sunEnable(false);
} }
} }
// Switch through lighting modes.
void RenderingManager::toggleLight()
{
if (mAmbientMode==2)
mAmbientMode = 0;
else
++mAmbientMode;
switch (mAmbientMode)
{
case 0: std::cout << "Setting lights to normal\n"; break;
case 1: std::cout << "Turning the lights up\n"; break;
case 2: std::cout << "Turning the lights to full\n"; break;
}
setAmbientMode();
}
void RenderingManager::setSunColour(const Ogre::ColourValue& colour) void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
{ {
@ -695,11 +677,6 @@ void RenderingManager::enableLights(bool sun)
sunEnable(sun); sunEnable(sun);
} }
Shadows* RenderingManager::getShadows()
{
return mShadows;
}
void RenderingManager::notifyWorldSpaceChanged() void RenderingManager::notifyWorldSpaceChanged()
{ {
mEffectManager->clear(); mEffectManager->clear();

View file

@ -93,7 +93,6 @@ public:
MWRender::Camera* getCamera() const; MWRender::Camera* getCamera() const;
void toggleLight();
bool toggleRenderMode(int mode); bool toggleRenderMode(int mode);
void removeCell (MWWorld::CellStore *store); void removeCell (MWWorld::CellStore *store);
@ -157,8 +156,6 @@ public:
float getTerrainHeightAt (Ogre::Vector3 worldPos); float getTerrainHeightAt (Ogre::Vector3 worldPos);
Shadows* getShadows();
void notifyWorldSpaceChanged(); void notifyWorldSpaceChanged();
void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches); void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches);

View file

@ -41,6 +41,9 @@ public:
void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
private: private:
RippleSimulation(const RippleSimulation&);
RippleSimulation& operator=(const RippleSimulation&);
std::vector<Emitter> mEmitters; std::vector<Emitter> mEmitters;
Ogre::RenderTexture* mRenderTargets[4]; Ogre::RenderTexture* mRenderTargets[4];

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