mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 09:45:36 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
82ff737c31
84 changed files with 887 additions and 654 deletions
|
@ -408,7 +408,7 @@ IF(NOT WIN32 AND NOT APPLE)
|
|||
# Install binaries
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
||||
IF(BUILD_LAUNCHER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-launcher" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_LAUNCHER)
|
||||
IF(BUILD_BSATOOL)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/bsatool" DESTINATION "${BINDIR}" )
|
||||
|
@ -417,7 +417,7 @@ IF(NOT WIN32 AND NOT APPLE)
|
|||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_ESMTOOL)
|
||||
IF(BUILD_MWINIIMPORTER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-iniimporter" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_MWINIIMPORTER)
|
||||
IF(BUILD_ESSIMPORTER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-essimporter" DESTINATION "${BINDIR}" )
|
||||
|
@ -476,10 +476,10 @@ if(WIN32)
|
|||
DESTINATION ".")
|
||||
|
||||
IF(BUILD_LAUNCHER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/omwlauncher.exe" DESTINATION ".")
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-launcher.exe" DESTINATION ".")
|
||||
ENDIF(BUILD_LAUNCHER)
|
||||
IF(BUILD_MWINIIMPORTER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/mwiniimport.exe" DESTINATION ".")
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-iniimporter.exe" DESTINATION ".")
|
||||
ENDIF(BUILD_MWINIIMPORTER)
|
||||
IF(BUILD_ESSIMPORTER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-essimporter.exe" DESTINATION ".")
|
||||
|
@ -506,7 +506,7 @@ if(WIN32)
|
|||
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
||||
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW")
|
||||
IF(BUILD_LAUNCHER)
|
||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};omwlauncher;OpenMW Launcher")
|
||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-launcher;OpenMW Launcher")
|
||||
ENDIF(BUILD_LAUNCHER)
|
||||
IF(BUILD_OPENCS)
|
||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};opencs;OpenMW Construction Set")
|
||||
|
@ -525,7 +525,7 @@ if(WIN32)
|
|||
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}")
|
||||
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
|
||||
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "openmw-launcher.exe")
|
||||
SET(CPACK_NSIS_MUI_ICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
||||
SET(CPACK_NSIS_MUI_UNIICON "${OpenMW_SOURCE_DIR}/files/windows/openmw.ico")
|
||||
SET(CPACK_PACKAGE_ICON "${OpenMW_SOURCE_DIR}\\\\files\\\\openmw.bmp")
|
||||
|
@ -699,7 +699,7 @@ if (WIN32)
|
|||
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
if (BUILD_LAUNCHER)
|
||||
set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(openmw-launcher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_LAUNCHER)
|
||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
if (BUILD_BSATOOL)
|
||||
|
@ -717,7 +717,7 @@ if (WIN32)
|
|||
set_target_properties(opencs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS})
|
||||
endif (BUILD_OPENCS)
|
||||
if (BUILD_MWINIIMPORTER)
|
||||
set_target_properties(mwiniimport PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(openmw-iniimporter PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif (BUILD_MWINIIMPORTER)
|
||||
endif(MSVC)
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ set(ESSIMPORTER_FILES
|
|||
convertcntc.cpp
|
||||
convertscri.cpp
|
||||
convertscpt.cpp
|
||||
convertplayer.cpp
|
||||
)
|
||||
|
||||
add_executable(openmw-essimporter
|
||||
|
|
|
@ -29,6 +29,12 @@ namespace ESSImport
|
|||
}
|
||||
cStats.mGoldPool = acdt.mGoldPool;
|
||||
cStats.mTalkedTo = acdt.mFlags & TalkedToPlayer;
|
||||
cStats.mAttacked = acdt.mFlags & Attacked;
|
||||
}
|
||||
|
||||
void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats)
|
||||
{
|
||||
cStats.mDead = acsc.mFlags & Dead;
|
||||
}
|
||||
|
||||
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats)
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace ESSImport
|
|||
|
||||
|
||||
void convertACDT (const ACDT& acdt, ESM::CreatureStats& cStats);
|
||||
void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats);
|
||||
|
||||
void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats);
|
||||
}
|
||||
|
|
|
@ -274,6 +274,8 @@ namespace ESSImport
|
|||
const CellRef& cellref = *refIt;
|
||||
ESM::CellRef out (cellref);
|
||||
|
||||
// TODO: use mContext->mCreatures/mNpcs
|
||||
|
||||
if (!isIndexedRefId(cellref.mIndexedRefId))
|
||||
{
|
||||
// non-indexed RefNum, i.e. no CREC/NPCC/CNTC record associated with it
|
||||
|
@ -309,9 +311,12 @@ namespace ESSImport
|
|||
objstate.blank();
|
||||
objstate.mRef = out;
|
||||
objstate.mRef.mRefID = idLower;
|
||||
// probably need more micromanagement here so we don't overwrite values
|
||||
// TODO: need more micromanagement here so we don't overwrite values
|
||||
// from the ESM with default values
|
||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||
if (cellref.mHasACDT)
|
||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||
if (cellref.mHasACSC)
|
||||
convertACSC(cellref.mACSC, objstate.mCreatureStats);
|
||||
convertNpcData(cellref, objstate.mNpcStats);
|
||||
convertNPCC(npccIt->second, objstate);
|
||||
convertCellRef(cellref, objstate);
|
||||
|
@ -343,9 +348,12 @@ namespace ESSImport
|
|||
objstate.blank();
|
||||
objstate.mRef = out;
|
||||
objstate.mRef.mRefID = idLower;
|
||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||
// probably need more micromanagement here so we don't overwrite values
|
||||
// TODO: need more micromanagement here so we don't overwrite values
|
||||
// from the ESM with default values
|
||||
if (cellref.mHasACDT)
|
||||
convertACDT(cellref.mACDT, objstate.mCreatureStats);
|
||||
if (cellref.mHasACSC)
|
||||
convertACSC(cellref.mACSC, objstate.mCreatureStats);
|
||||
convertCREC(crecIt->second, objstate);
|
||||
convertCellRef(cellref, objstate);
|
||||
esm.writeHNT ("OBJE", ESM::REC_CREA);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "convertacdt.hpp"
|
||||
#include "convertnpcc.hpp"
|
||||
#include "convertscpt.hpp"
|
||||
#include "convertplayer.hpp"
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
@ -104,10 +105,10 @@ public:
|
|||
npc.load(esm);
|
||||
if (id != "player")
|
||||
{
|
||||
// TODO:
|
||||
// this should handle changes to the NPC struct, but since there is no index here
|
||||
// Handles changes to the NPC struct, but since there is no index here
|
||||
// it will apply to ALL instances of the class. seems to be the reason for the
|
||||
// "feature" in MW where changing AI settings of one guard will change it for all guards of that refID.
|
||||
mContext->mNpcs[Misc::StringUtils::lowerCase(id)] = npc;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -139,6 +140,7 @@ public:
|
|||
ESM::Creature creature;
|
||||
std::string id = esm.getHNString("NAME");
|
||||
creature.load(esm);
|
||||
mContext->mCreatures[Misc::StringUtils::lowerCase(id)] = creature;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -259,32 +261,23 @@ private:
|
|||
class ConvertPCDT : public Converter
|
||||
{
|
||||
public:
|
||||
ConvertPCDT() : mFirstPersonCam(true) {}
|
||||
|
||||
virtual void read(ESM::ESMReader &esm)
|
||||
{
|
||||
PCDT pcdt;
|
||||
pcdt.load(esm);
|
||||
|
||||
mContext->mPlayer.mBirthsign = pcdt.mBirthsign;
|
||||
mContext->mPlayer.mObject.mNpcStats.mBounty = pcdt.mBounty;
|
||||
for (std::vector<PCDT::FNAM>::const_iterator it = pcdt.mFactions.begin(); it != pcdt.mFactions.end(); ++it)
|
||||
{
|
||||
ESM::NpcStats::Faction faction;
|
||||
faction.mExpelled = (it->mFlags & 0x2) != 0;
|
||||
faction.mRank = it->mRank;
|
||||
faction.mReputation = it->mReputation;
|
||||
mContext->mPlayer.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(it->mFactionName.toString())] = faction;
|
||||
}
|
||||
for (int i=0; i<8; ++i)
|
||||
mContext->mPlayer.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
||||
mContext->mPlayer.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
|
||||
it != pcdt.mKnownDialogueTopics.end(); ++it)
|
||||
{
|
||||
mContext->mDialogueState.mKnownTopics.push_back(Misc::StringUtils::lowerCase(*it));
|
||||
}
|
||||
|
||||
convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam);
|
||||
}
|
||||
virtual void write(ESM::ESMWriter &esm)
|
||||
{
|
||||
esm.startRecord(ESM::REC_CAM_);
|
||||
esm.writeHNT("FIRS", mFirstPersonCam);
|
||||
esm.endRecord(ESM::REC_CAM_);
|
||||
}
|
||||
private:
|
||||
bool mFirstPersonCam;
|
||||
};
|
||||
|
||||
class ConvertCNTC : public Converter
|
||||
|
@ -416,7 +409,7 @@ private:
|
|||
|
||||
/// Seen responses for a dialogue topic?
|
||||
/// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs
|
||||
/// Dialogue conversion problems (probably have to adjust OpenMW format) -
|
||||
/// Dialogue conversion problems:
|
||||
/// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID.
|
||||
/// - Seen dialogue responses only store the INFO id, rather than the fulltext.
|
||||
/// - Quest stages only store the INFO id, rather than the journal entry fulltext.
|
||||
|
|
39
apps/essimporter/convertplayer.cpp
Normal file
39
apps/essimporter/convertplayer.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "convertplayer.hpp"
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
||||
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<std::string>& outDialogueTopics, bool& firstPersonCam)
|
||||
{
|
||||
out.mBirthsign = pcdt.mBirthsign;
|
||||
out.mObject.mNpcStats.mBounty = pcdt.mBounty;
|
||||
for (std::vector<PCDT::FNAM>::const_iterator it = pcdt.mFactions.begin(); it != pcdt.mFactions.end(); ++it)
|
||||
{
|
||||
ESM::NpcStats::Faction faction;
|
||||
faction.mExpelled = (it->mFlags & 0x2) != 0;
|
||||
faction.mRank = it->mRank;
|
||||
faction.mReputation = it->mReputation;
|
||||
out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(it->mFactionName.toString())] = faction;
|
||||
}
|
||||
for (int i=0; i<8; ++i)
|
||||
out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i];
|
||||
out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress;
|
||||
|
||||
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Weapon)
|
||||
out.mObject.mCreatureStats.mDrawState = 1;
|
||||
if (pcdt.mPNAM.mDrawState & PCDT::DrawState_Spell)
|
||||
out.mObject.mCreatureStats.mDrawState = 2;
|
||||
|
||||
// TODO: convert PNAM.mSkillProgress, needs to be converted to uniform scale
|
||||
// (or change openmw to accept non-uniform skill progress)
|
||||
|
||||
firstPersonCam = (pcdt.mPNAM.mCameraState == PCDT::CameraState_FirstPerson);
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = pcdt.mKnownDialogueTopics.begin();
|
||||
it != pcdt.mKnownDialogueTopics.end(); ++it)
|
||||
{
|
||||
outDialogueTopics.push_back(Misc::StringUtils::lowerCase(*it));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
15
apps/essimporter/convertplayer.hpp
Normal file
15
apps/essimporter/convertplayer.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef OPENMW_ESSIMPORT_CONVERTPLAYER_H
|
||||
#define OPENMW_ESSIMPORT_CONVERTPLAYER_H
|
||||
|
||||
#include "importplayer.hpp"
|
||||
|
||||
#include <components/esm/player.hpp>
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
||||
void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector<std::string>& outDialogueTopics, bool& firstPersonCam);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -20,12 +20,22 @@ namespace ESSImport
|
|||
|
||||
ESM::CellRef::loadData(esm);
|
||||
|
||||
// FIXME: not all actors have this, add flag
|
||||
esm.getHNOT(mACDT, "ACDT");
|
||||
mHasACDT = false;
|
||||
if (esm.isNextSub("ACDT"))
|
||||
{
|
||||
mHasACDT = true;
|
||||
esm.getHT(mACDT);
|
||||
}
|
||||
|
||||
ACSC acsc;
|
||||
esm.getHNOT(acsc, "ACSC");
|
||||
esm.getHNOT(acsc, "ACSL");
|
||||
mHasACSC = false;
|
||||
if (esm.isNextSub("ACSC"))
|
||||
{
|
||||
mHasACSC = true;
|
||||
esm.getHT(mACSC);
|
||||
}
|
||||
|
||||
if (esm.isNextSub("ACSL"))
|
||||
esm.skipHSubSize(112);
|
||||
|
||||
if (esm.isNextSub("CSTN"))
|
||||
esm.skipHSub(); // "PlayerSaveGame", link to some object?
|
||||
|
|
|
@ -17,7 +17,13 @@ namespace ESSImport
|
|||
|
||||
enum ACDTFlags
|
||||
{
|
||||
TalkedToPlayer = 0x4
|
||||
TalkedToPlayer = 0x4,
|
||||
Attacked = 0x100,
|
||||
Unknown = 0x200
|
||||
};
|
||||
enum ACSCFlags
|
||||
{
|
||||
Dead = 0x2
|
||||
};
|
||||
|
||||
/// Actor data, shared by (at least) REFR and CellRef
|
||||
|
@ -28,23 +34,33 @@ namespace ESSImport
|
|||
// Note, not stored at *all*:
|
||||
// - Level changes are lost on reload, except for the player (there it's in the NPC record).
|
||||
unsigned char mUnknown[12];
|
||||
unsigned char mFlags; // ACDTFlags
|
||||
unsigned char mUnknown1[3];
|
||||
unsigned int mFlags;
|
||||
float mBreathMeter; // Seconds left before drowning
|
||||
unsigned char mUnknown2[20];
|
||||
float mDynamic[3][2];
|
||||
unsigned char mUnknown3[16];
|
||||
float mAttributes[8][2];
|
||||
unsigned char mUnknown4[112];
|
||||
float mMagicEffects[27]; // Effect attributes: https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attributes
|
||||
unsigned char mUnknown4[4];
|
||||
unsigned int mGoldPool;
|
||||
unsigned char mUnknown5[4];
|
||||
};
|
||||
struct ACSC
|
||||
{
|
||||
unsigned char mUnknown1[17];
|
||||
unsigned char mFlags; // ACSCFlags
|
||||
unsigned char mUnknown2[94];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct ActorData : public ESM::CellRef
|
||||
{
|
||||
bool mHasACDT;
|
||||
ACDT mACDT;
|
||||
|
||||
bool mHasACSC;
|
||||
ACSC mACSC;
|
||||
|
||||
int mSkills[27][2];
|
||||
|
||||
// creature combat stats, base and modified
|
||||
|
@ -60,12 +76,6 @@ namespace ESSImport
|
|||
void load(ESM::ESMReader& esm);
|
||||
};
|
||||
|
||||
/// Unknown, shared by (at least) REFR and CellRef
|
||||
struct ACSC
|
||||
{
|
||||
unsigned char unknown[112];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <components/esm/loadlevlist.hpp>
|
||||
#include <components/esm/loadglob.hpp>
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "importercontext.hpp"
|
||||
|
||||
#include "converter.hpp"
|
||||
|
@ -44,9 +46,10 @@ namespace
|
|||
namespace ESSImport
|
||||
{
|
||||
|
||||
Importer::Importer(const std::string &essfile, const std::string &outfile)
|
||||
Importer::Importer(const std::string &essfile, const std::string &outfile, const std::string &encoding)
|
||||
: mEssFile(essfile)
|
||||
, mOutFile(outfile)
|
||||
, mEncoding(encoding)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -167,14 +170,30 @@ namespace ESSImport
|
|||
std::cout << "Data 1:" << std::endl;
|
||||
for (unsigned int k=0; k<sub.mData.size(); ++k)
|
||||
{
|
||||
bool different = false;
|
||||
if (k >= sub2.mData.size() || sub2.mData[k] != sub.mData[k])
|
||||
different = true;
|
||||
|
||||
if (different)
|
||||
std::cout << "\033[033m";
|
||||
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)sub.mData[k] << " ";
|
||||
if (different)
|
||||
std::cout << "\033[0m";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Data 2:" << std::endl;
|
||||
for (unsigned int k=0; k<sub2.mData.size(); ++k)
|
||||
{
|
||||
bool different = false;
|
||||
if (k >= sub.mData.size() || sub.mData[k] != sub2.mData[k])
|
||||
different = true;
|
||||
|
||||
if (different)
|
||||
std::cout << "\033[033m";
|
||||
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)sub2.mData[k] << " ";
|
||||
if (different)
|
||||
std::cout << "\033[0m";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
@ -188,10 +207,10 @@ namespace ESSImport
|
|||
Ogre::LogManager logman;
|
||||
Ogre::Root root;
|
||||
|
||||
// TODO: set up encoding on ESMReader based on openmw.cfg / --encoding switch
|
||||
|
||||
ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncoding));
|
||||
ESM::ESMReader esm;
|
||||
esm.open(mEssFile);
|
||||
esm.setEncoder(&encoder);
|
||||
|
||||
Context context;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace ESSImport
|
|||
class Importer
|
||||
{
|
||||
public:
|
||||
Importer(const std::string& essfile, const std::string& outfile);
|
||||
Importer(const std::string& essfile, const std::string& outfile, const std::string& encoding);
|
||||
|
||||
void run();
|
||||
|
||||
|
@ -18,6 +18,7 @@ namespace ESSImport
|
|||
private:
|
||||
std::string mEssFile;
|
||||
std::string mOutFile;
|
||||
std::string mEncoding;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <components/esm/player.hpp>
|
||||
#include <components/esm/dialoguestate.hpp>
|
||||
#include <components/esm/globalmap.hpp>
|
||||
#include <components/esm/loadcrea.hpp>
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
||||
#include "importnpcc.hpp"
|
||||
#include "importcrec.hpp"
|
||||
|
@ -15,6 +17,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
namespace ESSImport
|
||||
{
|
||||
|
||||
|
@ -42,6 +45,9 @@ namespace ESSImport
|
|||
std::map<std::pair<int, std::string>, NPCC> mNpcChanges;
|
||||
std::map<std::pair<int, std::string>, CNTC> mContainerChanges;
|
||||
|
||||
std::map<std::string, ESM::Creature> mCreatures;
|
||||
std::map<std::string, ESM::NPC> mNpcs;
|
||||
|
||||
Context()
|
||||
{
|
||||
mPlayer.mAutoMove = 0;
|
||||
|
|
|
@ -38,6 +38,17 @@ struct PCDT
|
|||
|
||||
std::vector<std::string> mKnownDialogueTopics;
|
||||
|
||||
enum DrawState_
|
||||
{
|
||||
DrawState_Weapon = 0x80,
|
||||
DrawState_Spell = 0x100
|
||||
};
|
||||
enum CameraState
|
||||
{
|
||||
CameraState_FirstPerson = 0x8,
|
||||
CameraState_ThirdPerson = 0xa
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct FNAM
|
||||
|
@ -49,11 +60,13 @@ struct PCDT
|
|||
unsigned char mUnknown2[3];
|
||||
ESM::NAME32 mFactionName;
|
||||
};
|
||||
|
||||
struct PNAM
|
||||
{
|
||||
unsigned char mUnknown1[4];
|
||||
unsigned char mLevelProgress;
|
||||
unsigned char mUnknown2[111];
|
||||
short mDrawState; // DrawState
|
||||
short mCameraState; // CameraState
|
||||
unsigned int mLevelProgress;
|
||||
float mSkillProgress[27]; // skill progress, non-uniform scaled
|
||||
unsigned char mSkillIncreases[8]; // number of skill increases for each attribute
|
||||
unsigned char mUnknown3[88];
|
||||
};
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include "importer.hpp"
|
||||
|
||||
namespace bpo = boost::program_options;
|
||||
|
@ -23,31 +25,36 @@ int main(int argc, char** argv)
|
|||
("mwsave,m", bpo::value<std::string>(), "morrowind .ess save file")
|
||||
("output,o", bpo::value<std::string>(), "output file (.omwsave)")
|
||||
("compare,c", "compare two .ess files")
|
||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"), "encoding of the save file")
|
||||
;
|
||||
p_desc.add("mwsave", 1).add("output", 1);
|
||||
|
||||
bpo::variables_map vm;
|
||||
bpo::variables_map variables;
|
||||
|
||||
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
||||
.options(desc)
|
||||
.positional(p_desc)
|
||||
.run();
|
||||
|
||||
bpo::store(parsed, vm);
|
||||
bpo::store(parsed, variables);
|
||||
|
||||
if(vm.count("help") || !vm.count("mwsave") || !vm.count("output")) {
|
||||
if(variables.count("help") || !variables.count("mwsave") || !variables.count("output")) {
|
||||
std::cout << desc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpo::notify(vm);
|
||||
bpo::notify(variables);
|
||||
|
||||
std::string essFile = vm["mwsave"].as<std::string>();
|
||||
std::string outputFile = vm["output"].as<std::string>();
|
||||
Files::ConfigurationManager cfgManager(true);
|
||||
cfgManager.readConfiguration(variables, desc);
|
||||
|
||||
ESSImport::Importer importer(essFile, outputFile);
|
||||
std::string essFile = variables["mwsave"].as<std::string>();
|
||||
std::string outputFile = variables["output"].as<std::string>();
|
||||
std::string encoding = variables["encoding"].as<std::string>();
|
||||
|
||||
if (vm.count("compare"))
|
||||
ESSImport::Importer importer(essFile, outputFile, encoding);
|
||||
|
||||
if (variables.count("compare"))
|
||||
importer.compare();
|
||||
else
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ if(NOT WIN32)
|
|||
endif(NOT WIN32)
|
||||
|
||||
# Main executable
|
||||
add_executable(omwlauncher
|
||||
add_executable(openmw-launcher
|
||||
${GUI_TYPE}
|
||||
${LAUNCHER}
|
||||
${LAUNCHER_HEADER}
|
||||
|
@ -87,7 +87,7 @@ add_executable(omwlauncher
|
|||
${UI_HDRS}
|
||||
)
|
||||
|
||||
target_link_libraries(omwlauncher
|
||||
target_link_libraries(openmw-launcher
|
||||
${Boost_LIBRARIES}
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
|
@ -99,6 +99,6 @@ target_link_libraries(omwlauncher
|
|||
|
||||
if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(omwlauncher gcov)
|
||||
target_link_libraries(openmw-launcher gcov)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -27,25 +27,6 @@ using namespace Process;
|
|||
Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||
: mGameSettings(mCfgMgr), QMainWindow (parent)
|
||||
{
|
||||
// Install the stylesheet font
|
||||
QFile file;
|
||||
QFontDatabase fontDatabase;
|
||||
|
||||
const QStringList fonts = fontDatabase.families();
|
||||
|
||||
// Check if the font is installed
|
||||
if (!fonts.contains("EB Garamond")) {
|
||||
|
||||
QString font = QString::fromUtf8(mCfgMgr.getGlobalDataPath().string().c_str()) + QString("resources/mygui/EBGaramond-Regular.ttf");
|
||||
file.setFileName(font);
|
||||
|
||||
if (!file.exists()) {
|
||||
font = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str()) + QString("resources/mygui/EBGaramond-Regular.ttf");
|
||||
}
|
||||
|
||||
fontDatabase.addApplicationFont(font);
|
||||
}
|
||||
|
||||
setupUi(this);
|
||||
|
||||
mGameInvoker = new ProcessInvoker();
|
||||
|
|
|
@ -140,7 +140,7 @@ void Launcher::SettingsPage::on_importerButton_clicked()
|
|||
|
||||
qDebug() << "arguments " << arguments;
|
||||
|
||||
if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false))
|
||||
if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,16 +9,16 @@ set(MWINIIMPORT_HEADER
|
|||
|
||||
source_group(launcher FILES ${MWINIIMPORT} ${MWINIIMPORT_HEADER})
|
||||
|
||||
add_executable(mwiniimport
|
||||
add_executable(openmw-iniimporter
|
||||
${MWINIIMPORT}
|
||||
)
|
||||
|
||||
target_link_libraries(mwiniimport
|
||||
target_link_libraries(openmw-iniimporter
|
||||
${Boost_LIBRARIES}
|
||||
components
|
||||
)
|
||||
|
||||
if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(mwiniimport gcov)
|
||||
target_link_libraries(openmw-iniimporter gcov)
|
||||
endif()
|
||||
|
|
|
@ -59,7 +59,7 @@ int wmain(int argc, wchar_t *wargv[]) {
|
|||
|
||||
try
|
||||
{
|
||||
bpo::options_description desc("Syntax: mwiniimporter <options> inifile configfile\nAllowed options");
|
||||
bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options");
|
||||
bpo::positional_options_description p_desc;
|
||||
desc.add_options()
|
||||
("help,h", "produce help message")
|
||||
|
|
|
@ -190,29 +190,23 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
bpo::store(valid_opts, variables);
|
||||
bpo::notify(variables);
|
||||
|
||||
bool run = true;
|
||||
|
||||
if (variables.count ("help"))
|
||||
{
|
||||
std::cout << desc << std::endl;
|
||||
run = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "OpenMW version " << OPENMW_VERSION;
|
||||
std::string rev = OPENMW_VERSION_COMMITHASH;
|
||||
std::string tag = OPENMW_VERSION_TAGHASH;
|
||||
if (!rev.empty() && !tag.empty())
|
||||
{
|
||||
rev = rev.substr(0, 10);
|
||||
std::cout << " (revision " << rev << ")";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
if (variables.count ("version"))
|
||||
{
|
||||
std::cout << "OpenMW version " << OPENMW_VERSION << std::endl;
|
||||
|
||||
std::string rev = OPENMW_VERSION_COMMITHASH;
|
||||
std::string tag = OPENMW_VERSION_TAGHASH;
|
||||
if (!rev.empty() && !tag.empty())
|
||||
{
|
||||
rev = rev.substr(0, 10);
|
||||
std::cout << "Revision " << rev << std::endl;
|
||||
}
|
||||
run = false;
|
||||
}
|
||||
|
||||
if (!run)
|
||||
return false;
|
||||
|
||||
cfgMgr.readConfiguration(variables, desc);
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace ESM
|
|||
struct Class;
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
struct CellId;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include <components/esm/cellid.hpp>
|
||||
|
||||
#include "../mwworld/globals.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
|
@ -33,7 +35,6 @@ namespace ESM
|
|||
struct Potion;
|
||||
struct Spell;
|
||||
struct NPC;
|
||||
struct CellId;
|
||||
struct Armor;
|
||||
struct Weapon;
|
||||
struct Clothing;
|
||||
|
@ -92,6 +93,7 @@ namespace MWBase
|
|||
{
|
||||
std::string name;
|
||||
float x, y; // world position
|
||||
ESM::CellId dest;
|
||||
};
|
||||
|
||||
World() {}
|
||||
|
|
|
@ -228,18 +228,7 @@ namespace MWClass
|
|||
weapon = *weaponslot;
|
||||
}
|
||||
|
||||
// Reduce fatigue
|
||||
// somewhat of a guess, but using the weapon weight makes sense
|
||||
const float fFatigueAttackBase = gmst.find("fFatigueAttackBase")->getFloat();
|
||||
const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat();
|
||||
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
||||
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
||||
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||
if (!weapon.isEmpty())
|
||||
fatigueLoss += weapon.getClass().getWeight(weapon) * stats.getAttackStrength() * fWeaponFatigueMult;
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
||||
stats.setFatigue(fatigue);
|
||||
MWMechanics::applyFatigueLoss(ptr, weapon);
|
||||
|
||||
// TODO: where is the distance defined?
|
||||
float dist = 200.f;
|
||||
|
|
|
@ -93,9 +93,6 @@ namespace MWClass
|
|||
MWWorld::LiveCellRef<ESM::Door> *ref =
|
||||
ptr.get<ESM::Door>();
|
||||
|
||||
if (ptr.getCellRef().getTeleport() && !ptr.getCellRef().getDestCell().empty()) // TODO doors that lead to exteriors
|
||||
return ptr.getCellRef().getDestCell();
|
||||
|
||||
return ref->mBase->mName;
|
||||
}
|
||||
|
||||
|
|
|
@ -486,18 +486,7 @@ namespace MWClass
|
|||
if(!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||
weapon = MWWorld::Ptr();
|
||||
|
||||
// Reduce fatigue
|
||||
// somewhat of a guess, but using the weapon weight makes sense
|
||||
const float fFatigueAttackBase = store.find("fFatigueAttackBase")->getFloat();
|
||||
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
|
||||
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
|
||||
MWMechanics::DynamicStat<float> fatigue = getCreatureStats(ptr).getFatigue();
|
||||
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
|
||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||
if (!weapon.isEmpty())
|
||||
fatigueLoss += weapon.getClass().getWeight(weapon) * getNpcStats(ptr).getAttackStrength() * fWeaponFatigueMult;
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
||||
getCreatureStats(ptr).setFatigue(fatigue);
|
||||
MWMechanics::applyFatigueLoss(ptr, weapon);
|
||||
|
||||
const float fCombatDistance = store.find("fCombatDistance")->getFloat();
|
||||
float dist = fCombatDistance * (!weapon.isEmpty() ?
|
||||
|
|
|
@ -189,9 +189,8 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Weapon Longblade Up");
|
||||
}
|
||||
// Shortblade and thrown weapons
|
||||
// thrown weapons may not be entirely correct
|
||||
if (type == 0 || type == 11)
|
||||
// Shortblade
|
||||
if (type == 0)
|
||||
{
|
||||
return std::string("Item Weapon Shortblade Up");
|
||||
}
|
||||
|
@ -200,8 +199,8 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Weapon Spear Up");
|
||||
}
|
||||
// Blunts and Axes
|
||||
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8)
|
||||
// Blunts, Axes and Thrown weapons
|
||||
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11)
|
||||
{
|
||||
return std::string("Item Weapon Blunt Up");
|
||||
}
|
||||
|
@ -235,9 +234,8 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Weapon Longblade Down");
|
||||
}
|
||||
// Shortblade and thrown weapons
|
||||
// thrown weapons may not be entirely correct
|
||||
if (type == 0 || type == 11)
|
||||
// Shortblade
|
||||
if (type == 0)
|
||||
{
|
||||
return std::string("Item Weapon Shortblade Down");
|
||||
}
|
||||
|
@ -246,8 +244,8 @@ namespace MWClass
|
|||
{
|
||||
return std::string("Item Weapon Spear Down");
|
||||
}
|
||||
// Blunts and Axes
|
||||
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8)
|
||||
// Blunts, Axes and Thrown weapons
|
||||
if (type == 3 || type == 4 || type == 5 || type == 7 || type == 8 || type == 11)
|
||||
{
|
||||
return std::string("Item Weapon Blunt Down");
|
||||
}
|
||||
|
|
|
@ -3,6 +3,22 @@
|
|||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void modifyProfit(const MWWorld::Ptr& actor, int diff)
|
||||
{
|
||||
std::string script = actor.getClass().getScript(actor);
|
||||
if (!script.empty())
|
||||
{
|
||||
int profit = actor.getRefData().getLocals().getIntVar(script, "minimumprofit");
|
||||
profit += diff;
|
||||
actor.getRefData().getLocals().setVarByInt(script, "minimumprofit", profit);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
CompanionItemModel::CompanionItemModel(const MWWorld::Ptr &actor)
|
||||
|
@ -12,23 +28,25 @@ namespace MWGui
|
|||
|
||||
MWWorld::Ptr CompanionItemModel::copyItem (const ItemStack& item, size_t count, bool setNewOwner=false)
|
||||
{
|
||||
if (mActor.getClass().isNpc())
|
||||
{
|
||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats(mActor);
|
||||
stats.modifyProfit(item.mBase.getClass().getValue(item.mBase) * count);
|
||||
}
|
||||
if (hasProfit(mActor))
|
||||
modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count);
|
||||
|
||||
return InventoryItemModel::copyItem(item, count, setNewOwner);
|
||||
}
|
||||
|
||||
void CompanionItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
{
|
||||
if (mActor.getClass().isNpc())
|
||||
{
|
||||
MWMechanics::NpcStats& stats = mActor.getClass().getNpcStats(mActor);
|
||||
stats.modifyProfit(-item.mBase.getClass().getValue(item.mBase) * count);
|
||||
}
|
||||
if (hasProfit(mActor))
|
||||
modifyProfit(mActor, -item.mBase.getClass().getValue(item.mBase) * count);
|
||||
|
||||
InventoryItemModel::removeItem(item, count);
|
||||
}
|
||||
|
||||
bool CompanionItemModel::hasProfit(const MWWorld::Ptr &actor)
|
||||
{
|
||||
std::string script = actor.getClass().getScript(actor);
|
||||
if (script.empty())
|
||||
return false;
|
||||
return actor.getRefData().getLocals().hasVar(script, "minimumprofit");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace MWGui
|
|||
|
||||
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner);
|
||||
virtual void removeItem (const ItemStack& item, size_t count);
|
||||
|
||||
bool hasProfit(const MWWorld::Ptr& actor);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,21 @@
|
|||
#include "draganddrop.hpp"
|
||||
#include "countdialog.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int getProfit(const MWWorld::Ptr& actor)
|
||||
{
|
||||
std::string script = actor.getClass().getScript(actor);
|
||||
if (!script.empty())
|
||||
{
|
||||
return actor.getRefData().getLocals().getIntVar(script, "minimumprofit");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -116,13 +131,12 @@ void CompanionWindow::updateEncumbranceBar()
|
|||
float encumbrance = mPtr.getClass().getEncumbrance(mPtr);
|
||||
mEncumbranceBar->setValue(encumbrance, capacity);
|
||||
|
||||
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
|
||||
mProfitLabel->setCaption("");
|
||||
else
|
||||
if (mModel && mModel->hasProfit(mPtr))
|
||||
{
|
||||
MWMechanics::NpcStats& stats = mPtr.getClass().getNpcStats(mPtr);
|
||||
mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(stats.getProfit()));
|
||||
mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(getProfit(mPtr)));
|
||||
}
|
||||
else
|
||||
mProfitLabel->setCaption("");
|
||||
}
|
||||
|
||||
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -132,7 +146,7 @@ void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
|
|||
|
||||
void CompanionWindow::exit()
|
||||
{
|
||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && mPtr.getClass().getNpcStats(mPtr).getProfit() < 0)
|
||||
if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0)
|
||||
{
|
||||
std::vector<std::string> buttons;
|
||||
buttons.push_back("#{sCompanionWarningButtonOne}");
|
||||
|
@ -148,9 +162,6 @@ void CompanionWindow::onMessageBoxButtonClicked(int button)
|
|||
{
|
||||
if (button == 0)
|
||||
{
|
||||
mPtr.getRefData().getLocals().setVarByInt(mPtr.getClass().getScript(mPtr),
|
||||
"minimumprofit", mPtr.getClass().getNpcStats(mPtr).getProfit());
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
|
||||
// Important for Calvus' contract script to work properly
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||
|
|
|
@ -182,6 +182,10 @@ namespace MWGui
|
|||
|
||||
HUD::~HUD()
|
||||
{
|
||||
mMainWidget->eventMouseLostFocus.clear();
|
||||
mMainWidget->eventMouseMove.clear();
|
||||
mMainWidget->eventMouseButtonClick.clear();
|
||||
|
||||
delete mSpellIcons;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <MyGUI_RotatingSkin.h>
|
||||
#include <MyGUI_FactoryManager.h>
|
||||
|
||||
#include <components/esm/globalmap.hpp>
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -22,10 +24,9 @@
|
|||
|
||||
#include "../mwrender/globalmap.hpp"
|
||||
|
||||
#include <components/esm/globalmap.hpp>
|
||||
|
||||
#include "widgets.hpp"
|
||||
#include "confirmationdialog.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -226,7 +227,7 @@ namespace MWGui
|
|||
redraw();
|
||||
}
|
||||
|
||||
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerPosition& markerPos)
|
||||
MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos)
|
||||
{
|
||||
MyGUI::IntPoint widgetPos;
|
||||
// normalized cell coordinates
|
||||
|
@ -295,7 +296,7 @@ namespace MWGui
|
|||
continue;
|
||||
}
|
||||
|
||||
MarkerPosition markerPos;
|
||||
MarkerUserData markerPos;
|
||||
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos);
|
||||
|
||||
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
|
||||
|
@ -380,8 +381,17 @@ namespace MWGui
|
|||
{
|
||||
MWBase::World::DoorMarker marker = *it;
|
||||
|
||||
MarkerPosition markerPos;
|
||||
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.x, marker.y, markerPos);
|
||||
std::vector<std::string> destNotes;
|
||||
for (std::vector<ESM::CustomMarker>::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it)
|
||||
{
|
||||
if (it->mCell == marker.dest)
|
||||
destNotes.push_back(it->mNote);
|
||||
}
|
||||
|
||||
MarkerUserData data;
|
||||
data.notes = destNotes;
|
||||
data.caption = marker.name;
|
||||
MyGUI::IntPoint widgetPos = getMarkerPosition(marker.x, marker.y, data);
|
||||
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
|
||||
widgetPos.top - 4,
|
||||
8, 8);
|
||||
|
@ -392,12 +402,10 @@ namespace MWGui
|
|||
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("ToolTipLayout", "TextToolTipOneLine");
|
||||
markerWidget->setUserString("Caption_TextOneLine", marker.name);
|
||||
// Used by tooltips to not show the tooltip if marker is hidden by fog of war
|
||||
markerWidget->setUserString("IsMarker", "true");
|
||||
markerWidget->setUserData(markerPos);
|
||||
markerWidget->setUserString("ToolTipType", "MapMarker");
|
||||
|
||||
markerWidget->setUserData(data);
|
||||
doorMarkerCreated(markerWidget);
|
||||
|
||||
mDoorMarkerWidgets.push_back(markerWidget);
|
||||
|
@ -480,7 +488,7 @@ namespace MWGui
|
|||
for (std::vector<MWWorld::Ptr>::iterator it = markers.begin(); it != markers.end(); ++it)
|
||||
{
|
||||
const ESM::Position& worldPos = it->getRefData().getPosition();
|
||||
MarkerPosition markerPos;
|
||||
MarkerUserData markerPos;
|
||||
MyGUI::IntPoint widgetPos = getMarkerPosition(worldPos.pos[0], worldPos.pos[1], markerPos);
|
||||
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
|
||||
widgetPos.top - 4,
|
||||
|
@ -490,9 +498,8 @@ namespace MWGui
|
|||
widgetCoord, MyGUI::Align::Default);
|
||||
markerWidget->setDepth(Local_MarkerAboveFogLayer);
|
||||
markerWidget->setImageTexture(markerTexture);
|
||||
markerWidget->setUserString("IsMarker", "true");
|
||||
markerWidget->setUserData(markerPos);
|
||||
markerWidget->setColour(markerColour);
|
||||
markerWidget->setNeedMouseFocus(false);
|
||||
mMagicMarkerWidgets.push_back(markerWidget);
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +533,7 @@ namespace MWGui
|
|||
if (markedCell && markedCell->isExterior() == !mInterior
|
||||
&& (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName, mPrefix)))
|
||||
{
|
||||
MarkerPosition markerPos;
|
||||
MarkerUserData markerPos;
|
||||
MyGUI::IntPoint widgetPos = getMarkerPosition(markedPosition.pos[0], markedPosition.pos[1], markerPos);
|
||||
MyGUI::IntCoord widgetCoord(widgetPos.left - 4,
|
||||
widgetPos.top - 4,
|
||||
|
@ -535,8 +542,7 @@ namespace MWGui
|
|||
widgetCoord, MyGUI::Align::Default);
|
||||
markerWidget->setDepth(Local_MarkerAboveFogLayer);
|
||||
markerWidget->setImageTexture("textures\\menu_map_smark.dds");
|
||||
markerWidget->setUserString("IsMarker", "true");
|
||||
markerWidget->setUserData(markerPos);
|
||||
markerWidget->setNeedMouseFocus(false);
|
||||
mMagicMarkerWidgets.push_back(markerWidget);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,13 +65,15 @@ namespace MWGui
|
|||
|
||||
bool toggleFogOfWar();
|
||||
|
||||
struct MarkerPosition
|
||||
struct MarkerUserData
|
||||
{
|
||||
bool interior;
|
||||
int cellX;
|
||||
int cellY;
|
||||
float nX;
|
||||
float nY;
|
||||
std::vector<std::string> notes;
|
||||
std::string caption;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -100,7 +102,7 @@ namespace MWGui
|
|||
|
||||
void applyFogOfWar();
|
||||
|
||||
MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerPosition& markerPos);
|
||||
MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerUserData& markerPos);
|
||||
|
||||
virtual void notifyPlayerUpdate() {}
|
||||
virtual void notifyMapChanged() {}
|
||||
|
|
|
@ -163,15 +163,19 @@ namespace MWGui
|
|||
|
||||
// special handling for markers on the local map: the tooltip should only be visible
|
||||
// if the marker is not hidden due to the fog of war.
|
||||
if (focus->getUserString ("IsMarker") == "true")
|
||||
if (type == "MapMarker")
|
||||
{
|
||||
LocalMapBase::MarkerPosition pos = *focus->getUserData<LocalMapBase::MarkerPosition>();
|
||||
LocalMapBase::MarkerUserData data = *focus->getUserData<LocalMapBase::MarkerUserData>();
|
||||
|
||||
if (!MWBase::Environment::get().getWorld ()->isPositionExplored (pos.nX, pos.nY, pos.cellX, pos.cellY, pos.interior))
|
||||
if (!MWBase::Environment::get().getWorld ()->isPositionExplored (data.nX, data.nY, data.cellX, data.cellY, data.interior))
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "ItemPtr")
|
||||
ToolTipInfo info;
|
||||
info.text = data.caption;
|
||||
info.notes = data.notes;
|
||||
tooltipSize = createToolTip(info);
|
||||
}
|
||||
else if (type == "ItemPtr")
|
||||
{
|
||||
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
|
||||
tooltipSize = getToolTipViaPtr(false);
|
||||
|
@ -403,16 +407,33 @@ namespace MWGui
|
|||
MyGUI::IntSize totalSize = MyGUI::IntSize( std::min(std::max(textSize.width,captionSize.width + ((image != "") ? imageCaptionHPadding : 0)),maximumWidth),
|
||||
((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight );
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = info.notes.begin(); it != info.notes.end(); ++it)
|
||||
{
|
||||
MyGUI::ImageBox* icon = mDynamicToolTipBox->createWidget<MyGUI::ImageBox>("MarkerButton",
|
||||
MyGUI::IntCoord(padding.left, totalSize.height+padding.top, 8, 8), MyGUI::Align::Default);
|
||||
icon->setColour(MyGUI::Colour(1.0,0.3,0.3));
|
||||
MyGUI::EditBox* edit = mDynamicToolTipBox->createWidget<MyGUI::EditBox>("SandText",
|
||||
MyGUI::IntCoord(padding.left+8+4, totalSize.height+padding.top, 300-padding.left-8-4, 300-totalSize.height),
|
||||
MyGUI::Align::Default);
|
||||
edit->setEditMultiLine(true);
|
||||
edit->setEditWordWrap(true);
|
||||
edit->setCaption(*it);
|
||||
edit->setSize(edit->getWidth(), edit->getTextSize().height);
|
||||
icon->setPosition(icon->getLeft(),(edit->getTop()+edit->getBottom())/2-icon->getHeight()/2);
|
||||
totalSize.height += std::max(edit->getHeight(), icon->getHeight());
|
||||
totalSize.width = std::max(totalSize.width, edit->getWidth()+8+4);
|
||||
}
|
||||
|
||||
if (!info.effects.empty())
|
||||
{
|
||||
MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
|
||||
MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height),
|
||||
MyGUI::Align::Stretch, "ToolTipEffectArea");
|
||||
MyGUI::Align::Stretch);
|
||||
|
||||
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
|
||||
|
||||
Widgets::MWEffectListPtr effectsWidget = effectArea->createWidget<Widgets::MWEffectList>
|
||||
("MW_StatName", coord, MyGUI::Align::Default, "ToolTipEffectsWidget");
|
||||
("MW_StatName", coord, MyGUI::Align::Default);
|
||||
effectsWidget->setEffectList(info.effects);
|
||||
|
||||
std::vector<MyGUI::Widget*> effectItems;
|
||||
|
@ -426,12 +447,12 @@ namespace MWGui
|
|||
assert(enchant);
|
||||
MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget<MyGUI::Widget>("",
|
||||
MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height),
|
||||
MyGUI::Align::Stretch, "ToolTipEnchantArea");
|
||||
MyGUI::Align::Stretch);
|
||||
|
||||
MyGUI::IntCoord coord(0, 6, totalSize.width, 24);
|
||||
|
||||
Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget<Widgets::MWEffectList>
|
||||
("MW_StatName", coord, MyGUI::Align::Default, "ToolTipEnchantWidget");
|
||||
("MW_StatName", coord, MyGUI::Align::Default);
|
||||
enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->mEffects));
|
||||
|
||||
std::vector<MyGUI::Widget*> enchantEffectItems;
|
||||
|
@ -470,7 +491,7 @@ namespace MWGui
|
|||
chargeCoord = MyGUI::IntCoord((totalSize.width - chargeAndTextWidth)/2 + chargeTextWidth, coord.top+6, chargeWidth, 18);
|
||||
}
|
||||
Widgets::MWDynamicStatPtr chargeWidget = enchantArea->createWidget<Widgets::MWDynamicStat>
|
||||
("MW_ChargeBar", chargeCoord, MyGUI::Align::Default, "ToolTipEnchantCharge");
|
||||
("MW_ChargeBar", chargeCoord, MyGUI::Align::Default);
|
||||
chargeWidget->setValue(charge, maxCharge);
|
||||
totalSize.height += 24;
|
||||
}
|
||||
|
@ -505,7 +526,7 @@ namespace MWGui
|
|||
{
|
||||
MyGUI::ImageBox* imageWidget = mDynamicToolTipBox->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
MyGUI::IntCoord((totalSize.width - captionSize.width - imageCaptionHPadding)/2, 0, imageSize, imageSize),
|
||||
MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipImage");
|
||||
MyGUI::Align::Left | MyGUI::Align::Top);
|
||||
imageWidget->setImageTexture(realImage);
|
||||
imageWidget->setPosition (imageWidget->getPosition() + padding);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ namespace MWGui
|
|||
// effects (for potions, ingredients)
|
||||
Widgets::SpellEffectList effects;
|
||||
|
||||
// local map notes
|
||||
std::vector<std::string> notes;
|
||||
|
||||
bool isPotion; // potions do not show target in the tooltip
|
||||
bool wordWrap;
|
||||
};
|
||||
|
|
|
@ -352,6 +352,12 @@ namespace MWGui
|
|||
|
||||
WindowManager::~WindowManager()
|
||||
{
|
||||
MyGUI::LanguageManager::getInstance().eventRequestTag.clear();
|
||||
MyGUI::PointerManager::getInstance().eventChangeMousePointer.clear();
|
||||
MyGUI::InputManager::getInstance().eventChangeKeyFocus.clear();
|
||||
MyGUI::ClipboardManager::getInstance().eventClipboardChanged.clear();
|
||||
MyGUI::ClipboardManager::getInstance().eventClipboardRequested.clear();
|
||||
|
||||
delete mConsole;
|
||||
delete mMessageBoxManager;
|
||||
delete mHud;
|
||||
|
@ -385,7 +391,6 @@ namespace MWGui
|
|||
delete mMerchantRepair;
|
||||
delete mRepair;
|
||||
delete mSoulgemDialog;
|
||||
delete mCursorManager;
|
||||
delete mRecharge;
|
||||
delete mCompanionWindow;
|
||||
delete mHitFader;
|
||||
|
@ -394,6 +399,8 @@ namespace MWGui
|
|||
delete mBlindnessFader;
|
||||
delete mDebugWindow;
|
||||
|
||||
delete mCursorManager;
|
||||
|
||||
cleanupGarbage();
|
||||
|
||||
delete mGuiManager;
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace MWGui
|
|||
ExposedWindow* window = mMainWidget->castType<ExposedWindow>();
|
||||
mPinButton = window->getSkinWidget ("Button");
|
||||
|
||||
mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked);
|
||||
mPinButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonPressed);
|
||||
|
||||
MyGUI::Button* button = NULL;
|
||||
MyGUI::VectorWidgetPtr widgets = window->getSkinWidgetsByName("Action");
|
||||
|
@ -26,8 +26,11 @@ namespace MWGui
|
|||
button->eventMouseButtonDoubleClick += MyGUI::newDelegate(this, &WindowPinnableBase::onDoubleClick);
|
||||
}
|
||||
|
||||
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
|
||||
void WindowPinnableBase::onPinButtonPressed(MyGUI::Widget* _sender, int left, int top, MyGUI::MouseButton id)
|
||||
{
|
||||
if (id != MyGUI::MouseButton::Left)
|
||||
return;
|
||||
|
||||
mPinned = !mPinned;
|
||||
|
||||
if (mPinned)
|
||||
|
@ -46,7 +49,7 @@ namespace MWGui
|
|||
void WindowPinnableBase::setPinned(bool pinned)
|
||||
{
|
||||
if (pinned != mPinned)
|
||||
onPinButtonClicked(mPinButton);
|
||||
onPinButtonPressed(mPinButton, 0, 0, MyGUI::MouseButton::Left);
|
||||
}
|
||||
|
||||
void WindowPinnableBase::setPinButtonVisible(bool visible)
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace MWGui
|
|||
void setPinButtonVisible(bool visible);
|
||||
|
||||
private:
|
||||
void onPinButtonClicked(MyGUI::Widget* _sender);
|
||||
void onPinButtonPressed(MyGUI::Widget* _sender, int left, int top, MyGUI::MouseButton id);
|
||||
void onDoubleClick(MyGUI::Widget* _sender);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -1126,7 +1126,7 @@ bool CharacterController::updateWeaponState()
|
|||
attackStrength = std::min(1.f, 0.1f + std::rand() / float(RAND_MAX));
|
||||
}
|
||||
|
||||
if(mAttackType != "shoot")
|
||||
if(mWeaponType != WeapType_Crossbow && mWeaponType != WeapType_BowAndArrow)
|
||||
{
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
|
||||
|
|
|
@ -371,6 +371,23 @@ namespace MWMechanics
|
|||
sndMgr->playSound3D(victim, "Hand To Hand Hit", 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void applyFatigueLoss(const MWWorld::Ptr &attacker, const MWWorld::Ptr &weapon)
|
||||
{
|
||||
// somewhat of a guess, but using the weapon weight makes sense
|
||||
const MWWorld::Store<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
const float fFatigueAttackBase = store.find("fFatigueAttackBase")->getFloat();
|
||||
const float fFatigueAttackMult = store.find("fFatigueAttackMult")->getFloat();
|
||||
const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->getFloat();
|
||||
CreatureStats& stats = attacker.getClass().getCreatureStats(attacker);
|
||||
MWMechanics::DynamicStat<float> fatigue = stats.getFatigue();
|
||||
const float normalizedEncumbrance = attacker.getClass().getNormalizedEncumbrance(attacker);
|
||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||
if (!weapon.isEmpty())
|
||||
fatigueLoss += weapon.getClass().getWeight(weapon) * stats.getAttackStrength() * fWeaponFatigueMult;
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
||||
stats.setFatigue(fatigue);
|
||||
}
|
||||
|
||||
bool isEnvironmentCompatible(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim)
|
||||
{
|
||||
const MWWorld::Class& attackerClass = attacker.getClass();
|
||||
|
|
|
@ -34,6 +34,9 @@ void adjustWeaponDamage (float& damage, const MWWorld::Ptr& weapon);
|
|||
|
||||
void getHandToHandDamage (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, float& damage, bool& healthdmg);
|
||||
|
||||
/// Apply the fatigue loss incurred by attacking with the given weapon (weapon may be empty = hand-to-hand)
|
||||
void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon);
|
||||
|
||||
/// Can attacker operate in victim's environment?
|
||||
/// e.g. If attacker is a fish, is victim in water? Or, if attacker can't swim, is victim on land?
|
||||
bool isEnvironmentCompatible(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim);
|
||||
|
|
|
@ -495,7 +495,10 @@ namespace MWMechanics
|
|||
state.mDead = mDead;
|
||||
state.mDied = mDied;
|
||||
state.mMurdered = mMurdered;
|
||||
state.mFriendlyHits = mFriendlyHits;
|
||||
// The vanilla engine does not store friendly hits in the save file. Since there's no other mechanism
|
||||
// that ever resets the friendly hits (at least not to my knowledge) this should be regarded a feature
|
||||
// rather than a bug.
|
||||
//state.mFriendlyHits = mFriendlyHits;
|
||||
state.mTalkedTo = mTalkedTo;
|
||||
state.mAlarmed = mAlarmed;
|
||||
state.mAttacked = mAttacked;
|
||||
|
@ -544,7 +547,6 @@ namespace MWMechanics
|
|||
mDead = state.mDead;
|
||||
mDied = state.mDied;
|
||||
mMurdered = state.mMurdered;
|
||||
mFriendlyHits = state.mFriendlyHits;
|
||||
mTalkedTo = state.mTalkedTo;
|
||||
mAlarmed = state.mAlarmed;
|
||||
mAttacked = state.mAttacked;
|
||||
|
|
|
@ -31,7 +31,6 @@ MWMechanics::NpcStats::NpcStats()
|
|||
, mReputation(0)
|
||||
, mCrimeId(-1)
|
||||
, mWerewolfKills (0)
|
||||
, mProfit(0)
|
||||
, mTimeToStartDrowning(20.0)
|
||||
{
|
||||
mSkillIncreases.resize (ESM::Attribute::Length, 0);
|
||||
|
@ -448,16 +447,6 @@ void MWMechanics::NpcStats::addWerewolfKill()
|
|||
++mWerewolfKills;
|
||||
}
|
||||
|
||||
int MWMechanics::NpcStats::getProfit() const
|
||||
{
|
||||
return mProfit;
|
||||
}
|
||||
|
||||
void MWMechanics::NpcStats::modifyProfit(int diff)
|
||||
{
|
||||
mProfit += diff;
|
||||
}
|
||||
|
||||
float MWMechanics::NpcStats::getTimeToStartDrowning() const
|
||||
{
|
||||
return mTimeToStartDrowning;
|
||||
|
@ -501,7 +490,6 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const
|
|||
|
||||
state.mReputation = mReputation;
|
||||
state.mWerewolfKills = mWerewolfKills;
|
||||
state.mProfit = mProfit;
|
||||
state.mLevelProgress = mLevelProgress;
|
||||
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
|
@ -548,7 +536,6 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
|
|||
mBounty = state.mBounty;
|
||||
mReputation = state.mReputation;
|
||||
mWerewolfKills = state.mWerewolfKills;
|
||||
mProfit = state.mProfit;
|
||||
mLevelProgress = state.mLevelProgress;
|
||||
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
|
|
|
@ -28,8 +28,6 @@ namespace MWMechanics
|
|||
int mReputation;
|
||||
int mCrimeId;
|
||||
|
||||
int mProfit;
|
||||
|
||||
// ----- used by the player only, maybe should be moved at some point -------
|
||||
int mBounty;
|
||||
int mWerewolfKills;
|
||||
|
@ -49,10 +47,6 @@ namespace MWMechanics
|
|||
|
||||
NpcStats();
|
||||
|
||||
/// for mercenary companions. starts out as 0, and changes when items are added or removed through the UI.
|
||||
int getProfit() const;
|
||||
void modifyProfit(int diff);
|
||||
|
||||
int getBaseDisposition() const;
|
||||
void setBaseDisposition(int disposition);
|
||||
|
||||
|
|
|
@ -1272,8 +1272,7 @@ void Animation::addEffect(const std::string &model, int effectId, bool loop, con
|
|||
else
|
||||
params.mObjects = NifOgre::Loader::createObjects(mSkelBase, bonename, "", mInsert, model);
|
||||
|
||||
// TODO: turn off shadow casting
|
||||
setRenderProperties(params.mObjects, RV_Misc,
|
||||
setRenderProperties(params.mObjects, RV_Effects,
|
||||
RQG_Main, RQG_Alpha, 0.f, false, NULL);
|
||||
|
||||
params.mLoop = loop;
|
||||
|
|
|
@ -25,8 +25,7 @@ void EffectManager::addEffect(const std::string &model, std::string textureOverr
|
|||
|
||||
NifOgre::ObjectScenePtr scene = NifOgre::Loader::createObjects(sceneNode, model);
|
||||
|
||||
// TODO: turn off shadow casting
|
||||
MWRender::Animation::setRenderProperties(scene, RV_Misc,
|
||||
MWRender::Animation::setRenderProperties(scene, RV_Effects,
|
||||
RQG_Main, RQG_Alpha, 0.f, false, NULL);
|
||||
|
||||
for(size_t i = 0;i < scene->mControllers.size();i++)
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace MWRender
|
|||
Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera);
|
||||
vp->setOverlaysEnabled(false);
|
||||
vp->setShadowsEnabled(false);
|
||||
vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky + RV_FirstPerson);
|
||||
vp->setVisibilityMask(RV_Refraction);
|
||||
vp->setMaterialScheme("water_refraction");
|
||||
vp->setBackgroundColour (Ogre::ColourValue(0.090195, 0.115685, 0.12745));
|
||||
mRenderTarget->setAutoUpdated(true);
|
||||
|
|
|
@ -30,39 +30,44 @@ enum RenderQueueGroups
|
|||
enum VisibilityFlags
|
||||
{
|
||||
// Terrain
|
||||
RV_Terrain = 1,
|
||||
RV_Terrain = (1<<0),
|
||||
|
||||
// Statics (e.g. trees, houses)
|
||||
RV_Statics = 2,
|
||||
RV_Statics = (1<<1),
|
||||
|
||||
// Small statics
|
||||
RV_StaticsSmall = 4,
|
||||
RV_StaticsSmall = (1<<2),
|
||||
|
||||
// Water
|
||||
RV_Water = 8,
|
||||
RV_Water = (1<<3),
|
||||
|
||||
// Actors (npcs, creatures)
|
||||
RV_Actors = 16,
|
||||
RV_Actors = (1<<4),
|
||||
|
||||
// Misc objects (containers, dynamic objects)
|
||||
RV_Misc = 32,
|
||||
RV_Misc = (1<<5),
|
||||
|
||||
RV_Sky = 64,
|
||||
// VFX, don't appear on map and don't cast shadows
|
||||
RV_Effects = (1<<6),
|
||||
|
||||
RV_Sky = (1<<7),
|
||||
|
||||
// not visible in reflection
|
||||
RV_NoReflection = 128,
|
||||
RV_NoReflection = (1<<8),
|
||||
|
||||
RV_OcclusionQuery = 256,
|
||||
RV_OcclusionQuery = (1<<9),
|
||||
|
||||
RV_Debug = 512,
|
||||
RV_Debug = (1<<10),
|
||||
|
||||
// overlays, we only want these on the main render target
|
||||
RV_Overlay = 1024,
|
||||
RV_Overlay = (1<<11),
|
||||
|
||||
// First person meshes do not cast shadows
|
||||
RV_FirstPerson = 2048,
|
||||
RV_FirstPerson = (1<<12),
|
||||
|
||||
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water
|
||||
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water,
|
||||
|
||||
RV_Refraction = RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Effects + RV_Sky + RV_FirstPerson
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -409,6 +409,7 @@ void RenderingManager::update (float duration, bool paused)
|
|||
|
||||
mSkyManager->setGlare(mOcclusionQuery->getSunVisibility());
|
||||
|
||||
mWater->changeCell(player.getCell()->getCell());
|
||||
|
||||
mWater->updateUnderwater(world->isUnderwater(player.getCell(), cam));
|
||||
|
||||
|
|
|
@ -187,6 +187,8 @@ Moon::Moon( const String& textureName,
|
|||
{
|
||||
setVisibility(1.0);
|
||||
|
||||
mMaterial->setProperty("alphatexture", sh::makeProperty(new sh::StringValue(textureName + "_alpha")));
|
||||
|
||||
mPhase = Moon::Phase_Full;
|
||||
}
|
||||
|
||||
|
@ -215,9 +217,15 @@ void Moon::setPhase(const Moon::Phase& phase)
|
|||
textureName += ".dds";
|
||||
|
||||
if (mType == Moon::Type_Secunda)
|
||||
{
|
||||
sh::Factory::getInstance ().setTextureAlias ("secunda_texture", textureName);
|
||||
sh::Factory::getInstance ().setTextureAlias ("secunda_texture_alpha", "textures\\tx_mooncircle_full_s.dds");
|
||||
}
|
||||
else
|
||||
{
|
||||
sh::Factory::getInstance ().setTextureAlias ("masser_texture", textureName);
|
||||
sh::Factory::getInstance ().setTextureAlias ("masser_texture_alpha", "textures\\tx_mooncircle_full_m.dds");
|
||||
}
|
||||
|
||||
mPhase = phase;
|
||||
}
|
||||
|
|
|
@ -210,10 +210,10 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend) :
|
|||
|
||||
mWaterPlane = Plane(Vector3::UNIT_Z, 0);
|
||||
|
||||
int waterScale = 300;
|
||||
int waterScale = 30;
|
||||
|
||||
MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane,
|
||||
CELL_SIZE*5*waterScale, CELL_SIZE*5*waterScale, 10, 10, true, 1, 3*waterScale,3*waterScale, Vector3::UNIT_Y);
|
||||
CELL_SIZE*5*waterScale, CELL_SIZE*5*waterScale, 40, 40, true, 1, 3*waterScale,3*waterScale, Vector3::UNIT_Y);
|
||||
|
||||
mWater = mSceneMgr->createEntity("water");
|
||||
mWater->setVisibilityFlags(RV_Water);
|
||||
|
@ -305,11 +305,7 @@ Water::~Water()
|
|||
|
||||
void Water::changeCell(const ESM::Cell* cell)
|
||||
{
|
||||
mTop = cell->mWater;
|
||||
|
||||
setHeight(mTop);
|
||||
|
||||
if(!(cell->mData.mFlags & cell->Interior))
|
||||
if(cell->isExterior())
|
||||
mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY));
|
||||
}
|
||||
|
||||
|
@ -424,6 +420,7 @@ void Water::applyVisibilityMask()
|
|||
mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water")
|
||||
+ (RV_Statics + RV_StaticsSmall + RV_Misc) * Settings::Manager::getBool("reflect statics", "Water")
|
||||
+ RV_Actors * Settings::Manager::getBool("reflect actors", "Water")
|
||||
+ RV_Effects
|
||||
+ RV_Sky;
|
||||
|
||||
if (mReflection)
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/combat.hpp"
|
||||
|
||||
#include "animation.hpp"
|
||||
|
||||
|
@ -44,9 +46,22 @@ void WeaponAnimation::attachArrow(MWWorld::Ptr actor)
|
|||
{
|
||||
MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor);
|
||||
MWWorld::ContainerStoreIterator weaponSlot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if (weaponSlot != inv.end() && weaponSlot->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanThrown)
|
||||
if (weaponSlot == inv.end())
|
||||
return;
|
||||
if (weaponSlot->getTypeName() != typeid(ESM::Weapon).name())
|
||||
return;
|
||||
int weaponType = weaponSlot->get<ESM::Weapon>()->mBase->mData.mType;
|
||||
if (weaponType == ESM::Weapon::MarksmanThrown)
|
||||
{
|
||||
std::string soundid = weaponSlot->getClass().getUpSoundId(*weaponSlot);
|
||||
if(!soundid.empty())
|
||||
{
|
||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||
sndMgr->playSound3D(actor, soundid, 1.0f, 1.0f);
|
||||
}
|
||||
showWeapon(true);
|
||||
else
|
||||
}
|
||||
else if (weaponType == ESM::Weapon::MarksmanBow || weaponType == ESM::Weapon::MarksmanCrossbow)
|
||||
{
|
||||
NifOgre::ObjectScenePtr weapon = getWeapon();
|
||||
if (!weapon.get())
|
||||
|
@ -72,6 +87,8 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
|
|||
MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if (weapon == inv.end())
|
||||
return;
|
||||
if (weapon->getTypeName() != typeid(ESM::Weapon).name())
|
||||
return;
|
||||
|
||||
// The orientation of the launched projectile. Always the same as the actor orientation, even if the ArrowBone's orientation dictates otherwise.
|
||||
Ogre::Quaternion orient = Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
||||
|
@ -80,19 +97,7 @@ void WeaponAnimation::releaseArrow(MWWorld::Ptr actor)
|
|||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
// Reduce fatigue
|
||||
// somewhat of a guess, but using the weapon weight makes sense
|
||||
const float fFatigueAttackBase = gmst.find("fFatigueAttackBase")->getFloat();
|
||||
const float fFatigueAttackMult = gmst.find("fFatigueAttackMult")->getFloat();
|
||||
const float fWeaponFatigueMult = gmst.find("fWeaponFatigueMult")->getFloat();
|
||||
MWMechanics::CreatureStats& attackerStats = actor.getClass().getCreatureStats(actor);
|
||||
MWMechanics::DynamicStat<float> fatigue = attackerStats.getFatigue();
|
||||
const float normalizedEncumbrance = actor.getClass().getNormalizedEncumbrance(actor);
|
||||
float fatigueLoss = fFatigueAttackBase + normalizedEncumbrance * fFatigueAttackMult;
|
||||
if (!weapon->isEmpty())
|
||||
fatigueLoss += weapon->getClass().getWeight(*weapon) * attackerStats.getAttackStrength() * fWeaponFatigueMult;
|
||||
fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss);
|
||||
attackerStats.setFatigue(fatigue);
|
||||
MWMechanics::applyFatigueLoss(actor, *weapon);
|
||||
|
||||
if (weapon->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanThrown)
|
||||
{
|
||||
|
|
|
@ -35,8 +35,11 @@ namespace MWRender
|
|||
WeaponAnimation() : mPitchFactor(0) {}
|
||||
virtual ~WeaponAnimation() {}
|
||||
|
||||
virtual void attachArrow(MWWorld::Ptr actor);
|
||||
virtual void releaseArrow(MWWorld::Ptr actor);
|
||||
/// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op.
|
||||
void attachArrow(MWWorld::Ptr actor);
|
||||
|
||||
/// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op.
|
||||
void releaseArrow(MWWorld::Ptr actor);
|
||||
|
||||
protected:
|
||||
NifOgre::ObjectScenePtr mAmmunition;
|
||||
|
|
|
@ -32,6 +32,21 @@ namespace MWScript
|
|||
return (mShorts.empty() && mLongs.empty() && mFloats.empty());
|
||||
}
|
||||
|
||||
bool Locals::hasVar(const std::string &script, const std::string &var)
|
||||
{
|
||||
try
|
||||
{
|
||||
const Compiler::Locals& locals =
|
||||
MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||
int index = locals.getIndex(var);
|
||||
return (index != -1);
|
||||
}
|
||||
catch (const Compiler::SourceException&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int Locals::getIntVar(const std::string &script, const std::string &var)
|
||||
{
|
||||
const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||
|
|
|
@ -24,11 +24,15 @@ namespace MWScript
|
|||
bool isEmpty() const;
|
||||
|
||||
void configure (const ESM::Script& script);
|
||||
|
||||
/// @note var needs to be in lowercase
|
||||
bool setVarByInt(const std::string& script, const std::string& var, int val);
|
||||
int getIntVar (const std::string& script, const std::string& var);
|
||||
///< if var does not exist, returns 0
|
||||
|
||||
bool hasVar(const std::string& script, const std::string& var);
|
||||
|
||||
/// if var does not exist, returns 0
|
||||
/// @note var needs to be in lowercase
|
||||
int getIntVar (const std::string& script, const std::string& var);
|
||||
|
||||
void write (ESM::Locals& locals, const std::string& script) const;
|
||||
|
||||
|
|
|
@ -518,42 +518,41 @@ namespace MWScript
|
|||
if (count<0)
|
||||
throw std::runtime_error ("count must be non-negative");
|
||||
|
||||
// no-op
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
ESM::Position ipos = actor.getRefData().getPosition();
|
||||
Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]);
|
||||
Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||
if(direction == 0) pos = pos + distance*rot.yAxis();
|
||||
else if(direction == 1) pos = pos - distance*rot.yAxis();
|
||||
else if(direction == 2) pos = pos - distance*rot.xAxis();
|
||||
else if(direction == 3) pos = pos + distance*rot.xAxis();
|
||||
else throw std::runtime_error ("direction must be 0,1,2 or 3");
|
||||
|
||||
ipos.pos[0] = pos.x;
|
||||
ipos.pos[1] = pos.y;
|
||||
ipos.pos[2] = pos.z;
|
||||
|
||||
if (actor.getClass().isActor())
|
||||
for (int i=0; i<count; ++i)
|
||||
{
|
||||
// TODO: should this depend on the 'direction' parameter?
|
||||
ipos.rot[0] = 0;
|
||||
ipos.rot[1] = 0;
|
||||
ipos.rot[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipos.rot[0] = actor.getRefData().getPosition().rot[0];
|
||||
ipos.rot[1] = actor.getRefData().getPosition().rot[1];
|
||||
ipos.rot[2] = actor.getRefData().getPosition().rot[2];
|
||||
}
|
||||
// create item
|
||||
MWWorld::CellStore* store = actor.getCell();
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, count);
|
||||
ref.getPtr().getCellRef().setPosition(ipos);
|
||||
ESM::Position ipos = actor.getRefData().getPosition();
|
||||
Ogre::Vector3 pos(ipos.pos[0],ipos.pos[1],ipos.pos[2]);
|
||||
Ogre::Quaternion rot(Ogre::Radian(-ipos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||
if(direction == 0) pos = pos + distance*rot.yAxis();
|
||||
else if(direction == 1) pos = pos - distance*rot.yAxis();
|
||||
else if(direction == 2) pos = pos - distance*rot.xAxis();
|
||||
else if(direction == 3) pos = pos + distance*rot.xAxis();
|
||||
else throw std::runtime_error ("direction must be 0,1,2 or 3");
|
||||
|
||||
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos);
|
||||
ipos.pos[0] = pos.x;
|
||||
ipos.pos[1] = pos.y;
|
||||
ipos.pos[2] = pos.z;
|
||||
|
||||
if (actor.getClass().isActor())
|
||||
{
|
||||
// TODO: should this depend on the 'direction' parameter?
|
||||
ipos.rot[0] = 0;
|
||||
ipos.rot[1] = 0;
|
||||
ipos.rot[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipos.rot[0] = actor.getRefData().getPosition().rot[0];
|
||||
ipos.rot[1] = actor.getRefData().getPosition().rot[1];
|
||||
ipos.rot[2] = actor.getRefData().getPosition().rot[2];
|
||||
}
|
||||
// create item
|
||||
MWWorld::CellStore* store = actor.getCell();
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, 1);
|
||||
ref.getPtr().getCellRef().setPosition(ipos);
|
||||
|
||||
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,14 +25,28 @@ void FFmpeg_Decoder::fail(const std::string &msg)
|
|||
|
||||
int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size)
|
||||
{
|
||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
||||
return stream->read(buf, buf_size);
|
||||
try
|
||||
{
|
||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
||||
return stream->read(buf, buf_size);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int FFmpeg_Decoder::writePacket(void *user_data, uint8_t *buf, int buf_size)
|
||||
{
|
||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
||||
return stream->write(buf, buf_size);
|
||||
try
|
||||
{
|
||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
||||
return stream->write(buf, buf_size);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t FFmpeg_Decoder::seek(void *user_data, int64_t offset, int whence)
|
||||
|
|
|
@ -303,26 +303,15 @@ namespace MWWorld
|
|||
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
|
||||
position.z += halfExtents.z;
|
||||
|
||||
waterlevel -= halfExtents.z * 0.5;
|
||||
/*
|
||||
* A 3/4 submerged example
|
||||
*
|
||||
* +---+
|
||||
* | |
|
||||
* | | <- (original waterlevel)
|
||||
* | |
|
||||
* | | <- position <- waterlevel
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +---+ <- (original position)
|
||||
*/
|
||||
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("fSwimHeightScale")->getFloat();
|
||||
float swimlevel = waterlevel + halfExtents.z - (halfExtents.z * 2 * fSwimHeightScale);
|
||||
|
||||
OEngine::Physic::ActorTracer tracer;
|
||||
Ogre::Vector3 inertia = physicActor->getInertialForce();
|
||||
Ogre::Vector3 velocity;
|
||||
|
||||
if(position.z < waterlevel || isFlying)
|
||||
if(position.z < swimlevel || isFlying)
|
||||
{
|
||||
velocity = (Ogre::Quaternion(Ogre::Radian(refpos.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z)*
|
||||
Ogre::Quaternion(Ogre::Radian(refpos.rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X)) * movement;
|
||||
|
@ -364,12 +353,10 @@ namespace MWWorld
|
|||
Ogre::Vector3 nextpos = newPosition + velocity * remainingTime;
|
||||
|
||||
// If not able to fly, don't allow to swim up into the air
|
||||
// TODO: this if condition may not work for large creatures or situations
|
||||
// where the creature gets above the waterline for some reason
|
||||
if(newPosition.z < waterlevel && // started 3/4 under water
|
||||
if(newPosition.z < swimlevel &&
|
||||
!isFlying && // can't fly
|
||||
nextpos.z > waterlevel && // but about to go above water
|
||||
newPosition.z <= waterlevel)
|
||||
nextpos.z > swimlevel && // but about to go above water
|
||||
newPosition.z <= swimlevel)
|
||||
{
|
||||
const Ogre::Vector3 down(0,0,-1);
|
||||
Ogre::Real movelen = velocity.normalise();
|
||||
|
@ -423,7 +410,7 @@ namespace MWWorld
|
|||
{
|
||||
// don't let pure water creatures move out of water after stepMove
|
||||
if (ptr.getClass().isPureWaterCreature(ptr)
|
||||
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
|
||||
&& newPosition.z + halfExtents.z > waterlevel)
|
||||
newPosition = oldPosition;
|
||||
}
|
||||
else
|
||||
|
@ -444,13 +431,13 @@ namespace MWWorld
|
|||
|
||||
// Do not allow sliding upward if there is gravity. Stepping will have taken
|
||||
// care of that.
|
||||
if(!(newPosition.z < waterlevel || isFlying))
|
||||
if(!(newPosition.z < swimlevel || isFlying))
|
||||
velocity.z = std::min(velocity.z, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
bool isOnGround = false;
|
||||
if (!(inertia.z > 0.f) && !(newPosition.z < waterlevel))
|
||||
if (!(inertia.z > 0.f) && !(newPosition.z < swimlevel))
|
||||
{
|
||||
Ogre::Vector3 from = newPosition;
|
||||
Ogre::Vector3 to = newPosition - (physicActor->getOnGround() ?
|
||||
|
@ -494,7 +481,7 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
if(isOnGround || newPosition.z < waterlevel || isFlying)
|
||||
if(isOnGround || newPosition.z < swimlevel || isFlying)
|
||||
physicActor->setInertialForce(Ogre::Vector3(0.0f));
|
||||
else
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace MWWorld
|
|||
state.mObject->mControllers[i].setSource(Ogre::SharedPtr<MWRender::EffectAnimationTime> (new MWRender::EffectAnimationTime()));
|
||||
}
|
||||
|
||||
MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Misc,
|
||||
MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Effects,
|
||||
MWRender::RQG_Main, MWRender::RQG_Alpha, 0.f, false, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -544,9 +544,16 @@ namespace MWWorld
|
|||
|
||||
void Scene::addObjectToScene (const Ptr& ptr)
|
||||
{
|
||||
addObject(ptr, *mPhysics, mRendering);
|
||||
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
|
||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
|
||||
try
|
||||
{
|
||||
addObject(ptr, *mPhysics, mRendering);
|
||||
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
|
||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << "error during rendering: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::removeObjectFromScene (const Ptr& ptr)
|
||||
|
|
|
@ -360,6 +360,8 @@ namespace MWWorld
|
|||
std::pair<typename Static::iterator, bool> inserted = mStatic.insert(std::make_pair(scpt.mId, scpt));
|
||||
if (inserted.second)
|
||||
mShared.push_back(&inserted.first->second);
|
||||
else
|
||||
inserted.first->second = scpt;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -371,6 +373,8 @@ namespace MWWorld
|
|||
std::pair<typename Static::iterator, bool> inserted = mStatic.insert(std::make_pair(s.mId, s));
|
||||
if (inserted.second)
|
||||
mShared.push_back(&inserted.first->second);
|
||||
else
|
||||
inserted.first->second = s;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
|
@ -187,6 +187,8 @@ namespace MWWorld
|
|||
mStore.setUp();
|
||||
mStore.movePlayerRecord();
|
||||
|
||||
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat();
|
||||
|
||||
mGlobalVariables.fill (mStore);
|
||||
|
||||
mWorldScene = new Scene(*mRendering, mPhysics);
|
||||
|
@ -1735,6 +1737,23 @@ namespace MWWorld
|
|||
World::DoorMarker newMarker;
|
||||
newMarker.name = MWClass::Door::getDestination(ref);
|
||||
|
||||
ESM::CellId cellid;
|
||||
if (!ref.mRef.getDestCell().empty())
|
||||
{
|
||||
cellid.mWorldspace = ref.mRef.getDestCell();
|
||||
cellid.mPaged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellid.mPaged = true;
|
||||
MWBase::Environment::get().getWorld()->positionToIndex(
|
||||
ref.mRef.getDoorDest().pos[0],
|
||||
ref.mRef.getDoorDest().pos[1],
|
||||
cellid.mIndex.mX,
|
||||
cellid.mIndex.mY);
|
||||
}
|
||||
newMarker.dest = cellid;
|
||||
|
||||
ESM::Position pos = ref.mData.getPosition ();
|
||||
|
||||
newMarker.x = pos.pos[0];
|
||||
|
@ -1935,8 +1954,7 @@ namespace MWWorld
|
|||
mRendering->getTriangleBatchCount(triangles, batches);
|
||||
}
|
||||
|
||||
bool
|
||||
World::isFlying(const MWWorld::Ptr &ptr) const
|
||||
bool World::isFlying(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
|
||||
bool isParalyzed = (stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0);
|
||||
|
@ -1961,8 +1979,7 @@ namespace MWWorld
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
World::isSlowFalling(const MWWorld::Ptr &ptr) const
|
||||
bool World::isSlowFalling(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
if(!ptr.getClass().isActor())
|
||||
return false;
|
||||
|
@ -1976,27 +1993,21 @@ namespace MWWorld
|
|||
|
||||
bool World::isSubmerged(const MWWorld::Ptr &object) const
|
||||
{
|
||||
const float neckDeep = 1.85f;
|
||||
return isUnderwater(object, neckDeep);
|
||||
return isUnderwater(object, 1.0/mSwimHeightScale);
|
||||
}
|
||||
|
||||
bool
|
||||
World::isSwimming(const MWWorld::Ptr &object) const
|
||||
bool World::isSwimming(const MWWorld::Ptr &object) const
|
||||
{
|
||||
/// \todo add check ifActor() - only actors can swim
|
||||
/// \fixme 3/4ths submerged?
|
||||
return isUnderwater(object, 1.5f);
|
||||
return isUnderwater(object, mSwimHeightScale);
|
||||
}
|
||||
|
||||
bool
|
||||
World::isWading(const MWWorld::Ptr &object) const
|
||||
bool World::isWading(const MWWorld::Ptr &object) const
|
||||
{
|
||||
const float kneeDeep = 0.5f;
|
||||
const float kneeDeep = 0.25f;
|
||||
return isUnderwater(object, kneeDeep);
|
||||
}
|
||||
|
||||
bool
|
||||
World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
|
||||
bool World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
|
||||
{
|
||||
const float *fpos = object.getRefData().getPosition().pos;
|
||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
||||
|
@ -2004,14 +2015,13 @@ namespace MWWorld
|
|||
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
|
||||
if (actor)
|
||||
{
|
||||
pos.z += heightRatio*actor->getHalfExtents().z;
|
||||
pos.z += heightRatio*2*actor->getHalfExtents().z;
|
||||
}
|
||||
|
||||
return isUnderwater(object.getCell(), pos);
|
||||
}
|
||||
|
||||
bool
|
||||
World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
|
||||
bool World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
|
||||
{
|
||||
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
|
||||
return false;
|
||||
|
@ -2606,7 +2616,7 @@ namespace MWWorld
|
|||
|
||||
// Check mana
|
||||
MWMechanics::DynamicStat<float> magicka = stats.getMagicka();
|
||||
if (magicka.getCurrent() < spell->mData.mCost)
|
||||
if (magicka.getCurrent() < spell->mData.mCost && !(isPlayer && getGodModeState()))
|
||||
{
|
||||
message = "#{sMagicInsufficientSP}";
|
||||
fail = true;
|
||||
|
|
|
@ -139,6 +139,7 @@ namespace MWWorld
|
|||
void loadContentFiles(const Files::Collections& fileCollections,
|
||||
const std::vector<std::string>& content, ContentLoader& contentLoader);
|
||||
|
||||
float mSwimHeightScale;
|
||||
bool isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const;
|
||||
///< helper function for implementing isSwimming(), isSubmerged(), isWading()
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ void Wizard::MainWizard::runSettingsImporter()
|
|||
arguments.append(QLatin1String("--cfg"));
|
||||
arguments.append(userPath + QLatin1String("openmw.cfg"));
|
||||
|
||||
if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false))
|
||||
if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false))
|
||||
return qApp->quit();
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ void ESM::CellRef::blank()
|
|||
mLockLevel = 0;
|
||||
mKey.clear();
|
||||
mTrap.clear();
|
||||
mReferenceBlocked = 0;
|
||||
mReferenceBlocked = -1;
|
||||
mTeleport = false;
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
|
|
|
@ -24,8 +24,8 @@ void ESM::CreatureStats::load (ESMReader &esm)
|
|||
mMurdered = false;
|
||||
esm.getHNOT (mMurdered, "MURD");
|
||||
|
||||
mFriendlyHits = 0;
|
||||
esm.getHNOT (mFriendlyHits, "FRHT");
|
||||
if (esm.isNextSub("FRHT"))
|
||||
esm.skipHSub(); // Friendly hits, no longer used
|
||||
|
||||
mTalkedTo = false;
|
||||
esm.getHNOT (mTalkedTo, "TALK");
|
||||
|
@ -140,9 +140,6 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
|
|||
if (mMurdered)
|
||||
esm.writeHNT ("MURD", mMurdered);
|
||||
|
||||
if (mFriendlyHits)
|
||||
esm.writeHNT ("FRHT", mFriendlyHits);
|
||||
|
||||
if (mTalkedTo)
|
||||
esm.writeHNT ("TALK", mTalkedTo);
|
||||
|
||||
|
@ -235,7 +232,6 @@ void ESM::CreatureStats::blank()
|
|||
mDead = false;
|
||||
mDied = false;
|
||||
mMurdered = false;
|
||||
mFriendlyHits = 0;
|
||||
mTalkedTo = false;
|
||||
mAlarmed = false;
|
||||
mAttacked = false;
|
||||
|
|
|
@ -42,7 +42,6 @@ namespace ESM
|
|||
bool mDead;
|
||||
bool mDied;
|
||||
bool mMurdered;
|
||||
int mFriendlyHits;
|
||||
bool mTalkedTo;
|
||||
bool mAlarmed;
|
||||
bool mAttacked;
|
||||
|
|
|
@ -123,7 +123,7 @@ std::string ESMReader::getHString()
|
|||
// Skip the following zero byte
|
||||
mCtx.leftRec--;
|
||||
char c;
|
||||
mEsm->read(&c, 1);
|
||||
getExact(&c, 1);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ void ESMReader::getSubName()
|
|||
}
|
||||
|
||||
// reading the subrecord data anyway.
|
||||
mEsm->read(mCtx.subName.name, 4);
|
||||
getExact(mCtx.subName.name, 4);
|
||||
mCtx.leftRec -= 4;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ bool ESMReader::isEmptyOrGetName()
|
|||
{
|
||||
if (mCtx.leftRec)
|
||||
{
|
||||
mEsm->read(mCtx.subName.name, 4);
|
||||
getExact(mCtx.subName.name, 4);
|
||||
mCtx.leftRec -= 4;
|
||||
return false;
|
||||
}
|
||||
|
@ -294,9 +294,16 @@ void ESMReader::getRecHeader(uint32_t &flags)
|
|||
|
||||
void ESMReader::getExact(void*x, int size)
|
||||
{
|
||||
int t = mEsm->read(x, size);
|
||||
if (t != size)
|
||||
fail("Read error");
|
||||
try
|
||||
{
|
||||
int t = mEsm->read(x, size);
|
||||
if (t != size)
|
||||
fail("Read error");
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
fail(std::string("Read error: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::string ESMReader::getString(int size)
|
||||
|
|
|
@ -57,12 +57,13 @@ void ESM::NpcStats::load (ESMReader &esm)
|
|||
mWerewolfKills = 0;
|
||||
esm.getHNOT (mWerewolfKills, "WKIL");
|
||||
|
||||
mProfit = 0;
|
||||
esm.getHNOT (mProfit, "PROF");
|
||||
// No longer used
|
||||
if (esm.isNextSub("PROF"))
|
||||
esm.skipHSub(); // int profit
|
||||
|
||||
// No longer used. Now part of CreatureStats.
|
||||
float attackStrength = 0;
|
||||
esm.getHNOT (attackStrength, "ASTR");
|
||||
if (esm.isNextSub("ASTR"))
|
||||
esm.skipHSub(); // attackStrength
|
||||
|
||||
mLevelProgress = 0;
|
||||
esm.getHNOT (mLevelProgress, "LPRO");
|
||||
|
@ -132,9 +133,6 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
|||
if (mWerewolfKills)
|
||||
esm.writeHNT ("WKIL", mWerewolfKills);
|
||||
|
||||
if (mProfit)
|
||||
esm.writeHNT ("PROF", mProfit);
|
||||
|
||||
if (mLevelProgress)
|
||||
esm.writeHNT ("LPRO", mLevelProgress);
|
||||
|
||||
|
@ -158,7 +156,6 @@ void ESM::NpcStats::blank()
|
|||
mBounty = 0;
|
||||
mReputation = 0;
|
||||
mWerewolfKills = 0;
|
||||
mProfit = 0;
|
||||
mLevelProgress = 0;
|
||||
for (int i=0; i<8; ++i)
|
||||
mSkillIncrease[i] = 0;
|
||||
|
|
|
@ -40,7 +40,6 @@ namespace ESM
|
|||
int mBounty;
|
||||
int mReputation;
|
||||
int mWerewolfKills;
|
||||
int mProfit;
|
||||
int mLevelProgress;
|
||||
int mSkillIncrease[8];
|
||||
std::vector<std::string> mUsedIds; // lower case IDs
|
||||
|
|
|
@ -27,8 +27,9 @@ const char* const localToken = "?local?";
|
|||
const char* const userDataToken = "?userdata?";
|
||||
const char* const globalToken = "?global?";
|
||||
|
||||
ConfigurationManager::ConfigurationManager()
|
||||
ConfigurationManager::ConfigurationManager(bool silent)
|
||||
: mFixedPath(applicationName)
|
||||
, mSilent(silent)
|
||||
{
|
||||
setupTokensMapping();
|
||||
|
||||
|
@ -129,7 +130,8 @@ void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
|||
cfgFile /= std::string(openmwCfgFile);
|
||||
if (boost::filesystem::is_regular_file(cfgFile))
|
||||
{
|
||||
std::cout << "Loading config file: " << cfgFile.string() << "... ";
|
||||
if (!mSilent)
|
||||
std::cout << "Loading config file: " << cfgFile.string() << "... ";
|
||||
|
||||
boost::filesystem::ifstream configFileStream(cfgFile);
|
||||
if (configFileStream.is_open())
|
||||
|
@ -137,11 +139,13 @@ void ConfigurationManager::loadConfig(const boost::filesystem::path& path,
|
|||
boost::program_options::store(boost::program_options::parse_config_file(
|
||||
configFileStream, description, true), variables);
|
||||
|
||||
std::cout << "done." << std::endl;
|
||||
if (!mSilent)
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "failed." << std::endl;
|
||||
if (!mSilent)
|
||||
std::cout << "failed." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Files
|
|||
*/
|
||||
struct ConfigurationManager
|
||||
{
|
||||
ConfigurationManager();
|
||||
ConfigurationManager(bool silent=false); /// @param silent Emit log messages to cout?
|
||||
virtual ~ConfigurationManager();
|
||||
|
||||
void readConfiguration(boost::program_options::variables_map& variables,
|
||||
|
@ -69,6 +69,8 @@ struct ConfigurationManager
|
|||
boost::filesystem::path mLogPath;
|
||||
|
||||
TokensMappingContainer mTokensMapping;
|
||||
|
||||
bool mSilent;
|
||||
};
|
||||
|
||||
} /* namespace Cfg */
|
||||
|
|
|
@ -11,162 +11,172 @@ namespace {
|
|||
class ConstrainedDataStream : public Ogre::DataStream {
|
||||
public:
|
||||
|
||||
static const size_t sBufferSize = 4096; // somewhat arbitrary though 64KB buffers didn't seem to improve performance any
|
||||
static const size_t sBufferThreshold = 1024; // reads larger than this bypass buffering as cost of memcpy outweighs cost of system call
|
||||
static const size_t sBufferSize = 4096; // somewhat arbitrary though 64KB buffers didn't seem to improve performance any
|
||||
static const size_t sBufferThreshold = 1024; // reads larger than this bypass buffering as cost of memcpy outweighs cost of system call
|
||||
|
||||
ConstrainedDataStream(const Ogre::String &fname, size_t start, size_t length)
|
||||
{
|
||||
mFile.open (fname.c_str ());
|
||||
mSize = length != 0xFFFFFFFF ? length : mFile.size () - start;
|
||||
: Ogre::DataStream(fname)
|
||||
{
|
||||
mFile.open (fname.c_str ());
|
||||
mSize = length != 0xFFFFFFFF ? length : mFile.size () - start;
|
||||
|
||||
mPos = 0;
|
||||
mOrigin = start;
|
||||
mExtent = start + mSize;
|
||||
mPos = 0;
|
||||
mOrigin = start;
|
||||
mExtent = start + mSize;
|
||||
|
||||
mBufferOrigin = 0;
|
||||
mBufferExtent = 0;
|
||||
}
|
||||
mBufferOrigin = 0;
|
||||
mBufferExtent = 0;
|
||||
}
|
||||
|
||||
|
||||
size_t read(void* buf, size_t count)
|
||||
{
|
||||
assert (mPos <= mSize);
|
||||
size_t read(void* buf, size_t count)
|
||||
{
|
||||
try
|
||||
{
|
||||
assert (mPos <= mSize);
|
||||
|
||||
uint8_t * out = reinterpret_cast <uint8_t *> (buf);
|
||||
uint8_t * out = reinterpret_cast <uint8_t *> (buf);
|
||||
|
||||
size_t posBeg = mOrigin + mPos;
|
||||
size_t posEnd = posBeg + count;
|
||||
size_t posBeg = mOrigin + mPos;
|
||||
size_t posEnd = posBeg + count;
|
||||
|
||||
if (posEnd > mExtent)
|
||||
posEnd = mExtent;
|
||||
if (posEnd > mExtent)
|
||||
posEnd = mExtent;
|
||||
|
||||
size_t posCur = posBeg;
|
||||
size_t posCur = posBeg;
|
||||
|
||||
while (posCur != posEnd)
|
||||
{
|
||||
size_t readLeft = posEnd - posCur;
|
||||
while (posCur != posEnd)
|
||||
{
|
||||
size_t readLeft = posEnd - posCur;
|
||||
|
||||
if (posCur < mBufferOrigin || posCur >= mBufferExtent)
|
||||
{
|
||||
if (readLeft >= sBufferThreshold || (posCur == mOrigin && posEnd == mExtent))
|
||||
{
|
||||
assert (mFile.tell () == mBufferExtent);
|
||||
if (posCur < mBufferOrigin || posCur >= mBufferExtent)
|
||||
{
|
||||
if (readLeft >= sBufferThreshold || (posCur == mOrigin && posEnd == mExtent))
|
||||
{
|
||||
assert (mFile.tell () == mBufferExtent);
|
||||
|
||||
if (posCur != mBufferExtent)
|
||||
mFile.seek (posCur);
|
||||
if (posCur != mBufferExtent)
|
||||
mFile.seek (posCur);
|
||||
|
||||
posCur += mFile.read (out, readLeft);
|
||||
posCur += mFile.read (out, readLeft);
|
||||
|
||||
mBufferOrigin = mBufferExtent = posCur;
|
||||
mBufferOrigin = mBufferExtent = posCur;
|
||||
|
||||
mPos = posCur - mOrigin;
|
||||
mPos = posCur - mOrigin;
|
||||
|
||||
return posCur - posBeg;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t newBufferOrigin;
|
||||
return posCur - posBeg;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t newBufferOrigin;
|
||||
|
||||
if ((posCur < mBufferOrigin) && (mBufferOrigin - posCur < sBufferSize))
|
||||
newBufferOrigin = std::max (mOrigin, mBufferOrigin > sBufferSize ? mBufferOrigin - sBufferSize : 0);
|
||||
else
|
||||
newBufferOrigin = posCur;
|
||||
if ((posCur < mBufferOrigin) && (mBufferOrigin - posCur < sBufferSize))
|
||||
newBufferOrigin = std::max (mOrigin, mBufferOrigin > sBufferSize ? mBufferOrigin - sBufferSize : 0);
|
||||
else
|
||||
newBufferOrigin = posCur;
|
||||
|
||||
fill (newBufferOrigin);
|
||||
}
|
||||
}
|
||||
fill (newBufferOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
size_t xfer = std::min (readLeft, mBufferExtent - posCur);
|
||||
size_t xfer = std::min (readLeft, mBufferExtent - posCur);
|
||||
|
||||
memcpy (out, mBuffer + (posCur - mBufferOrigin), xfer);
|
||||
memcpy (out, mBuffer + (posCur - mBufferOrigin), xfer);
|
||||
|
||||
posCur += xfer;
|
||||
out += xfer;
|
||||
}
|
||||
posCur += xfer;
|
||||
out += xfer;
|
||||
}
|
||||
|
||||
count = posEnd - posBeg;
|
||||
mPos += count;
|
||||
return count;
|
||||
}
|
||||
count = posEnd - posBeg;
|
||||
mPos += count;
|
||||
return count;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "Failed to read '" << mName << "': " << e.what();
|
||||
throw std::runtime_error(error.str());
|
||||
}
|
||||
}
|
||||
|
||||
void skip(long count)
|
||||
{
|
||||
assert (mPos <= mSize);
|
||||
assert (mPos <= mSize);
|
||||
|
||||
if((count >= 0 && (size_t)count <= mSize-mPos) ||
|
||||
(count < 0 && (size_t)-count <= mPos))
|
||||
mPos += count;
|
||||
mPos += count;
|
||||
}
|
||||
|
||||
void seek(size_t pos)
|
||||
{
|
||||
assert (mPos <= mSize);
|
||||
assert (mPos <= mSize);
|
||||
|
||||
if (pos < mSize)
|
||||
mPos = pos;
|
||||
mPos = pos;
|
||||
}
|
||||
|
||||
virtual size_t tell() const
|
||||
{
|
||||
assert (mPos <= mSize);
|
||||
assert (mPos <= mSize);
|
||||
|
||||
return mPos;
|
||||
}
|
||||
return mPos;
|
||||
}
|
||||
|
||||
virtual bool eof() const
|
||||
{
|
||||
assert (mPos <= mSize);
|
||||
assert (mPos <= mSize);
|
||||
|
||||
return mPos == mSize;
|
||||
}
|
||||
return mPos == mSize;
|
||||
}
|
||||
|
||||
virtual void close()
|
||||
{
|
||||
mFile.close();
|
||||
}
|
||||
mFile.close();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void fill (size_t newOrigin)
|
||||
{
|
||||
assert (mFile.tell () == mBufferExtent);
|
||||
void fill (size_t newOrigin)
|
||||
{
|
||||
assert (mFile.tell () == mBufferExtent);
|
||||
|
||||
size_t newExtent = newOrigin + sBufferSize;
|
||||
size_t newExtent = newOrigin + sBufferSize;
|
||||
|
||||
if (newExtent > mExtent)
|
||||
newExtent = mExtent;
|
||||
if (newExtent > mExtent)
|
||||
newExtent = mExtent;
|
||||
|
||||
size_t oldExtent = mBufferExtent;
|
||||
size_t oldExtent = mBufferExtent;
|
||||
|
||||
if (newOrigin != oldExtent)
|
||||
mFile.seek (newOrigin);
|
||||
if (newOrigin != oldExtent)
|
||||
mFile.seek (newOrigin);
|
||||
|
||||
mBufferOrigin = mBufferExtent = newOrigin;
|
||||
mBufferOrigin = mBufferExtent = newOrigin;
|
||||
|
||||
size_t amountRequested = newExtent - newOrigin;
|
||||
size_t amountRequested = newExtent - newOrigin;
|
||||
|
||||
size_t amountRead = mFile.read (mBuffer, amountRequested);
|
||||
size_t amountRead = mFile.read (mBuffer, amountRequested);
|
||||
|
||||
if (amountRead != amountRequested)
|
||||
throw std::runtime_error ("An unexpected condition occurred while reading from a file.");
|
||||
if (amountRead != amountRequested)
|
||||
throw std::runtime_error ("An unexpected condition occurred while reading from a file.");
|
||||
|
||||
mBufferExtent = newExtent;
|
||||
}
|
||||
mBufferExtent = newExtent;
|
||||
}
|
||||
|
||||
LowLevelFile mFile;
|
||||
LowLevelFile mFile;
|
||||
|
||||
size_t mOrigin;
|
||||
size_t mExtent;
|
||||
size_t mPos;
|
||||
size_t mOrigin;
|
||||
size_t mExtent;
|
||||
size_t mPos;
|
||||
|
||||
uint8_t mBuffer [sBufferSize];
|
||||
size_t mBufferOrigin;
|
||||
size_t mBufferExtent;
|
||||
uint8_t mBuffer [sBufferSize];
|
||||
size_t mBufferOrigin;
|
||||
size_t mBufferExtent;
|
||||
};
|
||||
|
||||
} // end of unnamed namespace
|
||||
|
||||
Ogre::DataStreamPtr openConstrainedFileDataStream (char const * filename, size_t offset, size_t length)
|
||||
{
|
||||
return Ogre::DataStreamPtr(new ConstrainedDataStream(filename, offset, length));
|
||||
return Ogre::DataStreamPtr(new ConstrainedDataStream(filename, offset, length));
|
||||
}
|
||||
|
|
|
@ -13,196 +13,196 @@
|
|||
#if FILE_API == FILE_API_STDIO
|
||||
/*
|
||||
*
|
||||
* Implementation of LowLevelFile methods using c stdio
|
||||
* Implementation of LowLevelFile methods using c stdio
|
||||
*
|
||||
*/
|
||||
|
||||
LowLevelFile::LowLevelFile ()
|
||||
{
|
||||
mHandle = NULL;
|
||||
mHandle = NULL;
|
||||
}
|
||||
|
||||
LowLevelFile::~LowLevelFile ()
|
||||
{
|
||||
if (mHandle != NULL)
|
||||
fclose (mHandle);
|
||||
if (mHandle != NULL)
|
||||
fclose (mHandle);
|
||||
}
|
||||
|
||||
void LowLevelFile::open (char const * filename)
|
||||
{
|
||||
assert (mHandle == NULL);
|
||||
assert (mHandle == NULL);
|
||||
|
||||
mHandle = fopen (filename, "rb");
|
||||
mHandle = fopen (filename, "rb");
|
||||
|
||||
if (mHandle == NULL)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to open '" << filename << "' for reading.";
|
||||
throw std::runtime_error (os.str ());
|
||||
}
|
||||
if (mHandle == NULL)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to open '" << filename << "' for reading.";
|
||||
throw std::runtime_error (os.str ());
|
||||
}
|
||||
}
|
||||
|
||||
void LowLevelFile::close ()
|
||||
{
|
||||
assert (mHandle != NULL);
|
||||
assert (mHandle != NULL);
|
||||
|
||||
fclose (mHandle);
|
||||
fclose (mHandle);
|
||||
|
||||
mHandle = NULL;
|
||||
mHandle = NULL;
|
||||
}
|
||||
|
||||
size_t LowLevelFile::size ()
|
||||
{
|
||||
assert (mHandle != NULL);
|
||||
assert (mHandle != NULL);
|
||||
|
||||
long oldPosition = ftell (mHandle);
|
||||
long oldPosition = ftell (mHandle);
|
||||
|
||||
if (oldPosition == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (oldPosition == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
if (fseek (mHandle, 0, SEEK_END) != 0)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (fseek (mHandle, 0, SEEK_END) != 0)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
long Size = ftell (mHandle);
|
||||
long Size = ftell (mHandle);
|
||||
|
||||
if (Size == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (Size == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
if (fseek (mHandle, oldPosition, SEEK_SET) != 0)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (fseek (mHandle, oldPosition, SEEK_SET) != 0)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
return size_t (Size);
|
||||
return size_t (Size);
|
||||
}
|
||||
|
||||
void LowLevelFile::seek (size_t Position)
|
||||
{
|
||||
assert (mHandle != NULL);
|
||||
assert (mHandle != NULL);
|
||||
|
||||
if (fseek (mHandle, Position, SEEK_SET) != 0)
|
||||
throw std::runtime_error ("A seek operation on a file failed.");
|
||||
if (fseek (mHandle, Position, SEEK_SET) != 0)
|
||||
throw std::runtime_error ("A seek operation on a file failed.");
|
||||
}
|
||||
|
||||
size_t LowLevelFile::tell ()
|
||||
{
|
||||
assert (mHandle != NULL);
|
||||
assert (mHandle != NULL);
|
||||
|
||||
long Position = ftell (mHandle);
|
||||
long Position = ftell (mHandle);
|
||||
|
||||
if (Position == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (Position == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
return size_t (Position);
|
||||
return size_t (Position);
|
||||
}
|
||||
|
||||
size_t LowLevelFile::read (void * data, size_t size)
|
||||
{
|
||||
assert (mHandle != NULL);
|
||||
assert (mHandle != NULL);
|
||||
|
||||
int amount = fread (data, 1, size, mHandle);
|
||||
int amount = fread (data, 1, size, mHandle);
|
||||
|
||||
if (amount == 0 && ferror (mHandle))
|
||||
throw std::runtime_error ("A read operation on a file failed.");
|
||||
if (amount == 0 && ferror (mHandle))
|
||||
throw std::runtime_error ("A read operation on a file failed.");
|
||||
|
||||
return amount;
|
||||
return amount;
|
||||
}
|
||||
|
||||
#elif FILE_API == FILE_API_POSIX
|
||||
/*
|
||||
*
|
||||
* Implementation of LowLevelFile methods using posix IO calls
|
||||
* Implementation of LowLevelFile methods using posix IO calls
|
||||
*
|
||||
*/
|
||||
|
||||
LowLevelFile::LowLevelFile ()
|
||||
{
|
||||
mHandle = -1;
|
||||
mHandle = -1;
|
||||
}
|
||||
|
||||
LowLevelFile::~LowLevelFile ()
|
||||
{
|
||||
if (mHandle != -1)
|
||||
::close (mHandle);
|
||||
if (mHandle != -1)
|
||||
::close (mHandle);
|
||||
}
|
||||
|
||||
void LowLevelFile::open (char const * filename)
|
||||
{
|
||||
assert (mHandle == -1);
|
||||
assert (mHandle == -1);
|
||||
|
||||
#ifdef O_BINARY
|
||||
static const int openFlags = O_RDONLY | O_BINARY;
|
||||
static const int openFlags = O_RDONLY | O_BINARY;
|
||||
#else
|
||||
static const int openFlags = O_RDONLY;
|
||||
static const int openFlags = O_RDONLY;
|
||||
#endif
|
||||
|
||||
mHandle = ::open (filename, openFlags, 0);
|
||||
mHandle = ::open (filename, openFlags, 0);
|
||||
|
||||
if (mHandle == -1)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to open '" << filename << "' for reading.";
|
||||
throw std::runtime_error (os.str ());
|
||||
}
|
||||
if (mHandle == -1)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to open '" << filename << "' for reading.";
|
||||
throw std::runtime_error (os.str ());
|
||||
}
|
||||
}
|
||||
|
||||
void LowLevelFile::close ()
|
||||
{
|
||||
assert (mHandle != -1);
|
||||
assert (mHandle != -1);
|
||||
|
||||
::close (mHandle);
|
||||
::close (mHandle);
|
||||
|
||||
mHandle = -1;
|
||||
mHandle = -1;
|
||||
}
|
||||
|
||||
size_t LowLevelFile::size ()
|
||||
{
|
||||
assert (mHandle != -1);
|
||||
assert (mHandle != -1);
|
||||
|
||||
size_t oldPosition = ::lseek (mHandle, 0, SEEK_CUR);
|
||||
size_t oldPosition = ::lseek (mHandle, 0, SEEK_CUR);
|
||||
|
||||
if (oldPosition == size_t (-1))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (oldPosition == size_t (-1))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
size_t Size = ::lseek (mHandle, 0, SEEK_END);
|
||||
size_t Size = ::lseek (mHandle, 0, SEEK_END);
|
||||
|
||||
if (Size == size_t (-1))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (Size == size_t (-1))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
if (lseek (mHandle, oldPosition, SEEK_SET) == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (lseek (mHandle, oldPosition, SEEK_SET) == -1)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
return Size;
|
||||
return Size;
|
||||
}
|
||||
|
||||
void LowLevelFile::seek (size_t Position)
|
||||
{
|
||||
assert (mHandle != -1);
|
||||
assert (mHandle != -1);
|
||||
|
||||
if (::lseek (mHandle, Position, SEEK_SET) == -1)
|
||||
throw std::runtime_error ("A seek operation on a file failed.");
|
||||
if (::lseek (mHandle, Position, SEEK_SET) == -1)
|
||||
throw std::runtime_error ("A seek operation on a file failed.");
|
||||
}
|
||||
|
||||
size_t LowLevelFile::tell ()
|
||||
{
|
||||
assert (mHandle != -1);
|
||||
assert (mHandle != -1);
|
||||
|
||||
size_t Position = ::lseek (mHandle, 0, SEEK_CUR);
|
||||
size_t Position = ::lseek (mHandle, 0, SEEK_CUR);
|
||||
|
||||
if (Position == size_t (-1))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (Position == size_t (-1))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
return Position;
|
||||
return Position;
|
||||
}
|
||||
|
||||
size_t LowLevelFile::read (void * data, size_t size)
|
||||
{
|
||||
assert (mHandle != -1);
|
||||
assert (mHandle != -1);
|
||||
|
||||
int amount = ::read (mHandle, data, size);
|
||||
int amount = ::read (mHandle, data, size);
|
||||
|
||||
if (amount == -1)
|
||||
throw std::runtime_error ("A read operation on a file failed.");
|
||||
if (amount == -1)
|
||||
throw std::runtime_error ("A read operation on a file failed.");
|
||||
|
||||
return amount;
|
||||
return amount;
|
||||
}
|
||||
|
||||
#elif FILE_API == FILE_API_WIN32
|
||||
|
@ -210,93 +210,93 @@ size_t LowLevelFile::read (void * data, size_t size)
|
|||
#include <boost/locale.hpp>
|
||||
/*
|
||||
*
|
||||
* Implementation of LowLevelFile methods using Win32 API calls
|
||||
* Implementation of LowLevelFile methods using Win32 API calls
|
||||
*
|
||||
*/
|
||||
|
||||
LowLevelFile::LowLevelFile ()
|
||||
{
|
||||
mHandle = INVALID_HANDLE_VALUE;
|
||||
mHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
LowLevelFile::~LowLevelFile ()
|
||||
{
|
||||
if (mHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (mHandle);
|
||||
if (mHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (mHandle);
|
||||
}
|
||||
|
||||
void LowLevelFile::open (char const * filename)
|
||||
{
|
||||
assert (mHandle == INVALID_HANDLE_VALUE);
|
||||
assert (mHandle == INVALID_HANDLE_VALUE);
|
||||
|
||||
std::wstring wname = boost::locale::conv::utf_to_utf<wchar_t>(filename);
|
||||
HANDLE handle = CreateFileW (wname.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
std::wstring wname = boost::locale::conv::utf_to_utf<wchar_t>(filename);
|
||||
HANDLE handle = CreateFileW (wname.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to open '" << filename << "' for reading.";
|
||||
throw std::runtime_error (os.str ());
|
||||
}
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "Failed to open '" << filename << "' for reading.";
|
||||
throw std::runtime_error (os.str ());
|
||||
}
|
||||
|
||||
mHandle = handle;
|
||||
mHandle = handle;
|
||||
}
|
||||
|
||||
void LowLevelFile::close ()
|
||||
{
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
|
||||
CloseHandle (mHandle);
|
||||
CloseHandle (mHandle);
|
||||
|
||||
mHandle = INVALID_HANDLE_VALUE;
|
||||
mHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
size_t LowLevelFile::size ()
|
||||
{
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
|
||||
if (!GetFileInformationByHandle (mHandle, &info))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (!GetFileInformationByHandle (mHandle, &info))
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
if (info.nFileSizeHigh != 0)
|
||||
throw std::runtime_error ("Files greater that 4GB are not supported.");
|
||||
if (info.nFileSizeHigh != 0)
|
||||
throw std::runtime_error ("Files greater that 4GB are not supported.");
|
||||
|
||||
return info.nFileSizeLow;
|
||||
return info.nFileSizeLow;
|
||||
}
|
||||
|
||||
void LowLevelFile::seek (size_t Position)
|
||||
{
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
|
||||
if (SetFilePointer (mHandle, Position, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER)
|
||||
if (GetLastError () != NO_ERROR)
|
||||
throw std::runtime_error ("A seek operation on a file failed.");
|
||||
if (SetFilePointer (mHandle, Position, NULL, SEEK_SET) == INVALID_SET_FILE_POINTER)
|
||||
if (GetLastError () != NO_ERROR)
|
||||
throw std::runtime_error ("A seek operation on a file failed.");
|
||||
}
|
||||
|
||||
size_t LowLevelFile::tell ()
|
||||
{
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
|
||||
DWORD value = SetFilePointer (mHandle, 0, NULL, SEEK_CUR);
|
||||
DWORD value = SetFilePointer (mHandle, 0, NULL, SEEK_CUR);
|
||||
|
||||
if (value == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
if (value == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
|
||||
throw std::runtime_error ("A query operation on a file failed.");
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
size_t LowLevelFile::read (void * data, size_t size)
|
||||
{
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
assert (mHandle != INVALID_HANDLE_VALUE);
|
||||
|
||||
DWORD read;
|
||||
DWORD read;
|
||||
|
||||
if (!ReadFile (mHandle, data, size, &read, NULL))
|
||||
throw std::runtime_error ("A read operation on a file failed.");
|
||||
if (!ReadFile (mHandle, data, size, &read, NULL))
|
||||
throw std::runtime_error ("A read operation on a file failed.");
|
||||
|
||||
return read;
|
||||
return read;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
|
||||
#include <cstdlib>
|
||||
|
||||
#define FILE_API_STDIO 0
|
||||
#define FILE_API_POSIX 1
|
||||
#define FILE_API_WIN32 2
|
||||
#define FILE_API_STDIO 0
|
||||
#define FILE_API_POSIX 1
|
||||
#define FILE_API_WIN32 2
|
||||
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||
#define FILE_API FILE_API_POSIX
|
||||
#define FILE_API FILE_API_POSIX
|
||||
#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
#define FILE_API FILE_API_WIN32
|
||||
#define FILE_API FILE_API_WIN32
|
||||
#else
|
||||
#define FILE_API FILE_API_STDIO
|
||||
#define FILE_API FILE_API_STDIO
|
||||
#endif
|
||||
|
||||
#if FILE_API == FILE_API_STDIO
|
||||
|
@ -30,26 +30,26 @@ class LowLevelFile
|
|||
{
|
||||
public:
|
||||
|
||||
LowLevelFile ();
|
||||
~LowLevelFile ();
|
||||
LowLevelFile ();
|
||||
~LowLevelFile ();
|
||||
|
||||
void open (char const * filename);
|
||||
void close ();
|
||||
void open (char const * filename);
|
||||
void close ();
|
||||
|
||||
size_t size ();
|
||||
size_t size ();
|
||||
|
||||
void seek (size_t Position);
|
||||
size_t tell ();
|
||||
void seek (size_t Position);
|
||||
size_t tell ();
|
||||
|
||||
size_t read (void * data, size_t size);
|
||||
size_t read (void * data, size_t size);
|
||||
|
||||
private:
|
||||
#if FILE_API == FILE_API_STDIO
|
||||
FILE* mHandle;
|
||||
FILE* mHandle;
|
||||
#elif FILE_API == FILE_API_POSIX
|
||||
int mHandle;
|
||||
int mHandle;
|
||||
#elif FILE_API == FILE_API_WIN32
|
||||
HANDLE mHandle;
|
||||
HANDLE mHandle;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -37,31 +37,7 @@ public:
|
|||
|
||||
NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {}
|
||||
|
||||
/*************************************************
|
||||
Parser functions
|
||||
****************************************************/
|
||||
|
||||
template <typename T>
|
||||
struct GetHandler
|
||||
{
|
||||
typedef T (NIFStream::*fn_t)();
|
||||
|
||||
static const fn_t sValue; // this is specialized per supported type in the .cpp file
|
||||
|
||||
static T read (NIFStream* nif)
|
||||
{
|
||||
return (nif->*sValue) ();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void read (NIFStream* nif, T & Value)
|
||||
{
|
||||
Value = GetHandler <T>::read (nif);
|
||||
}
|
||||
|
||||
void skip(size_t size) { inp->skip(size); }
|
||||
void read (void * data, size_t size) { inp->read (data, size); }
|
||||
|
||||
char getChar() { return read_byte(); }
|
||||
short getShort() { return read_le16(); }
|
||||
|
|
18
extern/ogre-ffmpeg-videoplayer/videostate.cpp
vendored
18
extern/ogre-ffmpeg-videoplayer/videostate.cpp
vendored
|
@ -175,13 +175,27 @@ void PacketQueue::clear()
|
|||
int VideoState::OgreResource_Read(void *user_data, uint8_t *buf, int buf_size)
|
||||
{
|
||||
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
||||
return stream->read(buf, buf_size);
|
||||
try
|
||||
{
|
||||
return stream->read(buf, buf_size);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int VideoState::OgreResource_Write(void *user_data, uint8_t *buf, int buf_size)
|
||||
{
|
||||
Ogre::DataStreamPtr stream = static_cast<VideoState*>(user_data)->stream;
|
||||
return stream->write(buf, buf_size);
|
||||
try
|
||||
{
|
||||
return stream->write(buf, buf_size);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t VideoState::OgreResource_Seek(void *user_data, int64_t offset, int whence)
|
||||
|
|
|
@ -38,16 +38,14 @@ shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
|
|||
|
||||
SH_START_PROGRAM
|
||||
{
|
||||
|
||||
float4 tex = shSample(diffuseMap, UV);
|
||||
|
||||
shOutputColour(0) = float4(materialEmissive.xyz, 1) * tex;
|
||||
|
||||
shOutputColour(0).a = shSample(alphaMap, UV).a * materialDiffuse.a;
|
||||
|
||||
shOutputColour(0).rgb += (1.0-tex.a) * shOutputColour(0).a * atmosphereColour.rgb; //fill dark side of moon with atmosphereColour
|
||||
shOutputColour(0).rgb += (1.0-materialDiffuse.a) * atmosphereColour.rgb; //fade bump
|
||||
float4 phaseTex = shSample(diffuseMap, UV);
|
||||
float4 fullCircleTex = shSample(alphaMap, UV);
|
||||
|
||||
shOutputColour(0).a = max(phaseTex.a, fullCircleTex.a) * materialDiffuse.a;
|
||||
|
||||
shOutputColour(0).xyz = fullCircleTex.xyz * atmosphereColour.xyz;
|
||||
shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, phaseTex.xyz, phaseTex.a);
|
||||
shOutputColour(0).xyz *= materialEmissive.xyz;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,7 +50,7 @@ material openmw_moon
|
|||
|
||||
texture_unit alphaMap
|
||||
{
|
||||
direct_texture textures\tx_secunda_full.dds
|
||||
texture_alias $alphatexture
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,6 @@
|
|||
|
||||
SH_BEGIN_PROGRAM
|
||||
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||
shVertexInput(float2, uv0)
|
||||
shOutput(float2, UV)
|
||||
|
||||
shOutput(float3, screenCoordsPassthrough)
|
||||
shOutput(float4, position)
|
||||
|
@ -98,7 +96,6 @@
|
|||
SH_START_PROGRAM
|
||||
{
|
||||
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||
UV = uv0;
|
||||
|
||||
|
||||
#if !SH_GLSL
|
||||
|
@ -187,7 +184,6 @@
|
|||
}
|
||||
|
||||
SH_BEGIN_PROGRAM
|
||||
shInput(float2, UV)
|
||||
shInput(float3, screenCoordsPassthrough)
|
||||
shInput(float4, position)
|
||||
shInput(float, depthPassthrough)
|
||||
|
@ -206,9 +202,10 @@
|
|||
shSampler2D(depthMap)
|
||||
shSampler2D(normalMap)
|
||||
|
||||
shUniform(float4x4, wMat) @shAutoConstant(wMat, world_matrix)
|
||||
|
||||
#if RIPPLES
|
||||
shSampler2D(rippleNormalMap)
|
||||
shUniform(float4x4, wMat) @shAutoConstant(wMat, world_matrix)
|
||||
#endif
|
||||
|
||||
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
|
||||
|
@ -251,6 +248,10 @@
|
|||
|
||||
SH_START_PROGRAM
|
||||
{
|
||||
float3 worldPos = shMatrixMult (wMat, position).xyz;
|
||||
float2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
|
||||
UV.y *= -1.0;
|
||||
|
||||
#if SHADOWS
|
||||
float shadow = depthShadowPCF (shadowMap0, lightSpacePos0, invShadowmapSize0);
|
||||
#endif
|
||||
|
|
|
@ -137,4 +137,19 @@
|
|||
</Widget>
|
||||
</Resource>
|
||||
|
||||
<!-- Same as MW_Caption, but reserves some free space on the right for the Pin button -
|
||||
i.e. not allowing the caption label to stretch there, but still showing the tiling background. -->
|
||||
<Resource type="ResourceLayout" name="MW_Caption_Pin" version="3.2.0">
|
||||
<Widget type="Widget" skin="" position="0 0 88 20" name="Root">
|
||||
<Widget type="Widget" skin="HB_ALL" position="0 0 30 20" align="Default" name="Left"/>
|
||||
<Widget type="Widget" skin="" position="0 0 69 20" align="Stretch">
|
||||
<Widget type="TextBox" skin="SandText" position="30 0 28 20" align="Left VStretch" name="Client">
|
||||
<Property key="FontName" value="Default"/>
|
||||
<Property key="TextAlign" value="Center"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="Widget" skin="HB_ALL" position="0 0 30 20" align="Right" name="Right"/>
|
||||
</Widget>
|
||||
</Resource>
|
||||
|
||||
</MyGUI>
|
||||
|
|
|
@ -804,7 +804,7 @@
|
|||
</Child>
|
||||
|
||||
<!-- Caption -->
|
||||
<Child type="WindowCaption" skin="MW_Caption" offset="4 4 228 20" align="HStretch Top" name="Caption">
|
||||
<Child type="WindowCaption" skin="MW_Caption_Pin" offset="4 4 248 20" align="HStretch Top" name="Caption">
|
||||
</Child>
|
||||
|
||||
<!-- This invisible button makes it possible to move the
|
||||
|
|
|
@ -4,8 +4,8 @@ Name=OpenMW Launcher
|
|||
GenericName=Role Playing Game
|
||||
Comment=An engine replacement for The Elder Scrolls III: Morrowind
|
||||
Keywords=Morrowind;Reimplementation Mods;esm;bsa;
|
||||
TryExec=omwlauncher
|
||||
Exec=omwlauncher
|
||||
TryExec=openmw-launcher
|
||||
Exec=openmw-launcher
|
||||
Icon=openmw
|
||||
Categories=Game;RolePlaying;
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
border-radius: 2px;
|
||||
|
||||
font-size: 12pt;
|
||||
font-family: "EB Garamond", "EB Garamond 08";
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
@ -95,7 +94,6 @@
|
|||
<property name="styleSheet">
|
||||
<string notr="true">#profileLabel {
|
||||
font-size: 18pt;
|
||||
font-family: "EB Garamond", "EB Garamond 08";
|
||||
color: black;
|
||||
}
|
||||
</string>
|
||||
|
@ -133,7 +131,6 @@
|
|||
stop:1 rgba(0, 0, 0, 100));
|
||||
|
||||
font-size: 26pt;
|
||||
font-family: "EB Garamond", "EB Garamond 08";
|
||||
color: black;
|
||||
|
||||
border-right: 1px solid rgba(0, 0, 0, 155);
|
||||
|
|
Loading…
Reference in a new issue