Merge remote branch 'gus/Factions2'

Conflicts:
	apps/openmw/mwclass/npc.cpp
	apps/openmw/mwscript/docs/vmformat.txt
	apps/openmw/mwscript/statsextensions.cpp
actorid
Marc Zinnschlag 13 years ago
commit 73df51695c

@ -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]);
for (std::vector<std::string>::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);
data->mCreatureStats.mLevel = ref->base->npdt52.level;
if(ref->base->npdt52.gold != -10)
{
for (int i=0; i<27; ++i)
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
// 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;
}
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<Class> instance (new Npc);
std::cout << "class npc:" << typeid (ESM::NPC).name();
registerClass (typeid (ESM::NPC).name(), instance);
}
}

@ -39,6 +39,9 @@
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/scriptparser.hpp>
#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<int,int>(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<int,int>(comp,sameFaction,select.i)) return false;
}
break;
case 48://Detected
@ -190,7 +202,6 @@ namespace MWDialogue
break;
case 50://choice
if(choice)
{
if(!selectCompare<int,int>(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<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
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<std::string,int>::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<std::string,int>::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<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@ -658,6 +677,7 @@ namespace MWDialogue
void DialogueManager::executeScript(std::string script)
{
std::cout << script;
std::vector<Interpreter::Type_Code> 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;
}
}

@ -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();

@ -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,5 @@ op 0x2000149: RemoveSpell
op 0x200014a: RemoveSpell, explicit reference
op 0x200014b: GetSpell
op 0x200014c: GetSpell, explicit reference
opcodes 0x200014d-0x3ffffff unused
op 0x200014d: ModDisposition
opcodes 0x200014e-0x3ffffff unused

@ -8,6 +8,8 @@
#include <components/interpreter/opcodes.hpp>
#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,107 @@ 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<MWScript::InterpreterContext&> (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<MWScript::InterpreterContext&> (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<MWScript::InterpreterContext&> (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;
}
}
}
};
class OpModDisposition : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
}
};
const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027;
@ -377,6 +483,11 @@ 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;
void registerExtensions (Compiler::Extensions& extensions)
{
static const char *attributes[numberOfAttributes] =
@ -452,6 +563,11 @@ 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);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
@ -515,6 +631,11 @@ namespace MWScript
new OpRemoveSpell<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank);
interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank);
interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction);
interpreter.installSegment5(opcodeModDisposition,new OpModDisposition);
}
}
}

Loading…
Cancel
Save