1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-19 10:09:43 +00:00

Implemented script commands StartCombat, StopCombat, GetTarget.

Also renamed one field of AIWander class because it's not longer
unknown.
This commit is contained in:
Sergey Shambir 2014-01-07 04:12:37 +04:00
parent 0ad7aa1f53
commit 5c7e39a92f
15 changed files with 154 additions and 48 deletions

View file

@ -13,8 +13,8 @@ void printAIPackage(ESM::AIPackage p)
std::cout << " Distance: " << p.mWander.mDistance << std::endl; std::cout << " Distance: " << p.mWander.mDistance << std::endl;
std::cout << " Duration: " << p.mWander.mDuration << std::endl; std::cout << " Duration: " << p.mWander.mDuration << std::endl;
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
if (p.mWander.mUnk != 1) if (p.mWander.mShouldRepeat != 1)
std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl; std::cout << " Unknown: " << (int)p.mWander.mShouldRepeat << std::endl;
std::cout << " Idle: "; std::cout << " Idle: ";
for (int i = 0; i != 8; i++) for (int i = 0; i != 8; i++)

View file

@ -1,21 +1,21 @@
#include "aiactivate.hpp" #include "aiactivate.hpp"
#include <iostream> #include <iostream>
MWMechanics::AiActivate::AiActivate(const std::string &objectId) MWMechanics::AiActivate::AiActivate(const std::string &objectId)
: mObjectId(objectId) : mObjectId(objectId)
{ {
} }
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
{ {
return new AiActivate(*this); return new AiActivate(*this);
} }
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
{ {
std::cout << "AiActivate completed.\n"; std::cout << "AiActivate completed.\n";
return true; return true;
} }
int MWMechanics::AiActivate::getTypeId() const int MWMechanics::AiActivate::getTypeId() const
{ {
return 4; return TypeIdActivate;
} }

View file

@ -135,7 +135,7 @@ namespace MWMechanics
int AiCombat::getTypeId() const int AiCombat::getTypeId() const
{ {
return 5; return TypeIdCombat;
} }
unsigned int AiCombat::getPriority() const unsigned int AiCombat::getPriority() const
@ -143,6 +143,11 @@ namespace MWMechanics
return 1; return 1;
} }
const std::string &AiCombat::getTargetId() const
{
return mTargetId;
}
AiCombat *MWMechanics::AiCombat::clone() const AiCombat *MWMechanics::AiCombat::clone() const
{ {
return new AiCombat(*this); return new AiCombat(*this);

View file

@ -23,6 +23,8 @@ namespace MWMechanics
virtual unsigned int getPriority() const; virtual unsigned int getPriority() const;
const std::string &getTargetId() const;
private: private:
std::string mTargetId; std::string mTargetId;
@ -33,4 +35,4 @@ namespace MWMechanics
}; };
} }
#endif #endif

View file

@ -179,7 +179,7 @@ namespace MWMechanics
int AiEscort::getTypeId() const int AiEscort::getTypeId() const
{ {
return 2; return TypeIdEscort;
} }
} }

View file

@ -1,7 +1,7 @@
#include "aifollow.hpp" #include "aifollow.hpp"
#include <iostream> #include <iostream>
MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z) MWMechanics::AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z)
: mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId) : mDuration(duration), mX(x), mY(y), mZ(z), mActorId(actorId)
{ {
} }
@ -10,18 +10,18 @@ MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &ce
{ {
} }
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
{ {
return new AiFollow(*this); return new AiFollow(*this);
} }
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration) bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
{ {
std::cout << "AiFollow completed.\n"; std::cout << "AiFollow completed.\n";
return true; return true;
} }
int MWMechanics::AiFollow::getTypeId() const int MWMechanics::AiFollow::getTypeId() const
{ {
return 3; return TypeIdFollow;
} }

View file

@ -12,7 +12,16 @@ namespace MWMechanics
class AiPackage class AiPackage
{ {
public: public:
enum TypeId {
TypeIdNone = -1,
TypeIdWander = 0,
TypeIdTravel = 1,
TypeIdEscort = 2,
TypeIdFollow = 3,
TypeIdActivate = 4,
TypeIdCombat = 5
};
virtual ~AiPackage(); virtual ~AiPackage();
virtual AiPackage *clone() const = 0; virtual AiPackage *clone() const = 0;
@ -21,7 +30,7 @@ namespace MWMechanics
///< \return Package completed? ///< \return Package completed?
virtual int getTypeId() const = 0; virtual int getTypeId() const = 0;
///< 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate ///< @see enum TypeId
virtual unsigned int getPriority() const {return 0;} virtual unsigned int getPriority() const {return 0;}
///< higher number is higher priority (0 beeing the lowest) ///< higher number is higher priority (0 beeing the lowest)

View file

@ -56,6 +56,21 @@ int MWMechanics::AiSequence::getTypeId() const
return mPackages.front()->getTypeId(); return mPackages.front()->getTypeId();
} }
bool MWMechanics::AiSequence::getCombatTarget(std::string &targetActorId) const
{
if (getTypeId() != AiPackage::TypeIdCombat)
return false;
const AiCombat *combat = static_cast<const AiCombat *>(mPackages.front());
targetActorId = combat->getTargetId();
return true;
}
void MWMechanics::AiSequence::stopCombat()
{
while (getTypeId() == AiPackage::TypeIdCombat)
mPackages.erase (mPackages.begin());
}
bool MWMechanics::AiSequence::isPackageDone() const bool MWMechanics::AiSequence::isPackageDone() const
{ {
return mDone; return mDone;
@ -114,7 +129,7 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
std::vector<int> idles; std::vector<int> idles;
for (int i=0; i<8; ++i) for (int i=0; i<8; ++i)
idles.push_back(data.mIdle[i]); idles.push_back(data.mIdle[i]);
package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mUnk); package = new MWMechanics::AiWander(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat);
} }
else if (it->mType == ESM::AI_Escort) else if (it->mType == ESM::AI_Escort)
{ {

View file

@ -34,7 +34,14 @@ namespace MWMechanics
virtual ~AiSequence(); virtual ~AiSequence();
int getTypeId() const; int getTypeId() const;
///< -1: None, 0: Wanter, 1 Travel, 2 Escort, 3 Follow, 4 Activate, 5 Combat ///< @see enum AiPackage::TypeId
bool getCombatTarget (std::string &targetActorId) const;
///< Return true and assign target if combat package is currently
/// active, return false otherwise
void stopCombat();
///< Removes all combat packages until first non-combat or stack empty.
bool isPackageDone() const; bool isPackageDone() const;
///< Has a package been completed during the last update? ///< Has a package been completed during the last update?

View file

@ -106,7 +106,7 @@ namespace MWMechanics
int AiTravel::getTypeId() const int AiTravel::getTypeId() const
{ {
return 1; return TypeIdTravel;
} }
} }

View file

@ -254,7 +254,7 @@ namespace MWMechanics
int AiWander::getTypeId() const int AiWander::getTypeId() const
{ {
return 0; return TypeIdWander;
} }
void AiWander::stopWalking(const MWWorld::Ptr& actor) void AiWander::stopWalking(const MWWorld::Ptr& actor)

View file

@ -16,6 +16,7 @@
#include "../mwmechanics/aifollow.hpp" #include "../mwmechanics/aifollow.hpp"
#include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aitravel.hpp"
#include "../mwmechanics/aiwander.hpp" #include "../mwmechanics/aiwander.hpp"
#include "../mwmechanics/aicombat.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -399,6 +400,58 @@ namespace MWScript
} }
}; };
template<class R>
class OpGetTarget : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime &runtime)
{
MWWorld::Ptr actor = R()(runtime);
std::string testedTargetId = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
const MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
std::string currentTargetId;
bool targetsAreEqual = false;
if (creatureStats.getAiSequence().getCombatTarget (currentTargetId))
{
if (currentTargetId == testedTargetId)
targetsAreEqual = true;
}
runtime.push(int(targetsAreEqual));
}
};
template<class R>
class OpStartCombat : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime &runtime)
{
MWWorld::Ptr actor = R()(runtime);
std::string actorID = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
creatureStats.getAiSequence().stack(MWMechanics::AiCombat(actorID));
if (actorID == "player")
creatureStats.setHostile(true);
}
};
template<class R>
class OpStopCombat : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr actor = R()(runtime);
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
creatureStats.getAiSequence().stopCombat();
}
};
template<class R> template<class R>
class OpToggleAI : public Interpreter::Opcode0 class OpToggleAI : public Interpreter::Opcode0
{ {
@ -436,6 +489,12 @@ namespace MWScript
interpreter.installSegment3 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected<ExplicitRef>); interpreter.installSegment3 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected<ExplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSight, new OpGetLineOfSight<ImplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSight, new OpGetLineOfSight<ImplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSightExplicit, new OpGetLineOfSight<ExplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSightExplicit, new OpGetLineOfSight<ExplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeGetTarget, new OpGetTarget<ImplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeGetTargetExplicit, new OpGetTarget<ExplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeStartCombat, new OpStartCombat<ImplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeStartCombatExplicit, new OpStartCombat<ExplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeStopCombat, new OpStopCombat<ImplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeStopCombatExplicit, new OpStopCombat<ExplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeToggleAI, new OpToggleAI<ImplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeToggleAI, new OpToggleAI<ImplicitRef>);
interpreter.installSegment5 (Compiler::Ai::opcodeToggleAIExplicit, new OpToggleAI<ExplicitRef>); interpreter.installSegment5 (Compiler::Ai::opcodeToggleAIExplicit, new OpToggleAI<ExplicitRef>);

View file

@ -61,12 +61,15 @@ namespace Compiler
extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit); extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit);
extensions.registerInstruction ("toggleai", "", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction ("toggleai", "", opcodeToggleAI, opcodeToggleAI);
extensions.registerInstruction ("tai", "", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction ("tai", "", opcodeToggleAI, opcodeToggleAI);
extensions.registerInstruction("startcombat", "c", opcodeStartCombat, opcodeStartCombatExplicit);
extensions.registerInstruction("stopcombat", "", opcodeStopCombat, opcodeStopCombatExplicit);
extensions.registerFunction ("gethello", 'l', "", opcodeGetHello, opcodeGetHelloExplicit); extensions.registerFunction ("gethello", 'l', "", opcodeGetHello, opcodeGetHelloExplicit);
extensions.registerFunction ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit); extensions.registerFunction ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit);
extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit); extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit);
extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit); extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit);
extensions.registerFunction ("getlineofsight", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction ("getlineofsight", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit);
extensions.registerFunction ("getlos", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction ("getlos", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit);
extensions.registerFunction("gettarget", 'l', "c", opcodeGetTarget, opcodeGetTargetExplicit);
} }
} }

View file

@ -53,6 +53,12 @@ namespace Compiler
const int opcodeGetLineOfSightExplicit = 0x2000223; const int opcodeGetLineOfSightExplicit = 0x2000223;
const int opcodeToggleAI = 0x2000224; const int opcodeToggleAI = 0x2000224;
const int opcodeToggleAIExplicit = 0x2000225; const int opcodeToggleAIExplicit = 0x2000225;
const int opcodeGetTarget = 0x2000b23;
const int opcodeGetTargetExplicit = 0x2000b24;
const int opcodeStartCombat = 0x2000b25;
const int opcodeStartCombatExplicit = 0x2000b26;
const int opcodeStopCombat = 0x2000b27;
const int opcodeStopCombatExplicit = 0x2000b28;
} }
namespace Animation namespace Animation

View file

@ -30,7 +30,7 @@ namespace ESM
short mDuration; short mDuration;
unsigned char mTimeOfDay; unsigned char mTimeOfDay;
unsigned char mIdle[8]; unsigned char mIdle[8];
unsigned char mUnk; unsigned char mShouldRepeat;
}; };
struct AITravel struct AITravel