diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 57cc3560a..43e04ab52 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -53,32 +53,40 @@ namespace MWClass // NPC stats if (!ref->base->faction.empty()) { - // TODO research how initial rank is stored. The information in loadnpc.hpp are at - // best very unclear. - data->mNpcStats.mFactionRank[ref->base->faction] = 0; + if(ref->base->npdt52.gold != -10) + { + data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank; + } + else + { + data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank; + } } - for (int i=0; i<27; ++i) - data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); + if(ref->base->npdt52.gold != -10) + { + for (int i=0; i<27; ++i) + data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); - for (std::vector::const_iterator iter (ref->base->spells.list.begin()); - iter!=ref->base->spells.list.end(); ++iter) - data->mCreatureStats.mSpells.add (*iter); + // creature stats + data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); + data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); + data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); + data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); + data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); + data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); + data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); + data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); + data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); + data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); + data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); - // creature stats - data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); - data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); - data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); - data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); - data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); - data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); - data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); - data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); - data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); - data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); - data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); - - data->mCreatureStats.mLevel = ref->base->npdt52.level; + data->mCreatureStats.mLevel = ref->base->npdt52.level; + } + else + { + //TODO: do something with npdt12 maybe:p + } // \todo add initial container content @@ -285,7 +293,7 @@ namespace MWClass void Npc::registerSelf() { boost::shared_ptr instance (new Npc); - + std::cout << "class npc:" << typeid (ESM::NPC).name(); registerClass (typeid (ESM::NPC).name(), instance); } } diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index b06605cc2..90f0c0231 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -39,6 +39,9 @@ #include "../mwscript/interpretercontext.hpp" #include +#include "../mwclass/npc.hpp" +#include "../mwmechanics/npcstats.hpp" + namespace { std::string toLower (const std::string& name) @@ -109,16 +112,15 @@ namespace switch (world.getGlobalVariableType (name)) { case 's': - - return selectCompare (comp, value, world.getGlobalVariable (name).mShort); + return selectCompare (comp, world.getGlobalVariable (name).mShort, value); case 'l': - return selectCompare (comp, value, world.getGlobalVariable (name).mLong); + return selectCompare (comp, world.getGlobalVariable (name).mLong, value); case 'f': - return selectCompare (comp, value, world.getGlobalVariable (name).mFloat); + return selectCompare (comp, world.getGlobalVariable (name).mFloat, value); case ' ': @@ -178,7 +180,17 @@ namespace MWDialogue break; case 46://Same faction - if(!selectCompare(comp,0,select.i)) return false; + { + MWMechanics::NpcStats PCstats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor); + int sameFaction = 0; + if(!NPCstats.mFactionRank.empty()) + { + std::string NPCFaction = NPCstats.mFactionRank.begin()->first; + if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1; + } + if(!selectCompare(comp,sameFaction,select.i)) return false; + } break; case 48://Detected @@ -190,7 +202,6 @@ namespace MWDialogue break; case 50://choice - if(choice) { if(!selectCompare(comp,mChoice,select.i)) return false; @@ -270,7 +281,7 @@ namespace MWDialogue { case '1': // function - return true; // TODO implement functions + return true; // Done elsewhere. case '2': // global @@ -444,9 +455,6 @@ namespace MWDialogue if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) return false; - //PC Faction - if(!info.pcFaction.empty()) return false; - //NPC race if (!info.race.empty()) { @@ -474,26 +482,37 @@ namespace MWDialogue //NPC faction if (!info.npcFaction.empty()) { - ESMS::LiveCellRef *cellRef = actor.get(); - - if (!cellRef) - return false; - - if (toLower (info.npcFaction)!=toLower (cellRef->base->faction)) - return false; - - //check NPC rank - if(cellRef->base->npdt52.gold != -10) + //MWWorld::Class npcClass = MWWorld::Class::get(actor); + MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor); + std::map::iterator it = stats.mFactionRank.find(info.npcFaction); + if(it!=stats.mFactionRank.end()) { - if(cellRef->base->npdt52.rank < info.data.rank) return false; + //check rank + if(it->second < (int)info.data.rank) return false; } else { - if(cellRef->base->npdt12.rank < info.data.rank) return false; + //not in the faction + return false; } } // TODO check player faction + if(!info.pcFaction.empty()) + { + MWMechanics::NpcStats stats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + std::map::iterator it = stats.mFactionRank.find(info.pcFaction); + if(it!=stats.mFactionRank.end()) + { + //check rank + if(it->second < (int)info.data.PCrank) return false; + } + else + { + //not in the faction + return false; + } + } //check gender ESMS::LiveCellRef* npc = actor.get(); @@ -658,6 +677,7 @@ namespace MWDialogue void DialogueManager::executeScript(std::string script) { + std::cout << script; std::vector code; if(compile(script,code)) { @@ -799,4 +819,19 @@ namespace MWDialogue mChoiceMap[question] = choice; mIsInChoice = true; } + + std::string DialogueManager::getFaction() + { + std::string factionID(""); + MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor); + if(stats.mFactionRank.empty()) + { + std::cout << "No faction for this actor!"; + } + else + { + factionID = stats.mFactionRank.begin()->first; + } + return factionID; + } } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index 260d8e339..d0380fa71 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -63,6 +63,9 @@ namespace MWDialogue void askQuestion(std::string question,int choice); + ///get the faction of the actor you are talking with + std::string getFaction(); + //calbacks for the GUI void keywordSelected(std::string keyword); void goodbyeSelected(); diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 6d8aa901b..21302d7c1 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -67,17 +67,8 @@ HUD::HUD(int width, int height, int fpsLevel) getWidget(crosshair, "Crosshair"); - if ( fpsLevel == 2 ){ - getWidget(fpsbox, "FPSBoxAdv"); - fpsbox->setVisible(true); - getWidget(fpscounter, "FPSCounterAdv"); - }else if ( fpsLevel == 1 ){ - getWidget(fpsbox, "FPSBox"); - fpsbox->setVisible(true); - getWidget(fpscounter, "FPSCounter"); - }else{ - getWidget(fpscounter, "FPSCounter"); - } + setFpsLevel(fpsLevel); + getWidget(trianglecounter, "TriangleCounter"); getWidget(batchcounter, "BatchCounter"); @@ -95,6 +86,28 @@ HUD::HUD(int width, int height, int fpsLevel) LocalMapBase::init(minimap, this); } +void HUD::setFpsLevel(int level) +{ + MyGUI::Widget* fps; + getWidget(fps, "FPSBoxAdv"); + fps->setVisible(false); + getWidget(fps, "FPSBox"); + fps->setVisible(false); + + if (level == 2) + { + getWidget(fpsbox, "FPSBoxAdv"); + fpsbox->setVisible(true); + getWidget(fpscounter, "FPSCounterAdv"); + } + else if (level == 1) + { + getWidget(fpsbox, "FPSBox"); + fpsbox->setVisible(true); + getWidget(fpscounter, "FPSCounter"); + } +} + void HUD::setFPS(float fps) { fpscounter->setCaption(boost::lexical_cast((int)fps)); diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 0614708cf..19d96d2ef 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -78,6 +78,7 @@ namespace MWGui void setPlayerPos(const float x, const float y); void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); + void setFpsLevel(const int level); MyGUI::ProgressPtr health, magicka, stamina; MyGUI::Widget *weapBox, *spellBox; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 13b6fab31..34d62ba08 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -15,6 +15,8 @@ #include "journalwindow.hpp" #include "charactercreation.hpp" +#include + #include #include #include @@ -472,3 +474,11 @@ void WindowManager::toggleFogOfWar() map->toggleFogOfWar(); hud->toggleFogOfWar(); } + +int WindowManager::toggleFps() +{ + showFPSLevel = (showFPSLevel+1)%3; + hud->setFpsLevel(showFPSLevel); + Settings::Manager::setInt("fps", "HUD", showFPSLevel); + return showFPSLevel; +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index f1db11731..2b53560ba 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -158,7 +158,10 @@ namespace MWGui void setPlayerDir(const float x, const float y); ///< set player view direction in map space void toggleFogOfWar(); - + + int toggleFps(); + ///< toggle fps display @return resulting fps level + void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index bd27de029..9b5a9ae30 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -68,6 +68,8 @@ namespace MWInput A_ToggleWeapon, A_ToggleSpell, + A_ToggleFps, // Toggle FPS display (this is temporary) + A_LAST // Marker for the last item }; @@ -88,6 +90,11 @@ namespace MWInput /* InputImpl Methods */ + void toggleFps() + { + windows.toggleFps(); + } + void toggleSpell() { DrawState state = player.getDrawState(); @@ -235,6 +242,8 @@ namespace MWInput "Draw Weapon"); disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), "Ready hands"); + disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this), + "Toggle FPS display"); // Add the exit listener ogre.getRoot()->addFrameListener(&exit); @@ -281,6 +290,7 @@ namespace MWInput disp->bind(A_ToggleWalk, KC_C); disp->bind(A_ToggleWeapon,KC_F); disp->bind(A_ToggleSpell,KC_R); + disp->bind(A_ToggleFps, KC_F10); // Key bindings for polled keys // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame. diff --git a/apps/openmw/mwmechanics/drawstate.hpp b/apps/openmw/mwmechanics/drawstate.hpp index ded25f8d5..772086d90 100644 --- a/apps/openmw/mwmechanics/drawstate.hpp +++ b/apps/openmw/mwmechanics/drawstate.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWMECHANICS_DRAWSTATE_H #define GAME_MWMECHANICS_DRAWSTATE_H +#undef DrawState + enum DrawState { DrawState_Weapon = 0, diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index c69ed3a61..9785ec903 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -39,6 +39,8 @@ THE SOFTWARE. #include #include "renderingmanager.hpp" +#undef far + namespace Ogre { //--------------------------------------------------------------------- @@ -538,7 +540,6 @@ namespace Ogre params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, Terrain::LOD_MORPH_CUSTOM_PARAM); - params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { @@ -574,7 +575,7 @@ namespace Ogre { params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); - if (prof->getNumberOfLightsSupported() > 1) + if (i > 0) params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); //params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i); } @@ -584,6 +585,7 @@ namespace Ogre params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { @@ -811,11 +813,11 @@ namespace Ogre outStream << "out float4 oPos : POSITION,\n" - "out float4 oPosObj : COLOR \n"; + "out float4 oPosObj : TEXCOORD0 \n"; - uint texCoordSet = 0; + uint texCoordSet = 1; outStream << - ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<" // xy = uv, z = camDepth\n"; + ", out float4 oUVMisc : COLOR0 // xy = uv, z = camDepth\n"; // layer UV's premultiplied, packed as xy/zw uint numUVSets = numLayers / 2; @@ -835,14 +837,6 @@ namespace Ogre outStream << ", out float2 lodInfo : TEXCOORD" << texCoordSet++ << "\n"; } - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << - ", uniform float4 fogParams\n"; - //", out float fogVal : COLOR\n"; - } - if (prof->isShadowingEnabled(tt, terrain)) { texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); @@ -938,11 +932,11 @@ namespace Ogre outStream << "void main_fp(\n" - "float4 position : COLOR,\n"; + "float4 position : TEXCOORD0,\n"; - uint texCoordSet = 0; + uint texCoordSet = 1; outStream << - "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n"; + "float4 uvMisc : COLOR0,\n"; // UV's premultiplied, packed as xy/zw uint maxLayers = prof->getMaxLayers(terrain); @@ -969,8 +963,8 @@ namespace Ogre if (fog) { outStream << + "uniform float4 fogParams, \n" "uniform float3 fogColour, \n"; - //"float fogVal : COLOR,\n"; } uint currentSamplerIdx = 0; @@ -989,7 +983,7 @@ namespace Ogre //"uniform float3 lightSpecularColour"<getNumberOfLightsSupported() > 1) + if (i > 0) outStream << "uniform float4 lightAttenuation"<getNumberOfLightsSupported() > 1) + if (i > 0) outStream << // pre-multiply light color with attenuation factor "d = length( lightDir"<getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) - { - outStream << - " float fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; - } - else - { - outStream << - " float fogVal = saturate(1 / (exp(oPos.z * fogParams.x)));\n"; - } - outStream << - " oPosObj.w = fogVal; \n"; - } + " oPosObj.w = oPos.z;\n"; if (prof->isShadowingEnabled(tt, terrain)) generateVpDynamicShadows(prof, terrain, tt, outStream); @@ -1373,6 +1349,16 @@ namespace Ogre bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; if (fog) { + if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) + { + outStream << + " float fogVal = saturate((position.w - fogParams.y) * fogParams.w);\n"; + } + else + { + outStream << + " float fogVal = saturate(1 / (exp(position.w * fogParams.x)));\n"; + } outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n"; } @@ -1380,7 +1366,7 @@ namespace Ogre outStream << " oColor = outputCol;\n"; if (MWRender::RenderingManager::useMRT()) outStream << - " oColor1 = float4(uvMisc.z / far, 0, 0, 1); \n"; + " oColor1 = float4(position.w / far, 0, 0, 1); \n"; outStream << "}\n"; @@ -1589,7 +1575,7 @@ namespace Ogre { uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); outStream << - " float camDepth = uvMisc.z;\n"; + " float camDepth = position.w;\n"; if (prof->getReceiveDynamicShadowsDepth()) { @@ -1633,8 +1619,8 @@ namespace Ogre outStream << " float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n" - " float fade = 1-((uvMisc.z - shadowFar_fadeStart.y) / fadeRange); \n" - " rtshadow = (uvMisc.z > shadowFar_fadeStart.x) ? 1 : ((uvMisc.z > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" + " float fade = 1-((position.w - shadowFar_fadeStart.y) / fadeRange); \n" + " rtshadow = (position.w > shadowFar_fadeStart.x) ? 1 : ((position.w > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" " rtshadow = (1-(1-rtshadow)*0.6); \n" // make the shadow a little less intensive " shadow = min(shadow, rtshadow);\n"; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 1317794fa..fda8d1954 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -24,7 +24,10 @@ op 0x20007: PlayAnim, explicit reference op 0x20008: LoopAnim op 0x20009: LoopAnim, explicit reference op 0x2000a: Choice -opcodes 0x2000b-0x3ffff unused +op 0x2000b: PCRaiseRank +op 0x2000c: PCLowerRank +op x20000d: PCJoinFaction +opcodes 0x2000e-0x3ffff unused Segment 4: (not implemented yet) @@ -135,4 +138,6 @@ op 0x2000149: RemoveSpell op 0x200014a: RemoveSpell, explicit reference op 0x200014b: GetSpell op 0x200014c: GetSpell, explicit reference -opcodes 0x200014d-0x3ffffff unused +op 0x200014d: ModDisposition +op 0x200014e: ModDisposition, explicit reference +opcodes 0x200014f-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 011b8b010..9d3009870 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -8,6 +8,8 @@ #include #include "../mwworld/class.hpp" +#include "../mwworld/environment.hpp" +#include "../mwworld/player.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" @@ -15,6 +17,8 @@ #include "interpretercontext.hpp" #include "ref.hpp" +#include "../mwdialogue/dialoguemanager.hpp" + namespace MWScript { namespace Stats @@ -319,6 +323,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); std::string id = runtime.getStringLiteral (runtime[0].mInteger); @@ -339,6 +344,113 @@ namespace MWScript } }; + class OpPCJoinFaction : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; + } + } + } + }; + + class OpPCRaiseRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; + } + else + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] +1; + } + } + } + }; + + class OpPCLowerRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) != MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] -1; + } + } + } + }; + + template + class OpModDisposition : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + +// Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + /// \todo modify disposition towards the player + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -377,6 +489,12 @@ namespace MWScript const int opcodeGetSpell = 0x200014b; const int opcodeGetSpellExplicit = 0x200014c; + const int opcodePCRaiseRank = 0x2000b; + const int opcodePCLowerRank = 0x2000c; + const int opcodePCJoinFaction = 0x2000d; + const int opcodeModDisposition = 0x200014d; + const int opcodeModDispositionExplicit = 0x200014e; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -452,6 +570,12 @@ namespace MWScript 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); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -515,6 +639,12 @@ namespace MWScript new OpRemoveSpell); interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell); interpreter.installSegment5 (opcodeGetSpellExplicit, new OpGetSpell); + + interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); + interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); + interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction); + interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); + interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); } } }