forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'kcat/script-functions'
This commit is contained in:
commit
aee0336780
12 changed files with 168 additions and 13 deletions
|
@ -389,6 +389,10 @@ namespace MWBase
|
|||
|
||||
/// Turn actor into werewolf or normal form.
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
||||
|
||||
/// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST.
|
||||
/// It only applies to the current form the NPC is in.
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -393,6 +393,11 @@ void MWMechanics::NpcStats::setWerewolf (bool set)
|
|||
for(size_t i = 0;i < ESM::Skill::Length;i++)
|
||||
{
|
||||
mWerewolfSkill[i] = getSkill(i);
|
||||
|
||||
// Acrobatics is set separately for some reason.
|
||||
if(i == ESM::Skill::Acrobatics)
|
||||
continue;
|
||||
|
||||
// "Mercantile"! >_<
|
||||
std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
|
||||
ESM::Skill::sSkillNames[i]);
|
||||
|
|
|
@ -349,5 +349,7 @@ op 0x2000219: UndoWerewolf
|
|||
op 0x200021a: UndoWerewolfExplicit
|
||||
op 0x200021b: SetWerewolfAcrobatics
|
||||
op 0x200021c: SetWerewolfAcrobaticsExplicit
|
||||
op 0x200021d: ShowVars
|
||||
op 0x200021e: ShowVarsExplicit
|
||||
|
||||
opcodes 0x200021d-0x3ffffff unused
|
||||
opcodes 0x200021f-0x3ffffff unused
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
|
||||
#include "miscextensions.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <libs/openengine/ogre/fader.hpp>
|
||||
|
||||
#include <components/compiler/extensions.hpp>
|
||||
#include <components/compiler/opcodes.hpp>
|
||||
#include <components/compiler/locals.hpp>
|
||||
|
||||
#include <components/interpreter/interpreter.hpp>
|
||||
#include <components/interpreter/runtime.hpp>
|
||||
|
@ -12,6 +15,7 @@
|
|||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/scriptmanager.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
@ -315,10 +319,15 @@ namespace MWScript
|
|||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
int key = runtime[0].mInteger;
|
||||
std::string effect = runtime.getStringLiteral(runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
runtime.push (MWWorld::Class::get(ptr).getCreatureStats (ptr).getMagicEffects ().get (
|
||||
char *end;
|
||||
long key = strtol(effect.c_str(), &end, 10);
|
||||
if(key < 0 || key > 32767 || *end != '\0')
|
||||
key = ESM::MagicEffect::effectStringToId(effect);
|
||||
|
||||
runtime.push(MWWorld::Class::get(ptr).getCreatureStats(ptr).getMagicEffects().get(
|
||||
MWMechanics::EffectKey(key)).mMagnitude > 0);
|
||||
}
|
||||
};
|
||||
|
@ -630,6 +639,87 @@ namespace MWScript
|
|||
};
|
||||
|
||||
|
||||
template <class R>
|
||||
class OpShowVars : public Interpreter::Opcode0
|
||||
{
|
||||
void printLocalVars(Interpreter::Runtime &runtime, const MWWorld::Ptr &ptr)
|
||||
{
|
||||
std::stringstream str;
|
||||
|
||||
const std::string script = MWWorld::Class::get(ptr).getScript(ptr);
|
||||
if(script.empty())
|
||||
str<< ptr.getCellRef().mRefID<<" ("<<ptr.getRefData().getHandle()<<") does not have a script.";
|
||||
else
|
||||
{
|
||||
str<< "Local variables for "<<ptr.getCellRef().mRefID<<" ("<<ptr.getRefData().getHandle()<<")";
|
||||
|
||||
const Locals &locals = ptr.getRefData().getLocals();
|
||||
const Compiler::Locals &complocals = MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||
|
||||
const std::vector<std::string> *names = &complocals.get('s');
|
||||
for(size_t i = 0;i < names->size();++i)
|
||||
{
|
||||
if(i >= locals.mShorts.size())
|
||||
break;
|
||||
str<<std::endl<< " "<<(*names)[i]<<" = "<<locals.mShorts[i]<<" (short)";
|
||||
}
|
||||
names = &complocals.get('l');
|
||||
for(size_t i = 0;i < names->size();++i)
|
||||
{
|
||||
if(i >= locals.mLongs.size())
|
||||
break;
|
||||
str<<std::endl<< " "<<(*names)[i]<<" = "<<locals.mLongs[i]<<" (long)";
|
||||
}
|
||||
names = &complocals.get('f');
|
||||
for(size_t i = 0;i < names->size();++i)
|
||||
{
|
||||
if(i >= locals.mFloats.size())
|
||||
break;
|
||||
str<<std::endl<< " "<<(*names)[i]<<" = "<<locals.mFloats[i]<<" (float)";
|
||||
}
|
||||
}
|
||||
|
||||
runtime.getContext().report(str.str());
|
||||
}
|
||||
|
||||
void printGlobalVars(Interpreter::Runtime &runtime)
|
||||
{
|
||||
std::stringstream str;
|
||||
str<< "Global variables:";
|
||||
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
std::vector<std::string> names = world->getGlobals();
|
||||
for(size_t i = 0;i < names.size();++i)
|
||||
{
|
||||
char type = world->getGlobalVariableType(names[i]);
|
||||
if(type == 's')
|
||||
str<<std::endl<< " "<<names[i]<<" = "<<world->getGlobalVariable(names[i]).mShort<<" (short)";
|
||||
else if(type == 'l')
|
||||
str<<std::endl<< " "<<names[i]<<" = "<<world->getGlobalVariable(names[i]).mLong<<" (long)";
|
||||
else if(type == 'f')
|
||||
str<<std::endl<< " "<<names[i]<<" = "<<world->getGlobalVariable(names[i]).mFloat<<" (float)";
|
||||
}
|
||||
|
||||
runtime.getContext().report(str.str());
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void execute(Interpreter::Runtime& runtime)
|
||||
{
|
||||
// No way to tell if we have a reference before trying to get it, and it will
|
||||
// cause an exception is there isn't one :(
|
||||
try {
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
printLocalVars(runtime, ptr);
|
||||
}
|
||||
catch(std::runtime_error&) {
|
||||
// No reference, no problem.
|
||||
printGlobalVars(runtime);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
{
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox);
|
||||
|
@ -685,6 +775,8 @@ namespace MWScript
|
|||
interpreter.installSegment5 (Compiler::Misc::opcodeHitOnMeExplicit, new OpHitOnMe<ExplicitRef>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeDisableTeleporting, new OpEnableTeleporting<false>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeEnableTeleporting, new OpEnableTeleporting<true>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeShowVars, new OpShowVars<ImplicitRef>);
|
||||
interpreter.installSegment5 (Compiler::Misc::opcodeShowVarsExplicit, new OpShowVars<ExplicitRef>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1076,8 +1076,8 @@ namespace MWScript
|
|||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
// What to do? Stats (attributes, skills) are already set and unset with
|
||||
// BecomeWerewolf and UndoWerewolf.
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
MWBase::Environment::get().getWorld()->applyWerewolfAcrobatics(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1925,4 +1925,12 @@ namespace MWWorld
|
|||
mRendering->rebuildPtr(actor);
|
||||
}
|
||||
|
||||
void World::applyWerewolfAcrobatics(const Ptr &actor)
|
||||
{
|
||||
const Store<ESM::GameSetting> &gmst = getStore().get<ESM::GameSetting>();
|
||||
MWMechanics::NpcStats &stats = Class::get(actor).getNpcStats(actor);
|
||||
|
||||
stats.getSkill(ESM::Skill::Acrobatics).setModified(gmst.find("fWerewolfAcrobatics")->getFloat(), 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -432,6 +432,8 @@ namespace MWWorld
|
|||
virtual bool isTeleportingEnabled() const;
|
||||
|
||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
|
||||
|
||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ namespace Compiler
|
|||
extensions.registerInstruction ("wakeuppc", "", opcodeWakeUpPc);
|
||||
extensions.registerInstruction ("playbink", "Sl", opcodePlayBink);
|
||||
extensions.registerFunction ("getlocked", 'l', "", opcodeGetLocked, opcodeGetLockedExplicit);
|
||||
extensions.registerFunction ("geteffect", 'l', "l", opcodeGetEffect, opcodeGetEffectExplicit);
|
||||
extensions.registerFunction ("geteffect", 'l', "S", opcodeGetEffect, opcodeGetEffectExplicit);
|
||||
extensions.registerInstruction ("addsoulgem", "cc", opcodeAddSoulGem, opcodeAddSoulGemExplicit);
|
||||
extensions.registerInstruction ("removesoulgem", "c", opcodeRemoveSoulGem, opcodeRemoveSoulGemExplicit);
|
||||
extensions.registerInstruction ("drop", "cl", opcodeDrop, opcodeDropExplicit);
|
||||
|
@ -256,6 +256,8 @@ namespace Compiler
|
|||
extensions.registerFunction ("hitonme", 'l', "S", opcodeHitOnMe, opcodeHitOnMeExplicit);
|
||||
extensions.registerInstruction ("disableteleporting", "", opcodeDisableTeleporting);
|
||||
extensions.registerInstruction ("enableteleporting", "", opcodeEnableTeleporting);
|
||||
extensions.registerInstruction ("showvars", "", opcodeShowVars, opcodeShowVarsExplicit);
|
||||
extensions.registerInstruction ("sv", "", opcodeShowVars, opcodeShowVarsExplicit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@ namespace Compiler
|
|||
std::vector<std::string> mLongs;
|
||||
std::vector<std::string> mFloats;
|
||||
|
||||
const std::vector<std::string>& get (char type) const;
|
||||
|
||||
int searchIndex (char type, const std::string& name) const;
|
||||
|
||||
bool search (char type, const std::string& name) const;
|
||||
|
@ -31,6 +29,8 @@ namespace Compiler
|
|||
int getIndex (const std::string& name) const;
|
||||
///< return index for local variable \a name (-1: does not exist).
|
||||
|
||||
const std::vector<std::string>& get (char type) const;
|
||||
|
||||
void write (std::ostream& localFile) const;
|
||||
///< write declarations to file.
|
||||
|
||||
|
|
|
@ -219,6 +219,8 @@ namespace Compiler
|
|||
const int opcodeHitOnMeExplicit = 0x2000214;
|
||||
const int opcodeDisableTeleporting = 0x2000215;
|
||||
const int opcodeEnableTeleporting = 0x2000216;
|
||||
const int opcodeShowVars = 0x200021d;
|
||||
const int opcodeShowVarsExplicit = 0x200021e;
|
||||
}
|
||||
|
||||
namespace Sky
|
||||
|
|
|
@ -83,7 +83,8 @@ void MagicEffect::save(ESMWriter &esm)
|
|||
esm.writeHNOString("DESC", mDescription);
|
||||
}
|
||||
|
||||
std::string MagicEffect::effectIdToString(short effectID)
|
||||
|
||||
static std::map<short,std::string> genNameMap()
|
||||
{
|
||||
// Map effect ID to GMST name
|
||||
// http://www.uesp.net/morrow/hints/mweffects.shtml
|
||||
|
@ -235,10 +236,43 @@ std::string MagicEffect::effectIdToString(short effectID)
|
|||
// tribunal
|
||||
names[137] ="sEffectSummonFabricant";
|
||||
|
||||
if (names.find(effectID) == names.end())
|
||||
throw std::runtime_error( std::string("Unimplemented effect ID ") + boost::lexical_cast<std::string>(effectID));
|
||||
return names;
|
||||
}
|
||||
const std::map<short,std::string> MagicEffect::sNames = genNameMap();
|
||||
|
||||
return names[effectID];
|
||||
const std::string &MagicEffect::effectIdToString(short effectID)
|
||||
{
|
||||
std::map<short,std::string>::const_iterator name = sNames.find(effectID);
|
||||
if(name == sNames.end())
|
||||
throw std::runtime_error(std::string("Unimplemented effect ID ")+boost::lexical_cast<std::string>(effectID));
|
||||
|
||||
return name->second;
|
||||
}
|
||||
|
||||
class FindSecond {
|
||||
const std::string &mName;
|
||||
|
||||
public:
|
||||
FindSecond(const std::string &name) : mName(name) { }
|
||||
|
||||
bool operator()(const std::pair<short,std::string> &item) const
|
||||
{
|
||||
if(Misc::StringUtils::ciEqual(item.second, mName))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
short MagicEffect::effectStringToId(const std::string &effect)
|
||||
{
|
||||
std::map<short,std::string>::const_iterator name;
|
||||
|
||||
name = std::find_if(sNames.begin(), sNames.end(), FindSecond(effect));
|
||||
if(name == sNames.end())
|
||||
throw std::runtime_error(std::string("Unimplemented effect ")+effect);
|
||||
|
||||
return name->first;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define OPENMW_ESM_MGEF_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -42,7 +43,10 @@ struct MagicEffect
|
|||
float mSpeed, mSize, mSizeCap;
|
||||
}; // 36 bytes
|
||||
|
||||
static std::string effectIdToString(short effectID);
|
||||
static const std::map<short,std::string> sNames;
|
||||
|
||||
static const std::string &effectIdToString(short effectID);
|
||||
static short effectStringToId(const std::string &effect);
|
||||
|
||||
|
||||
MEDTstruct mData;
|
||||
|
|
Loading…
Reference in a new issue