Merge pull request #1 from kcat/werewolf

Update to latest master
This commit is contained in:
Emanuel Guével 2013-08-08 01:38:15 -07:00
commit 8bde8d7c11
91 changed files with 2256 additions and 1864 deletions

View file

@ -78,6 +78,7 @@ set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
set(OENGINE_OGRE set(OENGINE_OGRE
${LIBDIR}/openengine/ogre/renderer.cpp ${LIBDIR}/openengine/ogre/renderer.cpp
${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/lights.cpp
${LIBDIR}/openengine/ogre/particles.cpp ${LIBDIR}/openengine/ogre/particles.cpp
${LIBDIR}/openengine/ogre/selectionbuffer.cpp ${LIBDIR}/openengine/ogre/selectionbuffer.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp ${LIBDIR}/openengine/ogre/imagerotate.cpp

View file

@ -7,6 +7,8 @@
#include <MyGUI_WidgetManager.h> #include <MyGUI_WidgetManager.h>
#include <components/compiler/extensions0.hpp>
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/translation/translation.hpp> #include <components/translation/translation.hpp>
@ -395,7 +397,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster[i]); mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster[i]);
// Create window manager - this manages all the MW-specific GUI windows // Create window manager - this manages all the MW-specific GUI windows
MWScript::registerExtensions (mExtensions); Compiler::registerExtensions (mExtensions);
mEnvironment.setWindowManager (new MWGui::WindowManager( mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
@ -478,7 +480,7 @@ void OMW::Engine::go()
assert (!mOgre); assert (!mOgre);
Settings::Manager settings; Settings::Manager settings;
std::string settingspath; std::string settingspath;
settingspath = loadSettings (settings); settingspath = loadSettings (settings);

View file

@ -141,6 +141,10 @@ namespace MWBase
virtual void setValue (const std::string& id, const std::string& value) = 0; virtual void setValue (const std::string& id, const std::string& value) = 0;
virtual void setValue (const std::string& id, int value) = 0; virtual void setValue (const std::string& id, int value) = 0;
/// Set time left for the player to start drowning (update the drowning bar)
/// @param time value from [0,20]
virtual void setDrowningTimeLeft (float time) =0;
virtual void setPlayerClass (const ESM::Class &class_) = 0; virtual void setPlayerClass (const ESM::Class &class_) = 0;
///< set current class of player ///< set current class of player
@ -184,6 +188,9 @@ namespace MWBase
virtual void setInteriorMapTexture(const int x, const int y) = 0; virtual void setInteriorMapTexture(const int x, const int y) = 0;
///< set the index of the map texture that should be used (for interiors) ///< set the index of the map texture that should be used (for interiors)
/// sets the visibility of the drowning bar
virtual void setDrowningBarVisibility(bool visible) = 0;
/// sets the visibility of the hud health/magicka/stamina bars /// sets the visibility of the hud health/magicka/stamina bars
virtual void setHMSVisibility(bool visible) = 0; virtual void setHMSVisibility(bool visible) = 0;

View file

@ -323,6 +323,8 @@ namespace MWBase
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0; virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0; virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
///Is the head of the creature underwater?
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;

View file

@ -25,9 +25,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -30,9 +30,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -23,9 +23,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -27,9 +27,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -61,9 +61,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -29,9 +29,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -36,9 +36,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -26,19 +26,10 @@ namespace MWClass
{ {
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = const std::string model = getModel(ptr);
ptr.get<ESM::Light>(); if(!model.empty()) {
assert (ref->mBase != NULL); renderingInterface.getObjects().insertModel(ptr, model);
}
const std::string &model = ref->mBase->mModel;
MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
if (!model.empty())
objects.insertMesh(ptr, "meshes\\" + model, true);
else
objects.insertLight(ptr);
} }
void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const

View file

@ -26,9 +26,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -42,9 +42,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -725,15 +725,15 @@ namespace MWClass
float x = fJumpAcrobaticsBase->getFloat() + float x = fJumpAcrobaticsBase->getFloat() +
std::pow(a / 15.0f, fJumpAcroMultiplier->getFloat()); std::pow(a / 15.0f, fJumpAcroMultiplier->getFloat());
x += 3 * b * fJumpAcroMultiplier->getFloat(); x += 3.0f * b * fJumpAcroMultiplier->getFloat();
x += mageffects.get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude * 64; x += mageffects.get(MWMechanics::EffectKey(ESM::MagicEffect::Jump)).mMagnitude * 64;
x *= encumbranceTerm; x *= encumbranceTerm;
if(Npc::getStance(ptr, Run, false)) if(Npc::getStance(ptr, Run, false))
x *= fJumpRunMultiplier->getFloat(); x *= fJumpRunMultiplier->getFloat();
x *= 1.25f;//fatigueTerm; x *= npcdata->mCreatureStats.getFatigueTerm();
x -= -627.2/*gravity constant*/; x -= -627.2f;/*gravity constant*/
x /= 3; x /= 3.0f;
return x; return x;
} }

View file

@ -28,9 +28,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -26,9 +26,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -25,9 +25,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -15,9 +15,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), true);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -33,9 +33,7 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
MWRender::Objects& objects = renderingInterface.getObjects(); renderingInterface.getObjects().insertModel(ptr, model);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertMesh(ptr, model);
} }
} }

View file

@ -1,6 +1,7 @@
#include "console.hpp" #include "console.hpp"
#include <components/compiler/exception.hpp> #include <components/compiler/exception.hpp>
#include <components/compiler/extensions0.hpp>
#include "../mwscript/extensions.hpp" #include "../mwscript/extensions.hpp"
@ -122,7 +123,7 @@ namespace MWGui
mHistory->setVisibleVScroll(true); mHistory->setVisibleVScroll(true);
// compiler // compiler
MWScript::registerExtensions (mExtensions, mConsoleOnlyScripts); Compiler::registerExtensions (mExtensions, mConsoleOnlyScripts);
mCompilerContext.setExtensions (&mExtensions); mCompilerContext.setExtensions (&mExtensions);
} }

View file

@ -26,6 +26,8 @@ namespace MWGui
, mHealth(NULL) , mHealth(NULL)
, mMagicka(NULL) , mMagicka(NULL)
, mStamina(NULL) , mStamina(NULL)
, mDrowning(NULL)
, mDrowningFrame(NULL)
, mWeapImage(NULL) , mWeapImage(NULL)
, mSpellImage(NULL) , mSpellImage(NULL)
, mWeapStatus(NULL) , mWeapStatus(NULL)
@ -70,6 +72,11 @@ namespace MWGui
magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
//Drowning bar
getWidget(mDrowningFrame, "DrowningFrame");
getWidget(mDrowning, "Drowning");
mDrowning->setProgressRange(200);
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
// Item and spell images and status bars // Item and spell images and status bars
@ -198,6 +205,16 @@ namespace MWGui
} }
} }
void HUD::setDrowningTimeLeft(float time)
{
mDrowning->setProgressPosition(time/20.0*200.0);
}
void HUD::setDrowningBarVisible(bool visible)
{
mDrowningFrame->setVisible(visible);
}
void HUD::onWorldClicked(MyGUI::Widget* _sender) void HUD::onWorldClicked(MyGUI::Widget* _sender)
{ {
if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ()) if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ())

View file

@ -18,6 +18,11 @@ namespace MWGui
void setTriangleCount(unsigned int count); void setTriangleCount(unsigned int count);
void setBatchCount(unsigned int count); void setBatchCount(unsigned int count);
/// Set time left for the player to start drowning
/// @param time value from [0,20]
void setDrowningTimeLeft(float time);
void setDrowningBarVisible(bool visible);
void setHmsVisible(bool visible); void setHmsVisible(bool visible);
void setWeapVisible(bool visible); void setWeapVisible(bool visible);
void setSpellVisible(bool visible); void setSpellVisible(bool visible);
@ -50,7 +55,7 @@ namespace MWGui
void setEnemy(const MWWorld::Ptr& enemy); void setEnemy(const MWWorld::Ptr& enemy);
private: private:
MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth; MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning;
MyGUI::Widget* mHealthFrame; MyGUI::Widget* mHealthFrame;
MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox; MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox;
MyGUI::ImageBox *mWeapImage, *mSpellImage; MyGUI::ImageBox *mWeapImage, *mSpellImage;
@ -62,6 +67,7 @@ namespace MWGui
MyGUI::ImageBox* mCrosshair; MyGUI::ImageBox* mCrosshair;
MyGUI::TextBox* mCellNameBox; MyGUI::TextBox* mCellNameBox;
MyGUI::TextBox* mWeaponSpellBox; MyGUI::TextBox* mWeaponSpellBox;
MyGUI::Widget* mDrowningFrame;
MyGUI::Widget* mDummy; MyGUI::Widget* mDummy;

View file

@ -600,6 +600,11 @@ namespace MWGui
mStatsWindow->setValue (id, value); mStatsWindow->setValue (id, value);
} }
void WindowManager::setDrowningTimeLeft (float time)
{
mHud->setDrowningTimeLeft(time);
}
void WindowManager::setPlayerClass (const ESM::Class &class_) void WindowManager::setPlayerClass (const ESM::Class &class_)
{ {
mStatsWindow->setValue("class", class_.mName); mStatsWindow->setValue("class", class_.mName);
@ -788,6 +793,11 @@ namespace MWGui
mHud->setPlayerDir(x,y); mHud->setPlayerDir(x,y);
} }
void WindowManager::setDrowningBarVisibility(bool visible)
{
mHud->setDrowningBarVisible(visible);
}
void WindowManager::setHMSVisibility(bool visible) void WindowManager::setHMSVisibility(bool visible)
{ {
mHud->setHmsVisible (visible); mHud->setHmsVisible (visible);

View file

@ -151,6 +151,10 @@ namespace MWGui
virtual void setValue (const std::string& id, const std::string& value); virtual void setValue (const std::string& id, const std::string& value);
virtual void setValue (const std::string& id, int value); virtual void setValue (const std::string& id, int value);
/// Set time left for the player to start drowning (update the drowning bar)
/// @param time value from [0,20]
virtual void setDrowningTimeLeft (float time);
virtual void setPlayerClass (const ESM::Class &class_); ///< set current class of player virtual void setPlayerClass (const ESM::Class &class_); ///< set current class of player
virtual void configureSkills (const SkillList& major, const SkillList& minor); ///< configure skill groups, each set contains the skill ID for that group. virtual void configureSkills (const SkillList& major, const SkillList& minor); ///< configure skill groups, each set contains the skill ID for that group.
virtual void setReputation (int reputation); ///< set the current reputation value virtual void setReputation (int reputation); ///< set the current reputation value
@ -176,6 +180,9 @@ namespace MWGui
virtual void setInteriorMapTexture(const int x, const int y); virtual void setInteriorMapTexture(const int x, const int y);
///< set the index of the map texture that should be used (for interiors) ///< set the index of the map texture that should be used (for interiors)
/// sets the visibility of the drowning bar
virtual void setDrowningBarVisibility(bool visible);
// sets the visibility of the hud health/magicka/stamina bars // sets the visibility of the hud health/magicka/stamina bars
virtual void setHMSVisibility(bool visible); virtual void setHMSVisibility(bool visible);
// sets the visibility of the hud minimap // sets the visibility of the hud minimap

View file

@ -268,10 +268,6 @@ namespace MWInput
case A_ToggleHUD: case A_ToggleHUD:
mWindows.toggleHud(); mWindows.toggleHud();
break; break;
case A_Use:
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
mPlayer.use();
break;
} }
} }
} }
@ -643,6 +639,10 @@ namespace MWInput
{ {
if (mWindows.isGuiMode()) return; if (mWindows.isGuiMode()) return;
// Not allowed before the magic window is accessible
if (!mWindows.isAllowed(MWGui::GW_Magic))
return;
MWMechanics::DrawState_ state = mPlayer.getDrawState(); MWMechanics::DrawState_ state = mPlayer.getDrawState();
if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing) if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing)
mPlayer.setDrawState(MWMechanics::DrawState_Spell); mPlayer.setDrawState(MWMechanics::DrawState_Spell);
@ -654,6 +654,10 @@ namespace MWInput
{ {
if (mWindows.isGuiMode()) return; if (mWindows.isGuiMode()) return;
// Not allowed before the inventory window is accessible
if (!mWindows.isAllowed(MWGui::GW_Inventory))
return;
MWMechanics::DrawState_ state = mPlayer.getDrawState(); MWMechanics::DrawState_ state = mPlayer.getDrawState();
if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
mPlayer.setDrawState(MWMechanics::DrawState_Weapon); mPlayer.setDrawState(MWMechanics::DrawState_Weapon);

View file

@ -16,6 +16,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "npcstats.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
#include "movement.hpp" #include "movement.hpp"
@ -36,6 +37,12 @@ namespace MWMechanics
} }
} }
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
{
if(!paused)
updateDrowning(ptr, duration);
}
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature) void Actors::adjustMagicEffects (const MWWorld::Ptr& creature)
{ {
CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature); CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature);
@ -153,6 +160,37 @@ namespace MWMechanics
} }
} }
void Actors::updateDrowning(const MWWorld::Ptr& ptr, float duration)
{
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
CreatureStats& creatureStats=MWWorld::Class::get(ptr).getCreatureStats(ptr);
NpcStats& stats=MWWorld::Class::get(ptr).getNpcStats(ptr);
bool waterBreathing=creatureStats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).mMagnitude>0;
if(MWBase::Environment::get().getWorld()->isSubmerged(ptr) && !waterBreathing)
{
if(creatureStats.getFatigue().getCurrent()==0)
stats.setTimeToStartDrowning(0);
float timeLeft=stats.getTimeToStartDrowning()-duration;
if(timeLeft<0)
timeLeft=0;
stats.setTimeToStartDrowning(timeLeft);
if(timeLeft==0)
stats.setLastDrowningHitTime(stats.getLastDrowningHitTime()+duration);
}
else
{
stats.setTimeToStartDrowning(20);
stats.setLastDrowningHitTime(0);
}
//if npc is drowning and it's time to hit, then hit
while(stats.getTimeToStartDrowning()==0.0 && stats.getLastDrowningHitTime()>0.33)
{
stats.setLastDrowningHitTime(stats.getLastDrowningHitTime()-0.33);
//fixme: replace it with something different once screen hit effects are implemented (blood on screen)
MWWorld::Class::get(ptr).setActorHealth(ptr, creatureStats.getHealth().getCurrent()-1.0);
}
}
Actors::Actors() : mDuration (0) {} Actors::Actors() : mDuration (0) {}
void Actors::addActor (const MWWorld::Ptr& ptr) void Actors::addActor (const MWWorld::Ptr& ptr)
@ -225,6 +263,8 @@ namespace MWMechanics
iter->second->resurrect(); iter->second->resurrect();
updateActor(iter->first, totalDuration); updateActor(iter->first, totalDuration);
if(iter->first.getTypeName() == typeid(ESM::NPC).name())
updateNpc(iter->first, totalDuration, paused);
if(!stats.isDead()) if(!stats.isDead())
continue; continue;

View file

@ -34,6 +34,8 @@ namespace MWMechanics
float mDuration; float mDuration;
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);
void adjustMagicEffects (const MWWorld::Ptr& creature); void adjustMagicEffects (const MWWorld::Ptr& creature);
void calculateDynamicStats (const MWWorld::Ptr& ptr); void calculateDynamicStats (const MWWorld::Ptr& ptr);
@ -42,6 +44,7 @@ namespace MWMechanics
void calculateRestoration (const MWWorld::Ptr& ptr, float duration); void calculateRestoration (const MWWorld::Ptr& ptr, float duration);
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
public: public:

View file

@ -24,12 +24,14 @@
#include "movement.hpp" #include "movement.hpp"
#include "npcstats.hpp" #include "npcstats.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
#include "security.hpp"
#include "../mwrender/animation.hpp" #include "../mwrender/animation.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -465,7 +467,36 @@ bool CharacterController::updateNpcState()
sndMgr->playSound3D(mPtr, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f); sndMgr->playSound3D(mPtr, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f);
} }
} }
else if(mWeaponType != WeapType_PickProbe) else if(mWeaponType == WeapType_PickProbe)
{
MWWorld::Ptr item = *weapon;
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject();
std::string resultMessage, resultSound;
if(!target.isEmpty())
{
if(item.getTypeName() == typeid(ESM::Lockpick).name())
Security(mPtr).pickLock(target, item, resultMessage, resultSound);
else if(item.getTypeName() == typeid(ESM::Probe).name())
Security(mPtr).probeTrap(target, item, resultMessage, resultSound);
}
mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true,
1.0f, "start", "stop", 0.0, 0);
mUpperBodyState = UpperCharState_FollowStartToFollowStop;
if(!resultMessage.empty())
MWBase::Environment::get().getWindowManager()->messageBox(resultMessage);
if(!resultSound.empty())
MWBase::Environment::get().getSoundManager()->playSound(resultSound, 1.0f, 1.0f);
// tool used up?
if(!item.getRefData().getCount())
MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon();
else
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(item);
}
else
{ {
if(mWeaponType == WeapType_Crossbow || mWeaponType == WeapType_BowAndArrow || if(mWeaponType == WeapType_Crossbow || mWeaponType == WeapType_BowAndArrow ||
mWeaponType == WeapType_ThowWeapon) mWeaponType == WeapType_ThowWeapon)

View file

@ -110,7 +110,7 @@ namespace MWMechanics
return mMagicEffects; return mMagicEffects;
} }
const bool &CreatureStats::getAttackingOrSpell() const bool CreatureStats::getAttackingOrSpell() const
{ {
return mAttackingOrSpell; return mAttackingOrSpell;
} }
@ -216,7 +216,7 @@ namespace MWMechanics
mMagicEffects = effects; mMagicEffects = effects;
} }
void CreatureStats::setAttackingOrSpell(const bool &attackingOrSpell) void CreatureStats::setAttackingOrSpell(bool attackingOrSpell)
{ {
mAttackingOrSpell = attackingOrSpell; mAttackingOrSpell = attackingOrSpell;
} }

View file

@ -59,7 +59,7 @@ namespace MWMechanics
const MagicEffects & getMagicEffects() const; const MagicEffects & getMagicEffects() const;
const bool & getAttackingOrSpell() const; bool getAttackingOrSpell() const;
int getLevel() const; int getLevel() const;
@ -90,7 +90,7 @@ namespace MWMechanics
void setMagicEffects(const MagicEffects &effects); void setMagicEffects(const MagicEffects &effects);
void setAttackingOrSpell(const bool &attackingOrSpell); void setAttackingOrSpell(bool attackingOrSpell);
enum AttackType enum AttackType
{ {

View file

@ -254,6 +254,20 @@ namespace MWMechanics
MWBase::Environment::get().getWindowManager()->setValue(dynamicNames[2], stats.getFatigue()); MWBase::Environment::get().getWindowManager()->setValue(dynamicNames[2], stats.getFatigue());
} }
if(npcStats.getTimeToStartDrowning() != mWatchedNpc.getTimeToStartDrowning())
{
mWatchedNpc.setTimeToStartDrowning(npcStats.getTimeToStartDrowning());
if(npcStats.getTimeToStartDrowning()>=20.0)
{
MWBase::Environment::get().getWindowManager()->setDrowningBarVisibility(false);
}
else
{
MWBase::Environment::get().getWindowManager()->setDrowningBarVisibility(true);
MWBase::Environment::get().getWindowManager()->setDrowningTimeLeft(npcStats.getTimeToStartDrowning());
}
}
bool update = false; bool update = false;
//Loop over ESM::Skill::SkillEnum //Loop over ESM::Skill::SkillEnum

View file

@ -34,6 +34,8 @@ MWMechanics::NpcStats::NpcStats()
, mWerewolfKills (0) , mWerewolfKills (0)
, mProfit(0) , mProfit(0)
, mAttackStrength(0.0f) , mAttackStrength(0.0f)
, mTimeToStartDrowning(20.0)
, mLastDrowningHit(0)
{ {
mSkillIncreases.resize (ESM::Attribute::Length); mSkillIncreases.resize (ESM::Attribute::Length);
for (int i=0; i<ESM::Attribute::Length; ++i) for (int i=0; i<ESM::Attribute::Length; ++i)
@ -384,3 +386,23 @@ void MWMechanics::NpcStats::modifyProfit(int diff)
{ {
mProfit += diff; mProfit += diff;
} }
float MWMechanics::NpcStats::getTimeToStartDrowning()
{
return mTimeToStartDrowning;
}
void MWMechanics::NpcStats::setTimeToStartDrowning(float time)
{
assert(time>=0 && time<=20);
mTimeToStartDrowning=time;
}
float MWMechanics::NpcStats::getLastDrowningHitTime()
{
return mLastDrowningHit;
}
void MWMechanics::NpcStats::setLastDrowningHitTime(float time)
{
mLastDrowningHit=time;
}

View file

@ -62,6 +62,11 @@ namespace MWMechanics
std::set<std::string> mUsedIds; std::set<std::string> mUsedIds;
/// Countdown to getting damage while underwater
float mTimeToStartDrowning;
/// time since last hit from drowning
float mLastDrowningHit;
public: public:
NpcStats(); NpcStats();
@ -142,6 +147,16 @@ namespace MWMechanics
void setWerewolf (bool set); void setWerewolf (bool set);
int getWerewolfKills() const; int getWerewolfKills() const;
float getTimeToStartDrowning();
/// Sets time left for the creature to drown if it stays underwater.
/// @param time value from [0,20]
void setTimeToStartDrowning(float time);
float getLastDrowningHitTime();
/// Sets time since last hit caused by drowning.
/// @param time value from [0,0.33]
void setLastDrowningHitTime(float time);
}; };
} }

View file

@ -12,16 +12,16 @@ ActivatorAnimation::~ActivatorAnimation()
} }
ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr) ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
: Animation(ptr) : Animation(ptr, ptr.getRefData().getBaseNode())
{ {
MWWorld::LiveCellRef<ESM::Activator> *ref = mPtr.get<ESM::Activator>(); MWWorld::LiveCellRef<ESM::Activator> *ref = mPtr.get<ESM::Activator>();
assert (ref->mBase != NULL); assert(ref->mBase != NULL);
if(!ref->mBase->mModel.empty()) if(!ref->mBase->mModel.empty())
{ {
const std::string name = "meshes\\"+ref->mBase->mModel; const std::string name = "meshes\\"+ref->mBase->mModel;
setObjectRoot(mPtr.getRefData().getBaseNode(), name, false); setObjectRoot(name, false);
setRenderProperties(mObjectRoot, RV_Misc, RQG_Main, RQG_Alpha); setRenderProperties(mObjectRoot, RV_Misc, RQG_Main, RQG_Alpha);
addAnimSource(name); addAnimSource(name);

View file

@ -27,6 +27,8 @@ namespace MWRender
CellSceneNodeMap mCellSceneNodes; CellSceneNodeMap mCellSceneNodes;
PtrAnimationMap mAllActors; PtrAnimationMap mAllActors;
void insertBegin(const MWWorld::Ptr &ptr);
public: public:
Actors(OEngine::Render::OgreRenderer& _rend, MWRender::RenderingManager* rendering) Actors(OEngine::Render::OgreRenderer& _rend, MWRender::RenderingManager* rendering)
: mRend(_rend) : mRend(_rend)
@ -36,7 +38,7 @@ namespace MWRender
~Actors(); ~Actors();
void setRootNode(Ogre::SceneNode* root); void setRootNode(Ogre::SceneNode* root);
void insertBegin (const MWWorld::Ptr& ptr);
void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv); void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
void insertCreature (const MWWorld::Ptr& ptr); void insertCreature (const MWWorld::Ptr& ptr);
void insertActivator (const MWWorld::Ptr& ptr); void insertActivator (const MWWorld::Ptr& ptr);

View file

@ -8,6 +8,10 @@
#include <OgreBone.h> #include <OgreBone.h>
#include <OgreSubMesh.h> #include <OgreSubMesh.h>
#include <OgreSceneManager.h> #include <OgreSceneManager.h>
#include <OgreControllerManager.h>
#include <OgreStaticGeometry.h>
#include <libs/openengine/ogre/lights.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
@ -16,6 +20,9 @@
#include "../mwmechanics/character.hpp" #include "../mwmechanics/character.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
#include "renderconst.hpp"
namespace MWRender namespace MWRender
{ {
@ -35,17 +42,26 @@ void Animation::AnimationValue::setValue(Ogre::Real)
void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects) void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects)
{ {
for(size_t i = 0;i < objects.mLights.size();i++)
{
Ogre::Light *light = objects.mLights[i];
// If parent is a scene node, it was created specifically for this light. Destroy it now.
if(light->isAttached() && !light->isParentTagPoint())
sceneMgr->destroySceneNode(light->getParentSceneNode());
sceneMgr->destroyLight(light);
}
for(size_t i = 0;i < objects.mParticles.size();i++) for(size_t i = 0;i < objects.mParticles.size();i++)
sceneMgr->destroyParticleSystem(objects.mParticles[i]); sceneMgr->destroyParticleSystem(objects.mParticles[i]);
for(size_t i = 0;i < objects.mEntities.size();i++) for(size_t i = 0;i < objects.mEntities.size();i++)
sceneMgr->destroyEntity(objects.mEntities[i]); sceneMgr->destroyEntity(objects.mEntities[i]);
objects.mControllers.clear(); objects.mControllers.clear();
objects.mLights.clear();
objects.mParticles.clear(); objects.mParticles.clear();
objects.mEntities.clear(); objects.mEntities.clear();
objects.mSkelBase = NULL; objects.mSkelBase = NULL;
} }
Animation::Animation(const MWWorld::Ptr &ptr) Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node)
: mPtr(ptr) : mPtr(ptr)
, mCamera(NULL) , mCamera(NULL)
, mInsert(NULL) , mInsert(NULL)
@ -58,6 +74,7 @@ Animation::Animation(const MWWorld::Ptr &ptr)
{ {
for(size_t i = 0;i < sNumGroups;i++) for(size_t i = 0;i < sNumGroups;i++)
mAnimationValuePtr[i].bind(OGRE_NEW AnimationValue(this)); mAnimationValuePtr[i].bind(OGRE_NEW AnimationValue(this));
mInsert = node->createChildSceneNode();
} }
Animation::~Animation() Animation::~Animation()
@ -68,15 +85,21 @@ Animation::~Animation()
Ogre::SceneManager *sceneMgr = mInsert->getCreator(); Ogre::SceneManager *sceneMgr = mInsert->getCreator();
destroyObjectList(sceneMgr, mObjectRoot); destroyObjectList(sceneMgr, mObjectRoot);
sceneMgr->destroySceneNode(mInsert);
} }
} }
void Animation::setObjectRoot(Ogre::SceneNode *node, const std::string &model, bool baseonly) void Animation::setObjectRoot(const std::string &model, bool baseonly)
{ {
OgreAssert(mAnimSources.empty(), "Setting object root while animation sources are set!"); OgreAssert(mAnimSources.empty(), "Setting object root while animation sources are set!");
if(!mInsert)
mInsert = node->createChildSceneNode(); mSkelBase = NULL;
destroyObjectList(mInsert->getCreator(), mObjectRoot);
if(model.empty())
return;
std::string mdlname = Misc::StringUtils::lowerCase(model); std::string mdlname = Misc::StringUtils::lowerCase(model);
std::string::size_type p = mdlname.rfind('\\'); std::string::size_type p = mdlname.rfind('\\');
@ -92,9 +115,6 @@ void Animation::setObjectRoot(Ogre::SceneNode *node, const std::string &model, b
Misc::StringUtils::toLower(mdlname); Misc::StringUtils::toLower(mdlname);
} }
mSkelBase = NULL;
destroyObjectList(mInsert->getCreator(), mObjectRoot);
mObjectRoot = (!baseonly ? NifOgre::Loader::createObjects(mInsert, mdlname) : mObjectRoot = (!baseonly ? NifOgre::Loader::createObjects(mInsert, mdlname) :
NifOgre::Loader::createObjectBase(mInsert, mdlname)); NifOgre::Loader::createObjectBase(mInsert, mdlname));
if(mObjectRoot.mSkelBase) if(mObjectRoot.mSkelBase)
@ -140,28 +160,47 @@ void Animation::setObjectRoot(Ogre::SceneNode *node, const std::string &model, b
} }
} }
void Animation::setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue)
{
for(size_t i = 0;i < objlist.mEntities.size();i++)
{
Ogre::Entity *ent = objlist.mEntities[i];
if(visflags != 0)
ent->setVisibilityFlags(visflags);
for(unsigned int j = 0;j < ent->getNumSubEntities();++j) class VisQueueSet {
Ogre::uint32 mVisFlags;
Ogre::uint8 mSolidQueue, mTransQueue;
Ogre::Real mDist;
public:
VisQueueSet(Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue, Ogre::Real dist)
: mVisFlags(visflags), mSolidQueue(solidqueue), mTransQueue(transqueue), mDist(dist)
{ }
void operator()(Ogre::Entity *entity) const
{
if(mVisFlags != 0)
entity->setVisibilityFlags(mVisFlags);
entity->setRenderingDistance(mDist);
unsigned int numsubs = entity->getNumSubEntities();
for(unsigned int i = 0;i < numsubs;++i)
{ {
Ogre::SubEntity* subEnt = ent->getSubEntity(j); Ogre::SubEntity* subEnt = entity->getSubEntity(i);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? transqueue : solidqueue); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? mTransQueue : mSolidQueue);
} }
} }
for(size_t i = 0;i < objlist.mParticles.size();i++)
void operator()(Ogre::ParticleSystem *psys) const
{ {
Ogre::ParticleSystem *part = objlist.mParticles[i]; if(mVisFlags != 0)
if(visflags != 0) psys->setVisibilityFlags(mVisFlags);
part->setVisibilityFlags(visflags); psys->setRenderingDistance(mDist);
// TODO: Check particle material for actual transparency // TODO: Check particle material for actual transparency
part->setRenderQueueGroup(transqueue); psys->setRenderQueueGroup(mTransQueue);
} }
};
void Animation::setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue, Ogre::Real dist)
{
std::for_each(objlist.mEntities.begin(), objlist.mEntities.end(),
VisQueueSet(visflags, solidqueue, transqueue, dist));
std::for_each(objlist.mParticles.begin(), objlist.mParticles.end(),
VisQueueSet(visflags, solidqueue, transqueue, dist));
} }
@ -254,6 +293,76 @@ void Animation::clearAnimSources()
} }
void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objlist, const ESM::Light *light)
{
const MWWorld::Fallback *fallback = MWBase::Environment::get().getWorld()->getFallback();
const int clr = light->mData.mColor;
Ogre::ColourValue color(((clr >> 0) & 0xFF) / 255.0f,
((clr >> 8) & 0xFF) / 255.0f,
((clr >> 16) & 0xFF) / 255.0f);
const float radius = float(light->mData.mRadius);
if((light->mData.mFlags&ESM::Light::Negative))
color *= -1;
objlist.mLights.push_back(sceneMgr->createLight());
Ogre::Light *olight = objlist.mLights.back();
olight->setDiffuseColour(color);
Ogre::ControllerValueRealPtr src(Ogre::ControllerManager::getSingleton().getFrameTimeSource());
Ogre::ControllerValueRealPtr dest(OGRE_NEW OEngine::Render::LightValue(olight, color));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW OEngine::Render::LightFunction(
(light->mData.mFlags&ESM::Light::Flicker) ? OEngine::Render::LT_Flicker :
(light->mData.mFlags&ESM::Light::FlickerSlow) ? OEngine::Render::LT_FlickerSlow :
(light->mData.mFlags&ESM::Light::Pulse) ? OEngine::Render::LT_Pulse :
(light->mData.mFlags&ESM::Light::PulseSlow) ? OEngine::Render::LT_PulseSlow :
OEngine::Render::LT_Normal
));
objlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(src, dest, func));
bool interior = !(mPtr.isInCell() && mPtr.getCell()->mCell->isExterior());
bool quadratic = fallback->getFallbackBool("LightAttenuation_OutQuadInLin") ?
!interior : fallback->getFallbackBool("LightAttenuation_UseQuadratic");
// with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
// so we ignore lights if their attenuation falls below this factor.
const float threshold = 0.03;
if (!quadratic)
{
float r = radius * fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
float attenuation = fallback->getFallbackFloat("LightAttenuation_LinearValue") / r;
float activationRange = 1.0f / (threshold * attenuation);
olight->setAttenuation(activationRange, 0, attenuation, 0);
}
else
{
float r = radius * fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
float attenuation = fallback->getFallbackFloat("LightAttenuation_QuadraticValue") / std::pow(r, 2);
float activationRange = std::sqrt(1.0f / (threshold * attenuation));
olight->setAttenuation(activationRange, 0, 0, attenuation);
}
// If there's an AttachLight bone, attach the light to that, otherwise put it in the center,
if(objlist.mSkelBase && objlist.mSkelBase->getSkeleton()->hasBone("AttachLight"))
objlist.mSkelBase->attachObjectToBone("AttachLight", olight);
else
{
Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
for(size_t i = 0;i < objlist.mEntities.size();i++)
{
Ogre::Entity *ent = objlist.mEntities[i];
bounds.merge(ent->getBoundingBox());
}
Ogre::SceneNode *node = bounds.isFinite() ? mInsert->createChildSceneNode(bounds.getCenter())
: mInsert->createChildSceneNode();
node->attachObject(olight);
}
}
Ogre::Node *Animation::getNode(const std::string &name) Ogre::Node *Animation::getNode(const std::string &name)
{ {
if(mSkelBase) if(mSkelBase)
@ -805,6 +914,43 @@ void Animation::showWeapons(bool showWeapon)
{ {
} }
class ToggleLight {
bool mEnable;
public:
ToggleLight(bool enable) : mEnable(enable) { }
void operator()(Ogre::Light *light) const
{ light->setVisible(mEnable); }
};
void Animation::enableLights(bool enable)
{
std::for_each(mObjectRoot.mLights.begin(), mObjectRoot.mLights.end(), ToggleLight(enable));
}
class MergeBounds {
Ogre::AxisAlignedBox *mBounds;
public:
MergeBounds(Ogre::AxisAlignedBox *bounds) : mBounds(bounds) { }
void operator()(Ogre::MovableObject *obj)
{
mBounds->merge(obj->getWorldBoundingBox(true));
}
};
Ogre::AxisAlignedBox Animation::getWorldBounds()
{
Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
std::for_each(mObjectRoot.mEntities.begin(), mObjectRoot.mEntities.end(), MergeBounds(&bounds));
return bounds;
}
bool Animation::isPriorityActive(int priority) const bool Animation::isPriorityActive(int priority) const
{ {
for (AnimStateMap::const_iterator it = mStates.begin(); it != mStates.end(); ++it) for (AnimStateMap::const_iterator it = mStates.begin(); it != mStates.end(); ++it)
@ -833,4 +979,66 @@ void Animation::detachObjectFromBone(Ogre::MovableObject *obj)
mSkelBase->detachObjectFromBone(obj); mSkelBase->detachObjectFromBone(obj);
} }
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model)
: Animation(ptr, ptr.getRefData().getBaseNode())
{
setObjectRoot(model, false);
Ogre::AxisAlignedBox bounds = getWorldBounds();
Ogre::Vector3 extents = bounds.getSize();
extents *= mInsert->getParentSceneNode()->getScale();
float size = std::max(std::max(extents.x, extents.y), extents.z);
bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) &&
Settings::Manager::getBool("limit small object distance", "Viewing distance");
// do not fade out doors. that will cause holes and look stupid
if(ptr.getTypeName().find("Door") != std::string::npos)
small = false;
float dist = small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0.0f;
setRenderProperties(mObjectRoot, (mPtr.getTypeName() == typeid(ESM::Static).name()) ?
(small ? RV_StaticsSmall : RV_Statics) : RV_Misc,
RQG_Main, RQG_Alpha, dist);
}
void ObjectAnimation::addLight(const ESM::Light *light)
{
addExtraLight(mInsert->getCreator(), mObjectRoot, light);
}
class FindEntityTransparency {
public:
bool operator()(Ogre::Entity *ent) const
{
unsigned int numsubs = ent->getNumSubEntities();
for(unsigned int i = 0;i < numsubs;++i)
{
if(ent->getSubEntity(i)->getMaterial()->isTransparent())
return true;
}
return false;
}
};
bool ObjectAnimation::canBatch() const
{
if(!mObjectRoot.mParticles.empty() || !mObjectRoot.mLights.empty() || !mObjectRoot.mControllers.empty())
return false;
return std::find_if(mObjectRoot.mEntities.begin(), mObjectRoot.mEntities.end(),
FindEntityTransparency()) == mObjectRoot.mEntities.end();
}
void ObjectAnimation::fillBatch(Ogre::StaticGeometry *sg)
{
std::vector<Ogre::Entity*>::reverse_iterator iter = mObjectRoot.mEntities.rbegin();
for(;iter != mObjectRoot.mEntities.rend();++iter)
{
Ogre::Node *node = (*iter)->getParentNode();
sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale());
}
}
} }

View file

@ -52,6 +52,7 @@ protected:
virtual void setValue(Ogre::Real value); virtual void setValue(Ogre::Real value);
}; };
class NullAnimationValue : public Ogre::ControllerValue<Ogre::Real> class NullAnimationValue : public Ogre::ControllerValue<Ogre::Real>
{ {
public: public:
@ -61,6 +62,7 @@ protected:
{ } { }
}; };
struct AnimSource : public Ogre::AnimationAlloc { struct AnimSource : public Ogre::AnimationAlloc {
NifOgre::TextKeyMap mTextKeys; NifOgre::TextKeyMap mTextKeys;
std::vector<Ogre::Controller<Ogre::Real> > mControllers[sNumGroups]; std::vector<Ogre::Controller<Ogre::Real> > mControllers[sNumGroups];
@ -151,21 +153,24 @@ protected:
* Note that you must make sure all animation sources are cleared before reseting the object * Note that you must make sure all animation sources are cleared before reseting the object
* root. All nodes previously retrieved with getNode will also become invalidated. * root. All nodes previously retrieved with getNode will also become invalidated.
*/ */
void setObjectRoot(Ogre::SceneNode *node, const std::string &model, bool baseonly); void setObjectRoot(const std::string &model, bool baseonly);
/* Adds the keyframe controllers in the specified model as a new animation source. Note that /* Adds the keyframe controllers in the specified model as a new animation source. Note that
* the filename portion of the provided model name will be prepended with 'x', and the .nif * the filename portion of the provided model name will be prepended with 'x', and the .nif
* extension will be replaced with .kf. */ * extension will be replaced with .kf. */
void addAnimSource(const std::string &model); void addAnimSource(const std::string &model);
/** Adds an additional light to the given object list using the specified ESM record. */
void addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objlist, const ESM::Light *light);
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects); static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
static void setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue); static void setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue, Ogre::Real dist=0.0f);
void clearAnimSources(); void clearAnimSources();
public: public:
Animation(const MWWorld::Ptr &ptr); Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node);
virtual ~Animation(); virtual ~Animation();
void updatePtr(const MWWorld::Ptr &ptr); void updatePtr(const MWWorld::Ptr &ptr);
@ -224,6 +229,10 @@ public:
virtual void showWeapons(bool showWeapon); virtual void showWeapons(bool showWeapon);
void enableLights(bool enable);
Ogre::AxisAlignedBox getWorldBounds();
void setCamera(Camera *cam) void setCamera(Camera *cam)
{ mCamera = cam; } { mCamera = cam; }
@ -236,5 +245,15 @@ public:
void detachObjectFromBone(Ogre::MovableObject *obj); void detachObjectFromBone(Ogre::MovableObject *obj);
}; };
class ObjectAnimation : public Animation {
public:
ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model);
void addLight(const ESM::Light *light);
bool canBatch() const;
void fillBatch(Ogre::StaticGeometry *sg);
};
} }
#endif #endif

View file

@ -12,7 +12,7 @@ CreatureAnimation::~CreatureAnimation()
} }
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr) CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
: Animation(ptr) : Animation(ptr, ptr.getRefData().getBaseNode())
{ {
MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>(); MWWorld::LiveCellRef<ESM::Creature> *ref = mPtr.get<ESM::Creature>();
@ -21,7 +21,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
{ {
std::string model = "meshes\\"+ref->mBase->mModel; std::string model = "meshes\\"+ref->mBase->mModel;
setObjectRoot(mPtr.getRefData().getBaseNode(), model, false); setObjectRoot(model, false);
setRenderProperties(mObjectRoot, RV_Actors, RQG_Main, RQG_Alpha); setRenderProperties(mObjectRoot, RV_Actors, RQG_Main, RQG_Alpha);
if((ref->mBase->mFlags&ESM::Creature::Biped)) if((ref->mBase->mFlags&ESM::Creature::Biped))

View file

@ -20,46 +20,50 @@
namespace MWRender namespace MWRender
{ {
const NpcAnimation::PartInfo NpcAnimation::sPartList[NpcAnimation::sPartListSize] = { static NpcAnimation::PartBoneMap createPartListMap()
{ ESM::PRT_Head, "Head" }, {
{ ESM::PRT_Hair, "Head" }, NpcAnimation::PartBoneMap result;
{ ESM::PRT_Neck, "Neck" }, result.insert(std::make_pair(ESM::PRT_Head, "Head"));
{ ESM::PRT_Cuirass, "Chest" }, result.insert(std::make_pair(ESM::PRT_Hair, "Head"));
{ ESM::PRT_Groin, "Groin" }, result.insert(std::make_pair(ESM::PRT_Neck, "Neck"));
{ ESM::PRT_Skirt, "Groin" }, result.insert(std::make_pair(ESM::PRT_Cuirass, "Chest"));
{ ESM::PRT_RHand, "Right Hand" }, result.insert(std::make_pair(ESM::PRT_Groin, "Groin"));
{ ESM::PRT_LHand, "Left Hand" }, result.insert(std::make_pair(ESM::PRT_Skirt, "Groin"));
{ ESM::PRT_RWrist, "Right Wrist" }, result.insert(std::make_pair(ESM::PRT_RHand, "Right Hand"));
{ ESM::PRT_LWrist, "Left Wrist" }, result.insert(std::make_pair(ESM::PRT_LHand, "Left Hand"));
{ ESM::PRT_Shield, "Shield Bone" }, result.insert(std::make_pair(ESM::PRT_RWrist, "Right Wrist"));
{ ESM::PRT_RForearm, "Right Forearm" }, result.insert(std::make_pair(ESM::PRT_LWrist, "Left Wrist"));
{ ESM::PRT_LForearm, "Left Forearm" }, result.insert(std::make_pair(ESM::PRT_Shield, "Shield Bone"));
{ ESM::PRT_RUpperarm, "Right Upper Arm" }, result.insert(std::make_pair(ESM::PRT_RForearm, "Right Forearm"));
{ ESM::PRT_LUpperarm, "Left Upper Arm" }, result.insert(std::make_pair(ESM::PRT_LForearm, "Left Forearm"));
{ ESM::PRT_RFoot, "Right Foot" }, result.insert(std::make_pair(ESM::PRT_RUpperarm, "Right Upper Arm"));
{ ESM::PRT_LFoot, "Left Foot" }, result.insert(std::make_pair(ESM::PRT_LUpperarm, "Left Upper Arm"));
{ ESM::PRT_RAnkle, "Right Ankle" }, result.insert(std::make_pair(ESM::PRT_RFoot, "Right Foot"));
{ ESM::PRT_LAnkle, "Left Ankle" }, result.insert(std::make_pair(ESM::PRT_LFoot, "Left Foot"));
{ ESM::PRT_RKnee, "Right Knee" }, result.insert(std::make_pair(ESM::PRT_RAnkle, "Right Ankle"));
{ ESM::PRT_LKnee, "Left Knee" }, result.insert(std::make_pair(ESM::PRT_LAnkle, "Left Ankle"));
{ ESM::PRT_RLeg, "Right Upper Leg" }, result.insert(std::make_pair(ESM::PRT_RKnee, "Right Knee"));
{ ESM::PRT_LLeg, "Left Upper Leg" }, result.insert(std::make_pair(ESM::PRT_LKnee, "Left Knee"));
{ ESM::PRT_RPauldron, "Right Clavicle" }, result.insert(std::make_pair(ESM::PRT_RLeg, "Right Upper Leg"));
{ ESM::PRT_LPauldron, "Left Clavicle" }, result.insert(std::make_pair(ESM::PRT_LLeg, "Left Upper Leg"));
{ ESM::PRT_Weapon, "Weapon Bone" }, result.insert(std::make_pair(ESM::PRT_RPauldron, "Right Clavicle"));
{ ESM::PRT_Tail, "Tail" } result.insert(std::make_pair(ESM::PRT_LPauldron, "Left Clavicle"));
}; result.insert(std::make_pair(ESM::PRT_Weapon, "Weapon Bone"));
result.insert(std::make_pair(ESM::PRT_Tail, "Tail"));
return result;
}
const NpcAnimation::PartBoneMap NpcAnimation::sPartList = createPartListMap();
NpcAnimation::~NpcAnimation() NpcAnimation::~NpcAnimation()
{ {
Ogre::SceneManager *sceneMgr = mInsert->getCreator(); Ogre::SceneManager *sceneMgr = mInsert->getCreator();
for(size_t i = 0;i < sPartListSize;i++) for(size_t i = 0;i < ESM::PRT_Count;i++)
destroyObjectList(sceneMgr, mObjectParts[i]); destroyObjectList(sceneMgr, mObjectParts[i]);
} }
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags, ViewMode viewMode) NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWorld::InventoryStore& inv, int visibilityFlags, ViewMode viewMode)
: Animation(ptr), : Animation(ptr, node),
mStateID(-1), mStateID(-1),
mTimeToChange(0), mTimeToChange(0),
mVisibilityFlags(visibilityFlags), mVisibilityFlags(visibilityFlags),
@ -82,7 +86,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
{ {
mNpc = mPtr.get<ESM::NPC>()->mBase; mNpc = mPtr.get<ESM::NPC>()->mBase;
for(size_t i = 0;i < sPartListSize;i++) for(size_t i = 0;i < ESM::PRT_Count;i++)
{ {
mPartslots[i] = -1; //each slot is empty mPartslots[i] = -1; //each slot is empty
mPartPriorities[i] = 0; mPartPriorities[i] = 0;
@ -102,7 +106,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
std::string smodel = (viewMode != VM_FirstPerson) ? std::string smodel = (viewMode != VM_FirstPerson) ?
(!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif") : (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif") :
(!isBeast ? "meshes\\base_anim.1st.nif" : "meshes\\base_animkna.1st.nif") ; (!isBeast ? "meshes\\base_anim.1st.nif" : "meshes\\base_animkna.1st.nif") ;
setObjectRoot(node, smodel, true); setObjectRoot(smodel, true);
if(mViewMode != VM_FirstPerson) if(mViewMode != VM_FirstPerson)
{ {
@ -143,7 +147,7 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
std::string smodel = (viewMode != VM_FirstPerson) ? std::string smodel = (viewMode != VM_FirstPerson) ?
(!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif") : (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif") :
(!isBeast ? "meshes\\base_anim.1st.nif" : "meshes\\base_animkna.1st.nif") ; (!isBeast ? "meshes\\base_anim.1st.nif" : "meshes\\base_animkna.1st.nif") ;
setObjectRoot(mInsert->getParentSceneNode(), smodel, true); setObjectRoot(smodel, true);
if(mViewMode != VM_FirstPerson) if(mViewMode != VM_FirstPerson)
{ {
@ -168,8 +172,8 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
} }
MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr); MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr);
for(size_t i = 0;i < sPartListSize;i++) for(size_t i = 0;i < ESM::PRT_Count;i++)
removeIndividualPart(i); removeIndividualPart((ESM::PartReferenceType)i);
forceUpdate(); forceUpdate();
} }
@ -267,6 +271,19 @@ void NpcAnimation::updateParts(bool forceupdate)
if(mViewMode == VM_HeadOnly) if(mViewMode == VM_HeadOnly)
return; return;
if(mPartPriorities[ESM::PRT_Shield] < 1)
{
MWWorld::ContainerStoreIterator store = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
MWWorld::Ptr part;
if(store != inv.end() && (part=*store).getTypeName() == typeid(ESM::Light).name())
{
const ESM::Light *light = part.get<ESM::Light>()->mBase;
addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft,
1, "meshes\\"+light->mModel);
addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], light);
}
}
showWeapons(mShowWeapons); showWeapons(mShowWeapons);
const int Flag_Female = 0x01; const int Flag_Female = 0x01;
@ -366,23 +383,31 @@ void NpcAnimation::updateParts(bool forceupdate)
{ {
const ESM::BodyPart* bodypart = parts[part]; const ESM::BodyPart* bodypart = parts[part];
if(bodypart) if(bodypart)
addOrReplaceIndividualPart(part, -1,1, "meshes\\"+bodypart->mModel); addOrReplaceIndividualPart((ESM::PartReferenceType)part, -1, 1,
"meshes\\"+bodypart->mModel);
} }
} }
} }
class SetObjectGroup {
int mGroup;
public:
SetObjectGroup(int group) : mGroup(group) { }
void operator()(Ogre::MovableObject *obj) const
{
obj->getUserObjectBindings().setUserAny(Ogre::Any(mGroup));
}
};
NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename) NifOgre::ObjectList NpcAnimation::insertBoundedPart(const std::string &model, int group, const std::string &bonename)
{ {
NifOgre::ObjectList objects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model); NifOgre::ObjectList objects = NifOgre::Loader::createObjects(mSkelBase, bonename, mInsert, model);
setRenderProperties(objects, (mViewMode == VM_FirstPerson) ? RV_FirstPerson : mVisibilityFlags, RQG_Main, RQG_Alpha); setRenderProperties(objects, (mViewMode == VM_FirstPerson) ? RV_FirstPerson : mVisibilityFlags, RQG_Main, RQG_Alpha);
for(size_t i = 0;i < objects.mEntities.size();i++) std::for_each(objects.mEntities.begin(), objects.mEntities.end(), SetObjectGroup(group));
{ std::for_each(objects.mParticles.begin(), objects.mParticles.end(), SetObjectGroup(group));
Ogre::Entity *ent = objects.mEntities[i];
ent->getUserObjectBindings().setUserAny(Ogre::Any(group));
}
for(size_t i = 0;i < objects.mParticles.size();i++)
objects.mParticles[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
if(objects.mSkelBase) if(objects.mSkelBase)
{ {
@ -422,7 +447,7 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD); node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD);
} }
for(size_t i = 0;i < sPartListSize;i++) for(size_t i = 0;i < ESM::PRT_Count;i++)
{ {
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[i].mControllers.begin()); std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[i].mControllers.begin());
for(;ctrl != mObjectParts[i].mControllers.end();ctrl++) for(;ctrl != mObjectParts[i].mControllers.end();ctrl++)
@ -437,22 +462,15 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
return ret; return ret;
} }
void NpcAnimation::removeIndividualPart(int type) void NpcAnimation::removeIndividualPart(ESM::PartReferenceType type)
{ {
mPartPriorities[type] = 0; mPartPriorities[type] = 0;
mPartslots[type] = -1; mPartslots[type] = -1;
for(size_t i = 0;i < sPartListSize;i++) destroyObjectList(mInsert->getCreator(), mObjectParts[type]);
{
if(type == sPartList[i].type)
{
destroyObjectList(mInsert->getCreator(), mObjectParts[i]);
break;
}
}
} }
void NpcAnimation::reserveIndividualPart(int type, int group, int priority) void NpcAnimation::reserveIndividualPart(ESM::PartReferenceType type, int group, int priority)
{ {
if(priority > mPartPriorities[type]) if(priority > mPartPriorities[type])
{ {
@ -464,14 +482,14 @@ void NpcAnimation::reserveIndividualPart(int type, int group, int priority)
void NpcAnimation::removePartGroup(int group) void NpcAnimation::removePartGroup(int group)
{ {
for(int i = 0; i < 27; i++) for(int i = 0; i < ESM::PRT_Count; i++)
{ {
if(mPartslots[i] == group) if(mPartslots[i] == group)
removeIndividualPart(i); removeIndividualPart((ESM::PartReferenceType)i);
} }
} }
bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh) bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh)
{ {
if(priority <= mPartPriorities[type]) if(priority <= mPartPriorities[type])
return false; return false;
@ -480,28 +498,36 @@ bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority,
mPartslots[type] = group; mPartslots[type] = group;
mPartPriorities[type] = priority; mPartPriorities[type] = priority;
for(size_t i = 0;i < sPartListSize;i++) mObjectParts[type] = insertBoundedPart(mesh, group, sPartList.at(type));
if(mObjectParts[type].mSkelBase && mObjectParts[type].mSkelBase->isParentTagPoint())
{ {
if(type == sPartList[i].type) Ogre::Node *root = mObjectParts[type].mSkelBase->getParentNode();
Ogre::SkeletonInstance *skel = mObjectParts[type].mSkelBase->getSkeleton();
if(skel->hasBone("BoneOffset"))
{ {
mObjectParts[i] = insertBoundedPart(mesh, group, sPartList[i].name); Ogre::Bone *offset = skel->getBone("BoneOffset");
root->translate(offset->getPosition());
// TODO: root->rotate(offset->getOrientation());
// type == ESM::PRT_Head should get an animation source based on the current output of // HACK: Why an extra -90 degree rotation?
// the actor's 'say' sound (0 = silent, 1 = loud?). root->pitch(Ogre::Degree(-90.0f));
// type == ESM::PRT_Weapon should get an animation source based on the current offset root->scale(offset->getScale());
// of the weapon attack animation (from its beginning, or start marker?) root->setInitialState();
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[i].mControllers.begin());
for(;ctrl != mObjectParts[i].mControllers.end();ctrl++)
{
if(ctrl->getSource().isNull())
ctrl->setSource(mNullAnimationValuePtr);
}
break;
} }
} }
return true;
// TODO:
// type == ESM::PRT_Head should get an animation source based on the current output of
// the actor's 'say' sound (0 = silent, 1 = loud?).
// type == ESM::PRT_Weapon should get an animation source based on the current offset
// of the weapon attack animation (from its beginning, or start marker?)
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[type].mControllers.begin());
for(;ctrl != mObjectParts[type].mControllers.end();ctrl++)
{
if(ctrl->getSource().isNull())
ctrl->setSource(mNullAnimationValuePtr);
}
return true;
} }
void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts) void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts)
@ -542,9 +568,9 @@ void NpcAnimation::addPartGroup(int group, int priority, const std::vector<ESM::
} }
if(bodypart) if(bodypart)
addOrReplaceIndividualPart(part->mPart, group, priority, "meshes\\"+bodypart->mModel); addOrReplaceIndividualPart((ESM::PartReferenceType)part->mPart, group, priority, "meshes\\"+bodypart->mModel);
else else
reserveIndividualPart(part->mPart, group, priority); reserveIndividualPart((ESM::PartReferenceType)part->mPart, group, priority);
} }
} }
@ -557,7 +583,8 @@ void NpcAnimation::showWeapons(bool showWeapon)
mWeapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); mWeapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if(mWeapon != inv.end()) // special case for weapons if(mWeapon != inv.end()) // special case for weapons
{ {
std::string mesh = MWWorld::Class::get(*mWeapon).getModel(*mWeapon); MWWorld::Ptr weapon = *mWeapon;
std::string mesh = MWWorld::Class::get(weapon).getModel(weapon);
addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, mesh); addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, mesh);
} }
} }

View file

@ -21,25 +21,21 @@ namespace MWRender
class NpcAnimation : public Animation class NpcAnimation : public Animation
{ {
public: public:
struct PartInfo { typedef std::map<ESM::PartReferenceType,std::string> PartBoneMap;
ESM::PartReferenceType type;
const char name[32];
};
enum ViewMode { enum ViewMode {
VM_Normal, VM_Normal,
VM_FirstPerson, VM_FirstPerson,
VM_HeadOnly VM_HeadOnly
}; };
private: private:
static const size_t sPartListSize = 27; static const PartBoneMap sPartList;
static const PartInfo sPartList[sPartListSize];
int mStateID; int mStateID;
// Bounded Parts // Bounded Parts
NifOgre::ObjectList mObjectParts[sPartListSize]; NifOgre::ObjectList mObjectParts[ESM::PRT_Count];
const ESM::NPC *mNpc; const ESM::NPC *mNpc;
std::string mHeadModel; std::string mHeadModel;
@ -66,17 +62,17 @@ private:
int mVisibilityFlags; int mVisibilityFlags;
int mPartslots[sPartListSize]; //Each part slot is taken by clothing, armor, or is empty int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty
int mPartPriorities[sPartListSize]; int mPartPriorities[ESM::PRT_Count];
NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename); NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename);
void updateParts(bool forceupdate = false); void updateParts(bool forceupdate = false);
void removeIndividualPart(int type); void removeIndividualPart(ESM::PartReferenceType type);
void reserveIndividualPart(int type, int group, int priority); void reserveIndividualPart(ESM::PartReferenceType type, int group, int priority);
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); bool addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh);
void removePartGroup(int group); void removePartGroup(int group);
void addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts); void addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts);

View file

@ -18,70 +18,18 @@
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "renderconst.hpp" #include "renderconst.hpp"
#include "animation.hpp"
using namespace MWRender; using namespace MWRender;
float Objects::lightLinearValue()
{
return mFallback->getFallbackFloat("LightAttenuation_LinearValue");
}
float Objects::lightLinearRadiusMult()
{
return mFallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
}
float Objects::lightQuadraticValue()
{
return mFallback->getFallbackFloat("LightAttenuation_QuadraticValue");
}
float Objects::lightQuadraticRadiusMult()
{
return mFallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
}
bool Objects::lightOutQuadInLin()
{
return mFallback->getFallbackBool("LightAttenuation_OutQuadInLin");
}
bool Objects::lightQuadratic()
{
return mFallback->getFallbackBool("LightAttenuation_UseQuadratic");
}
int Objects::uniqueID = 0; int Objects::uniqueID = 0;
void Objects::clearSceneNode (Ogre::SceneNode *node)
{
for (int i=node->numAttachedObjects()-1; i>=0; --i)
{
Ogre::MovableObject *object = node->getAttachedObject (i);
// for entities, destroy any objects attached to bones
if (object->getTypeFlags () == Ogre::SceneManager::ENTITY_TYPE_MASK)
{
Ogre::Entity* ent = static_cast<Ogre::Entity*>(object);
Ogre::Entity::ChildObjectListIterator children = ent->getAttachedObjectIterator ();
while (children.hasMoreElements())
{
mRenderer.getScene ()->destroyMovableObject (children.getNext ());
}
}
node->detachObject (object);
mRenderer.getScene()->destroyMovableObject (object);
}
Ogre::Node::ChildNodeIterator it = node->getChildIterator ();
while (it.hasMoreElements ())
{
clearSceneNode(static_cast<Ogre::SceneNode*>(it.getNext ()));
}
}
void Objects::setRootNode(Ogre::SceneNode* root) void Objects::setRootNode(Ogre::SceneNode* root)
{ {
mRootNode = root; mRootNode = root;
} }
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_) void Objects::insertBegin(const MWWorld::Ptr& ptr)
{ {
Ogre::SceneNode* root = mRootNode; Ogre::SceneNode* root = mRootNode;
Ogre::SceneNode* cellnode; Ogre::SceneNode* cellnode;
@ -118,79 +66,45 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
// Rotates first around z, then y, then x // Rotates first around z, then y, then x
insert->setOrientation(xr*yr*zr); insert->setOrientation(xr*yr*zr);
if (!enabled)
insert->setVisible (false);
ptr.getRefData().setBaseNode(insert); ptr.getRefData().setBaseNode(insert);
mIsStatic = static_;
} }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light) void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh)
{ {
Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); insertBegin(ptr);
assert(insert);
Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; std::auto_ptr<ObjectAnimation> anim(new ObjectAnimation(ptr, mesh));
NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh);
for(size_t i = 0;i < objects.mEntities.size();i++)
bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true));
Ogre::AxisAlignedBox bounds = anim->getWorldBounds();
Ogre::Vector3 extents = bounds.getSize(); Ogre::Vector3 extents = bounds.getSize();
extents *= insert->getScale(); extents *= ptr.getRefData().getBaseNode()->getScale();
float size = std::max(std::max(extents.x, extents.y), extents.z); float size = std::max(std::max(extents.x, extents.y), extents.z);
bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) &&
Settings::Manager::getBool("limit small object distance", "Viewing distance");
// do not fade out doors. that will cause holes and look stupid // do not fade out doors. that will cause holes and look stupid
if (ptr.getTypeName().find("Door") != std::string::npos) if(ptr.getTypeName().find("Door") != std::string::npos)
small = false; small = false;
if (mBounds.find(ptr.getCell()) == mBounds.end()) if (mBounds.find(ptr.getCell()) == mBounds.end())
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
mBounds[ptr.getCell()].merge(bounds); mBounds[ptr.getCell()].merge(bounds);
bool anyTransparency = false; if(ptr.getTypeName() == typeid(ESM::Light).name())
for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++) anim->addLight(ptr.get<ESM::Light>()->mBase);
{
Ogre::Entity *ent = objects.mEntities[i];
for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i)
{
anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent();
}
}
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || if(ptr.getTypeName() == typeid(ESM::Static).name() &&
anyTransparency || !objects.mParticles.empty()) Settings::Manager::getBool("use static geometry", "Objects") &&
{ anim->canBatch())
for(size_t i = 0;i < objects.mEntities.size();i++)
{
Ogre::Entity *ent = objects.mEntities[i];
for(unsigned int i=0; i < ent->getNumSubEntities(); ++i)
{
Ogre::SubEntity* subEnt = ent->getSubEntity(i);
subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main);
}
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
}
for(size_t i = 0;i < objects.mParticles.size();i++)
{
Ogre::ParticleSystem *part = objects.mParticles[i];
// TODO: Check the particle system's material for actual transparency
part->setRenderQueueGroup(RQG_Alpha);
part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
}
}
else
{ {
Ogre::StaticGeometry* sg = 0; Ogre::StaticGeometry* sg = 0;
if (small) if (small)
{ {
if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) if(mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end())
{ {
uniqueID = uniqueID +1; uniqueID = uniqueID+1;
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); sg = mRenderer.getScene()->createStaticGeometry("sg" + Ogre::StringConverter::toString(uniqueID));
mStaticGeometrySmall[ptr.getCell()] = sg; mStaticGeometrySmall[ptr.getCell()] = sg;
sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance"));
@ -200,11 +114,10 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
} }
else else
{ {
if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) if(mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end())
{ {
uniqueID = uniqueID+1;
uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry("sg" + Ogre::StringConverter::toString(uniqueID));
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
mStaticGeometry[ptr.getCell()] = sg; mStaticGeometry[ptr.getCell()] = sg;
} }
else else
@ -225,155 +138,75 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
sg->setRenderQueueGroup(RQG_Main); sg->setRenderQueueGroup(RQG_Main);
std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin(); anim->fillBatch(sg);
while(iter != objects.mEntities.rend()) /* TODO: We could hold on to this and just detach it from the scene graph, so if the Ptr
{ * ever needs to modify we can reattach it and rebuild the StaticGeometry object without
Ogre::Node *node = (*iter)->getParentNode(); * it. Would require associating the Ptr with the StaticGeometry. */
sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); anim.reset();
(*iter)->detachFromParent();
mRenderer.getScene()->destroyEntity(*iter);
++iter;
}
} }
if (light) if(anim.get() != NULL)
{ mObjects.insert(std::make_pair(ptr, anim.release()));
insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition());
}
}
void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre::Vector3 fallbackCenter)
{
Ogre::SceneNode* insert = mRenderer.getScene()->getSceneNode(ptr.getRefData().getHandle());
assert(insert);
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
const int color = ref->mBase->mData.mColor;
const float r = ((color >> 0) & 0xFF) / 255.0f;
const float g = ((color >> 8) & 0xFF) / 255.0f;
const float b = ((color >> 16) & 0xFF) / 255.0f;
const float radius = float (ref->mBase->mData.mRadius);
Ogre::Light *light = mRenderer.getScene()->createLight();
light->setDiffuseColour (r, g, b);
LightInfo info;
info.name = light->getName();
info.radius = radius;
info.colour = Ogre::ColourValue(r, g, b);
if (ref->mBase->mData.mFlags & ESM::Light::Negative)
info.colour *= -1;
info.interior = !ptr.getCell()->mCell->isExterior();
if (ref->mBase->mData.mFlags & ESM::Light::Flicker)
info.type = LT_Flicker;
else if (ref->mBase->mData.mFlags & ESM::Light::FlickerSlow)
info.type = LT_FlickerSlow;
else if (ref->mBase->mData.mFlags & ESM::Light::Pulse)
info.type = LT_Pulse;
else if (ref->mBase->mData.mFlags & ESM::Light::PulseSlow)
info.type = LT_PulseSlow;
else
info.type = LT_Normal;
// randomize lights animations
info.time = Ogre::Math::RangeRandom(-500, +500);
info.phase = Ogre::Math::RangeRandom(-500, +500);
bool quadratic = lightOutQuadInLin() ? !info.interior : lightQuadratic();
// with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
// so we ignore lights if their attenuation falls below this factor.
const float threshold = 0.03;
if (!quadratic)
{
float r = radius * lightLinearRadiusMult();
float attenuation = lightLinearValue() / r;
float activationRange = 1 / (threshold * attenuation);
light->setAttenuation(activationRange, 0, attenuation, 0);
}
else
{
float r = radius * lightQuadraticRadiusMult();
float attenuation = lightQuadraticValue() / std::pow(r, 2);
float activationRange = std::sqrt(1 / (threshold * attenuation));
light->setAttenuation(activationRange, 0, 0, attenuation);
}
// If there's an AttachLight bone, attach the light to that, otherwise attach it to the base scene node
if (skelBase && skelBase->getSkeleton ()->hasBone ("AttachLight"))
{
skelBase->attachObjectToBone ("AttachLight", light);
}
else
{
Ogre::SceneNode* childNode = insert->createChildSceneNode (fallbackCenter);
childNode->attachObject(light);
}
mLights.push_back(info);
} }
bool Objects::deleteObject (const MWWorld::Ptr& ptr) bool Objects::deleteObject (const MWWorld::Ptr& ptr)
{ {
if (Ogre::SceneNode *base = ptr.getRefData().getBaseNode()) if(!ptr.getRefData().getBaseNode())
return true;
PtrAnimationMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
{ {
Ogre::SceneNode *parent = base->getParentSceneNode(); delete iter->second;
mObjects.erase(iter);
for (std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *>::const_iterator iter ( mRenderer.getScene()->destroySceneNode(ptr.getRefData().getBaseNode());
mCellSceneNodes.begin()); iter!=mCellSceneNodes.end(); ++iter) ptr.getRefData().setBaseNode(0);
if (iter->second==parent) return true;
{
clearSceneNode (base);
base->removeAndDestroyAllChildren();
mRenderer.getScene()->destroySceneNode (base);
ptr.getRefData().setBaseNode (0);
return true;
}
return false;
} }
return true; return false;
} }
void Objects::removeCell(MWWorld::Ptr::CellStore* store) void Objects::removeCell(MWWorld::Ptr::CellStore* store)
{ {
if(mCellSceneNodes.find(store) != mCellSceneNodes.end()) for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();)
{ {
Ogre::SceneNode* base = mCellSceneNodes[store]; if(iter->first.getCell() == store)
{
for (int i=0; i<base->numChildren(); ++i) delete iter->second;
clearSceneNode (static_cast<Ogre::SceneNode *> (base->getChild (i))); mObjects.erase(iter++);
}
base->removeAndDestroyAllChildren(); else
mCellSceneNodes.erase(store); ++iter;
mRenderer.getScene()->destroySceneNode(base);
base = 0;
} }
if(mStaticGeometry.find(store) != mStaticGeometry.end()) std::map<MWWorld::CellStore*,Ogre::StaticGeometry*>::iterator geom = mStaticGeometry.find(store);
if(geom != mStaticGeometry.end())
{ {
Ogre::StaticGeometry* sg = mStaticGeometry[store]; Ogre::StaticGeometry *sg = geom->second;
mStaticGeometry.erase(store); mStaticGeometry.erase(geom);
mRenderer.getScene()->destroyStaticGeometry (sg); mRenderer.getScene()->destroyStaticGeometry(sg);
sg = 0;
} }
if(mStaticGeometrySmall.find(store) != mStaticGeometrySmall.end())
geom = mStaticGeometrySmall.find(store);
if(geom != mStaticGeometrySmall.end())
{ {
Ogre::StaticGeometry* sg = mStaticGeometrySmall[store]; Ogre::StaticGeometry *sg = geom->second;
mStaticGeometrySmall.erase(store); mStaticGeometrySmall.erase(store);
mRenderer.getScene()->destroyStaticGeometry (sg); mRenderer.getScene()->destroyStaticGeometry(sg);
sg = 0;
} }
if(mBounds.find(store) != mBounds.end()) mBounds.erase(store);
mBounds.erase(store);
std::map<MWWorld::CellStore*,Ogre::SceneNode*>::iterator cell = mCellSceneNodes.find(store);
if(cell != mCellSceneNodes.end())
{
cell->second->removeAndDestroyAllChildren();
mRenderer.getScene()->destroySceneNode(cell->second);
mCellSceneNodes.erase(cell);
}
} }
void Objects::buildStaticGeometry(MWWorld::Ptr::CellStore& cell) void Objects::buildStaticGeometry(MWWorld::Ptr::CellStore& cell)
@ -397,146 +230,23 @@ Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell)
void Objects::enableLights() void Objects::enableLights()
{ {
std::vector<LightInfo>::iterator it = mLights.begin(); PtrAnimationMap::const_iterator it = mObjects.begin();
while (it != mLights.end()) for(;it != mObjects.end();it++)
{ it->second->enableLights(true);
if (mRootNode->getCreator()->hasLight(it->name))
{
mRootNode->getCreator()->getLight(it->name)->setVisible(true);
++it;
}
else
it = mLights.erase(it);
}
} }
void Objects::disableLights() void Objects::disableLights()
{ {
std::vector<LightInfo>::iterator it = mLights.begin(); PtrAnimationMap::const_iterator it = mObjects.begin();
while (it != mLights.end()) for(;it != mObjects.end();it++)
{ it->second->enableLights(false);
if (mRootNode->getCreator()->hasLight(it->name))
{
mRootNode->getCreator()->getLight(it->name)->setVisible(false);
++it;
}
else
it = mLights.erase(it);
}
}
namespace MWRender
{
namespace Pulse
{
static float amplitude (float phase)
{
return sin (phase);
}
}
namespace Flicker
{
static const float fa = 0.785398f;
static const float fb = 1.17024f;
static const float tdo = 0.94f;
static const float tdm = 2.48f;
static const float f [3] = { 1.5708f, 4.18774f, 5.19934f };
static const float o [3] = { 0.804248f, 2.11115f, 3.46832f };
static const float m [3] = { 1.0f, 0.785f, 0.876f };
static const float s = 0.394f;
static const float phase_wavelength = 120.0f * 3.14159265359f / fa;
static float frequency (float x)
{
return tdo + tdm * sin (fa * x);
}
static float amplitude (float x)
{
float v = 0.0f;
for (int i = 0; i < 3; ++i)
v += sin (fb*x*f[i] + o[1])*m[i];
return v * s;
}
}
} }
void Objects::update(const float dt) void Objects::update(const float dt)
{ {
std::vector<LightInfo>::iterator it = mLights.begin(); PtrAnimationMap::const_iterator it = mObjects.begin();
while (it != mLights.end()) for(;it != mObjects.end();it++)
{ it->second->runAnimation(dt);
if (mRootNode->getCreator()->hasLight(it->name))
{
Ogre::Light* light = mRootNode->getCreator()->getLight(it->name);
float brightness;
float cycle_time;
float time_distortion;
if ((it->type == LT_Pulse) && (it->type == LT_PulseSlow))
{
cycle_time = 2 * Ogre::Math::PI;
time_distortion = 20.0f;
}
else
{
cycle_time = 500.0f;
it->phase = fmod (it->phase + dt, Flicker::phase_wavelength);
time_distortion = Flicker::frequency (it->phase);
}
it->time += it->dir*dt*time_distortion;
if (it->dir > 0 && it->time > +cycle_time)
{
it->dir = -1.0f;
it->time = +2*cycle_time - it->time;
}
if (it->dir < 0 && it->time < -cycle_time)
{
it->dir = +1.0f;
it->time = -2*cycle_time - it->time;
}
static const float fast = 4.0f/1.0f;
static const float slow = 1.0f/1.0f;
// These formulas are just guesswork, but they work pretty well
if (it->type == LT_Normal)
{
// Less than 1/255 light modifier for a constant light:
brightness = (const float)(1.0 + Flicker::amplitude(it->time*slow) / 255.0 );
}
else if (it->type == LT_Flicker)
{
brightness = (const float)(0.75 + Flicker::amplitude(it->time*fast) * 0.25);
}
else if (it->type == LT_FlickerSlow)
{
brightness = (const float)(0.75 + Flicker::amplitude(it->time*slow) * 0.25);
}
else if (it->type == LT_Pulse)
{
brightness = (const float)(1.0 + Pulse::amplitude (it->time*fast) * 0.25);
}
else if (it->type == LT_PulseSlow)
{
brightness = (const float)(1.0 + Pulse::amplitude (it->time*slow) * 0.25);
}
else
assert(0 && "Invalid light type");
light->setDiffuseColour(it->colour * brightness);
++it;
}
else
it = mLights.erase(it);
}
} }
void Objects::rebuildStaticGeometry() void Objects::rebuildStaticGeometry()

View file

@ -5,7 +5,6 @@
#include <OgreAxisAlignedBox.h> #include <OgreAxisAlignedBox.h>
#include <openengine/ogre/renderer.hpp> #include <openengine/ogre/renderer.hpp>
#include "../mwworld/fallback.hpp"
namespace MWWorld namespace MWWorld
{ {
@ -15,72 +14,32 @@ namespace MWWorld
namespace MWRender{ namespace MWRender{
/// information about light needed for rendering class ObjectAnimation;
enum LightType
{
// These are all mutually exclusive
LT_Normal=0,
LT_Flicker=1,
LT_FlickerSlow=2,
LT_Pulse=3,
LT_PulseSlow=4
};
struct LightInfo
{
// Constants
std::string name; // ogre handle
Ogre::ColourValue colour;
float radius;
bool interior; // Does this light belong to an interior or exterior cell
LightType type;
// Runtime variables
float dir; // direction time is running...
float time; // current time
float phase; // current phase
LightInfo() :
dir(1.0f), time(0.0f), phase (0.0f),
interior(true), type(LT_Normal), radius(1.0)
{
}
};
class Objects{ class Objects{
typedef std::map<MWWorld::Ptr,ObjectAnimation*> PtrAnimationMap;
OEngine::Render::OgreRenderer &mRenderer; OEngine::Render::OgreRenderer &mRenderer;
std::map<MWWorld::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
std::map<MWWorld::CellStore *, Ogre::StaticGeometry*> mStaticGeometry; std::map<MWWorld::CellStore*,Ogre::SceneNode*> mCellSceneNodes;
std::map<MWWorld::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall; std::map<MWWorld::CellStore*,Ogre::StaticGeometry*> mStaticGeometry;
std::map<MWWorld::CellStore *, Ogre::AxisAlignedBox> mBounds; std::map<MWWorld::CellStore*,Ogre::StaticGeometry*> mStaticGeometrySmall;
std::vector<LightInfo> mLights; std::map<MWWorld::CellStore*,Ogre::AxisAlignedBox> mBounds;
PtrAnimationMap mObjects;
Ogre::SceneNode* mRootNode; Ogre::SceneNode* mRootNode;
bool mIsStatic;
static int uniqueID; static int uniqueID;
MWWorld::Fallback* mFallback;
float lightLinearValue();
float lightLinearRadiusMult();
bool lightQuadratic(); void insertBegin(const MWWorld::Ptr& ptr);
float lightQuadraticValue();
float lightQuadraticRadiusMult();
bool lightOutQuadInLin();
void clearSceneNode (Ogre::SceneNode *node);
///< Remove all movable objects from \a node.
public: public:
Objects(OEngine::Render::OgreRenderer& renderer, MWWorld::Fallback* fallback) Objects(OEngine::Render::OgreRenderer &renderer)
: mRenderer (renderer) : mRenderer(renderer)
, mIsStatic(false)
, mFallback(fallback)
, mRootNode(NULL) , mRootNode(NULL)
{} {}
~Objects(){} ~Objects(){}
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertModel(const MWWorld::Ptr& ptr, const std::string &model);
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light=false);
void insertLight (const MWWorld::Ptr& ptr, Ogre::Entity *skelBase=0, Ogre::Vector3 fallbackCenter=Ogre::Vector3(0.0f));
void enableLights(); void enableLights();
void disableLights(); void disableLights();

View file

@ -57,7 +57,7 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
MWWorld::Fallback* fallback) MWWorld::Fallback* fallback)
: mRendering(_rend) : mRendering(_rend)
, mFallback(fallback) , mFallback(fallback)
, mObjects(mRendering, mFallback) , mObjects(mRendering)
, mActors(mRendering, this) , mActors(mRendering, this)
, mPlayerAnimation(NULL) , mPlayerAnimation(NULL)
, mAmbientMode(0) , mAmbientMode(0)

View file

@ -45,7 +45,7 @@ namespace MWRender
// Setting this to 0 seems to cause glitches though. :/ // Setting this to 0 seems to cause glitches though. :/
mTerrainGlobals->setMaxPixelError(1); mTerrainGlobals->setMaxPixelError(1);
mTerrainGlobals->setLayerBlendMapSize(32); mTerrainGlobals->setLayerBlendMapSize(ESM::Land::LAND_TEXTURE_SIZE/2 + 1);
//10 (default) didn't seem to be quite enough //10 (default) didn't seem to be quite enough
mTerrainGlobals->setSkirtSize(128); mTerrainGlobals->setSkirtSize(128);
@ -246,9 +246,9 @@ namespace MWRender
//cells which may lead to inconsistent results when shading between cells //cells which may lead to inconsistent results when shading between cells
int num = MWBase::Environment::get().getWorld()->getStore().get<ESM::LandTexture>().getSize(plugin); int num = MWBase::Environment::get().getWorld()->getStore().get<ESM::LandTexture>().getSize(plugin);
std::set<uint16_t> ltexIndexes; std::set<uint16_t> ltexIndexes;
for ( int y = fromY - 1; y < fromY + size + 1; y++ ) for ( int y = fromY; y < fromY + size + 1; y++ )
{ {
for ( int x = fromX - 1; x < fromX + size + 1; x++ ) for ( int x = fromX - 1; x < fromX + size; x++ ) // NB we wrap X from the other side because Y is reversed
{ {
int idx = getLtexIndexAt(cellX, cellY, x, y); int idx = getLtexIndexAt(cellX, cellY, x, y);
// This is a quick hack to prevent the program from trying to fetch textures // This is a quick hack to prevent the program from trying to fetch textures
@ -340,7 +340,6 @@ namespace MWRender
assert( (size & (size - 1)) == 0 && "Size must be a power of 2"); assert( (size & (size - 1)) == 0 && "Size must be a power of 2");
const int blendMapSize = terrain->getLayerBlendMapSize(); const int blendMapSize = terrain->getLayerBlendMapSize();
const int splatSize = blendMapSize / size;
//zero out every map //zero out every map
std::map<uint16_t, int>::const_iterator iter; std::map<uint16_t, int>::const_iterator iter;
@ -352,9 +351,9 @@ namespace MWRender
} }
//covert the ltex data into a set of blend maps //covert the ltex data into a set of blend maps
for ( int texY = fromY - 1; texY < fromY + size + 1; texY++ ) for ( int texY = fromY; texY < fromY + size + 1; texY++ )
{ {
for ( int texX = fromX - 1; texX < fromX + size + 1; texX++ ) for ( int texX = fromX - 1; texX < fromX + size; texX++ ) // NB we wrap X from the other side because Y is reversed
{ {
const uint16_t ltexIndex = getLtexIndexAt(cellX, cellY, texX, texY); const uint16_t ltexIndex = getLtexIndexAt(cellX, cellY, texX, texY);
@ -367,7 +366,7 @@ namespace MWRender
//while texX is the splat index relative to the entire cell, //while texX is the splat index relative to the entire cell,
//relX is relative to the current segment we are splatting //relX is relative to the current segment we are splatting
const int relX = texX - fromX; const int relX = texX - fromX + 1;
const int relY = texY - fromY; const int relY = texY - fromY;
const int layerIndex = indexes.find(ltexIndex)->second; const int layerIndex = indexes.find(ltexIndex)->second;
@ -375,35 +374,15 @@ namespace MWRender
float* const pBlend = terrain->getLayerBlendMap(layerIndex) float* const pBlend = terrain->getLayerBlendMap(layerIndex)
->getBlendPointer(); ->getBlendPointer();
for ( int y = -1; y < splatSize + 1; y++ )
{
for ( int x = -1; x < splatSize + 1; x++ )
{
//Note: Y is reversed //Note: Y is reversed
const int splatY = blendMapSize - 1 - relY * splatSize - y; const int splatY = blendMapSize - relY - 1;
const int splatX = relX * splatSize + x; const int splatX = relX;
if ( splatX >= 0 && splatX < blendMapSize && assert(splatX >= 0 && splatX < blendMapSize);
splatY >= 0 && splatY < blendMapSize ) assert(splatY >= 0 && splatY < blendMapSize);
{
const int index = (splatY)*blendMapSize + splatX;
if ( y >= 0 && y < splatSize && const int index = (splatY)*blendMapSize + splatX;
x >= 0 && x < splatSize ) pBlend[index] = 1;
{
pBlend[index] = 1;
}
else
{
//this provides a transition shading but also
//rounds off the corners slightly
pBlend[index] = std::min(1.0f, pBlend[index] + 0.5f);
}
}
}
}
} }
} }

View file

@ -2,6 +2,7 @@
#include "aiextensions.hpp" #include "aiextensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -365,137 +366,56 @@ namespace MWScript
}; };
const int opcodeAiTravel = 0x20000;
const int opcodeAiTravelExplicit = 0x20001;
const int opcodeAiEscort = 0x20002;
const int opcodeAiEscortExplicit = 0x20003;
const int opcodeGetAiPackageDone = 0x200007c;
const int opcodeGetAiPackageDoneExplicit = 0x200007d;
const int opcodeGetCurrentAiPackage = 0x20001ef;
const int opcodeGetCurrentAiPackageExplicit = 0x20001f0;
const int opcodeGetDetected = 0x20001f1;
const int opcodeGetDetectedExplicit = 0x20001f2;
const int opcodeAiWander = 0x20010;
const int opcodeAiWanderExplicit = 0x20011;
const int opcodeAIActivate = 0x2001e;
const int opcodeAIActivateExplicit = 0x2001f;
const int opcodeAiEscortCell = 0x20020;
const int opcodeAiEscortCellExplicit = 0x20021;
const int opcodeAiFollow = 0x20022;
const int opcodeAiFollowExplicit = 0x20023;
const int opcodeAiFollowCell = 0x20024;
const int opcodeAiFollowCellExplicit = 0x20025;
const int opcodeSetHello = 0x200015e;
const int opcodeSetHelloExplicit = 0x200015d;
const int opcodeSetFight = 0x200015e;
const int opcodeSetFightExplicit = 0x200015f;
const int opcodeSetFlee = 0x2000160;
const int opcodeSetFleeExplicit = 0x2000161;
const int opcodeSetAlarm = 0x2000162;
const int opcodeSetAlarmExplicit = 0x2000163;
const int opcodeModHello = 0x20001b7;
const int opcodeModHelloExplicit = 0x20001b8;
const int opcodeModFight = 0x20001b9;
const int opcodeModFightExplicit = 0x20001ba;
const int opcodeModFlee = 0x20001bb;
const int opcodeModFleeExplicit = 0x20001bc;
const int opcodeModAlarm = 0x20001bd;
const int opcodeModAlarmExplicit = 0x20001be;
const int opcodeGetHello = 0x20001bf;
const int opcodeGetHelloExplicit = 0x20001c0;
const int opcodeGetFight = 0x20001c1;
const int opcodeGetFightExplicit = 0x20001c2;
const int opcodeGetFlee = 0x20001c3;
const int opcodeGetFleeExplicit = 0x20001c4;
const int opcodeGetAlarm = 0x20001c5;
const int opcodeGetAlarmExplicit = 0x20001c6;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("aiactivate", "c/l", opcodeAIActivate,
opcodeAIActivateExplicit);
extensions.registerInstruction ("aitravel", "fff/l", opcodeAiTravel,
opcodeAiTravelExplicit);
extensions.registerInstruction ("aiescort", "cffff/l", opcodeAiEscort,
opcodeAiEscortExplicit);
extensions.registerInstruction ("aiescortcell", "ccffff/l", opcodeAiEscortCell,
opcodeAiEscortCellExplicit);
extensions.registerInstruction ("aiwander", "fff/llllllllll", opcodeAiWander,
opcodeAiWanderExplicit);
extensions.registerInstruction ("aifollow", "cffff/l", opcodeAiFollow,
opcodeAiFollowExplicit);
extensions.registerInstruction ("aifollowcell", "ccffff/l", opcodeAiFollowCell,
opcodeAiFollowCellExplicit);
extensions.registerFunction ("getaipackagedone", 'l', "", opcodeGetAiPackageDone,
opcodeGetAiPackageDoneExplicit);
extensions.registerFunction ("getcurrentaipackage", 'l', "", opcodeGetCurrentAiPackage,
opcodeGetAiPackageDoneExplicit);
extensions.registerFunction ("getdetected", 'l', "c", opcodeGetDetected,
opcodeGetDetectedExplicit);
extensions.registerInstruction ("sethello", "l", opcodeSetHello, opcodeSetHelloExplicit);
extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit);
extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit);
extensions.registerInstruction ("setalarm", "l", opcodeSetAlarm, opcodeSetAlarmExplicit);
extensions.registerInstruction ("modhello", "l", opcodeModHello, opcodeModHelloExplicit);
extensions.registerInstruction ("modfight", "l", opcodeModFight, opcodeModFightExplicit);
extensions.registerInstruction ("modflee", "l", opcodeModFlee, opcodeModFleeExplicit);
extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit);
extensions.registerFunction ("gethello", 'l', "", opcodeGetHello, opcodeGetHelloExplicit);
extensions.registerFunction ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit);
extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit);
extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment3 (opcodeAIActivate, new OpAiActivate<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAIActivate, new OpAiActivate<ImplicitRef>);
interpreter.installSegment3 (opcodeAIActivateExplicit, new OpAiActivate<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAIActivateExplicit, new OpAiActivate<ExplicitRef>);
interpreter.installSegment3 (opcodeAiTravel, new OpAiTravel<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiTravel, new OpAiTravel<ImplicitRef>);
interpreter.installSegment3 (opcodeAiTravelExplicit, new OpAiTravel<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiTravelExplicit, new OpAiTravel<ExplicitRef>);
interpreter.installSegment3 (opcodeAiEscort, new OpAiEscort<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiEscort, new OpAiEscort<ImplicitRef>);
interpreter.installSegment3 (opcodeAiEscortExplicit, new OpAiEscort<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiEscortExplicit, new OpAiEscort<ExplicitRef>);
interpreter.installSegment3 (opcodeAiEscortCell, new OpAiEscortCell<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiEscortCell, new OpAiEscortCell<ImplicitRef>);
interpreter.installSegment3 (opcodeAiEscortCellExplicit, new OpAiEscortCell<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiEscortCellExplicit, new OpAiEscortCell<ExplicitRef>);
interpreter.installSegment3 (opcodeAiWander, new OpAiWander<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiWander, new OpAiWander<ImplicitRef>);
interpreter.installSegment3 (opcodeAiWanderExplicit, new OpAiWander<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiWanderExplicit, new OpAiWander<ExplicitRef>);
interpreter.installSegment3 (opcodeAiFollow, new OpAiFollow<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiFollow, new OpAiFollow<ImplicitRef>);
interpreter.installSegment3 (opcodeAiFollowExplicit, new OpAiFollow<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiFollowExplicit, new OpAiFollow<ExplicitRef>);
interpreter.installSegment3 (opcodeAiFollowCell, new OpAiFollowCell<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiFollowCell, new OpAiFollowCell<ImplicitRef>);
interpreter.installSegment3 (opcodeAiFollowCellExplicit, new OpAiFollowCell<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeAiFollowCellExplicit, new OpAiFollowCell<ExplicitRef>);
interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>);
interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit, interpreter.installSegment5 (Compiler::Ai::opcodeGetAiPackageDoneExplicit,
new OpGetAiPackageDone<ExplicitRef>); new OpGetAiPackageDone<ExplicitRef>);
interpreter.installSegment5 (opcodeGetCurrentAiPackage, new OpGetCurrentAIPackage<ImplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeGetCurrentAiPackage, new OpGetCurrentAIPackage<ImplicitRef>);
interpreter.installSegment5 (opcodeGetCurrentAiPackageExplicit, new OpGetCurrentAIPackage<ExplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeGetCurrentAiPackageExplicit, new OpGetCurrentAIPackage<ExplicitRef>);
interpreter.installSegment3 (opcodeGetDetected, new OpGetDetected<ImplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeGetDetected, new OpGetDetected<ImplicitRef>);
interpreter.installSegment3 (opcodeGetDetectedExplicit, new OpGetDetected<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected<ExplicitRef>);
interpreter.installSegment5 (opcodeSetHello, new OpSetAiSetting<ImplicitRef>(0)); interpreter.installSegment5 (Compiler::Ai::opcodeSetHello, new OpSetAiSetting<ImplicitRef>(0));
interpreter.installSegment5 (opcodeSetHelloExplicit, new OpSetAiSetting<ExplicitRef>(0)); interpreter.installSegment5 (Compiler::Ai::opcodeSetHelloExplicit, new OpSetAiSetting<ExplicitRef>(0));
interpreter.installSegment5 (opcodeSetFight, new OpSetAiSetting<ImplicitRef>(1)); interpreter.installSegment5 (Compiler::Ai::opcodeSetFight, new OpSetAiSetting<ImplicitRef>(1));
interpreter.installSegment5 (opcodeSetFightExplicit, new OpSetAiSetting<ExplicitRef>(1)); interpreter.installSegment5 (Compiler::Ai::opcodeSetFightExplicit, new OpSetAiSetting<ExplicitRef>(1));
interpreter.installSegment5 (opcodeSetFlee, new OpSetAiSetting<ImplicitRef>(2)); interpreter.installSegment5 (Compiler::Ai::opcodeSetFlee, new OpSetAiSetting<ImplicitRef>(2));
interpreter.installSegment5 (opcodeSetFleeExplicit, new OpSetAiSetting<ExplicitRef>(2)); interpreter.installSegment5 (Compiler::Ai::opcodeSetFleeExplicit, new OpSetAiSetting<ExplicitRef>(2));
interpreter.installSegment5 (opcodeSetAlarm, new OpSetAiSetting<ImplicitRef>(3)); interpreter.installSegment5 (Compiler::Ai::opcodeSetAlarm, new OpSetAiSetting<ImplicitRef>(3));
interpreter.installSegment5 (opcodeSetAlarmExplicit, new OpSetAiSetting<ExplicitRef>(3)); interpreter.installSegment5 (Compiler::Ai::opcodeSetAlarmExplicit, new OpSetAiSetting<ExplicitRef>(3));
interpreter.installSegment5 (opcodeModHello, new OpModAiSetting<ImplicitRef>(0)); interpreter.installSegment5 (Compiler::Ai::opcodeModHello, new OpModAiSetting<ImplicitRef>(0));
interpreter.installSegment5 (opcodeModHelloExplicit, new OpModAiSetting<ExplicitRef>(0)); interpreter.installSegment5 (Compiler::Ai::opcodeModHelloExplicit, new OpModAiSetting<ExplicitRef>(0));
interpreter.installSegment5 (opcodeModFight, new OpModAiSetting<ImplicitRef>(1)); interpreter.installSegment5 (Compiler::Ai::opcodeModFight, new OpModAiSetting<ImplicitRef>(1));
interpreter.installSegment5 (opcodeModFightExplicit, new OpModAiSetting<ExplicitRef>(1)); interpreter.installSegment5 (Compiler::Ai::opcodeModFightExplicit, new OpModAiSetting<ExplicitRef>(1));
interpreter.installSegment5 (opcodeModFlee, new OpModAiSetting<ImplicitRef>(2)); interpreter.installSegment5 (Compiler::Ai::opcodeModFlee, new OpModAiSetting<ImplicitRef>(2));
interpreter.installSegment5 (opcodeModFleeExplicit, new OpModAiSetting<ExplicitRef>(2)); interpreter.installSegment5 (Compiler::Ai::opcodeModFleeExplicit, new OpModAiSetting<ExplicitRef>(2));
interpreter.installSegment5 (opcodeModAlarm, new OpModAiSetting<ImplicitRef>(3)); interpreter.installSegment5 (Compiler::Ai::opcodeModAlarm, new OpModAiSetting<ImplicitRef>(3));
interpreter.installSegment5 (opcodeModAlarmExplicit, new OpModAiSetting<ExplicitRef>(3)); interpreter.installSegment5 (Compiler::Ai::opcodeModAlarmExplicit, new OpModAiSetting<ExplicitRef>(3));
interpreter.installSegment5 (opcodeGetHello, new OpGetAiSetting<ImplicitRef>(0)); interpreter.installSegment5 (Compiler::Ai::opcodeGetHello, new OpGetAiSetting<ImplicitRef>(0));
interpreter.installSegment5 (opcodeGetHelloExplicit, new OpGetAiSetting<ExplicitRef>(0)); interpreter.installSegment5 (Compiler::Ai::opcodeGetHelloExplicit, new OpGetAiSetting<ExplicitRef>(0));
interpreter.installSegment5 (opcodeGetFight, new OpGetAiSetting<ImplicitRef>(1)); interpreter.installSegment5 (Compiler::Ai::opcodeGetFight, new OpGetAiSetting<ImplicitRef>(1));
interpreter.installSegment5 (opcodeGetFightExplicit, new OpGetAiSetting<ExplicitRef>(1)); interpreter.installSegment5 (Compiler::Ai::opcodeGetFightExplicit, new OpGetAiSetting<ExplicitRef>(1));
interpreter.installSegment5 (opcodeGetFlee, new OpGetAiSetting<ImplicitRef>(2)); interpreter.installSegment5 (Compiler::Ai::opcodeGetFlee, new OpGetAiSetting<ImplicitRef>(2));
interpreter.installSegment5 (opcodeGetFleeExplicit, new OpGetAiSetting<ExplicitRef>(2)); interpreter.installSegment5 (Compiler::Ai::opcodeGetFleeExplicit, new OpGetAiSetting<ExplicitRef>(2));
interpreter.installSegment5 (opcodeGetAlarm, new OpGetAiSetting<ImplicitRef>(3)); interpreter.installSegment5 (Compiler::Ai::opcodeGetAlarm, new OpGetAiSetting<ImplicitRef>(3));
interpreter.installSegment5 (opcodeGetAlarmExplicit, new OpGetAiSetting<ExplicitRef>(3)); interpreter.installSegment5 (Compiler::Ai::opcodeGetAlarmExplicit, new OpGetAiSetting<ExplicitRef>(3));
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief AI-related script functionality /// \brief AI-related script functionality
namespace Ai namespace Ai
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -4,6 +4,7 @@
#include <stdexcept> #include <stdexcept>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -91,28 +92,15 @@ namespace MWScript
} }
}; };
const int opcodeSkipAnim = 0x2000138;
const int opcodeSkipAnimExplicit = 0x2000139;
const int opcodePlayAnim = 0x20006;
const int opcodePlayAnimExplicit = 0x20007;
const int opcodeLoopAnim = 0x20008;
const int opcodeLoopAnimExplicit = 0x20009;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("skipanim", "", opcodeSkipAnim, opcodeSkipAnimExplicit);
extensions.registerInstruction ("playgroup", "c/l", opcodePlayAnim, opcodePlayAnimExplicit);
extensions.registerInstruction ("loopgroup", "cl/l", opcodeLoopAnim, opcodeLoopAnimExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeSkipAnim, new OpSkipAnim<ImplicitRef>); interpreter.installSegment5 (Compiler::Animation::opcodeSkipAnim, new OpSkipAnim<ImplicitRef>);
interpreter.installSegment5 (opcodeSkipAnimExplicit, new OpSkipAnim<ExplicitRef>); interpreter.installSegment5 (Compiler::Animation::opcodeSkipAnimExplicit, new OpSkipAnim<ExplicitRef>);
interpreter.installSegment3 (opcodePlayAnim, new OpPlayAnim<ImplicitRef>); interpreter.installSegment3 (Compiler::Animation::opcodePlayAnim, new OpPlayAnim<ImplicitRef>);
interpreter.installSegment3 (opcodePlayAnimExplicit, new OpPlayAnim<ExplicitRef>); interpreter.installSegment3 (Compiler::Animation::opcodePlayAnimExplicit, new OpPlayAnim<ExplicitRef>);
interpreter.installSegment3 (opcodeLoopAnim, new OpLoopAnim<ImplicitRef>); interpreter.installSegment3 (Compiler::Animation::opcodeLoopAnim, new OpLoopAnim<ImplicitRef>);
interpreter.installSegment3 (opcodeLoopAnimExplicit, new OpLoopAnim<ExplicitRef>); interpreter.installSegment3 (Compiler::Animation::opcodeLoopAnimExplicit, new OpLoopAnim<ExplicitRef>);
} }
} }
} }

View file

@ -4,6 +4,7 @@
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -165,39 +166,17 @@ namespace MWScript
} }
}; };
const int opcodeCellChanged = 0x2000000;
const int opcodeCOC = 0x2000026;
const int opcodeCOE = 0x200008e;
const int opcodeGetInterior = 0x2000131;
const int opcodeGetPCCell = 0x2000136;
const int opcodeGetWaterLevel = 0x2000141;
const int opcodeSetWaterLevel = 0x2000142;
const int opcodeModWaterLevel = 0x2000143;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerFunction ("cellchanged", 'l', "", opcodeCellChanged);
extensions.registerInstruction ("coc", "S", opcodeCOC);
extensions.registerInstruction ("centeroncell", "S", opcodeCOC);
extensions.registerInstruction ("coe", "ll", opcodeCOE);
extensions.registerInstruction ("centeronexterior", "ll", opcodeCOE);
extensions.registerInstruction ("setwaterlevel", "f", opcodeSetWaterLevel);
extensions.registerInstruction ("modwaterlevel", "f", opcodeModWaterLevel);
extensions.registerFunction ("getinterior", 'l', "", opcodeGetInterior);
extensions.registerFunction ("getpccell", 'l', "c", opcodeGetPCCell);
extensions.registerFunction ("getwaterlevel", 'f', "", opcodeGetWaterLevel);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeCellChanged, new OpCellChanged); interpreter.installSegment5 (Compiler::Cell::opcodeCellChanged, new OpCellChanged);
interpreter.installSegment5 (opcodeCOC, new OpCOC); interpreter.installSegment5 (Compiler::Cell::opcodeCOC, new OpCOC);
interpreter.installSegment5 (opcodeCOE, new OpCOE); interpreter.installSegment5 (Compiler::Cell::opcodeCOE, new OpCOE);
interpreter.installSegment5 (opcodeGetInterior, new OpGetInterior); interpreter.installSegment5 (Compiler::Cell::opcodeGetInterior, new OpGetInterior);
interpreter.installSegment5 (opcodeGetPCCell, new OpGetPCCell); interpreter.installSegment5 (Compiler::Cell::opcodeGetPCCell, new OpGetPCCell);
interpreter.installSegment5 (opcodeGetWaterLevel, new OpGetWaterLevel); interpreter.installSegment5 (Compiler::Cell::opcodeGetWaterLevel, new OpGetWaterLevel);
interpreter.installSegment5 (opcodeSetWaterLevel, new OpSetWaterLevel); interpreter.installSegment5 (Compiler::Cell::opcodeSetWaterLevel, new OpSetWaterLevel);
interpreter.installSegment5 (opcodeModWaterLevel, new OpModWaterLevel); interpreter.installSegment5 (Compiler::Cell::opcodeModWaterLevel, new OpModWaterLevel);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief cell-related script functionality /// \brief cell-related script functionality
namespace Cell namespace Cell
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -2,6 +2,7 @@
#include "consoleextensions.hpp" #include "consoleextensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -11,11 +12,6 @@ namespace MWScript
{ {
namespace Console namespace Console
{ {
void registerExtensions (Compiler::Extensions& extensions)
{
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief Script functionality limited to the console /// \brief Script functionality limited to the console
namespace Console namespace Console
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -8,6 +8,7 @@
#include <MyGUI_LanguageManager.h> #include <MyGUI_LanguageManager.h>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -360,55 +361,25 @@ namespace MWScript
} }
}; };
const int opcodeAddItem = 0x2000076;
const int opcodeAddItemExplicit = 0x2000077;
const int opcodeGetItemCount = 0x2000078;
const int opcodeGetItemCountExplicit = 0x2000079;
const int opcodeRemoveItem = 0x200007a;
const int opcodeRemoveItemExplicit = 0x200007b;
const int opcodeEquip = 0x20001b3;
const int opcodeEquipExplicit = 0x20001b4;
const int opcodeGetArmorType = 0x20001d1;
const int opcodeGetArmorTypeExplicit = 0x20001d2;
const int opcodeHasItemEquipped = 0x20001d5;
const int opcodeHasItemEquippedExplicit = 0x20001d6;
const int opcodeHasSoulGem = 0x20001de;
const int opcodeHasSoulGemExplicit = 0x20001df;
const int opcodeGetWeaponType = 0x20001e0;
const int opcodeGetWeaponTypeExplicit = 0x20001e1;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit);
extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount,
opcodeGetItemCountExplicit);
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,
opcodeRemoveItemExplicit);
extensions.registerInstruction ("equip", "c", opcodeEquip, opcodeEquipExplicit);
extensions.registerFunction ("getarmortype", 'l', "l", opcodeGetArmorType, opcodeGetArmorTypeExplicit);
extensions.registerFunction ("hasitemequipped", 'l', "c", opcodeHasItemEquipped, opcodeHasItemEquippedExplicit);
extensions.registerFunction ("hassoulgem", 'l', "c", opcodeHasSoulGem, opcodeHasSoulGemExplicit);
extensions.registerFunction ("getweapontype", 'l', "", opcodeGetWeaponType, opcodeGetWeaponTypeExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeAddItem, new OpAddItem<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeAddItem, new OpAddItem<ImplicitRef>);
interpreter.installSegment5 (opcodeAddItemExplicit, new OpAddItem<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeAddItemExplicit, new OpAddItem<ExplicitRef>);
interpreter.installSegment5 (opcodeGetItemCount, new OpGetItemCount<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeGetItemCount, new OpGetItemCount<ImplicitRef>);
interpreter.installSegment5 (opcodeGetItemCountExplicit, new OpGetItemCount<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeGetItemCountExplicit, new OpGetItemCount<ExplicitRef>);
interpreter.installSegment5 (opcodeRemoveItem, new OpRemoveItem<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeRemoveItem, new OpRemoveItem<ImplicitRef>);
interpreter.installSegment5 (opcodeRemoveItemExplicit, new OpRemoveItem<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeRemoveItemExplicit, new OpRemoveItem<ExplicitRef>);
interpreter.installSegment5 (opcodeEquip, new OpEquip<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeEquip, new OpEquip<ImplicitRef>);
interpreter.installSegment5 (opcodeEquipExplicit, new OpEquip<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeEquipExplicit, new OpEquip<ExplicitRef>);
interpreter.installSegment5 (opcodeGetArmorType, new OpGetArmorType<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeGetArmorType, new OpGetArmorType<ImplicitRef>);
interpreter.installSegment5 (opcodeGetArmorTypeExplicit, new OpGetArmorType<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeGetArmorTypeExplicit, new OpGetArmorType<ExplicitRef>);
interpreter.installSegment5 (opcodeHasItemEquipped, new OpHasItemEquipped<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeHasItemEquipped, new OpHasItemEquipped<ImplicitRef>);
interpreter.installSegment5 (opcodeHasItemEquippedExplicit, new OpHasItemEquipped<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeHasItemEquippedExplicit, new OpHasItemEquipped<ExplicitRef>);
interpreter.installSegment5 (opcodeHasSoulGem, new OpHasSoulGem<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeHasSoulGem, new OpHasSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeHasSoulGemExplicit, new OpHasSoulGem<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeHasSoulGemExplicit, new OpHasSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponType, new OpGetWeaponType<ImplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeGetWeaponType, new OpGetWeaponType<ImplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponTypeExplicit, new OpGetWeaponType<ExplicitRef>); interpreter.installSegment5 (Compiler::Container::opcodeGetWeaponTypeExplicit, new OpGetWeaponType<ExplicitRef>);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief Container-related script functionality (chests, NPCs, creatures) /// \brief Container-related script functionality (chests, NPCs, creatures)
namespace Container namespace Container
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -2,6 +2,7 @@
#include "controlextensions.hpp" #include "controlextensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -159,97 +160,41 @@ namespace MWScript
} }
}; };
const int numberOfControls = 7;
const int opcodeEnable = 0x200007e;
const int opcodeDisable = 0x2000085;
const int opcodeToggleCollision = 0x2000130;
const int opcodeClearForceRun = 0x2000154;
const int opcodeClearForceRunExplicit = 0x2000155;
const int opcodeForceRun = 0x2000156;
const int opcodeForceRunExplicit = 0x2000157;
const int opcodeClearForceSneak = 0x2000158;
const int opcodeClearForceSneakExplicit = 0x2000159;
const int opcodeForceSneak = 0x200015a;
const int opcodeForceSneakExplicit = 0x200015b;
const int opcodeGetDisabled = 0x2000175;
const int opcodeGetPcRunning = 0x20001c9;
const int opcodeGetPcSneaking = 0x20001ca;
const int opcodeGetForceRun = 0x20001cb;
const int opcodeGetForceSneak = 0x20001cc;
const int opcodeGetForceRunExplicit = 0x20001cd;
const int opcodeGetForceSneakExplicit = 0x20001ce;
const char *controls[numberOfControls] =
{
"playercontrols", "playerfighting", "playerjumping", "playerlooking", "playermagic",
"playerviewswitch", "vanitymode"
};
void registerExtensions (Compiler::Extensions& extensions)
{
std::string enable ("enable");
std::string disable ("disable");
for (int i=0; i<numberOfControls; ++i)
{
extensions.registerInstruction (enable + controls[i], "", opcodeEnable+i);
extensions.registerInstruction (disable + controls[i], "", opcodeDisable+i);
extensions.registerFunction (std::string("get") + controls[i] + std::string("disabled"), 'l', "", opcodeGetDisabled+i);
}
extensions.registerInstruction ("togglecollision", "", opcodeToggleCollision);
extensions.registerInstruction ("tcl", "", opcodeToggleCollision);
extensions.registerInstruction ("clearforcerun", "", opcodeClearForceRun,
opcodeClearForceRunExplicit);
extensions.registerInstruction ("forcerun", "", opcodeForceRun,
opcodeForceRunExplicit);
extensions.registerInstruction ("clearforcesneak", "", opcodeClearForceSneak,
opcodeClearForceSneakExplicit);
extensions.registerInstruction ("forcesneak", "", opcodeForceSneak,
opcodeForceSneakExplicit);
extensions.registerFunction ("getpcrunning", 'l', "", opcodeGetPcRunning);
extensions.registerFunction ("getpcsneaking", 'l', "", opcodeGetPcSneaking);
extensions.registerFunction ("getforcerun", 'l', "", opcodeGetForceRun, opcodeGetForceRunExplicit);
extensions.registerFunction ("getforcesneak", 'l', "", opcodeGetForceSneak, opcodeGetForceSneakExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
for (int i=0; i<numberOfControls; ++i) for (int i=0; i<Compiler::Control::numberOfControls; ++i)
{ {
interpreter.installSegment5 (opcodeEnable+i, new OpSetControl (controls[i], true)); interpreter.installSegment5 (Compiler::Control::opcodeEnable+i, new OpSetControl (Compiler::Control::controls[i], true));
interpreter.installSegment5 (opcodeDisable+i, new OpSetControl (controls[i], false)); interpreter.installSegment5 (Compiler::Control::opcodeDisable+i, new OpSetControl (Compiler::Control::controls[i], false));
interpreter.installSegment5 (opcodeGetDisabled+i, new OpGetDisabled (controls[i])); interpreter.installSegment5 (Compiler::Control::opcodeGetDisabled+i, new OpGetDisabled (Compiler::Control::controls[i]));
} }
interpreter.installSegment5 (opcodeToggleCollision, new OpToggleCollision); interpreter.installSegment5 (Compiler::Control::opcodeToggleCollision, new OpToggleCollision);
interpreter.installSegment5 (opcodeClearForceRun, interpreter.installSegment5 (Compiler::Control::opcodeClearForceRun,
new OpClearMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceRun)); new OpClearMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
interpreter.installSegment5 (opcodeForceRun, interpreter.installSegment5 (Compiler::Control::opcodeForceRun,
new OpSetMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceRun)); new OpSetMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
interpreter.installSegment5 (opcodeClearForceSneak, interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneak,
new OpClearMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak)); new OpClearMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
interpreter.installSegment5 (opcodeForceSneak, interpreter.installSegment5 (Compiler::Control::opcodeForceSneak,
new OpSetMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak)); new OpSetMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
interpreter.installSegment5 (opcodeClearForceRunExplicit, interpreter.installSegment5 (Compiler::Control::opcodeClearForceRunExplicit,
new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceRun)); new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
interpreter.installSegment5 (opcodeForceRunExplicit, interpreter.installSegment5 (Compiler::Control::opcodeForceRunExplicit,
new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceRun)); new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
interpreter.installSegment5 (opcodeClearForceSneakExplicit, interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneakExplicit,
new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak)); new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
interpreter.installSegment5 (opcodeForceSneakExplicit, interpreter.installSegment5 (Compiler::Control::opcodeForceSneakExplicit,
new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak)); new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
interpreter.installSegment5 (opcodeGetPcRunning, new OpGetPcRunning); interpreter.installSegment5 (Compiler::Control::opcodeGetPcRunning, new OpGetPcRunning);
interpreter.installSegment5 (opcodeGetPcSneaking, new OpGetPcSneaking); interpreter.installSegment5 (Compiler::Control::opcodeGetPcSneaking, new OpGetPcSneaking);
interpreter.installSegment5 (opcodeGetForceRun, new OpGetForceRun<ImplicitRef>); interpreter.installSegment5 (Compiler::Control::opcodeGetForceRun, new OpGetForceRun<ImplicitRef>);
interpreter.installSegment5 (opcodeGetForceRunExplicit, new OpGetForceRun<ExplicitRef>); interpreter.installSegment5 (Compiler::Control::opcodeGetForceRunExplicit, new OpGetForceRun<ExplicitRef>);
interpreter.installSegment5 (opcodeGetForceSneak, new OpGetForceSneak<ImplicitRef>); interpreter.installSegment5 (Compiler::Control::opcodeGetForceSneak, new OpGetForceSneak<ImplicitRef>);
interpreter.installSegment5 (opcodeGetForceSneakExplicit, new OpGetForceSneak<ExplicitRef>); interpreter.installSegment5 (Compiler::Control::opcodeGetForceSneakExplicit, new OpGetForceSneak<ExplicitRef>);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief player controls-related script functionality /// \brief player controls-related script functionality
namespace Control namespace Control
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -2,6 +2,7 @@
#include "dialogueextensions.hpp" #include "dialogueextensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -188,62 +189,25 @@ namespace MWScript
} }
}; };
const int opcodeJournal = 0x2000133;
const int opcodeSetJournalIndex = 0x2000134;
const int opcodeGetJournalIndex = 0x2000135;
const int opcodeAddTopic = 0x200013a;
const int opcodeChoice = 0x2000a;
const int opcodeForceGreeting = 0x200014f;
const int opcodeForceGreetingExplicit = 0x2000150;
const int opcodeGoodbye = 0x2000152;
const int opcodeSetReputation = 0x20001ad;
const int opcodeModReputation = 0x20001ae;
const int opcodeSetReputationExplicit = 0x20001af;
const int opcodeModReputationExplicit = 0x20001b0;
const int opcodeGetReputation = 0x20001b1;
const int opcodeGetReputationExplicit = 0x20001b2;
const int opcodeSameFaction = 0x20001b5;
const int opcodeSameFactionExplicit = 0x20001b6;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("journal", "cl", opcodeJournal);
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);
extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting);
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
opcodeForceGreetingExplicit);
extensions.registerInstruction("goodbye", "", opcodeGoodbye);
extensions.registerInstruction("setreputation", "l", opcodeSetReputation,
opcodeSetReputationExplicit);
extensions.registerInstruction("modreputation", "l", opcodeModReputation,
opcodeModReputationExplicit);
extensions.registerFunction("getreputation", 'l', "", opcodeGetReputation,
opcodeGetReputationExplicit);
extensions.registerFunction("samefaction", 'l', "", opcodeSameFaction,
opcodeSameFactionExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeJournal, new OpJournal); interpreter.installSegment5 (Compiler::Dialogue::opcodeJournal, new OpJournal);
interpreter.installSegment5 (opcodeSetJournalIndex, new OpSetJournalIndex); interpreter.installSegment5 (Compiler::Dialogue::opcodeSetJournalIndex, new OpSetJournalIndex);
interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex); interpreter.installSegment5 (Compiler::Dialogue::opcodeGetJournalIndex, new OpGetJournalIndex);
interpreter.installSegment5 (opcodeAddTopic, new OpAddTopic); interpreter.installSegment5 (Compiler::Dialogue::opcodeAddTopic, new OpAddTopic);
interpreter.installSegment3 (opcodeChoice,new OpChoice); interpreter.installSegment3 (Compiler::Dialogue::opcodeChoice,new OpChoice);
interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting<ImplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeForceGreeting, new OpForceGreeting<ImplicitRef>);
interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeForceGreetingExplicit, new OpForceGreeting<ExplicitRef>);
interpreter.installSegment5 (opcodeGoodbye, new OpGoodbye); interpreter.installSegment5 (Compiler::Dialogue::opcodeGoodbye, new OpGoodbye);
interpreter.installSegment5 (opcodeGetReputation, new OpGetReputation<ImplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeGetReputation, new OpGetReputation<ImplicitRef>);
interpreter.installSegment5 (opcodeSetReputation, new OpSetReputation<ImplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeSetReputation, new OpSetReputation<ImplicitRef>);
interpreter.installSegment5 (opcodeModReputation, new OpModReputation<ImplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeModReputation, new OpModReputation<ImplicitRef>);
interpreter.installSegment5 (opcodeSetReputationExplicit, new OpSetReputation<ExplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeSetReputationExplicit, new OpSetReputation<ExplicitRef>);
interpreter.installSegment5 (opcodeModReputationExplicit, new OpModReputation<ExplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeModReputationExplicit, new OpModReputation<ExplicitRef>);
interpreter.installSegment5 (opcodeGetReputationExplicit, new OpGetReputation<ExplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeGetReputationExplicit, new OpGetReputation<ExplicitRef>);
interpreter.installSegment5 (opcodeSameFaction, new OpSameFaction<ImplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFaction, new OpSameFaction<ImplicitRef>);
interpreter.installSegment5 (opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>); interpreter.installSegment5 (Compiler::Dialogue::opcodeSameFactionExplicit, new OpSameFaction<ExplicitRef>);
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief Dialogue/Journal-related script functionality /// \brief Dialogue/Journal-related script functionality
namespace Dialogue namespace Dialogue
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -21,28 +21,6 @@
namespace MWScript namespace MWScript
{ {
void registerExtensions (Compiler::Extensions& extensions, bool consoleOnly)
{
Cell::registerExtensions (extensions);
Misc::registerExtensions (extensions);
Gui::registerExtensions (extensions);
Sound::registerExtensions (extensions);
Sky::registerExtensions (extensions);
Stats::registerExtensions (extensions);
Container::registerExtensions (extensions);
Ai::registerExtensions (extensions);
Control::registerExtensions (extensions);
Dialogue::registerExtensions (extensions);
Animation::registerExtensions (extensions);
Transformation::registerExtensions (extensions);
if (consoleOnly)
{
Console::registerExtensions (extensions);
User::registerExtensions (extensions);
}
}
void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly) void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly)
{ {
Interpreter::installOpcodes (interpreter); Interpreter::installOpcodes (interpreter);

View file

@ -13,9 +13,6 @@ namespace Interpreter
namespace MWScript namespace MWScript
{ {
void registerExtensions (Compiler::Extensions& extensions, bool consoleOnly = false);
///< \param consoleOnly include console only extensions
void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly = false); void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly = false);
///< \param consoleOnly include console only opcodes ///< \param consoleOnly include console only opcodes
} }

View file

@ -4,6 +4,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -150,90 +151,42 @@ namespace MWScript
}; };
const int opcodeEnableBirthMenu = 0x200000e;
const int opcodeEnableClassMenu = 0x200000f;
const int opcodeEnableNameMenu = 0x2000010;
const int opcodeEnableRaceMenu = 0x2000011;
const int opcodeEnableStatsReviewMenu = 0x2000012;
const int opcodeEnableInventoryMenu = 0x2000013;
const int opcodeEnableMagicMenu = 0x2000014;
const int opcodeEnableMapMenu = 0x2000015;
const int opcodeEnableStatsMenu = 0x2000016;
const int opcodeEnableRest = 0x2000017;
const int opcodeShowRestMenu = 0x2000018;
const int opcodeGetButtonPressed = 0x2000137;
const int opcodeToggleFogOfWar = 0x2000145;
const int opcodeToggleFullHelp = 0x2000151;
const int opcodeShowMap = 0x20001a0;
const int opcodeFillMap = 0x20001a1;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("enablebirthmenu", "", opcodeEnableBirthMenu);
extensions.registerInstruction ("enableclassmenu", "", opcodeEnableClassMenu);
extensions.registerInstruction ("enablenamemenu", "", opcodeEnableNameMenu);
extensions.registerInstruction ("enableracemenu", "", opcodeEnableRaceMenu);
extensions.registerInstruction ("enablestatreviewmenu", "",
opcodeEnableStatsReviewMenu);
extensions.registerInstruction ("enableinventorymenu", "", opcodeEnableInventoryMenu);
extensions.registerInstruction ("enablemagicmenu", "", opcodeEnableMagicMenu);
extensions.registerInstruction ("enablemapmenu", "", opcodeEnableMapMenu);
extensions.registerInstruction ("enablestatsmenu", "", opcodeEnableStatsMenu);
extensions.registerInstruction ("enablerest", "", opcodeEnableRest);
extensions.registerInstruction ("enablelevelupmenu", "", opcodeEnableRest);
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu);
extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed);
extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar);
extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar);
extensions.registerInstruction ("togglefullhelp", "", opcodeToggleFullHelp);
extensions.registerInstruction ("tfh", "", opcodeToggleFullHelp);
extensions.registerInstruction ("showmap", "S", opcodeShowMap);
extensions.registerInstruction ("fillmap", "", opcodeFillMap);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeEnableBirthMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableBirthMenu,
new OpShowDialogue (MWGui::GM_Birth)); new OpShowDialogue (MWGui::GM_Birth));
interpreter.installSegment5 (opcodeEnableClassMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableClassMenu,
new OpShowDialogue (MWGui::GM_Class)); new OpShowDialogue (MWGui::GM_Class));
interpreter.installSegment5 (opcodeEnableNameMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableNameMenu,
new OpShowDialogue (MWGui::GM_Name)); new OpShowDialogue (MWGui::GM_Name));
interpreter.installSegment5 (opcodeEnableRaceMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableRaceMenu,
new OpShowDialogue (MWGui::GM_Race)); new OpShowDialogue (MWGui::GM_Race));
interpreter.installSegment5 (opcodeEnableStatsReviewMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableStatsReviewMenu,
new OpShowDialogue (MWGui::GM_Review)); new OpShowDialogue (MWGui::GM_Review));
interpreter.installSegment5 (opcodeEnableInventoryMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableInventoryMenu,
new OpEnableWindow (MWGui::GW_Inventory)); new OpEnableWindow (MWGui::GW_Inventory));
interpreter.installSegment5 (opcodeEnableMagicMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableMagicMenu,
new OpEnableWindow (MWGui::GW_Magic)); new OpEnableWindow (MWGui::GW_Magic));
interpreter.installSegment5 (opcodeEnableMapMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableMapMenu,
new OpEnableWindow (MWGui::GW_Map)); new OpEnableWindow (MWGui::GW_Map));
interpreter.installSegment5 (opcodeEnableStatsMenu, interpreter.installSegment5 (Compiler::Gui::opcodeEnableStatsMenu,
new OpEnableWindow (MWGui::GW_Stats)); new OpEnableWindow (MWGui::GW_Stats));
interpreter.installSegment5 (opcodeEnableRest, interpreter.installSegment5 (Compiler::Gui::opcodeEnableRest,
new OpEnableRest ()); new OpEnableRest ());
interpreter.installSegment5 (opcodeShowRestMenu, interpreter.installSegment5 (Compiler::Gui::opcodeShowRestMenu,
new OpShowDialogue (MWGui::GM_RestBed)); new OpShowDialogue (MWGui::GM_RestBed));
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); interpreter.installSegment5 (Compiler::Gui::opcodeGetButtonPressed, new OpGetButtonPressed);
interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar); interpreter.installSegment5 (Compiler::Gui::opcodeToggleFogOfWar, new OpToggleFogOfWar);
interpreter.installSegment5 (opcodeToggleFullHelp, new OpToggleFullHelp); interpreter.installSegment5 (Compiler::Gui::opcodeToggleFullHelp, new OpToggleFullHelp);
interpreter.installSegment5 (opcodeShowMap, new OpShowMap); interpreter.installSegment5 (Compiler::Gui::opcodeShowMap, new OpShowMap);
interpreter.installSegment5 (opcodeFillMap, new OpFillMap); interpreter.installSegment5 (Compiler::Gui::opcodeFillMap, new OpFillMap);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief GUI-related script functionality /// \brief GUI-related script functionality
namespace Gui namespace Gui
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -4,6 +4,7 @@
#include <libs/openengine/ogre/fader.hpp> #include <libs/openengine/ogre/fader.hpp>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -628,165 +629,62 @@ namespace MWScript
} }
}; };
const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075;
const int opcodeLock = 0x20004;
const int opcodeLockExplicit = 0x20005;
const int opcodeUnlock = 0x200008c;
const int opcodeUnlockExplicit = 0x200008d;
const int opcodeToggleCollisionDebug = 0x2000132;
const int opcodeToggleCollisionBoxes = 0x20001ac;
const int opcodeToggleWireframe = 0x200013b;
const int opcodeFadeIn = 0x200013c;
const int opcodeFadeOut = 0x200013d;
const int opcodeFadeTo = 0x200013e;
const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000146;
const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174;
const int opcodeGetPcSleep = 0x200019f;
const int opcodeWakeUpPc = 0x20001a2;
const int opcodeGetLocked = 0x20001c7;
const int opcodeGetLockedExplicit = 0x20001c8;
const int opcodeGetEffect = 0x20001cf;
const int opcodeGetEffectExplicit = 0x20001d0;
const int opcodeAddSoulGem = 0x20001f3;
const int opcodeAddSoulGemExplicit = 0x20001f4;
const int opcodeRemoveSoulGem = 0x20001f5;
const int opcodeRemoveSoulGemExplicit = 0x20001f6;
const int opcodeDrop = 0x20001f8;
const int opcodeDropExplicit = 0x20001f9;
const int opcodeDropSoulGem = 0x20001fa;
const int opcodeDropSoulGemExplicit = 0x20001fb;
const int opcodeGetAttacked = 0x20001d3;
const int opcodeGetAttackedExplicit = 0x20001d4;
const int opcodeGetWeaponDrawn = 0x20001d7;
const int opcodeGetWeaponDrawnExplicit = 0x20001d8;
const int opcodeGetSpellEffects = 0x20001db;
const int opcodeGetSpellEffectsExplicit = 0x20001dc;
const int opcodeGetCurrentTime = 0x20001dd;
const int opcodeSetDelete = 0x20001e5;
const int opcodeSetDeleteExplicit = 0x20001e6;
const int opcodeGetSquareRoot = 0x20001e7;
const int opcodeFall = 0x200020a;
const int opcodeFallExplicit = 0x200020b;
const int opcodeGetStandingPc = 0x200020c;
const int opcodeGetStandingPcExplicit = 0x200020d;
const int opcodeGetStandingActor = 0x200020e;
const int opcodeGetStandingActorExplicit = 0x200020f;
const int opcodeGetWindSpeed = 0x2000212;
const int opcodePlayBink = 0x20001f7;
const int opcodeHitOnMe = 0x2000213;
const int opcodeHitOnMeExplicit = 0x2000214;
const int opcodeDisableTeleporting = 0x2000215;
const int opcodeEnableTeleporting = 0x2000216;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerFunction ("xbox", 'l', "", opcodeXBox);
extensions.registerFunction ("onactivate", 'l', "", opcodeOnActivate);
extensions.registerInstruction ("activate", "", opcodeActivate);
extensions.registerInstruction ("lock", "/l", opcodeLock, opcodeLockExplicit);
extensions.registerInstruction ("unlock", "", opcodeUnlock, opcodeUnlockExplicit);
extensions.registerInstruction ("togglecollisionboxes", "", opcodeToggleCollisionBoxes);
extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
extensions.registerInstruction ("tcb", "", opcodeToggleCollisionBoxes);
extensions.registerInstruction ("tcg", "", opcodeToggleCollisionDebug);
extensions.registerInstruction ("twf", "", opcodeToggleWireframe);
extensions.registerInstruction ("togglewireframe", "", opcodeToggleWireframe);
extensions.registerInstruction ("fadein", "f", opcodeFadeIn);
extensions.registerInstruction ("fadeout", "f", opcodeFadeOut);
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
extensions.registerInstruction ("twa", "", opcodeToggleWater);
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc);
extensions.registerInstruction ("playbink", "Sl", opcodePlayBink);
extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit);
extensions.registerFunction ("geteffect", 'l', "l", opcodeGetEffect, opcodeGetEffectExplicit);
extensions.registerInstruction ("addsoulgem", "cc", opcodeAddSoulGem, opcodeAddSoulGemExplicit);
extensions.registerInstruction ("removesoulgem", "c", opcodeRemoveSoulGem, opcodeRemoveSoulGemExplicit);
extensions.registerInstruction ("drop", "cl", opcodeDrop, opcodeDropExplicit);
extensions.registerInstruction ("dropsoulgem", "c", opcodeDropSoulGem, opcodeDropSoulGemExplicit);
extensions.registerFunction ("getattacked", 'l', "", opcodeGetAttacked, opcodeGetAttackedExplicit);
extensions.registerFunction ("getweapondrawn", 'l', "", opcodeGetWeaponDrawn, opcodeGetWeaponDrawnExplicit);
extensions.registerFunction ("getspelleffects", 'l', "c", opcodeGetSpellEffects, opcodeGetSpellEffectsExplicit);
extensions.registerFunction ("getcurrenttime", 'f', "", opcodeGetCurrentTime);
extensions.registerInstruction ("setdelete", "l", opcodeSetDelete, opcodeSetDeleteExplicit);
extensions.registerFunction ("getsquareroot", 'f', "f", opcodeGetSquareRoot);
extensions.registerInstruction ("fall", "", opcodeFall, opcodeFallExplicit);
extensions.registerFunction ("getstandingpc", 'l', "", opcodeGetStandingPc, opcodeGetStandingPcExplicit);
extensions.registerFunction ("getstandingactor", 'l', "", opcodeGetStandingActor, opcodeGetStandingActorExplicit);
extensions.registerFunction ("getwindspeed", 'f', "", opcodeGetWindSpeed);
extensions.registerFunction ("hitonme", 'l', "S", opcodeHitOnMe, opcodeHitOnMeExplicit);
extensions.registerInstruction ("disableteleporting", "", opcodeDisableTeleporting);
extensions.registerInstruction ("enableteleporting", "", opcodeEnableTeleporting);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeXBox, new OpXBox); interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox);
interpreter.installSegment5 (opcodeOnActivate, new OpOnActivate); interpreter.installSegment5 (Compiler::Misc::opcodeOnActivate, new OpOnActivate);
interpreter.installSegment5 (opcodeActivate, new OpActivate); interpreter.installSegment5 (Compiler::Misc::opcodeActivate, new OpActivate);
interpreter.installSegment3 (opcodeLock, new OpLock<ImplicitRef>); interpreter.installSegment3 (Compiler::Misc::opcodeLock, new OpLock<ImplicitRef>);
interpreter.installSegment3 (opcodeLockExplicit, new OpLock<ExplicitRef>); interpreter.installSegment3 (Compiler::Misc::opcodeLockExplicit, new OpLock<ExplicitRef>);
interpreter.installSegment5 (opcodeUnlock, new OpUnlock<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeUnlock, new OpUnlock<ImplicitRef>);
interpreter.installSegment5 (opcodeUnlockExplicit, new OpUnlock<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeUnlockExplicit, new OpUnlock<ExplicitRef>);
interpreter.installSegment5 (opcodeToggleCollisionDebug, new OpToggleCollisionDebug); interpreter.installSegment5 (Compiler::Misc::opcodeToggleCollisionDebug, new OpToggleCollisionDebug);
interpreter.installSegment5 (opcodeToggleCollisionBoxes, new OpToggleCollisionBoxes); interpreter.installSegment5 (Compiler::Misc::opcodeToggleCollisionBoxes, new OpToggleCollisionBoxes);
interpreter.installSegment5 (opcodeToggleWireframe, new OpToggleWireframe); interpreter.installSegment5 (Compiler::Misc::opcodeToggleWireframe, new OpToggleWireframe);
interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn); interpreter.installSegment5 (Compiler::Misc::opcodeFadeIn, new OpFadeIn);
interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut); interpreter.installSegment5 (Compiler::Misc::opcodeFadeOut, new OpFadeOut);
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo); interpreter.installSegment5 (Compiler::Misc::opcodeFadeTo, new OpFadeTo);
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); interpreter.installSegment5 (Compiler::Misc::opcodeTogglePathgrid, new OpTogglePathgrid);
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); interpreter.installSegment5 (Compiler::Misc::opcodeToggleWater, new OpToggleWater);
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject); interpreter.installSegment5 (Compiler::Misc::opcodeDontSaveObject, new OpDontSaveObject);
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode); interpreter.installSegment5 (Compiler::Misc::opcodeToggleVanityMode, new OpToggleVanityMode);
interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep); interpreter.installSegment5 (Compiler::Misc::opcodeGetPcSleep, new OpGetPcSleep);
interpreter.installSegment5 (opcodeWakeUpPc, new OpWakeUpPc); interpreter.installSegment5 (Compiler::Misc::opcodeWakeUpPc, new OpWakeUpPc);
interpreter.installSegment5 (opcodePlayBink, new OpPlayBink); interpreter.installSegment5 (Compiler::Misc::opcodePlayBink, new OpPlayBink);
interpreter.installSegment5 (opcodeGetLocked, new OpGetLocked<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetLocked, new OpGetLocked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetLockedExplicit, new OpGetLocked<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetLockedExplicit, new OpGetLocked<ExplicitRef>);
interpreter.installSegment5 (opcodeGetEffect, new OpGetEffect<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetEffect, new OpGetEffect<ImplicitRef>);
interpreter.installSegment5 (opcodeGetEffectExplicit, new OpGetEffect<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetEffectExplicit, new OpGetEffect<ExplicitRef>);
interpreter.installSegment5 (opcodeAddSoulGem, new OpAddSoulGem<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeAddSoulGem, new OpAddSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeAddSoulGemExplicit, new OpAddSoulGem<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeAddSoulGemExplicit, new OpAddSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeRemoveSoulGem, new OpRemoveSoulGem<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeRemoveSoulGem, new OpRemoveSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeRemoveSoulGemExplicit, new OpRemoveSoulGem<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeRemoveSoulGemExplicit, new OpRemoveSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeDrop, new OpDrop<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeDrop, new OpDrop<ImplicitRef>);
interpreter.installSegment5 (opcodeDropExplicit, new OpDrop<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeDropExplicit, new OpDrop<ExplicitRef>);
interpreter.installSegment5 (opcodeDropSoulGem, new OpDropSoulGem<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeDropSoulGem, new OpDropSoulGem<ImplicitRef>);
interpreter.installSegment5 (opcodeDropSoulGemExplicit, new OpDropSoulGem<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeDropSoulGemExplicit, new OpDropSoulGem<ExplicitRef>);
interpreter.installSegment5 (opcodeGetAttacked, new OpGetAttacked<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetAttacked, new OpGetAttacked<ImplicitRef>);
interpreter.installSegment5 (opcodeGetAttackedExplicit, new OpGetAttacked<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetAttackedExplicit, new OpGetAttacked<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponDrawn, new OpGetWeaponDrawn<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetWeaponDrawn, new OpGetWeaponDrawn<ImplicitRef>);
interpreter.installSegment5 (opcodeGetWeaponDrawnExplicit, new OpGetWeaponDrawn<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetWeaponDrawnExplicit, new OpGetWeaponDrawn<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSpellEffects, new OpGetSpellEffects<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetSpellEffects, new OpGetSpellEffects<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSpellEffectsExplicit, new OpGetSpellEffects<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetSpellEffectsExplicit, new OpGetSpellEffects<ExplicitRef>);
interpreter.installSegment5 (opcodeGetCurrentTime, new OpGetCurrentTime); interpreter.installSegment5 (Compiler::Misc::opcodeGetCurrentTime, new OpGetCurrentTime);
interpreter.installSegment5 (opcodeSetDelete, new OpSetDelete<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeSetDelete, new OpSetDelete<ImplicitRef>);
interpreter.installSegment5 (opcodeSetDeleteExplicit, new OpSetDelete<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeSetDeleteExplicit, new OpSetDelete<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSquareRoot, new OpGetSquareRoot); interpreter.installSegment5 (Compiler::Misc::opcodeGetSquareRoot, new OpGetSquareRoot);
interpreter.installSegment5 (opcodeFall, new OpFall<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeFall, new OpFall<ImplicitRef>);
interpreter.installSegment5 (opcodeFallExplicit, new OpFall<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeFallExplicit, new OpFall<ExplicitRef>);
interpreter.installSegment5 (opcodeGetStandingPc, new OpGetStandingPc<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetStandingPc, new OpGetStandingPc<ImplicitRef>);
interpreter.installSegment5 (opcodeGetStandingPcExplicit, new OpGetStandingPc<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetStandingPcExplicit, new OpGetStandingPc<ExplicitRef>);
interpreter.installSegment5 (opcodeGetStandingActor, new OpGetStandingActor<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetStandingActor, new OpGetStandingActor<ImplicitRef>);
interpreter.installSegment5 (opcodeGetStandingActorExplicit, new OpGetStandingActor<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeGetStandingActorExplicit, new OpGetStandingActor<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWindSpeed, new OpGetWindSpeed); interpreter.installSegment5 (Compiler::Misc::opcodeGetWindSpeed, new OpGetWindSpeed);
interpreter.installSegment5 (opcodeHitOnMe, new OpHitOnMe<ImplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeHitOnMe, new OpHitOnMe<ImplicitRef>);
interpreter.installSegment5 (opcodeHitOnMeExplicit, new OpHitOnMe<ExplicitRef>); interpreter.installSegment5 (Compiler::Misc::opcodeHitOnMeExplicit, new OpHitOnMe<ExplicitRef>);
interpreter.installSegment5 (opcodeDisableTeleporting, new OpEnableTeleporting<false>); interpreter.installSegment5 (Compiler::Misc::opcodeDisableTeleporting, new OpEnableTeleporting<false>);
interpreter.installSegment5 (opcodeEnableTeleporting, new OpEnableTeleporting<true>); interpreter.installSegment5 (Compiler::Misc::opcodeEnableTeleporting, new OpEnableTeleporting<true>);
} }
} }
} }

View file

@ -15,8 +15,6 @@ namespace MWScript
{ {
namespace Misc namespace Misc
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -2,6 +2,7 @@
#include "skyextensions.hpp" #include "skyextensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -118,38 +119,17 @@ namespace MWScript
} }
}; };
const int opcodeToggleSky = 0x2000021;
const int opcodeTurnMoonWhite = 0x2000022;
const int opcodeTurnMoonRed = 0x2000023;
const int opcodeGetMasserPhase = 0x2000024;
const int opcodeGetSecundaPhase = 0x2000025;
const int opcodeGetCurrentWeather = 0x200013f;
const int opcodeChangeWeather = 0x2000140;
const int opcodeModRegion = 0x20026;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("togglesky", "", opcodeToggleSky);
extensions.registerInstruction ("ts", "", opcodeToggleSky);
extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite);
extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed);
extensions.registerInstruction ("changeweather", "Sl", opcodeChangeWeather);
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather);
extensions.registerInstruction ("modregion", "S/llllllllll", opcodeModRegion);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeToggleSky, new OpToggleSky); interpreter.installSegment5 (Compiler::Sky::opcodeToggleSky, new OpToggleSky);
interpreter.installSegment5 (opcodeTurnMoonWhite, new OpTurnMoonWhite); interpreter.installSegment5 (Compiler::Sky::opcodeTurnMoonWhite, new OpTurnMoonWhite);
interpreter.installSegment5 (opcodeTurnMoonRed, new OpTurnMoonRed); interpreter.installSegment5 (Compiler::Sky::opcodeTurnMoonRed, new OpTurnMoonRed);
interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase); interpreter.installSegment5 (Compiler::Sky::opcodeGetMasserPhase, new OpGetMasserPhase);
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase); interpreter.installSegment5 (Compiler::Sky::opcodeGetSecundaPhase, new OpGetSecundaPhase);
interpreter.installSegment5 (opcodeGetCurrentWeather, new OpGetCurrentWeather); interpreter.installSegment5 (Compiler::Sky::opcodeGetCurrentWeather, new OpGetCurrentWeather);
interpreter.installSegment5 (opcodeChangeWeather, new OpChangeWeather); interpreter.installSegment5 (Compiler::Sky::opcodeChangeWeather, new OpChangeWeather);
interpreter.installSegment3 (opcodeModRegion, new OpModRegion); interpreter.installSegment3 (Compiler::Sky::opcodeModRegion, new OpModRegion);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief sky-related script functionality /// \brief sky-related script functionality
namespace Sky namespace Sky
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -2,6 +2,7 @@
#include "extensions.hpp" #include "extensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -188,75 +189,34 @@ namespace MWScript
} }
}; };
const int opcodeSay = 0x2000001;
const int opcodeSayDone = 0x2000002;
const int opcodeStreamMusic = 0x2000003;
const int opcodePlaySound = 0x2000004;
const int opcodePlaySoundVP = 0x2000005;
const int opcodePlaySound3D = 0x2000006;
const int opcodePlaySound3DVP = 0x2000007;
const int opcodePlayLoopSound3D = 0x2000008;
const int opcodePlayLoopSound3DVP = 0x2000009;
const int opcodeStopSound = 0x200000a;
const int opcodeGetSoundPlaying = 0x200000b;
const int opcodeSayExplicit = 0x2000019;
const int opcodeSayDoneExplicit = 0x200001a;
const int opcodePlaySound3DExplicit = 0x200001b;
const int opcodePlaySound3DVPExplicit = 0x200001c;
const int opcodePlayLoopSound3DExplicit = 0x200001d;
const int opcodePlayLoopSound3DVPExplicit = 0x200001e;
const int opcodeStopSoundExplicit = 0x200001f;
const int opcodeGetSoundPlayingExplicit = 0x2000020;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("say", "SS", opcodeSay, opcodeSayExplicit);
extensions.registerFunction ("saydone", 'l', "", opcodeSayDone, opcodeSayDoneExplicit);
extensions.registerInstruction ("streammusic", "S", opcodeStreamMusic);
extensions.registerInstruction ("playsound", "c", opcodePlaySound);
extensions.registerInstruction ("playsoundvp", "cff", opcodePlaySoundVP);
extensions.registerInstruction ("playsound3d", "c", opcodePlaySound3D,
opcodePlaySound3DExplicit);
extensions.registerInstruction ("playsound3dvp", "cff", opcodePlaySound3DVP,
opcodePlaySound3DVPExplicit);
extensions.registerInstruction ("playloopsound3d", "c", opcodePlayLoopSound3D,
opcodePlayLoopSound3DExplicit);
extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP,
opcodePlayLoopSound3DVPExplicit);
extensions.registerInstruction ("stopsound", "c", opcodeStopSound,
opcodeStopSoundExplicit);
extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying,
opcodeGetSoundPlayingExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeSay, new OpSay<ImplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeSay, new OpSay<ImplicitRef>);
interpreter.installSegment5 (opcodeSayDone, new OpSayDone<ImplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeSayDone, new OpSayDone<ImplicitRef>);
interpreter.installSegment5 (opcodeStreamMusic, new OpStreamMusic); interpreter.installSegment5 (Compiler::Sound::opcodeStreamMusic, new OpStreamMusic);
interpreter.installSegment5 (opcodePlaySound, new OpPlaySound); interpreter.installSegment5 (Compiler::Sound::opcodePlaySound, new OpPlaySound);
interpreter.installSegment5 (opcodePlaySoundVP, new OpPlaySoundVP); interpreter.installSegment5 (Compiler::Sound::opcodePlaySoundVP, new OpPlaySoundVP);
interpreter.installSegment5 (opcodePlaySound3D, new OpPlaySound3D<ImplicitRef> (false)); interpreter.installSegment5 (Compiler::Sound::opcodePlaySound3D, new OpPlaySound3D<ImplicitRef> (false));
interpreter.installSegment5 (opcodePlaySound3DVP, new OpPlaySoundVP3D<ImplicitRef> (false)); interpreter.installSegment5 (Compiler::Sound::opcodePlaySound3DVP, new OpPlaySoundVP3D<ImplicitRef> (false));
interpreter.installSegment5 (opcodePlayLoopSound3D, new OpPlaySound3D<ImplicitRef> (true)); interpreter.installSegment5 (Compiler::Sound::opcodePlayLoopSound3D, new OpPlaySound3D<ImplicitRef> (true));
interpreter.installSegment5 (opcodePlayLoopSound3DVP, interpreter.installSegment5 (Compiler::Sound::opcodePlayLoopSound3DVP,
new OpPlaySoundVP3D<ImplicitRef> (true)); new OpPlaySoundVP3D<ImplicitRef> (true));
interpreter.installSegment5 (opcodeStopSound, new OpStopSound<ImplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeStopSound, new OpStopSound<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSoundPlaying, new OpGetSoundPlaying<ImplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeGetSoundPlaying, new OpGetSoundPlaying<ImplicitRef>);
interpreter.installSegment5 (opcodeSayExplicit, new OpSay<ExplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeSayExplicit, new OpSay<ExplicitRef>);
interpreter.installSegment5 (opcodeSayDoneExplicit, new OpSayDone<ExplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeSayDoneExplicit, new OpSayDone<ExplicitRef>);
interpreter.installSegment5 (opcodePlaySound3DExplicit, interpreter.installSegment5 (Compiler::Sound::opcodePlaySound3DExplicit,
new OpPlaySound3D<ExplicitRef> (false)); new OpPlaySound3D<ExplicitRef> (false));
interpreter.installSegment5 (opcodePlaySound3DVPExplicit, interpreter.installSegment5 (Compiler::Sound::opcodePlaySound3DVPExplicit,
new OpPlaySoundVP3D<ExplicitRef> (false)); new OpPlaySoundVP3D<ExplicitRef> (false));
interpreter.installSegment5 (opcodePlayLoopSound3DExplicit, interpreter.installSegment5 (Compiler::Sound::opcodePlayLoopSound3DExplicit,
new OpPlaySound3D<ExplicitRef> (true)); new OpPlaySound3D<ExplicitRef> (true));
interpreter.installSegment5 (opcodePlayLoopSound3DVPExplicit, interpreter.installSegment5 (Compiler::Sound::opcodePlayLoopSound3DVPExplicit,
new OpPlaySoundVP3D<ExplicitRef> (true)); new OpPlaySoundVP3D<ExplicitRef> (true));
interpreter.installSegment5 (opcodeStopSoundExplicit, new OpStopSound<ExplicitRef>); interpreter.installSegment5 (Compiler::Sound::opcodeStopSoundExplicit, new OpStopSound<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSoundPlayingExplicit, interpreter.installSegment5 (Compiler::Sound::opcodeGetSoundPlayingExplicit,
new OpGetSoundPlaying<ExplicitRef>); new OpGetSoundPlaying<ExplicitRef>);
} }
} }

View file

@ -16,9 +16,6 @@ namespace MWScript
namespace Sound namespace Sound
{ {
// Script-extensions related to sound // Script-extensions related to sound
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -10,6 +10,7 @@
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -1068,348 +1069,131 @@ namespace MWScript
} }
}; };
const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027;
const int opcodeGetAttributeExplicit = 0x200002f;
const int opcodeSetAttribute = 0x2000037;
const int opcodeSetAttributeExplicit = 0x200003f;
const int opcodeModAttribute = 0x2000047;
const int opcodeModAttributeExplicit = 0x200004f;
const int numberOfDynamics = 3;
const int opcodeGetDynamic = 0x2000057;
const int opcodeGetDynamicExplicit = 0x200005a;
const int opcodeSetDynamic = 0x200005d;
const int opcodeSetDynamicExplicit = 0x2000060;
const int opcodeModDynamic = 0x2000063;
const int opcodeModDynamicExplicit = 0x2000066;
const int opcodeModCurrentDynamic = 0x2000069;
const int opcodeModCurrentDynamicExplicit = 0x200006c;
const int opcodeGetDynamicGetRatio = 0x200006f;
const int opcodeGetDynamicGetRatioExplicit = 0x2000072;
const int numberOfSkills = 27;
const int opcodeGetSkill = 0x200008e;
const int opcodeGetSkillExplicit = 0x20000a9;
const int opcodeSetSkill = 0x20000c4;
const int opcodeSetSkillExplicit = 0x20000df;
const int opcodeModSkill = 0x20000fa;
const int opcodeModSkillExplicit = 0x2000115;
const int opcodeGetPCCrimeLevel = 0x20001ec;
const int opcodeSetPCCrimeLevel = 0x20001ed;
const int opcodeModPCCrimeLevel = 0x20001ee;
const int opcodeAddSpell = 0x2000147;
const int opcodeAddSpellExplicit = 0x2000148;
const int opcodeRemoveSpell = 0x2000149;
const int opcodeRemoveSpellExplicit = 0x200014a;
const int opcodeGetSpell = 0x200014b;
const int opcodeGetSpellExplicit = 0x200014c;
const int opcodePCRaiseRank = 0x2000b;
const int opcodePCLowerRank = 0x2000c;
const int opcodePCJoinFaction = 0x2000d;
const int opcodeGetPCRank = 0x2000e;
const int opcodeGetPCRankExplicit = 0x2000f;
const int opcodeModDisposition = 0x200014d;
const int opcodeModDispositionExplicit = 0x200014e;
const int opcodeSetDisposition = 0x20001a4;
const int opcodeSetDispositionExplicit = 0x20001a5;
const int opcodeGetDisposition = 0x20001a6;
const int opcodeGetDispositionExplicit = 0x20001a7;
const int opcodeGetLevel = 0x200018c;
const int opcodeGetLevelExplicit = 0x200018d;
const int opcodeSetLevel = 0x200018e;
const int opcodeSetLevelExplicit = 0x200018f;
const int opcodeGetDeadCount = 0x20001a3;
const int opcodeGetPCFacRep = 0x20012;
const int opcodeGetPCFacRepExplicit = 0x20013;
const int opcodeSetPCFacRep = 0x20014;
const int opcodeSetPCFacRepExplicit = 0x20015;
const int opcodeModPCFacRep = 0x20016;
const int opcodeModPCFacRepExplicit = 0x20017;
const int opcodeGetCommonDisease = 0x20001a8;
const int opcodeGetCommonDiseaseExplicit = 0x20001a9;
const int opcodeGetBlightDisease = 0x20001aa;
const int opcodeGetBlightDiseaseExplicit = 0x20001ab;
const int opcodeGetRace = 0x20001d9;
const int opcodeGetRaceExplicit = 0x20001da;
const int opcodeGetWerewolfKills = 0x20001e2;
const int opcodePcExpelled = 0x20018;
const int opcodePcExpelledExplicit = 0x20019;
const int opcodePcExpell = 0x2001a;
const int opcodePcExpellExplicit = 0x2001b;
const int opcodePcClearExpelled = 0x2001c;
const int opcodePcClearExpelledExplicit = 0x2001d;
const int opcodeRaiseRank = 0x20001e8;
const int opcodeRaiseRankExplicit = 0x20001e9;
const int opcodeLowerRank = 0x20001ea;
const int opcodeLowerRankExplicit = 0x20001eb;
const int opcodeOnDeath = 0x20001fc;
const int opcodeOnDeathExplicit = 0x2000205;
const int opcodeIsWerewolf = 0x20001fd;
const int opcodeIsWerewolfExplicit = 0x20001fe;
const int opcodeBecomeWerewolf = 0x2000217;
const int opcodeBecomeWerewolfExplicit = 0x2000218;
const int opcodeUndoWerewolf = 0x2000219;
const int opcodeUndoWerewolfExplicit = 0x200021a;
void registerExtensions (Compiler::Extensions& extensions)
{
static const char *attributes[numberOfAttributes] =
{
"strength", "intelligence", "willpower", "agility", "speed", "endurance",
"personality", "luck"
};
static const char *dynamics[numberOfDynamics] =
{
"health", "magicka", "fatigue"
};
static const char *skills[numberOfSkills] =
{
"block", "armorer", "mediumarmor", "heavyarmor", "bluntweapon",
"longblade", "axe", "spear", "athletics", "enchant", "destruction",
"alteration", "illusion", "conjuration", "mysticism",
"restoration", "alchemy", "unarmored", "security", "sneak",
"acrobatics", "lightarmor", "shortblade", "marksman",
"mercantile", "speechcraft", "handtohand"
};
std::string get ("get");
std::string set ("set");
std::string mod ("mod");
std::string modCurrent ("modcurrent");
std::string getRatio ("getratio");
for (int i=0; i<numberOfAttributes; ++i)
{
extensions.registerFunction (get + attributes[i], 'l', "",
opcodeGetAttribute+i, opcodeGetAttributeExplicit+i);
extensions.registerInstruction (set + attributes[i], "l",
opcodeSetAttribute+i, opcodeSetAttributeExplicit+i);
extensions.registerInstruction (mod + attributes[i], "l",
opcodeModAttribute+i, opcodeModAttributeExplicit+i);
}
for (int i=0; i<numberOfDynamics; ++i)
{
extensions.registerFunction (get + dynamics[i], 'f', "",
opcodeGetDynamic+i, opcodeGetDynamicExplicit+i);
extensions.registerInstruction (set + dynamics[i], "f",
opcodeSetDynamic+i, opcodeSetDynamicExplicit+i);
extensions.registerInstruction (mod + dynamics[i], "f",
opcodeModDynamic+i, opcodeModDynamicExplicit+i);
extensions.registerInstruction (modCurrent + dynamics[i], "f",
opcodeModCurrentDynamic+i, opcodeModCurrentDynamicExplicit+i);
extensions.registerFunction (get + dynamics[i] + getRatio, 'f', "",
opcodeGetDynamicGetRatio+i, opcodeGetDynamicGetRatioExplicit+i);
}
for (int i=0; i<numberOfSkills; ++i)
{
extensions.registerFunction (get + skills[i], 'l', "",
opcodeGetSkill+i, opcodeGetSkillExplicit+i);
extensions.registerInstruction (set + skills[i], "l",
opcodeSetSkill+i, opcodeSetSkillExplicit+i);
extensions.registerInstruction (mod + skills[i], "l",
opcodeModSkill+i, opcodeModSkillExplicit+i);
}
extensions.registerFunction ("getpccrimelevel", 'f', "", opcodeGetPCCrimeLevel);
extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel);
extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel);
extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit);
extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
opcodeRemoveSpellExplicit);
extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit);
extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank);
extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank);
extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction);
extensions.registerInstruction ("moddisposition","l",opcodeModDisposition,
opcodeModDispositionExplicit);
extensions.registerInstruction ("setdisposition","l",opcodeSetDisposition,
opcodeSetDispositionExplicit);
extensions.registerFunction ("getdisposition",'l', "",opcodeGetDisposition,
opcodeGetDispositionExplicit);
extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit);
extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit);
extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit);
extensions.registerFunction ("getdeadcount", 'l', "c", opcodeGetDeadCount);
extensions.registerFunction ("getpcfacrep", 'l', "/c", opcodeGetPCFacRep, opcodeGetPCFacRepExplicit);
extensions.registerInstruction ("setpcfacrep", "l/c", opcodeSetPCFacRep, opcodeSetPCFacRepExplicit);
extensions.registerInstruction ("modpcfacrep", "l/c", opcodeModPCFacRep, opcodeModPCFacRepExplicit);
extensions.registerFunction ("getcommondisease", 'l', "", opcodeGetCommonDisease,
opcodeGetCommonDiseaseExplicit);
extensions.registerFunction ("getblightdisease", 'l', "", opcodeGetBlightDisease,
opcodeGetBlightDiseaseExplicit);
extensions.registerFunction ("getrace", 'l', "c", opcodeGetRace,
opcodeGetRaceExplicit);
extensions.registerFunction ("getwerewolfkills", 'f', "", opcodeGetWerewolfKills);
extensions.registerFunction ("pcexpelled", 'l', "/S", opcodePcExpelled, opcodePcExpelledExplicit);
extensions.registerInstruction ("pcexpell", "/S", opcodePcExpell, opcodePcExpellExplicit);
extensions.registerInstruction ("pcclearexpelled", "/S", opcodePcClearExpelled, opcodePcClearExpelledExplicit);
extensions.registerInstruction ("raiserank", "", opcodeRaiseRank, opcodeRaiseRankExplicit);
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath, opcodeOnDeathExplicit);
extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit);
extensions.registerInstruction("becomewerewolf", "", opcodeBecomeWerewolf, opcodeBecomeWerewolfExplicit);
extensions.registerInstruction("undowerewolf", "", opcodeUndoWerewolf, opcodeUndoWerewolfExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
for (int i=0; i<numberOfAttributes; ++i) for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i)
{ {
interpreter.installSegment5 (opcodeGetAttribute+i, new OpGetAttribute<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeGetAttribute+i, new OpGetAttribute<ImplicitRef> (i));
interpreter.installSegment5 (opcodeGetAttributeExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeGetAttributeExplicit+i,
new OpGetAttribute<ExplicitRef> (i)); new OpGetAttribute<ExplicitRef> (i));
interpreter.installSegment5 (opcodeSetAttribute+i, new OpSetAttribute<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeSetAttribute+i, new OpSetAttribute<ImplicitRef> (i));
interpreter.installSegment5 (opcodeSetAttributeExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeSetAttributeExplicit+i,
new OpSetAttribute<ExplicitRef> (i)); new OpSetAttribute<ExplicitRef> (i));
interpreter.installSegment5 (opcodeModAttribute+i, new OpModAttribute<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeModAttribute+i, new OpModAttribute<ImplicitRef> (i));
interpreter.installSegment5 (opcodeModAttributeExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeModAttributeExplicit+i,
new OpModAttribute<ExplicitRef> (i)); new OpModAttribute<ExplicitRef> (i));
} }
for (int i=0; i<numberOfDynamics; ++i) for (int i=0; i<Compiler::Stats::numberOfDynamics; ++i)
{ {
interpreter.installSegment5 (opcodeGetDynamic+i, new OpGetDynamic<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamic+i, new OpGetDynamic<ImplicitRef> (i));
interpreter.installSegment5 (opcodeGetDynamicExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamicExplicit+i,
new OpGetDynamic<ExplicitRef> (i)); new OpGetDynamic<ExplicitRef> (i));
interpreter.installSegment5 (opcodeSetDynamic+i, new OpSetDynamic<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeSetDynamic+i, new OpSetDynamic<ImplicitRef> (i));
interpreter.installSegment5 (opcodeSetDynamicExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeSetDynamicExplicit+i,
new OpSetDynamic<ExplicitRef> (i)); new OpSetDynamic<ExplicitRef> (i));
interpreter.installSegment5 (opcodeModDynamic+i, new OpModDynamic<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeModDynamic+i, new OpModDynamic<ImplicitRef> (i));
interpreter.installSegment5 (opcodeModDynamicExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeModDynamicExplicit+i,
new OpModDynamic<ExplicitRef> (i)); new OpModDynamic<ExplicitRef> (i));
interpreter.installSegment5 (opcodeModCurrentDynamic+i, interpreter.installSegment5 (Compiler::Stats::opcodeModCurrentDynamic+i,
new OpModCurrentDynamic<ImplicitRef> (i)); new OpModCurrentDynamic<ImplicitRef> (i));
interpreter.installSegment5 (opcodeModCurrentDynamicExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeModCurrentDynamicExplicit+i,
new OpModCurrentDynamic<ExplicitRef> (i)); new OpModCurrentDynamic<ExplicitRef> (i));
interpreter.installSegment5 (opcodeGetDynamicGetRatio+i, interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamicGetRatio+i,
new OpGetDynamicGetRatio<ImplicitRef> (i)); new OpGetDynamicGetRatio<ImplicitRef> (i));
interpreter.installSegment5 (opcodeGetDynamicGetRatioExplicit+i, interpreter.installSegment5 (Compiler::Stats::opcodeGetDynamicGetRatioExplicit+i,
new OpGetDynamicGetRatio<ExplicitRef> (i)); new OpGetDynamicGetRatio<ExplicitRef> (i));
} }
for (int i=0; i<numberOfSkills; ++i) for (int i=0; i<Compiler::Stats::numberOfSkills; ++i)
{ {
interpreter.installSegment5 (opcodeGetSkill+i, new OpGetSkill<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeGetSkill+i, new OpGetSkill<ImplicitRef> (i));
interpreter.installSegment5 (opcodeGetSkillExplicit+i, new OpGetSkill<ExplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeGetSkillExplicit+i, new OpGetSkill<ExplicitRef> (i));
interpreter.installSegment5 (opcodeSetSkill+i, new OpSetSkill<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeSetSkill+i, new OpSetSkill<ImplicitRef> (i));
interpreter.installSegment5 (opcodeSetSkillExplicit+i, new OpSetSkill<ExplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeSetSkillExplicit+i, new OpSetSkill<ExplicitRef> (i));
interpreter.installSegment5 (opcodeModSkill+i, new OpModSkill<ImplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeModSkill+i, new OpModSkill<ImplicitRef> (i));
interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkill<ExplicitRef> (i)); interpreter.installSegment5 (Compiler::Stats::opcodeModSkillExplicit+i, new OpModSkill<ExplicitRef> (i));
} }
interpreter.installSegment5 (opcodeGetPCCrimeLevel, new OpGetPCCrimeLevel); interpreter.installSegment5 (Compiler::Stats::opcodeGetPCCrimeLevel, new OpGetPCCrimeLevel);
interpreter.installSegment5 (opcodeSetPCCrimeLevel, new OpSetPCCrimeLevel); interpreter.installSegment5 (Compiler::Stats::opcodeSetPCCrimeLevel, new OpSetPCCrimeLevel);
interpreter.installSegment5 (opcodeModPCCrimeLevel, new OpModPCCrimeLevel); interpreter.installSegment5 (Compiler::Stats::opcodeModPCCrimeLevel, new OpModPCCrimeLevel);
interpreter.installSegment5 (opcodeAddSpell, new OpAddSpell<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeAddSpell, new OpAddSpell<ImplicitRef>);
interpreter.installSegment5 (opcodeAddSpellExplicit, new OpAddSpell<ExplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeAddSpellExplicit, new OpAddSpell<ExplicitRef>);
interpreter.installSegment5 (opcodeRemoveSpell, new OpRemoveSpell<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpell, new OpRemoveSpell<ImplicitRef>);
interpreter.installSegment5 (opcodeRemoveSpellExplicit, interpreter.installSegment5 (Compiler::Stats::opcodeRemoveSpellExplicit,
new OpRemoveSpell<ExplicitRef>); new OpRemoveSpell<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); interpreter.installSegment5 (Compiler::Stats::opcodeGetSpell, new OpGetSpell<ImplicitRef>);
interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); interpreter.installSegment5 (Compiler::Stats::opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction);
interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank<ImplicitRef>);
interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank<ExplicitRef>);
interpreter.installSegment5(opcodeModDisposition,new OpModDisposition<ImplicitRef>); interpreter.installSegment3(Compiler::Stats::opcodePCRaiseRank,new OpPCRaiseRank);
interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition<ExplicitRef>); interpreter.installSegment3(Compiler::Stats::opcodePCLowerRank,new OpPCLowerRank);
interpreter.installSegment5(opcodeSetDisposition,new OpSetDisposition<ImplicitRef>); interpreter.installSegment3(Compiler::Stats::opcodePCJoinFaction,new OpPCJoinFaction);
interpreter.installSegment5(opcodeSetDispositionExplicit,new OpSetDisposition<ExplicitRef>); interpreter.installSegment3(Compiler::Stats::opcodeGetPCRank,new OpGetPCRank<ImplicitRef>);
interpreter.installSegment5(opcodeGetDisposition,new OpGetDisposition<ImplicitRef>); interpreter.installSegment3(Compiler::Stats::opcodeGetPCRankExplicit,new OpGetPCRank<ExplicitRef>);
interpreter.installSegment5(opcodeGetDispositionExplicit,new OpGetDisposition<ExplicitRef>);
interpreter.installSegment5 (opcodeGetLevel, new OpGetLevel<ImplicitRef>); interpreter.installSegment5(Compiler::Stats::opcodeModDisposition,new OpModDisposition<ImplicitRef>);
interpreter.installSegment5 (opcodeGetLevelExplicit, new OpGetLevel<ExplicitRef>); interpreter.installSegment5(Compiler::Stats::opcodeModDispositionExplicit,new OpModDisposition<ExplicitRef>);
interpreter.installSegment5 (opcodeSetLevel, new OpSetLevel<ImplicitRef>); interpreter.installSegment5(Compiler::Stats::opcodeSetDisposition,new OpSetDisposition<ImplicitRef>);
interpreter.installSegment5 (opcodeSetLevelExplicit, new OpSetLevel<ExplicitRef>); interpreter.installSegment5(Compiler::Stats::opcodeSetDispositionExplicit,new OpSetDisposition<ExplicitRef>);
interpreter.installSegment5(Compiler::Stats::opcodeGetDisposition,new OpGetDisposition<ImplicitRef>);
interpreter.installSegment5(Compiler::Stats::opcodeGetDispositionExplicit,new OpGetDisposition<ExplicitRef>);
interpreter.installSegment5 (opcodeGetDeadCount, new OpGetDeadCount); interpreter.installSegment5 (Compiler::Stats::opcodeGetLevel, new OpGetLevel<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetLevelExplicit, new OpGetLevel<ExplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeSetLevel, new OpSetLevel<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeSetLevelExplicit, new OpSetLevel<ExplicitRef>);
interpreter.installSegment3 (opcodeGetPCFacRep, new OpGetPCFacRep<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeGetDeadCount, new OpGetDeadCount);
interpreter.installSegment3 (opcodeGetPCFacRepExplicit, new OpGetPCFacRep<ExplicitRef>);
interpreter.installSegment3 (opcodeSetPCFacRep, new OpSetPCFacRep<ImplicitRef>);
interpreter.installSegment3 (opcodeSetPCFacRepExplicit, new OpSetPCFacRep<ExplicitRef>);
interpreter.installSegment3 (opcodeModPCFacRep, new OpModPCFacRep<ImplicitRef>);
interpreter.installSegment3 (opcodeModPCFacRepExplicit, new OpModPCFacRep<ExplicitRef>);
interpreter.installSegment5 (opcodeGetCommonDisease, new OpGetCommonDisease<ImplicitRef>); interpreter.installSegment3 (Compiler::Stats::opcodeGetPCFacRep, new OpGetPCFacRep<ImplicitRef>);
interpreter.installSegment5 (opcodeGetCommonDiseaseExplicit, new OpGetCommonDisease<ExplicitRef>); interpreter.installSegment3 (Compiler::Stats::opcodeGetPCFacRepExplicit, new OpGetPCFacRep<ExplicitRef>);
interpreter.installSegment5 (opcodeGetBlightDisease, new OpGetBlightDisease<ImplicitRef>); interpreter.installSegment3 (Compiler::Stats::opcodeSetPCFacRep, new OpSetPCFacRep<ImplicitRef>);
interpreter.installSegment5 (opcodeGetBlightDiseaseExplicit, new OpGetBlightDisease<ExplicitRef>); interpreter.installSegment3 (Compiler::Stats::opcodeSetPCFacRepExplicit, new OpSetPCFacRep<ExplicitRef>);
interpreter.installSegment3 (Compiler::Stats::opcodeModPCFacRep, new OpModPCFacRep<ImplicitRef>);
interpreter.installSegment3 (Compiler::Stats::opcodeModPCFacRepExplicit, new OpModPCFacRep<ExplicitRef>);
interpreter.installSegment5 (opcodeGetRace, new OpGetRace<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeGetCommonDisease, new OpGetCommonDisease<ImplicitRef>);
interpreter.installSegment5 (opcodeGetRaceExplicit, new OpGetRace<ExplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeGetCommonDiseaseExplicit, new OpGetCommonDisease<ExplicitRef>);
interpreter.installSegment5 (opcodeGetWerewolfKills, new OpGetWerewolfKills); interpreter.installSegment5 (Compiler::Stats::opcodeGetBlightDisease, new OpGetBlightDisease<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetBlightDiseaseExplicit, new OpGetBlightDisease<ExplicitRef>);
interpreter.installSegment3 (opcodePcExpelled, new OpPcExpelled<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeGetRace, new OpGetRace<ImplicitRef>);
interpreter.installSegment3 (opcodePcExpelledExplicit, new OpPcExpelled<ExplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeGetRaceExplicit, new OpGetRace<ExplicitRef>);
interpreter.installSegment3 (opcodePcExpell, new OpPcExpell<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeGetWerewolfKills, new OpGetWerewolfKills);
interpreter.installSegment3 (opcodePcExpellExplicit, new OpPcExpell<ExplicitRef>);
interpreter.installSegment3 (opcodePcClearExpelled, new OpPcClearExpelled<ImplicitRef>);
interpreter.installSegment3 (opcodePcClearExpelledExplicit, new OpPcClearExpelled<ExplicitRef>);
interpreter.installSegment5 (opcodeRaiseRank, new OpRaiseRank<ImplicitRef>);
interpreter.installSegment5 (opcodeRaiseRankExplicit, new OpRaiseRank<ExplicitRef>);
interpreter.installSegment5 (opcodeLowerRank, new OpLowerRank<ImplicitRef>);
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath<ImplicitRef>); interpreter.installSegment3 (Compiler::Stats::opcodePcExpelled, new OpPcExpelled<ImplicitRef>);
interpreter.installSegment5 (opcodeOnDeathExplicit, new OpOnDeath<ExplicitRef>); interpreter.installSegment3 (Compiler::Stats::opcodePcExpelledExplicit, new OpPcExpelled<ExplicitRef>);
interpreter.installSegment3 (Compiler::Stats::opcodePcExpell, new OpPcExpell<ImplicitRef>);
interpreter.installSegment3 (Compiler::Stats::opcodePcExpellExplicit, new OpPcExpell<ExplicitRef>);
interpreter.installSegment3 (Compiler::Stats::opcodePcClearExpelled, new OpPcClearExpelled<ImplicitRef>);
interpreter.installSegment3 (Compiler::Stats::opcodePcClearExpelledExplicit, new OpPcClearExpelled<ExplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeRaiseRank, new OpRaiseRank<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeRaiseRankExplicit, new OpRaiseRank<ExplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeLowerRank, new OpLowerRank<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
interpreter.installSegment5 (opcodeIsWerewolf, new OpIsWerewolf<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeOnDeath, new OpOnDeath<ImplicitRef>);
interpreter.installSegment5 (opcodeIsWerewolfExplicit, new OpIsWerewolf<ExplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeOnDeathExplicit, new OpOnDeath<ExplicitRef>);
interpreter.installSegment5 (opcodeBecomeWerewolf, new OpSetWerewolf<ImplicitRef, true>); interpreter.installSegment5 (Compiler::Stats::opcodeIsWerewolf, new OpIsWerewolf<ImplicitRef>);
interpreter.installSegment5 (opcodeBecomeWerewolfExplicit, new OpSetWerewolf<ExplicitRef, true>); interpreter.installSegment5 (Compiler::Stats::opcodeIsWerewolfExplicit, new OpIsWerewolf<ExplicitRef>);
interpreter.installSegment5 (opcodeUndoWerewolf, new OpSetWerewolf<ImplicitRef, false>);
interpreter.installSegment5 (opcodeUndoWerewolfExplicit, new OpSetWerewolf<ExplicitRef, false>); interpreter.installSegment5 (Compiler::Stats::opcodeBecomeWerewolf, new OpSetWerewolf<ImplicitRef, true>);
interpreter.installSegment5 (Compiler::Stats::opcodeBecomeWerewolfExplicit, new OpSetWerewolf<ExplicitRef, true>);
interpreter.installSegment5 (Compiler::Stats::opcodeUndoWerewolf, new OpSetWerewolf<ImplicitRef, false>);
interpreter.installSegment5 (Compiler::Stats::opcodeUndoWerewolfExplicit, new OpSetWerewolf<ExplicitRef, false>);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief stats-related script functionality (creatures and NPCs) /// \brief stats-related script functionality (creatures and NPCs)
namespace Stats namespace Stats
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -7,6 +7,7 @@
#include <components/esm/loadcell.hpp> #include <components/esm/loadcell.hpp>
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -707,108 +708,45 @@ namespace MWScript
}; };
const int opcodeSetScale = 0x2000164;
const int opcodeSetScaleExplicit = 0x2000165;
const int opcodeSetAngle = 0x2000166;
const int opcodeSetAngleExplicit = 0x2000167;
const int opcodeGetScale = 0x2000168;
const int opcodeGetScaleExplicit = 0x2000169;
const int opcodeGetAngle = 0x200016a;
const int opcodeGetAngleExplicit = 0x200016b;
const int opcodeGetPos = 0x2000190;
const int opcodeGetPosExplicit = 0x2000191;
const int opcodeSetPos = 0x2000192;
const int opcodeSetPosExplicit = 0x2000193;
const int opcodeGetStartingPos = 0x2000194;
const int opcodeGetStartingPosExplicit = 0x2000195;
const int opcodeGetStartingAngle = 0x2000210;
const int opcodeGetStartingAngleExplicit = 0x2000211;
const int opcodePosition = 0x2000196;
const int opcodePositionExplicit = 0x2000197;
const int opcodePositionCell = 0x2000198;
const int opcodePositionCellExplicit = 0x2000199;
const int opcodePlaceItemCell = 0x200019a;
const int opcodePlaceItem = 0x200019b;
const int opcodePlaceAtPc = 0x200019c;
const int opcodePlaceAtMe = 0x200019d;
const int opcodePlaceAtMeExplicit = 0x200019e;
const int opcodeModScale = 0x20001e3;
const int opcodeModScaleExplicit = 0x20001e4;
const int opcodeRotate = 0x20001ff;
const int opcodeRotateExplicit = 0x2000200;
const int opcodeRotateWorld = 0x2000201;
const int opcodeRotateWorldExplicit = 0x2000202;
const int opcodeSetAtStart = 0x2000203;
const int opcodeSetAtStartExplicit = 0x2000204;
const int opcodeMove = 0x2000206;
const int opcodeMoveExplicit = 0x2000207;
const int opcodeMoveWorld = 0x2000208;
const int opcodeMoveWorldExplicit = 0x2000209;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction("setscale","f",opcodeSetScale,opcodeSetScaleExplicit);
extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit);
extensions.registerInstruction("setangle","cf",opcodeSetAngle,opcodeSetAngleExplicit);
extensions.registerFunction("getangle",'f',"c",opcodeGetAngle,opcodeGetAngleExplicit);
extensions.registerInstruction("setpos","cf",opcodeSetPos,opcodeSetPosExplicit);
extensions.registerFunction("getpos",'f',"c",opcodeGetPos,opcodeGetPosExplicit);
extensions.registerFunction("getstartingpos",'f',"c",opcodeGetStartingPos,opcodeGetStartingPosExplicit);
extensions.registerInstruction("position","ffff",opcodePosition,opcodePositionExplicit);
extensions.registerInstruction("positioncell","ffffc",opcodePositionCell,opcodePositionCellExplicit);
extensions.registerInstruction("placeitemcell","ccffff",opcodePlaceItemCell);
extensions.registerInstruction("placeitem","cffff",opcodePlaceItem);
extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc);
extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit);
extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit);
extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit);
extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit);
extensions.registerInstruction("setatstart","",opcodeSetAtStart,opcodeSetAtStartExplicit);
extensions.registerInstruction("move","cf",opcodeMove,opcodeMoveExplicit);
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5(opcodeSetScale,new OpSetScale<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetScale,new OpSetScale<ImplicitRef>);
interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetScaleExplicit,new OpSetScale<ExplicitRef>);
interpreter.installSegment5(opcodeSetAngle,new OpSetAngle<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetAngle,new OpSetAngle<ImplicitRef>);
interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetAngleExplicit,new OpSetAngle<ExplicitRef>);
interpreter.installSegment5(opcodeGetScale,new OpGetScale<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetScale,new OpGetScale<ImplicitRef>);
interpreter.installSegment5(opcodeGetScaleExplicit,new OpGetScale<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetScaleExplicit,new OpGetScale<ExplicitRef>);
interpreter.installSegment5(opcodeGetAngle,new OpGetAngle<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetAngle,new OpGetAngle<ImplicitRef>);
interpreter.installSegment5(opcodeGetAngleExplicit,new OpGetAngle<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetAngleExplicit,new OpGetAngle<ExplicitRef>);
interpreter.installSegment5(opcodeGetPos,new OpGetPos<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetPos,new OpGetPos<ImplicitRef>);
interpreter.installSegment5(opcodeGetPosExplicit,new OpGetPos<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetPosExplicit,new OpGetPos<ExplicitRef>);
interpreter.installSegment5(opcodeSetPos,new OpSetPos<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetPos,new OpSetPos<ImplicitRef>);
interpreter.installSegment5(opcodeSetPosExplicit,new OpSetPos<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetPosExplicit,new OpSetPos<ExplicitRef>);
interpreter.installSegment5(opcodeGetStartingPos,new OpGetStartingPos<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingPos,new OpGetStartingPos<ImplicitRef>);
interpreter.installSegment5(opcodeGetStartingPosExplicit,new OpGetStartingPos<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingPosExplicit,new OpGetStartingPos<ExplicitRef>);
interpreter.installSegment5(opcodePosition,new OpPosition<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePosition,new OpPosition<ImplicitRef>);
interpreter.installSegment5(opcodePositionExplicit,new OpPosition<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePositionExplicit,new OpPosition<ExplicitRef>);
interpreter.installSegment5(opcodePositionCell,new OpPositionCell<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePositionCell,new OpPositionCell<ImplicitRef>);
interpreter.installSegment5(opcodePositionCellExplicit,new OpPositionCell<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePositionCellExplicit,new OpPositionCell<ExplicitRef>);
interpreter.installSegment5(opcodePlaceItemCell,new OpPlaceItemCell<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePlaceItemCell,new OpPlaceItemCell<ImplicitRef>);
interpreter.installSegment5(opcodePlaceItem,new OpPlaceItem<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePlaceItem,new OpPlaceItem<ImplicitRef>);
interpreter.installSegment5(opcodePlaceAtPc,new OpPlaceAtPc<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePlaceAtPc,new OpPlaceAtPc<ImplicitRef>);
interpreter.installSegment5(opcodePlaceAtMe,new OpPlaceAtMe<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePlaceAtMe,new OpPlaceAtMe<ImplicitRef>);
interpreter.installSegment5(opcodePlaceAtMeExplicit,new OpPlaceAtMe<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodePlaceAtMeExplicit,new OpPlaceAtMe<ExplicitRef>);
interpreter.installSegment5(opcodeModScale,new OpModScale<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeModScale,new OpModScale<ImplicitRef>);
interpreter.installSegment5(opcodeModScaleExplicit,new OpModScale<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeModScaleExplicit,new OpModScale<ExplicitRef>);
interpreter.installSegment5(opcodeRotate,new OpRotate<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeRotate,new OpRotate<ImplicitRef>);
interpreter.installSegment5(opcodeRotateExplicit,new OpRotate<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeRotateExplicit,new OpRotate<ExplicitRef>);
interpreter.installSegment5(opcodeRotateWorld,new OpRotateWorld<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeRotateWorld,new OpRotateWorld<ImplicitRef>);
interpreter.installSegment5(opcodeRotateWorldExplicit,new OpRotateWorld<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeRotateWorldExplicit,new OpRotateWorld<ExplicitRef>);
interpreter.installSegment5(opcodeSetAtStart,new OpSetAtStart<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetAtStart,new OpSetAtStart<ImplicitRef>);
interpreter.installSegment5(opcodeSetAtStartExplicit,new OpSetAtStart<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeSetAtStartExplicit,new OpSetAtStart<ExplicitRef>);
interpreter.installSegment5(opcodeMove,new OpMove<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeMove,new OpMove<ImplicitRef>);
interpreter.installSegment5(opcodeMoveExplicit,new OpMove<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeMoveExplicit,new OpMove<ExplicitRef>);
interpreter.installSegment5(opcodeMoveWorld,new OpMoveWorld<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeMoveWorld,new OpMoveWorld<ImplicitRef>);
interpreter.installSegment5(opcodeMoveWorldExplicit,new OpMoveWorld<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeMoveWorldExplicit,new OpMoveWorld<ExplicitRef>);
interpreter.installSegment5(opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>);
interpreter.installSegment5(opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>); interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief stats-related script functionality (creatures and NPCs) /// \brief stats-related script functionality (creatures and NPCs)
namespace Transformation namespace Transformation
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -2,6 +2,7 @@
#include "userextensions.hpp" #include "userextensions.hpp"
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/interpreter/interpreter.hpp> #include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp> #include <components/interpreter/runtime.hpp>
@ -63,29 +64,15 @@ namespace MWScript
} }
}; };
const int opcodeUser1 = 0x200016c;
const int opcodeUser2 = 0x200016d;
const int opcodeUser3 = 0x200016e;
const int opcodeUser3Explicit = 0x200016f;
const int opcodeUser4 = 0x2000170;
const int opcodeUser4Explicit = 0x2000171;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("user1", "", opcodeUser1);
extensions.registerInstruction ("user2", "", opcodeUser2);
extensions.registerInstruction ("user3", "", opcodeUser3, opcodeUser3);
extensions.registerInstruction ("user4", "", opcodeUser4, opcodeUser4);
}
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeUser1, new OpUser1); interpreter.installSegment5 (Compiler::User::opcodeUser1, new OpUser1);
interpreter.installSegment5 (opcodeUser2, new OpUser2); interpreter.installSegment5 (Compiler::User::opcodeUser2, new OpUser2);
interpreter.installSegment5 (opcodeUser3, new OpUser3<ImplicitRef>); interpreter.installSegment5 (Compiler::User::opcodeUser3, new OpUser3<ImplicitRef>);
interpreter.installSegment5 (opcodeUser3Explicit, new OpUser3<ExplicitRef>); interpreter.installSegment5 (Compiler::User::opcodeUser3Explicit, new OpUser3<ExplicitRef>);
interpreter.installSegment5 (opcodeUser4, new OpUser4<ImplicitRef>); interpreter.installSegment5 (Compiler::User::opcodeUser4, new OpUser4<ImplicitRef>);
interpreter.installSegment5 (opcodeUser4Explicit, new OpUser4<ExplicitRef>); interpreter.installSegment5 (Compiler::User::opcodeUser4Explicit, new OpUser4<ExplicitRef>);
} }
} }
} }

View file

@ -16,8 +16,6 @@ namespace MWScript
/// \brief Temporary script functionality limited to the console /// \brief Temporary script functionality limited to the console
namespace User namespace User
{ {
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter); void installOpcodes (Interpreter::Interpreter& interpreter);
} }
} }

View file

@ -11,10 +11,6 @@
#include "../mwmechanics/movement.hpp" #include "../mwmechanics/movement.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/character.hpp"
#include "../mwmechanics/security.hpp"
#include "../mwrender/animation.hpp"
#include "class.hpp" #include "class.hpp"
@ -144,51 +140,6 @@ namespace MWWorld
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] += roll; MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] += roll;
} }
void Player::use()
{
MWWorld::InventoryStore& store = MWWorld::Class::get(getPlayer()).getInventoryStore(getPlayer());
MWWorld::ContainerStoreIterator equipped = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if (getDrawState() == MWMechanics::DrawState_Weapon)
{
if (equipped != store.end())
{
MWWorld::Ptr item = *equipped;
MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(getPlayer());
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject();
if (anim->isPriorityActive(MWMechanics::Priority_Weapon))
return;
std::string resultMessage, resultSound;
if (item.getTypeName() == typeid(ESM::Lockpick).name())
{
if (!target.isEmpty())
MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound);
anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0);
}
else if (item.getTypeName() == typeid(ESM::Probe).name())
{
if (!target.isEmpty())
MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound);
anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0);
}
if (!resultMessage.empty())
MWBase::Environment::get().getWindowManager()->messageBox(resultMessage);
if (!resultSound.empty())
MWBase::Environment::get().getSoundManager()->playSound(resultSound,1,1);
// tool used up?
if (!item.getRefData().getCount())
MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon();
else
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(item);
}
}
}
MWMechanics::DrawState_ Player::getDrawState() MWMechanics::DrawState_ Player::getDrawState()
{ {
MWWorld::Ptr ptr = getPlayer(); MWWorld::Ptr ptr = getPlayer();

View file

@ -58,9 +58,6 @@ namespace MWWorld
void setForwardBackward (int value); void setForwardBackward (int value);
void setUpDown(int value); void setUpDown(int value);
void use ();
///< Use item equipped on right hand, or fists
void setRunState(bool run); void setRunState(bool run);
void setSneak(bool sneak); void setSneak(bool sneak);

View file

@ -74,7 +74,7 @@ namespace MWWorld
bool isInCell() const bool isInCell() const
{ {
return (mContainerStore == 0); return (mContainerStore == 0) && (mCell != 0);
} }
void setContainerStore (ContainerStore *store); void setContainerStore (ContainerStore *store);

View file

@ -1567,6 +1567,17 @@ namespace MWWorld
return false; return false;
} }
bool World::isSubmerged(const MWWorld::Ptr &object) const
{
float *fpos = object.getRefData().getPosition().pos;
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
if(actor) pos.z += 1.85*actor->getHalfExtents().z;
return isUnderwater(object.getCell(), pos);
}
bool bool
World::isSwimming(const MWWorld::Ptr &object) const World::isSwimming(const MWWorld::Ptr &object) const
{ {

View file

@ -348,6 +348,8 @@ namespace MWWorld
virtual void processChangedSettings(const Settings::CategorySettingVector& settings); virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
virtual bool isFlying(const MWWorld::Ptr &ptr) const; virtual bool isFlying(const MWWorld::Ptr &ptr) const;
///Is the head of the creature underwater?
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
virtual bool isSwimming(const MWWorld::Ptr &object) const; virtual bool isSwimming(const MWWorld::Ptr &object) const;
virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const;
virtual bool isOnGround(const MWWorld::Ptr &ptr) const; virtual bool isOnGround(const MWWorld::Ptr &ptr) const;

View file

@ -54,7 +54,7 @@ add_component_dir (files
add_component_dir (compiler add_component_dir (compiler
context controlparser errorhandler exception exprparser extensions fileparser generator context controlparser errorhandler exception exprparser extensions fileparser generator
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
stringparser tokenloc nullerrorhandler stringparser tokenloc nullerrorhandler opcodes extensions0
) )
add_component_dir (interpreter add_component_dir (interpreter

View file

@ -0,0 +1,464 @@
#include "extensions0.hpp"
#include "opcodes.hpp"
#include "extensions.hpp"
namespace Compiler
{
void registerExtensions (Extensions& extensions, bool consoleOnly)
{
Ai::registerExtensions (extensions);
Animation::registerExtensions (extensions);
Cell::registerExtensions (extensions);
Container::registerExtensions (extensions);
Control::registerExtensions (extensions);
Dialogue::registerExtensions (extensions);
Gui::registerExtensions (extensions);
Misc::registerExtensions (extensions);
Sky::registerExtensions (extensions);
Sound::registerExtensions (extensions);
Stats::registerExtensions (extensions);
Transformation::registerExtensions (extensions);
if (consoleOnly)
{
Console::registerExtensions (extensions);
User::registerExtensions (extensions);
}
}
namespace Ai
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("aiactivate", "c/l", opcodeAIActivate,
opcodeAIActivateExplicit);
extensions.registerInstruction ("aitravel", "fff/l", opcodeAiTravel,
opcodeAiTravelExplicit);
extensions.registerInstruction ("aiescort", "cffff/l", opcodeAiEscort,
opcodeAiEscortExplicit);
extensions.registerInstruction ("aiescortcell", "ccffff/l", opcodeAiEscortCell,
opcodeAiEscortCellExplicit);
extensions.registerInstruction ("aiwander", "fff/llllllllll", opcodeAiWander,
opcodeAiWanderExplicit);
extensions.registerInstruction ("aifollow", "cffff/l", opcodeAiFollow,
opcodeAiFollowExplicit);
extensions.registerInstruction ("aifollowcell", "ccffff/l", opcodeAiFollowCell,
opcodeAiFollowCellExplicit);
extensions.registerFunction ("getaipackagedone", 'l', "", opcodeGetAiPackageDone,
opcodeGetAiPackageDoneExplicit);
extensions.registerFunction ("getcurrentaipackage", 'l', "", opcodeGetCurrentAiPackage,
opcodeGetAiPackageDoneExplicit);
extensions.registerFunction ("getdetected", 'l', "c", opcodeGetDetected,
opcodeGetDetectedExplicit);
extensions.registerInstruction ("sethello", "l", opcodeSetHello, opcodeSetHelloExplicit);
extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit);
extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit);
extensions.registerInstruction ("setalarm", "l", opcodeSetAlarm, opcodeSetAlarmExplicit);
extensions.registerInstruction ("modhello", "l", opcodeModHello, opcodeModHelloExplicit);
extensions.registerInstruction ("modfight", "l", opcodeModFight, opcodeModFightExplicit);
extensions.registerInstruction ("modflee", "l", opcodeModFlee, opcodeModFleeExplicit);
extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit);
extensions.registerFunction ("gethello", 'l', "", opcodeGetHello, opcodeGetHelloExplicit);
extensions.registerFunction ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit);
extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit);
extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit);
}
}
namespace Animation
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("skipanim", "", opcodeSkipAnim, opcodeSkipAnimExplicit);
extensions.registerInstruction ("playgroup", "c/l", opcodePlayAnim, opcodePlayAnimExplicit);
extensions.registerInstruction ("loopgroup", "cl/l", opcodeLoopAnim, opcodeLoopAnimExplicit);
}
}
namespace Cell
{
void registerExtensions (Extensions& extensions)
{
extensions.registerFunction ("cellchanged", 'l', "", opcodeCellChanged);
extensions.registerInstruction ("coc", "S", opcodeCOC);
extensions.registerInstruction ("centeroncell", "S", opcodeCOC);
extensions.registerInstruction ("coe", "ll", opcodeCOE);
extensions.registerInstruction ("centeronexterior", "ll", opcodeCOE);
extensions.registerInstruction ("setwaterlevel", "f", opcodeSetWaterLevel);
extensions.registerInstruction ("modwaterlevel", "f", opcodeModWaterLevel);
extensions.registerFunction ("getinterior", 'l', "", opcodeGetInterior);
extensions.registerFunction ("getpccell", 'l', "c", opcodeGetPCCell);
extensions.registerFunction ("getwaterlevel", 'f', "", opcodeGetWaterLevel);
}
}
namespace Console
{
void registerExtensions (Extensions& extensions)
{
}
}
namespace Container
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit);
extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount,
opcodeGetItemCountExplicit);
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,
opcodeRemoveItemExplicit);
extensions.registerInstruction ("equip", "c", opcodeEquip, opcodeEquipExplicit);
extensions.registerFunction ("getarmortype", 'l', "l", opcodeGetArmorType, opcodeGetArmorTypeExplicit);
extensions.registerFunction ("hasitemequipped", 'l', "c", opcodeHasItemEquipped, opcodeHasItemEquippedExplicit);
extensions.registerFunction ("hassoulgem", 'l', "c", opcodeHasSoulGem, opcodeHasSoulGemExplicit);
extensions.registerFunction ("getweapontype", 'l', "", opcodeGetWeaponType, opcodeGetWeaponTypeExplicit);
}
}
namespace Control
{
void registerExtensions (Extensions& extensions)
{
std::string enable ("enable");
std::string disable ("disable");
for (int i=0; i<numberOfControls; ++i)
{
extensions.registerInstruction (enable + controls[i], "", opcodeEnable+i);
extensions.registerInstruction (disable + controls[i], "", opcodeDisable+i);
extensions.registerFunction (std::string("get") + controls[i] + std::string("disabled"), 'l', "", opcodeGetDisabled+i);
}
extensions.registerInstruction ("togglecollision", "", opcodeToggleCollision);
extensions.registerInstruction ("tcl", "", opcodeToggleCollision);
extensions.registerInstruction ("clearforcerun", "", opcodeClearForceRun,
opcodeClearForceRunExplicit);
extensions.registerInstruction ("forcerun", "", opcodeForceRun,
opcodeForceRunExplicit);
extensions.registerInstruction ("clearforcesneak", "", opcodeClearForceSneak,
opcodeClearForceSneakExplicit);
extensions.registerInstruction ("forcesneak", "", opcodeForceSneak,
opcodeForceSneakExplicit);
extensions.registerFunction ("getpcrunning", 'l', "", opcodeGetPcRunning);
extensions.registerFunction ("getpcsneaking", 'l', "", opcodeGetPcSneaking);
extensions.registerFunction ("getforcerun", 'l', "", opcodeGetForceRun, opcodeGetForceRunExplicit);
extensions.registerFunction ("getforcesneak", 'l', "", opcodeGetForceSneak, opcodeGetForceSneakExplicit);
}
}
namespace Dialogue
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("journal", "cl", opcodeJournal);
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);
extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting);
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
opcodeForceGreetingExplicit);
extensions.registerInstruction("goodbye", "", opcodeGoodbye);
extensions.registerInstruction("setreputation", "l", opcodeSetReputation,
opcodeSetReputationExplicit);
extensions.registerInstruction("modreputation", "l", opcodeModReputation,
opcodeModReputationExplicit);
extensions.registerFunction("getreputation", 'l', "", opcodeGetReputation,
opcodeGetReputationExplicit);
extensions.registerFunction("samefaction", 'l', "", opcodeSameFaction,
opcodeSameFactionExplicit);
}
}
namespace Gui
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("enablebirthmenu", "", opcodeEnableBirthMenu);
extensions.registerInstruction ("enableclassmenu", "", opcodeEnableClassMenu);
extensions.registerInstruction ("enablenamemenu", "", opcodeEnableNameMenu);
extensions.registerInstruction ("enableracemenu", "", opcodeEnableRaceMenu);
extensions.registerInstruction ("enablestatreviewmenu", "",
opcodeEnableStatsReviewMenu);
extensions.registerInstruction ("enableinventorymenu", "", opcodeEnableInventoryMenu);
extensions.registerInstruction ("enablemagicmenu", "", opcodeEnableMagicMenu);
extensions.registerInstruction ("enablemapmenu", "", opcodeEnableMapMenu);
extensions.registerInstruction ("enablestatsmenu", "", opcodeEnableStatsMenu);
extensions.registerInstruction ("enablerest", "", opcodeEnableRest);
extensions.registerInstruction ("enablelevelupmenu", "", opcodeEnableRest);
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu);
extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed);
extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar);
extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar);
extensions.registerInstruction ("togglefullhelp", "", opcodeToggleFullHelp);
extensions.registerInstruction ("tfh", "", opcodeToggleFullHelp);
extensions.registerInstruction ("showmap", "S", opcodeShowMap);
extensions.registerInstruction ("fillmap", "", opcodeFillMap);
}
}
namespace Misc
{
void registerExtensions (Extensions& extensions)
{
extensions.registerFunction ("xbox", 'l', "", opcodeXBox);
extensions.registerFunction ("onactivate", 'l', "", opcodeOnActivate);
extensions.registerInstruction ("activate", "", opcodeActivate);
extensions.registerInstruction ("lock", "/l", opcodeLock, opcodeLockExplicit);
extensions.registerInstruction ("unlock", "", opcodeUnlock, opcodeUnlockExplicit);
extensions.registerInstruction ("togglecollisionboxes", "", opcodeToggleCollisionBoxes);
extensions.registerInstruction ("togglecollisiongrid", "", opcodeToggleCollisionDebug);
extensions.registerInstruction ("tcb", "", opcodeToggleCollisionBoxes);
extensions.registerInstruction ("tcg", "", opcodeToggleCollisionDebug);
extensions.registerInstruction ("twf", "", opcodeToggleWireframe);
extensions.registerInstruction ("togglewireframe", "", opcodeToggleWireframe);
extensions.registerInstruction ("fadein", "f", opcodeFadeIn);
extensions.registerInstruction ("fadeout", "f", opcodeFadeOut);
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
extensions.registerInstruction ("twa", "", opcodeToggleWater);
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc);
extensions.registerInstruction ("playbink", "Sl", opcodePlayBink);
extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit);
extensions.registerFunction ("geteffect", 'l', "l", opcodeGetEffect, opcodeGetEffectExplicit);
extensions.registerInstruction ("addsoulgem", "cc", opcodeAddSoulGem, opcodeAddSoulGemExplicit);
extensions.registerInstruction ("removesoulgem", "c", opcodeRemoveSoulGem, opcodeRemoveSoulGemExplicit);
extensions.registerInstruction ("drop", "cl", opcodeDrop, opcodeDropExplicit);
extensions.registerInstruction ("dropsoulgem", "c", opcodeDropSoulGem, opcodeDropSoulGemExplicit);
extensions.registerFunction ("getattacked", 'l', "", opcodeGetAttacked, opcodeGetAttackedExplicit);
extensions.registerFunction ("getweapondrawn", 'l', "", opcodeGetWeaponDrawn, opcodeGetWeaponDrawnExplicit);
extensions.registerFunction ("getspelleffects", 'l', "c", opcodeGetSpellEffects, opcodeGetSpellEffectsExplicit);
extensions.registerFunction ("getcurrenttime", 'f', "", opcodeGetCurrentTime);
extensions.registerInstruction ("setdelete", "l", opcodeSetDelete, opcodeSetDeleteExplicit);
extensions.registerFunction ("getsquareroot", 'f', "f", opcodeGetSquareRoot);
extensions.registerInstruction ("fall", "", opcodeFall, opcodeFallExplicit);
extensions.registerFunction ("getstandingpc", 'l', "", opcodeGetStandingPc, opcodeGetStandingPcExplicit);
extensions.registerFunction ("getstandingactor", 'l', "", opcodeGetStandingActor, opcodeGetStandingActorExplicit);
extensions.registerFunction ("getwindspeed", 'f', "", opcodeGetWindSpeed);
extensions.registerFunction ("hitonme", 'l', "S", opcodeHitOnMe, opcodeHitOnMeExplicit);
extensions.registerInstruction ("disableteleporting", "", opcodeDisableTeleporting);
extensions.registerInstruction ("enableteleporting", "", opcodeEnableTeleporting);
}
}
namespace Sky
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("togglesky", "", opcodeToggleSky);
extensions.registerInstruction ("ts", "", opcodeToggleSky);
extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite);
extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed);
extensions.registerInstruction ("changeweather", "Sl", opcodeChangeWeather);
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather);
extensions.registerInstruction ("modregion", "S/llllllllll", opcodeModRegion);
}
}
namespace Sound
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("say", "SS", opcodeSay, opcodeSayExplicit);
extensions.registerFunction ("saydone", 'l', "", opcodeSayDone, opcodeSayDoneExplicit);
extensions.registerInstruction ("streammusic", "S", opcodeStreamMusic);
extensions.registerInstruction ("playsound", "c", opcodePlaySound);
extensions.registerInstruction ("playsoundvp", "cff", opcodePlaySoundVP);
extensions.registerInstruction ("playsound3d", "c", opcodePlaySound3D,
opcodePlaySound3DExplicit);
extensions.registerInstruction ("playsound3dvp", "cff", opcodePlaySound3DVP,
opcodePlaySound3DVPExplicit);
extensions.registerInstruction ("playloopsound3d", "c", opcodePlayLoopSound3D,
opcodePlayLoopSound3DExplicit);
extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP,
opcodePlayLoopSound3DVPExplicit);
extensions.registerInstruction ("stopsound", "c", opcodeStopSound,
opcodeStopSoundExplicit);
extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying,
opcodeGetSoundPlayingExplicit);
}
}
namespace Stats
{
void registerExtensions (Extensions& extensions)
{
static const char *attributes[numberOfAttributes] =
{
"strength", "intelligence", "willpower", "agility", "speed", "endurance",
"personality", "luck"
};
static const char *dynamics[numberOfDynamics] =
{
"health", "magicka", "fatigue"
};
static const char *skills[numberOfSkills] =
{
"block", "armorer", "mediumarmor", "heavyarmor", "bluntweapon",
"longblade", "axe", "spear", "athletics", "enchant", "destruction",
"alteration", "illusion", "conjuration", "mysticism",
"restoration", "alchemy", "unarmored", "security", "sneak",
"acrobatics", "lightarmor", "shortblade", "marksman",
"mercantile", "speechcraft", "handtohand"
};
std::string get ("get");
std::string set ("set");
std::string mod ("mod");
std::string modCurrent ("modcurrent");
std::string getRatio ("getratio");
for (int i=0; i<numberOfAttributes; ++i)
{
extensions.registerFunction (get + attributes[i], 'l', "",
opcodeGetAttribute+i, opcodeGetAttributeExplicit+i);
extensions.registerInstruction (set + attributes[i], "l",
opcodeSetAttribute+i, opcodeSetAttributeExplicit+i);
extensions.registerInstruction (mod + attributes[i], "l",
opcodeModAttribute+i, opcodeModAttributeExplicit+i);
}
for (int i=0; i<numberOfDynamics; ++i)
{
extensions.registerFunction (get + dynamics[i], 'f', "",
opcodeGetDynamic+i, opcodeGetDynamicExplicit+i);
extensions.registerInstruction (set + dynamics[i], "f",
opcodeSetDynamic+i, opcodeSetDynamicExplicit+i);
extensions.registerInstruction (mod + dynamics[i], "f",
opcodeModDynamic+i, opcodeModDynamicExplicit+i);
extensions.registerInstruction (modCurrent + dynamics[i], "f",
opcodeModCurrentDynamic+i, opcodeModCurrentDynamicExplicit+i);
extensions.registerFunction (get + dynamics[i] + getRatio, 'f', "",
opcodeGetDynamicGetRatio+i, opcodeGetDynamicGetRatioExplicit+i);
}
for (int i=0; i<numberOfSkills; ++i)
{
extensions.registerFunction (get + skills[i], 'l', "",
opcodeGetSkill+i, opcodeGetSkillExplicit+i);
extensions.registerInstruction (set + skills[i], "l",
opcodeSetSkill+i, opcodeSetSkillExplicit+i);
extensions.registerInstruction (mod + skills[i], "l",
opcodeModSkill+i, opcodeModSkillExplicit+i);
}
extensions.registerFunction ("getpccrimelevel", 'f', "", opcodeGetPCCrimeLevel);
extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel);
extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel);
extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit);
extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
opcodeRemoveSpellExplicit);
extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit);
extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank);
extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank);
extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction);
extensions.registerInstruction ("moddisposition","l",opcodeModDisposition,
opcodeModDispositionExplicit);
extensions.registerInstruction ("setdisposition","l",opcodeSetDisposition,
opcodeSetDispositionExplicit);
extensions.registerFunction ("getdisposition",'l', "",opcodeGetDisposition,
opcodeGetDispositionExplicit);
extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit);
extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit);
extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit);
extensions.registerFunction ("getdeadcount", 'l', "c", opcodeGetDeadCount);
extensions.registerFunction ("getpcfacrep", 'l', "/c", opcodeGetPCFacRep, opcodeGetPCFacRepExplicit);
extensions.registerInstruction ("setpcfacrep", "l/c", opcodeSetPCFacRep, opcodeSetPCFacRepExplicit);
extensions.registerInstruction ("modpcfacrep", "l/c", opcodeModPCFacRep, opcodeModPCFacRepExplicit);
extensions.registerFunction ("getcommondisease", 'l', "", opcodeGetCommonDisease,
opcodeGetCommonDiseaseExplicit);
extensions.registerFunction ("getblightdisease", 'l', "", opcodeGetBlightDisease,
opcodeGetBlightDiseaseExplicit);
extensions.registerFunction ("getrace", 'l', "c", opcodeGetRace,
opcodeGetRaceExplicit);
extensions.registerFunction ("getwerewolfkills", 'f', "", opcodeGetWerewolfKills);
extensions.registerFunction ("pcexpelled", 'l', "/S", opcodePcExpelled, opcodePcExpelledExplicit);
extensions.registerInstruction ("pcexpell", "/S", opcodePcExpell, opcodePcExpellExplicit);
extensions.registerInstruction ("pcclearexpelled", "/S", opcodePcClearExpelled, opcodePcClearExpelledExplicit);
extensions.registerInstruction ("raiserank", "", opcodeRaiseRank, opcodeRaiseRankExplicit);
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath, opcodeOnDeathExplicit);
extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit);
extensions.registerInstruction("becomewerewolf", "", opcodeBecomeWerewolf, opcodeBecomeWerewolfExplicit);
extensions.registerInstruction("undowerewolf", "", opcodeUndoWerewolf, opcodeUndoWerewolfExplicit);
}
}
namespace Transformation
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction("setscale","f",opcodeSetScale,opcodeSetScaleExplicit);
extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit);
extensions.registerInstruction("setangle","cf",opcodeSetAngle,opcodeSetAngleExplicit);
extensions.registerFunction("getangle",'f',"c",opcodeGetAngle,opcodeGetAngleExplicit);
extensions.registerInstruction("setpos","cf",opcodeSetPos,opcodeSetPosExplicit);
extensions.registerFunction("getpos",'f',"c",opcodeGetPos,opcodeGetPosExplicit);
extensions.registerFunction("getstartingpos",'f',"c",opcodeGetStartingPos,opcodeGetStartingPosExplicit);
extensions.registerInstruction("position","ffff",opcodePosition,opcodePositionExplicit);
extensions.registerInstruction("positioncell","ffffc",opcodePositionCell,opcodePositionCellExplicit);
extensions.registerInstruction("placeitemcell","ccffff",opcodePlaceItemCell);
extensions.registerInstruction("placeitem","cffff",opcodePlaceItem);
extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc);
extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit);
extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit);
extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit);
extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit);
extensions.registerInstruction("setatstart","",opcodeSetAtStart,opcodeSetAtStartExplicit);
extensions.registerInstruction("move","cf",opcodeMove,opcodeMoveExplicit);
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
}
}
namespace User
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("user1", "", opcodeUser1);
extensions.registerInstruction ("user2", "", opcodeUser2);
extensions.registerInstruction ("user3", "", opcodeUser3, opcodeUser3);
extensions.registerInstruction ("user4", "", opcodeUser4, opcodeUser4);
}
}
}

View file

@ -0,0 +1,81 @@
#ifndef COMPILER_EXTENSIONS0_H
#define COMPILER_EXTENSIONS0_H
namespace Compiler
{
class Extensions;
void registerExtensions (Extensions& extensions, bool consoleOnly = false);
namespace Ai
{
void registerExtensions (Extensions& extensions);
}
namespace Animation
{
void registerExtensions (Extensions& extensions);
}
namespace Cell
{
void registerExtensions (Extensions& extensions);
}
namespace Console
{
void registerExtensions (Extensions& extensions);
}
namespace Container
{
void registerExtensions (Extensions& extensions);
}
namespace Control
{
void registerExtensions (Extensions& extensions);
}
namespace Dialogue
{
void registerExtensions (Extensions& extensions);
}
namespace Gui
{
void registerExtensions (Extensions& extensions);
}
namespace Misc
{
void registerExtensions (Extensions& extensions);
}
namespace Sky
{
void registerExtensions (Extensions& extensions);
}
namespace Sound
{
void registerExtensions (Extensions& extensions);
}
namespace Stats
{
void registerExtensions (Extensions& extensions);
}
namespace Transformation
{
void registerExtensions (Extensions& extensions);
}
namespace User
{
void registerExtensions (Extensions& extensions);
}
}
#endif

View file

@ -0,0 +1,13 @@
#include "opcodes.hpp"
namespace Compiler
{
namespace Control
{
const char *controls[numberOfControls] =
{
"playercontrols", "playerfighting", "playerjumping", "playerlooking", "playermagic",
"playerviewswitch", "vanitymode"
};
}
}

View file

@ -0,0 +1,412 @@
#ifndef COMPILER_OPCODES_H
#define COMPILER_OPCODES_H
namespace Compiler
{
namespace Ai
{
const int opcodeAiTravel = 0x20000;
const int opcodeAiTravelExplicit = 0x20001;
const int opcodeAiEscort = 0x20002;
const int opcodeAiEscortExplicit = 0x20003;
const int opcodeGetAiPackageDone = 0x200007c;
const int opcodeGetAiPackageDoneExplicit = 0x200007d;
const int opcodeGetCurrentAiPackage = 0x20001ef;
const int opcodeGetCurrentAiPackageExplicit = 0x20001f0;
const int opcodeGetDetected = 0x20001f1;
const int opcodeGetDetectedExplicit = 0x20001f2;
const int opcodeAiWander = 0x20010;
const int opcodeAiWanderExplicit = 0x20011;
const int opcodeAIActivate = 0x2001e;
const int opcodeAIActivateExplicit = 0x2001f;
const int opcodeAiEscortCell = 0x20020;
const int opcodeAiEscortCellExplicit = 0x20021;
const int opcodeAiFollow = 0x20022;
const int opcodeAiFollowExplicit = 0x20023;
const int opcodeAiFollowCell = 0x20024;
const int opcodeAiFollowCellExplicit = 0x20025;
const int opcodeSetHello = 0x200015e;
const int opcodeSetHelloExplicit = 0x200015d;
const int opcodeSetFight = 0x200015e;
const int opcodeSetFightExplicit = 0x200015f;
const int opcodeSetFlee = 0x2000160;
const int opcodeSetFleeExplicit = 0x2000161;
const int opcodeSetAlarm = 0x2000162;
const int opcodeSetAlarmExplicit = 0x2000163;
const int opcodeModHello = 0x20001b7;
const int opcodeModHelloExplicit = 0x20001b8;
const int opcodeModFight = 0x20001b9;
const int opcodeModFightExplicit = 0x20001ba;
const int opcodeModFlee = 0x20001bb;
const int opcodeModFleeExplicit = 0x20001bc;
const int opcodeModAlarm = 0x20001bd;
const int opcodeModAlarmExplicit = 0x20001be;
const int opcodeGetHello = 0x20001bf;
const int opcodeGetHelloExplicit = 0x20001c0;
const int opcodeGetFight = 0x20001c1;
const int opcodeGetFightExplicit = 0x20001c2;
const int opcodeGetFlee = 0x20001c3;
const int opcodeGetFleeExplicit = 0x20001c4;
const int opcodeGetAlarm = 0x20001c5;
const int opcodeGetAlarmExplicit = 0x20001c6;
}
namespace Animation
{
const int opcodeSkipAnim = 0x2000138;
const int opcodeSkipAnimExplicit = 0x2000139;
const int opcodePlayAnim = 0x20006;
const int opcodePlayAnimExplicit = 0x20007;
const int opcodeLoopAnim = 0x20008;
const int opcodeLoopAnimExplicit = 0x20009;
}
namespace Cell
{
const int opcodeCellChanged = 0x2000000;
const int opcodeCOC = 0x2000026;
const int opcodeCOE = 0x200008e;
const int opcodeGetInterior = 0x2000131;
const int opcodeGetPCCell = 0x2000136;
const int opcodeGetWaterLevel = 0x2000141;
const int opcodeSetWaterLevel = 0x2000142;
const int opcodeModWaterLevel = 0x2000143;
}
namespace Console
{
}
namespace Container
{
const int opcodeAddItem = 0x2000076;
const int opcodeAddItemExplicit = 0x2000077;
const int opcodeGetItemCount = 0x2000078;
const int opcodeGetItemCountExplicit = 0x2000079;
const int opcodeRemoveItem = 0x200007a;
const int opcodeRemoveItemExplicit = 0x200007b;
const int opcodeEquip = 0x20001b3;
const int opcodeEquipExplicit = 0x20001b4;
const int opcodeGetArmorType = 0x20001d1;
const int opcodeGetArmorTypeExplicit = 0x20001d2;
const int opcodeHasItemEquipped = 0x20001d5;
const int opcodeHasItemEquippedExplicit = 0x20001d6;
const int opcodeHasSoulGem = 0x20001de;
const int opcodeHasSoulGemExplicit = 0x20001df;
const int opcodeGetWeaponType = 0x20001e0;
const int opcodeGetWeaponTypeExplicit = 0x20001e1;
}
namespace Control
{
const int numberOfControls = 7;
extern const char *controls[numberOfControls];
const int opcodeEnable = 0x200007e;
const int opcodeDisable = 0x2000085;
const int opcodeToggleCollision = 0x2000130;
const int opcodeClearForceRun = 0x2000154;
const int opcodeClearForceRunExplicit = 0x2000155;
const int opcodeForceRun = 0x2000156;
const int opcodeForceRunExplicit = 0x2000157;
const int opcodeClearForceSneak = 0x2000158;
const int opcodeClearForceSneakExplicit = 0x2000159;
const int opcodeForceSneak = 0x200015a;
const int opcodeForceSneakExplicit = 0x200015b;
const int opcodeGetDisabled = 0x2000175;
const int opcodeGetPcRunning = 0x20001c9;
const int opcodeGetPcSneaking = 0x20001ca;
const int opcodeGetForceRun = 0x20001cb;
const int opcodeGetForceSneak = 0x20001cc;
const int opcodeGetForceRunExplicit = 0x20001cd;
const int opcodeGetForceSneakExplicit = 0x20001ce;
}
namespace Dialogue
{
const int opcodeJournal = 0x2000133;
const int opcodeSetJournalIndex = 0x2000134;
const int opcodeGetJournalIndex = 0x2000135;
const int opcodeAddTopic = 0x200013a;
const int opcodeChoice = 0x2000a;
const int opcodeForceGreeting = 0x200014f;
const int opcodeForceGreetingExplicit = 0x2000150;
const int opcodeGoodbye = 0x2000152;
const int opcodeSetReputation = 0x20001ad;
const int opcodeModReputation = 0x20001ae;
const int opcodeSetReputationExplicit = 0x20001af;
const int opcodeModReputationExplicit = 0x20001b0;
const int opcodeGetReputation = 0x20001b1;
const int opcodeGetReputationExplicit = 0x20001b2;
const int opcodeSameFaction = 0x20001b5;
const int opcodeSameFactionExplicit = 0x20001b6;
}
namespace Gui
{
const int opcodeEnableBirthMenu = 0x200000e;
const int opcodeEnableClassMenu = 0x200000f;
const int opcodeEnableNameMenu = 0x2000010;
const int opcodeEnableRaceMenu = 0x2000011;
const int opcodeEnableStatsReviewMenu = 0x2000012;
const int opcodeEnableInventoryMenu = 0x2000013;
const int opcodeEnableMagicMenu = 0x2000014;
const int opcodeEnableMapMenu = 0x2000015;
const int opcodeEnableStatsMenu = 0x2000016;
const int opcodeEnableRest = 0x2000017;
const int opcodeShowRestMenu = 0x2000018;
const int opcodeGetButtonPressed = 0x2000137;
const int opcodeToggleFogOfWar = 0x2000145;
const int opcodeToggleFullHelp = 0x2000151;
const int opcodeShowMap = 0x20001a0;
const int opcodeFillMap = 0x20001a1;
}
namespace Misc
{
const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075;
const int opcodeLock = 0x20004;
const int opcodeLockExplicit = 0x20005;
const int opcodeUnlock = 0x200008c;
const int opcodeUnlockExplicit = 0x200008d;
const int opcodeToggleCollisionDebug = 0x2000132;
const int opcodeToggleCollisionBoxes = 0x20001ac;
const int opcodeToggleWireframe = 0x200013b;
const int opcodeFadeIn = 0x200013c;
const int opcodeFadeOut = 0x200013d;
const int opcodeFadeTo = 0x200013e;
const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000146;
const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174;
const int opcodeGetPcSleep = 0x200019f;
const int opcodeWakeUpPc = 0x20001a2;
const int opcodeGetLocked = 0x20001c7;
const int opcodeGetLockedExplicit = 0x20001c8;
const int opcodeGetEffect = 0x20001cf;
const int opcodeGetEffectExplicit = 0x20001d0;
const int opcodeAddSoulGem = 0x20001f3;
const int opcodeAddSoulGemExplicit = 0x20001f4;
const int opcodeRemoveSoulGem = 0x20001f5;
const int opcodeRemoveSoulGemExplicit = 0x20001f6;
const int opcodeDrop = 0x20001f8;
const int opcodeDropExplicit = 0x20001f9;
const int opcodeDropSoulGem = 0x20001fa;
const int opcodeDropSoulGemExplicit = 0x20001fb;
const int opcodeGetAttacked = 0x20001d3;
const int opcodeGetAttackedExplicit = 0x20001d4;
const int opcodeGetWeaponDrawn = 0x20001d7;
const int opcodeGetWeaponDrawnExplicit = 0x20001d8;
const int opcodeGetSpellEffects = 0x20001db;
const int opcodeGetSpellEffectsExplicit = 0x20001dc;
const int opcodeGetCurrentTime = 0x20001dd;
const int opcodeSetDelete = 0x20001e5;
const int opcodeSetDeleteExplicit = 0x20001e6;
const int opcodeGetSquareRoot = 0x20001e7;
const int opcodeFall = 0x200020a;
const int opcodeFallExplicit = 0x200020b;
const int opcodeGetStandingPc = 0x200020c;
const int opcodeGetStandingPcExplicit = 0x200020d;
const int opcodeGetStandingActor = 0x200020e;
const int opcodeGetStandingActorExplicit = 0x200020f;
const int opcodeGetWindSpeed = 0x2000212;
const int opcodePlayBink = 0x20001f7;
const int opcodeHitOnMe = 0x2000213;
const int opcodeHitOnMeExplicit = 0x2000214;
const int opcodeDisableTeleporting = 0x2000215;
const int opcodeEnableTeleporting = 0x2000216;
}
namespace Sky
{
const int opcodeToggleSky = 0x2000021;
const int opcodeTurnMoonWhite = 0x2000022;
const int opcodeTurnMoonRed = 0x2000023;
const int opcodeGetMasserPhase = 0x2000024;
const int opcodeGetSecundaPhase = 0x2000025;
const int opcodeGetCurrentWeather = 0x200013f;
const int opcodeChangeWeather = 0x2000140;
const int opcodeModRegion = 0x20026;
}
namespace Sound
{
const int opcodeSay = 0x2000001;
const int opcodeSayDone = 0x2000002;
const int opcodeStreamMusic = 0x2000003;
const int opcodePlaySound = 0x2000004;
const int opcodePlaySoundVP = 0x2000005;
const int opcodePlaySound3D = 0x2000006;
const int opcodePlaySound3DVP = 0x2000007;
const int opcodePlayLoopSound3D = 0x2000008;
const int opcodePlayLoopSound3DVP = 0x2000009;
const int opcodeStopSound = 0x200000a;
const int opcodeGetSoundPlaying = 0x200000b;
const int opcodeSayExplicit = 0x2000019;
const int opcodeSayDoneExplicit = 0x200001a;
const int opcodePlaySound3DExplicit = 0x200001b;
const int opcodePlaySound3DVPExplicit = 0x200001c;
const int opcodePlayLoopSound3DExplicit = 0x200001d;
const int opcodePlayLoopSound3DVPExplicit = 0x200001e;
const int opcodeStopSoundExplicit = 0x200001f;
const int opcodeGetSoundPlayingExplicit = 0x2000020;
}
namespace Stats
{
const int numberOfAttributes = 8;
const int numberOfDynamics = 3;
const int numberOfSkills = 27;
const int opcodeGetAttribute = 0x2000027;
const int opcodeGetAttributeExplicit = 0x200002f;
const int opcodeSetAttribute = 0x2000037;
const int opcodeSetAttributeExplicit = 0x200003f;
const int opcodeModAttribute = 0x2000047;
const int opcodeModAttributeExplicit = 0x200004f;
const int opcodeGetDynamic = 0x2000057;
const int opcodeGetDynamicExplicit = 0x200005a;
const int opcodeSetDynamic = 0x200005d;
const int opcodeSetDynamicExplicit = 0x2000060;
const int opcodeModDynamic = 0x2000063;
const int opcodeModDynamicExplicit = 0x2000066;
const int opcodeModCurrentDynamic = 0x2000069;
const int opcodeModCurrentDynamicExplicit = 0x200006c;
const int opcodeGetDynamicGetRatio = 0x200006f;
const int opcodeGetDynamicGetRatioExplicit = 0x2000072;
const int opcodeGetSkill = 0x200008e;
const int opcodeGetSkillExplicit = 0x20000a9;
const int opcodeSetSkill = 0x20000c4;
const int opcodeSetSkillExplicit = 0x20000df;
const int opcodeModSkill = 0x20000fa;
const int opcodeModSkillExplicit = 0x2000115;
const int opcodeGetPCCrimeLevel = 0x20001ec;
const int opcodeSetPCCrimeLevel = 0x20001ed;
const int opcodeModPCCrimeLevel = 0x20001ee;
const int opcodeAddSpell = 0x2000147;
const int opcodeAddSpellExplicit = 0x2000148;
const int opcodeRemoveSpell = 0x2000149;
const int opcodeRemoveSpellExplicit = 0x200014a;
const int opcodeGetSpell = 0x200014b;
const int opcodeGetSpellExplicit = 0x200014c;
const int opcodePCRaiseRank = 0x2000b;
const int opcodePCLowerRank = 0x2000c;
const int opcodePCJoinFaction = 0x2000d;
const int opcodeGetPCRank = 0x2000e;
const int opcodeGetPCRankExplicit = 0x2000f;
const int opcodeModDisposition = 0x200014d;
const int opcodeModDispositionExplicit = 0x200014e;
const int opcodeSetDisposition = 0x20001a4;
const int opcodeSetDispositionExplicit = 0x20001a5;
const int opcodeGetDisposition = 0x20001a6;
const int opcodeGetDispositionExplicit = 0x20001a7;
const int opcodeGetLevel = 0x200018c;
const int opcodeGetLevelExplicit = 0x200018d;
const int opcodeSetLevel = 0x200018e;
const int opcodeSetLevelExplicit = 0x200018f;
const int opcodeGetDeadCount = 0x20001a3;
const int opcodeGetPCFacRep = 0x20012;
const int opcodeGetPCFacRepExplicit = 0x20013;
const int opcodeSetPCFacRep = 0x20014;
const int opcodeSetPCFacRepExplicit = 0x20015;
const int opcodeModPCFacRep = 0x20016;
const int opcodeModPCFacRepExplicit = 0x20017;
const int opcodeGetCommonDisease = 0x20001a8;
const int opcodeGetCommonDiseaseExplicit = 0x20001a9;
const int opcodeGetBlightDisease = 0x20001aa;
const int opcodeGetBlightDiseaseExplicit = 0x20001ab;
const int opcodeGetRace = 0x20001d9;
const int opcodeGetRaceExplicit = 0x20001da;
const int opcodePcExpelled = 0x20018;
const int opcodePcExpelledExplicit = 0x20019;
const int opcodePcExpell = 0x2001a;
const int opcodePcExpellExplicit = 0x2001b;
const int opcodePcClearExpelled = 0x2001c;
const int opcodePcClearExpelledExplicit = 0x2001d;
const int opcodeRaiseRank = 0x20001e8;
const int opcodeRaiseRankExplicit = 0x20001e9;
const int opcodeLowerRank = 0x20001ea;
const int opcodeLowerRankExplicit = 0x20001eb;
const int opcodeOnDeath = 0x20001fc;
const int opcodeOnDeathExplicit = 0x2000205;
const int opcodeBecomeWerewolf = 0x2000217;
const int opcodeBecomeWerewolfExplicit = 0x2000218;
const int opcodeUndoWerewolf = 0x2000219;
const int opcodeUndoWerewolfExplicit = 0x200021a;
const int opcodeIsWerewolf = 0x20001fd;
const int opcodeIsWerewolfExplicit = 0x20001fe;
const int opcodeGetWerewolfKills = 0x20001e2;
}
namespace Transformation
{
const int opcodeSetScale = 0x2000164;
const int opcodeSetScaleExplicit = 0x2000165;
const int opcodeSetAngle = 0x2000166;
const int opcodeSetAngleExplicit = 0x2000167;
const int opcodeGetScale = 0x2000168;
const int opcodeGetScaleExplicit = 0x2000169;
const int opcodeGetAngle = 0x200016a;
const int opcodeGetAngleExplicit = 0x200016b;
const int opcodeGetPos = 0x2000190;
const int opcodeGetPosExplicit = 0x2000191;
const int opcodeSetPos = 0x2000192;
const int opcodeSetPosExplicit = 0x2000193;
const int opcodeGetStartingPos = 0x2000194;
const int opcodeGetStartingPosExplicit = 0x2000195;
const int opcodeGetStartingAngle = 0x2000210;
const int opcodeGetStartingAngleExplicit = 0x2000211;
const int opcodePosition = 0x2000196;
const int opcodePositionExplicit = 0x2000197;
const int opcodePositionCell = 0x2000198;
const int opcodePositionCellExplicit = 0x2000199;
const int opcodePlaceItemCell = 0x200019a;
const int opcodePlaceItem = 0x200019b;
const int opcodePlaceAtPc = 0x200019c;
const int opcodePlaceAtMe = 0x200019d;
const int opcodePlaceAtMeExplicit = 0x200019e;
const int opcodeModScale = 0x20001e3;
const int opcodeModScaleExplicit = 0x20001e4;
const int opcodeRotate = 0x20001ff;
const int opcodeRotateExplicit = 0x2000200;
const int opcodeRotateWorld = 0x2000201;
const int opcodeRotateWorldExplicit = 0x2000202;
const int opcodeSetAtStart = 0x2000203;
const int opcodeSetAtStartExplicit = 0x2000204;
const int opcodeMove = 0x2000206;
const int opcodeMoveExplicit = 0x2000207;
const int opcodeMoveWorld = 0x2000208;
const int opcodeMoveWorldExplicit = 0x2000209;
}
namespace User
{
const int opcodeUser1 = 0x200016c;
const int opcodeUser2 = 0x200016d;
const int opcodeUser3 = 0x200016e;
const int opcodeUser3Explicit = 0x200016f;
const int opcodeUser4 = 0x2000170;
const int opcodeUser4Explicit = 0x2000171;
}
}
#endif

View file

@ -43,6 +43,7 @@ struct ObjectList {
Ogre::Entity *mSkelBase; Ogre::Entity *mSkelBase;
std::vector<Ogre::Entity*> mEntities; std::vector<Ogre::Entity*> mEntities;
std::vector<Ogre::ParticleSystem*> mParticles; std::vector<Ogre::ParticleSystem*> mParticles;
std::vector<Ogre::Light*> mLights;
std::map<int,TextKeyMap> mTextKeys; std::map<int,TextKeyMap> mTextKeys;

View file

@ -125,7 +125,7 @@ namespace SFO
mOgreWindow->windowMovedOrResized(); mOgreWindow->windowMovedOrResized();
#endif #endif
if (mWindowListener) if (mWindowListener)
mWindowListener->windowResized(evt.window.data1, evt.window.data2); mWindowListener->windowResized(w, h);
break; break;
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:

View file

@ -205,7 +205,6 @@
shUniform(float, waterLevel) @shSharedParameter(waterLevel) shUniform(float, waterLevel) @shSharedParameter(waterLevel)
#endif #endif
SH_START_PROGRAM SH_START_PROGRAM
{ {
@ -232,26 +231,32 @@ float previousAlpha = 1.f;
#endif #endif
// Layer calculations // Layer calculations
// rescale UV to directly map vertices to texel centers
// TODO: parameterize texel size
float2 blendUV = (UV - 0.5) * (8.0 / (8.0+1.0)) + 0.5;
@shForeach(@shPropertyString(num_blendmaps)) @shForeach(@shPropertyString(num_blendmaps))
float4 blendValues@shIterator = shSample(blendMap@shIterator, UV); float4 blendValues@shIterator = shSample(blendMap@shIterator, blendUV);
@shEndForeach @shEndForeach
float3 albedo = float3(0,0,0); float3 albedo = float3(0,0,0);
float2 layerUV = UV * 8;
@shForeach(@shPropertyString(num_layers)) @shForeach(@shPropertyString(num_layers))
#if IS_FIRST_PASS #if IS_FIRST_PASS
#if @shIterator == 0 #if @shIterator == 0
// first layer of first pass is the base layer and doesn't need a blend map // first layer of first pass is the base layer and doesn't need a blend map
albedo = shSample(diffuseMap0, UV * 10).rgb; albedo = shSample(diffuseMap0, layerUV).rgb;
#else #else
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); albedo = shLerp(albedo, shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator));
#endif #endif
#else #else
#if @shIterator == 0 #if @shIterator == 0
albedo = shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator); albedo = shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator);
#else #else
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); albedo = shLerp(albedo, shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator));
#endif #endif
previousAlpha *= 1.f-blendValues@shPropertyString(blendmap_component_@shIterator); previousAlpha *= 1.f-blendValues@shPropertyString(blendmap_component_@shIterator);
#endif #endif
@ -259,8 +264,13 @@ float previousAlpha = 1.f;
shOutputColour(0) = float4(1,1,1,1); shOutputColour(0) = float4(1,1,1,1);
#if COLOUR_MAP #if COLOUR_MAP
shOutputColour(0).rgb *= shSample(colourMap, UV).rgb; // Since we're emulating vertex colors here,
// rescale UV to directly map vertices to texel centers. TODO: parameterize texel size
const float colourmapSize = 33.f;
float2 colourUV = (UV - 0.5) * (colourmapSize / (colourmapSize+1.f)) + 0.5;
shOutputColour(0).rgb *= shSample(colourMap, colourUV).rgb;
#endif #endif
shOutputColour(0).rgb *= albedo; shOutputColour(0).rgb *= albedo;
@ -347,6 +357,7 @@ float previousAlpha = 1.f;
#else #else
shOutputColour(0).a = 1.f-previousAlpha; shOutputColour(0).a = 1.f-previousAlpha;
#endif #endif
} }
#endif #endif

View file

@ -33,6 +33,20 @@
</Widget> </Widget>
</Widget> </Widget>
<!-- Drowning bar -->
<Widget type="Widget" skin="HUD_Box" position="0 36 220 56" align="Center Top" name="DrowningFrame">
<Property key="Visible" value="false"/>
<Widget type="TextBox" skin="SandText" position="0 8 220 24" name="DrowningTitle" align="Center Top HStretch">
<Property key="Caption" value="#{sBreath}"/>
<Property key="TextAlign" value="Center"/>
<Property key="TextShadow" value="true"/>
<Property key="TextShadowColour" value="0 0 0"/>
</Widget>
<Widget type="ProgressBar" skin="MW_Progress_Loading" position="12 36 196 8" align="Center Top" name="Drowning">
<Property key="NeedMouse" value="false"/>
</Widget>
</Widget>
<!-- Equipped weapon/selected spell name display for a few seconds after it changes --> <!-- Equipped weapon/selected spell name display for a few seconds after it changes -->
<Widget type="TextBox" skin="SandText" position="13 118 270 24" name="WeaponSpellName" align="Left Bottom HStretch"> <Widget type="TextBox" skin="SandText" position="13 118 270 24" name="WeaponSpellName" align="Left Bottom HStretch">
<Property key="Visible" value="false"/> <Property key="Visible" value="false"/>

View file

@ -0,0 +1,118 @@
#include "lights.hpp"
#include <OgreLight.h>
#include <OgreMath.h>
namespace OEngine {
namespace Render {
LightFunction::LightFunction(LightType type)
: ControllerFunction<Ogre::Real>(true)
, mType(type)
, mPhase(Ogre::Math::RangeRandom(-500.0f, +500.0f))
, mDirection(1.0f)
{
}
Ogre::Real LightFunction::pulseAmplitude(Ogre::Real time)
{
return std::sin(time);
}
Ogre::Real LightFunction::flickerAmplitude(Ogre::Real time)
{
static const float fb = 1.17024f;
static const float f[3] = { 1.5708f, 4.18774f, 5.19934f };
static const float o[3] = { 0.804248f, 2.11115f, 3.46832f };
static const float m[3] = { 1.0f, 0.785f, 0.876f };
static const float s = 0.394f;
float v = 0.0f;
for(int i = 0;i < 3;++i)
v += std::sin(fb*time*f[i] + o[1])*m[i];
return v * s;
}
Ogre::Real LightFunction::flickerFrequency(Ogre::Real phase)
{
static const float fa = 0.785398f;
static const float tdo = 0.94f;
static const float tdm = 2.48f;
return tdo + tdm*std::sin(fa * phase);
}
Ogre::Real LightFunction::calculate(Ogre::Real value)
{
Ogre::Real brightness = 1.0f;
float cycle_time;
float time_distortion;
if(mType == LT_Pulse || mType == LT_PulseSlow)
{
cycle_time = 2.0f * Ogre::Math::PI;
time_distortion = 20.0f;
}
else
{
static const float fa = 0.785398f;
static const float phase_wavelength = 120.0f * 3.14159265359f / fa;
cycle_time = 500.0f;
mPhase = std::fmod(mPhase + value, phase_wavelength);
time_distortion = flickerFrequency(mPhase);
}
mDeltaCount += mDirection*value*time_distortion;
if(mDirection > 0 && mDeltaCount > +cycle_time)
{
mDirection = -1.0f;
mDeltaCount = 2.0f*cycle_time - mDeltaCount;
}
if(mDirection < 0 && mDeltaCount < -cycle_time)
{
mDirection = +1.0f;
mDeltaCount = -2.0f*cycle_time - mDeltaCount;
}
static const float fast = 4.0f/1.0f;
static const float slow = 1.0f/1.0f;
// These formulas are just guesswork, but they work pretty well
if(mType == LT_Normal)
{
// Less than 1/255 light modifier for a constant light:
brightness = 1.0 + flickerAmplitude(mDeltaCount*slow)/255.0f;
}
else if(mType == LT_Flicker)
brightness = 0.75 + flickerAmplitude(mDeltaCount*fast)*0.25;
else if(mType == LT_FlickerSlow)
brightness = 0.75 + flickerAmplitude(mDeltaCount*slow)*0.25;
else if(mType == LT_Pulse)
brightness = 1.0 + pulseAmplitude(mDeltaCount*fast)*0.25;
else if(mType == LT_PulseSlow)
brightness = 1.0 + pulseAmplitude(mDeltaCount*slow)*0.25;
return brightness;
}
LightValue::LightValue(Ogre::Light *light, const Ogre::ColourValue &color)
: mTarget(light)
, mColor(color)
{
}
Ogre::Real LightValue::getValue() const
{
return 0.0f;
}
void LightValue::setValue(Ogre::Real value)
{
mTarget->setDiffuseColour(mColor * value);
}
}
}

View file

@ -0,0 +1,51 @@
#ifndef OENGINE_OGRE_LIGHTS_H
#define OENGINE_OGRE_LIGHTS_H
#include <OgreController.h>
#include <OgreColourValue.h>
/*
* Controller classes to handle pulsing and flicker lights
*/
namespace OEngine {
namespace Render {
enum LightType {
LT_Normal,
LT_Flicker,
LT_FlickerSlow,
LT_Pulse,
LT_PulseSlow
};
class LightFunction : public Ogre::ControllerFunction<Ogre::Real>
{
LightType mType;
Ogre::Real mPhase;
Ogre::Real mDirection;
static Ogre::Real pulseAmplitude(Ogre::Real time);
static Ogre::Real flickerAmplitude(Ogre::Real time);
static Ogre::Real flickerFrequency(Ogre::Real phase);
public:
LightFunction(LightType type);
virtual Ogre::Real calculate(Ogre::Real value);
};
class LightValue : public Ogre::ControllerValue<Ogre::Real>
{
Ogre::Light *mTarget;
Ogre::ColourValue mColor;
public:
LightValue(Ogre::Light *light, const Ogre::ColourValue &color);
virtual Ogre::Real getValue() const;
virtual void setValue(Ogre::Real value);
};
}
}
#endif

View file

@ -4,6 +4,7 @@
#include <OgreRenderTexture.h> #include <OgreRenderTexture.h>
#include <OgreSubEntity.h> #include <OgreSubEntity.h>
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreTechnique.h>
#include <stdexcept> #include <stdexcept>
#include <extern/shiny/Main/Factory.hpp> #include <extern/shiny/Main/Factory.hpp>
@ -100,7 +101,16 @@ namespace Render
return m->getTechnique(1); return m->getTechnique(1);
} }
else else
throw std::runtime_error("selectionbuffer only works with entities"); {
m = Ogre::MaterialManager::getSingleton().getByName("NullMaterial");
if(m.isNull())
{
m = Ogre::MaterialManager::getSingleton().create("NullMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
m->getTechnique(0)->getPass(0)->setDepthCheckEnabled(true);
m->getTechnique(0)->getPass(0)->setDepthFunction(Ogre::CMPF_ALWAYS_FAIL);
}
return m->getTechnique(0);
}
} }
return NULL; return NULL;
} }