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,18 +53,21 @@ namespace MWClass
// NPC stats // NPC stats
if (!ref->base->faction.empty()) if (!ref->base->faction.empty())
{ {
// TODO research how initial rank is stored. The information in loadnpc.hpp are at if(ref->base->npdt52.gold != -10)
// best very unclear. {
data->mNpcStats.mFactionRank[ref->base->faction] = 0; data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank;
}
else
{
data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank;
}
} }
if(ref->base->npdt52.gold != -10)
{
for (int i=0; i<27; ++i) for (int i=0; i<27; ++i)
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[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 // creature stats
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
@ -79,6 +82,11 @@ namespace MWClass
data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); 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 // \todo add initial container content
@ -285,7 +293,7 @@ namespace MWClass
void Npc::registerSelf() void Npc::registerSelf()
{ {
boost::shared_ptr<Class> instance (new Npc); boost::shared_ptr<Class> instance (new Npc);
std::cout << "class npc:" << typeid (ESM::NPC).name();
registerClass (typeid (ESM::NPC).name(), instance); registerClass (typeid (ESM::NPC).name(), instance);
} }
} }

@ -39,6 +39,9 @@
#include "../mwscript/interpretercontext.hpp" #include "../mwscript/interpretercontext.hpp"
#include <components/compiler/scriptparser.hpp> #include <components/compiler/scriptparser.hpp>
#include "../mwclass/npc.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace namespace
{ {
std::string toLower (const std::string& name) std::string toLower (const std::string& name)
@ -109,16 +112,15 @@ namespace
switch (world.getGlobalVariableType (name)) switch (world.getGlobalVariableType (name))
{ {
case 's': case 's':
return selectCompare (comp, world.getGlobalVariable (name).mShort, value);
return selectCompare (comp, value, world.getGlobalVariable (name).mShort);
case 'l': case 'l':
return selectCompare (comp, value, world.getGlobalVariable (name).mLong); return selectCompare (comp, world.getGlobalVariable (name).mLong, value);
case 'f': case 'f':
return selectCompare (comp, value, world.getGlobalVariable (name).mFloat); return selectCompare (comp, world.getGlobalVariable (name).mFloat, value);
case ' ': case ' ':
@ -178,7 +180,17 @@ namespace MWDialogue
break; break;
case 46://Same faction 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; break;
case 48://Detected case 48://Detected
@ -190,7 +202,6 @@ namespace MWDialogue
break; break;
case 50://choice case 50://choice
if(choice) if(choice)
{ {
if(!selectCompare<int,int>(comp,mChoice,select.i)) return false; if(!selectCompare<int,int>(comp,mChoice,select.i)) return false;
@ -270,7 +281,7 @@ namespace MWDialogue
{ {
case '1': // function case '1': // function
return true; // TODO implement functions return true; // Done elsewhere.
case '2': // global case '2': // global
@ -444,9 +455,6 @@ namespace MWDialogue
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
return false; return false;
//PC Faction
if(!info.pcFaction.empty()) return false;
//NPC race //NPC race
if (!info.race.empty()) if (!info.race.empty())
{ {
@ -474,26 +482,37 @@ namespace MWDialogue
//NPC faction //NPC faction
if (!info.npcFaction.empty()) if (!info.npcFaction.empty())
{ {
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>(); //MWWorld::Class npcClass = MWWorld::Class::get(actor);
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
if (!cellRef) std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
return false; if(it!=stats.mFactionRank.end())
if (toLower (info.npcFaction)!=toLower (cellRef->base->faction))
return false;
//check NPC rank
if(cellRef->base->npdt52.gold != -10)
{ {
if(cellRef->base->npdt52.rank < info.data.rank) return false; //check rank
if(it->second < (int)info.data.rank) return false;
} }
else else
{ {
if(cellRef->base->npdt12.rank < info.data.rank) return false; //not in the faction
return false;
} }
} }
// TODO check player faction // 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 //check gender
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>(); ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@ -658,6 +677,7 @@ namespace MWDialogue
void DialogueManager::executeScript(std::string script) void DialogueManager::executeScript(std::string script)
{ {
std::cout << script;
std::vector<Interpreter::Type_Code> code; std::vector<Interpreter::Type_Code> code;
if(compile(script,code)) if(compile(script,code))
{ {
@ -799,4 +819,19 @@ namespace MWDialogue
mChoiceMap[question] = choice; mChoiceMap[question] = choice;
mIsInChoice = true; 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); void askQuestion(std::string question,int choice);
///get the faction of the actor you are talking with
std::string getFaction();
//calbacks for the GUI //calbacks for the GUI
void keywordSelected(std::string keyword); void keywordSelected(std::string keyword);
void goodbyeSelected(); void goodbyeSelected();

@ -24,7 +24,10 @@ op 0x20007: PlayAnim, explicit reference
op 0x20008: LoopAnim op 0x20008: LoopAnim
op 0x20009: LoopAnim, explicit reference op 0x20009: LoopAnim, explicit reference
op 0x2000a: Choice op 0x2000a: Choice
opcodes 0x2000b-0x3ffff unused op 0x2000b: PCRaiseRank
op 0x2000c: PCLowerRank
op x20000d: PCJoinFaction
opcodes 0x2000e-0x3ffff unused
Segment 4: Segment 4:
(not implemented yet) (not implemented yet)
@ -135,4 +138,5 @@ op 0x2000149: RemoveSpell
op 0x200014a: RemoveSpell, explicit reference op 0x200014a: RemoveSpell, explicit reference
op 0x200014b: GetSpell op 0x200014b: GetSpell
op 0x200014c: GetSpell, explicit reference 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 <components/interpreter/opcodes.hpp>
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
@ -15,6 +17,8 @@
#include "interpretercontext.hpp" #include "interpretercontext.hpp"
#include "ref.hpp" #include "ref.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
namespace MWScript namespace MWScript
{ {
namespace Stats namespace Stats
@ -319,6 +323,7 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
std::string id = runtime.getStringLiteral (runtime[0].mInteger); 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 numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027; const int opcodeGetAttribute = 0x2000027;
@ -377,6 +483,11 @@ namespace MWScript
const int opcodeGetSpell = 0x200014b; const int opcodeGetSpell = 0x200014b;
const int opcodeGetSpellExplicit = 0x200014c; 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) void registerExtensions (Compiler::Extensions& extensions)
{ {
static const char *attributes[numberOfAttributes] = static const char *attributes[numberOfAttributes] =
@ -452,6 +563,11 @@ namespace MWScript
extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell, extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
opcodeRemoveSpellExplicit); opcodeRemoveSpellExplicit);
extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit); 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) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -515,6 +631,11 @@ namespace MWScript
new OpRemoveSpell<ExplicitRef>); new OpRemoveSpell<ExplicitRef>);
interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell<ImplicitRef>); interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell<ImplicitRef>);
interpreter.installSegment5 (opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>); 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