mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 15:15:31 +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:
parent
0ad7aa1f53
commit
5c7e39a92f
15 changed files with 154 additions and 48 deletions
|
@ -13,8 +13,8 @@ void printAIPackage(ESM::AIPackage p)
|
|||
std::cout << " Distance: " << p.mWander.mDistance << std::endl;
|
||||
std::cout << " Duration: " << p.mWander.mDuration << std::endl;
|
||||
std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl;
|
||||
if (p.mWander.mUnk != 1)
|
||||
std::cout << " Unknown: " << (int)p.mWander.mUnk << std::endl;
|
||||
if (p.mWander.mShouldRepeat != 1)
|
||||
std::cout << " Unknown: " << (int)p.mWander.mShouldRepeat << std::endl;
|
||||
|
||||
std::cout << " Idle: ";
|
||||
for (int i = 0; i != 8; i++)
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#include "aiactivate.hpp"
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
|
||||
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
||||
: mObjectId(objectId)
|
||||
{
|
||||
}
|
||||
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
||||
{
|
||||
return new AiActivate(*this);
|
||||
}
|
||||
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiActivate completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiActivate::getTypeId() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
||||
: mObjectId(objectId)
|
||||
{
|
||||
}
|
||||
MWMechanics::AiActivate *MWMechanics::AiActivate::clone() const
|
||||
{
|
||||
return new AiActivate(*this);
|
||||
}
|
||||
bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiActivate completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiActivate::getTypeId() const
|
||||
{
|
||||
return TypeIdActivate;
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace MWMechanics
|
|||
|
||||
int AiCombat::getTypeId() const
|
||||
{
|
||||
return 5;
|
||||
return TypeIdCombat;
|
||||
}
|
||||
|
||||
unsigned int AiCombat::getPriority() const
|
||||
|
@ -143,6 +143,11 @@ namespace MWMechanics
|
|||
return 1;
|
||||
}
|
||||
|
||||
const std::string &AiCombat::getTargetId() const
|
||||
{
|
||||
return mTargetId;
|
||||
}
|
||||
|
||||
AiCombat *MWMechanics::AiCombat::clone() const
|
||||
{
|
||||
return new AiCombat(*this);
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace MWMechanics
|
|||
|
||||
virtual unsigned int getPriority() const;
|
||||
|
||||
const std::string &getTargetId() const;
|
||||
|
||||
private:
|
||||
std::string mTargetId;
|
||||
|
||||
|
@ -33,4 +35,4 @@ namespace MWMechanics
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace MWMechanics
|
|||
|
||||
int AiEscort::getTypeId() const
|
||||
{
|
||||
return 2;
|
||||
return TypeIdEscort;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#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)
|
||||
{
|
||||
}
|
||||
|
@ -10,18 +10,18 @@ MWMechanics::AiFollow::AiFollow(const std::string &actorId,const std::string &ce
|
|||
{
|
||||
}
|
||||
|
||||
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
|
||||
{
|
||||
return new AiFollow(*this);
|
||||
}
|
||||
|
||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiFollow completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiFollow::getTypeId() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
MWMechanics::AiFollow *MWMechanics::AiFollow::clone() const
|
||||
{
|
||||
return new AiFollow(*this);
|
||||
}
|
||||
|
||||
bool MWMechanics::AiFollow::execute (const MWWorld::Ptr& actor,float duration)
|
||||
{
|
||||
std::cout << "AiFollow completed.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
int MWMechanics::AiFollow::getTypeId() const
|
||||
{
|
||||
return TypeIdFollow;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,16 @@ namespace MWMechanics
|
|||
class AiPackage
|
||||
{
|
||||
public:
|
||||
|
||||
enum TypeId {
|
||||
TypeIdNone = -1,
|
||||
TypeIdWander = 0,
|
||||
TypeIdTravel = 1,
|
||||
TypeIdEscort = 2,
|
||||
TypeIdFollow = 3,
|
||||
TypeIdActivate = 4,
|
||||
TypeIdCombat = 5
|
||||
};
|
||||
|
||||
virtual ~AiPackage();
|
||||
|
||||
virtual AiPackage *clone() const = 0;
|
||||
|
@ -21,7 +30,7 @@ namespace MWMechanics
|
|||
///< \return Package completed?
|
||||
|
||||
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;}
|
||||
///< higher number is higher priority (0 beeing the lowest)
|
||||
|
|
|
@ -56,6 +56,21 @@ int MWMechanics::AiSequence::getTypeId() const
|
|||
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
|
||||
{
|
||||
return mDone;
|
||||
|
@ -114,7 +129,7 @@ void MWMechanics::AiSequence::fill(const ESM::AIPackageList &list)
|
|||
std::vector<int> idles;
|
||||
for (int i=0; i<8; ++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)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,14 @@ namespace MWMechanics
|
|||
virtual ~AiSequence();
|
||||
|
||||
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;
|
||||
///< Has a package been completed during the last update?
|
||||
|
|
|
@ -106,7 +106,7 @@ namespace MWMechanics
|
|||
|
||||
int AiTravel::getTypeId() const
|
||||
{
|
||||
return 1;
|
||||
return TypeIdTravel;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace MWMechanics
|
|||
|
||||
int AiWander::getTypeId() const
|
||||
{
|
||||
return 0;
|
||||
return TypeIdWander;
|
||||
}
|
||||
|
||||
void AiWander::stopWalking(const MWWorld::Ptr& actor)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "../mwmechanics/aifollow.hpp"
|
||||
#include "../mwmechanics/aitravel.hpp"
|
||||
#include "../mwmechanics/aiwander.hpp"
|
||||
#include "../mwmechanics/aicombat.hpp"
|
||||
|
||||
#include "../mwbase/environment.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>
|
||||
class OpToggleAI : public Interpreter::Opcode0
|
||||
{
|
||||
|
@ -436,6 +489,12 @@ namespace MWScript
|
|||
interpreter.installSegment3 (Compiler::Ai::opcodeGetDetectedExplicit, new OpGetDetected<ExplicitRef>);
|
||||
interpreter.installSegment5 (Compiler::Ai::opcodeGetLineOfSight, new OpGetLineOfSight<ImplicitRef>);
|
||||
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::opcodeToggleAIExplicit, new OpToggleAI<ExplicitRef>);
|
||||
|
||||
|
|
|
@ -61,12 +61,15 @@ namespace Compiler
|
|||
extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit);
|
||||
extensions.registerInstruction ("toggleai", "", 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 ("getfight", 'l', "", opcodeGetFight, opcodeGetFightExplicit);
|
||||
extensions.registerFunction ("getflee", 'l', "", opcodeGetFlee, opcodeGetFleeExplicit);
|
||||
extensions.registerFunction ("getalarm", 'l', "", opcodeGetAlarm, opcodeGetAlarmExplicit);
|
||||
extensions.registerFunction ("getlineofsight", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit);
|
||||
extensions.registerFunction ("getlos", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit);
|
||||
extensions.registerFunction("gettarget", 'l', "c", opcodeGetTarget, opcodeGetTargetExplicit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,12 @@ namespace Compiler
|
|||
const int opcodeGetLineOfSightExplicit = 0x2000223;
|
||||
const int opcodeToggleAI = 0x2000224;
|
||||
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
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace ESM
|
|||
short mDuration;
|
||||
unsigned char mTimeOfDay;
|
||||
unsigned char mIdle[8];
|
||||
unsigned char mUnk;
|
||||
unsigned char mShouldRepeat;
|
||||
};
|
||||
|
||||
struct AITravel
|
||||
|
|
Loading…
Reference in a new issue