forked from teamnwah/openmw-tes3coop
npc ai packages
This commit is contained in:
parent
4f411ff1eb
commit
02d7aa4135
5 changed files with 155 additions and 25 deletions
128
components/esm/defs_ai.hpp
Normal file
128
components/esm/defs_ai.hpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
#ifndef _ESM_DEFS_AI_H
|
||||
#define _ESM_DEFS_AI_H
|
||||
|
||||
#include "esm_reader.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct AIDTstruct
|
||||
{
|
||||
// These are probabilities
|
||||
char hello, u1, fight, flee, alarm, u2, u3, u4;
|
||||
// The last u's might be the skills that this NPC can train you
|
||||
// in?
|
||||
int services; // See the Services enum
|
||||
}; // 12 bytes
|
||||
|
||||
struct AIWander
|
||||
{
|
||||
short distance;
|
||||
short duration;
|
||||
char timeOfDay;
|
||||
char idle[8];
|
||||
char unk;
|
||||
};
|
||||
|
||||
struct AITravel
|
||||
{
|
||||
float x, y, z;
|
||||
long unk;
|
||||
};
|
||||
|
||||
struct AITarget
|
||||
{
|
||||
float x, y, z;
|
||||
short duration;
|
||||
NAME32 id;
|
||||
short unk;
|
||||
};
|
||||
|
||||
struct AIActivate
|
||||
{
|
||||
NAME32 name;
|
||||
char unk;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
enum
|
||||
{
|
||||
AI_Wander = 0x575f4941,
|
||||
AI_Travel = 0x545f4941,
|
||||
AI_Follow = 0x465f4941,
|
||||
AI_Escort = 0x455f4941,
|
||||
AI_Activate = 0x415f4941,
|
||||
};
|
||||
|
||||
/// \note Used for storaging packages in a single container
|
||||
/// w/o manual memory allocation accordingly to policy standards
|
||||
struct AIPackage
|
||||
{
|
||||
int type;
|
||||
|
||||
// Anonymous union
|
||||
union
|
||||
{
|
||||
AIWander wander;
|
||||
AITravel travel;
|
||||
AITarget target;
|
||||
AIActivate activate;
|
||||
};
|
||||
|
||||
/// \note for AITarget only, placed here to stick with union,
|
||||
/// overhead should be not so awful
|
||||
std::string cellName;
|
||||
};
|
||||
|
||||
struct AIPackageList
|
||||
{
|
||||
std::vector<AIPackage> list;
|
||||
|
||||
/// \note This breaks consistency of subrecords reading:
|
||||
/// after calling it subrecord name is already read, so
|
||||
/// it needs to use retSubName() if needed. But, hey, there
|
||||
/// is only one field left (XSCL) and only two records uses AI
|
||||
void load(ESMReader &esm) {
|
||||
while (esm.hasMoreSubs()) {
|
||||
// initialize every iteration
|
||||
AIPackage pack;
|
||||
|
||||
esm.getSubName();
|
||||
std::cout << esm.retSubName().toString() << std::endl;
|
||||
if (esm.retSubName() == 0x54444e43) { // CNDT
|
||||
list.back().cellName = esm.getHString();
|
||||
} else if (esm.retSubName() == AI_Wander) {
|
||||
pack.type = AI_Wander;
|
||||
esm.getHExact(&pack.wander, 14);
|
||||
list.push_back(pack);
|
||||
} else if (esm.retSubName() == AI_Travel) {
|
||||
pack.type = AI_Travel;
|
||||
esm.getHExact(&pack.travel, 16);
|
||||
list.push_back(pack);
|
||||
} else if (esm.retSubName() == AI_Escort ||
|
||||
esm.retSubName() == AI_Follow)
|
||||
{
|
||||
pack.type =
|
||||
(esm.retSubName() == AI_Escort) ? AI_Escort : AI_Follow;
|
||||
|
||||
esm.getHExact(&pack.target, 48);
|
||||
list.push_back(pack);
|
||||
} else if (esm.retSubName() == AI_Activate) {
|
||||
pack.type = AI_Activate;
|
||||
esm.getHExact(&pack.activate, 33);
|
||||
list.push_back(pack);
|
||||
} else { // not AI package related data, so leave
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -49,23 +49,23 @@ union NAME_T
|
|||
char name[LEN];
|
||||
int32_t val;
|
||||
|
||||
bool operator==(const char *str)
|
||||
bool operator==(const char *str) const
|
||||
{
|
||||
for(int i=0; i<LEN; i++)
|
||||
if(name[i] != str[i]) return false;
|
||||
else if(name[i] == 0) return true;
|
||||
return str[LEN] == 0;
|
||||
}
|
||||
bool operator!=(const char *str) { return !((*this)==str); }
|
||||
bool operator!=(const char *str) const { return !((*this)==str); }
|
||||
|
||||
bool operator==(const std::string &str)
|
||||
bool operator==(const std::string &str) const
|
||||
{
|
||||
return (*this) == str.c_str();
|
||||
}
|
||||
bool operator!=(const std::string &str) { return !((*this)==str); }
|
||||
bool operator!=(const std::string &str) const { return !((*this)==str); }
|
||||
|
||||
bool operator==(int v) { return v == val; }
|
||||
bool operator!=(int v) { return v != val; }
|
||||
bool operator==(int v) const { return v == val; }
|
||||
bool operator!=(int v) const { return v != val; }
|
||||
|
||||
std::string toString() const { return std::string(name, strnlen(name, LEN)); }
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "esm_reader.hpp"
|
||||
#include "loadcont.hpp"
|
||||
#include "defs_ai.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
@ -51,15 +52,6 @@ struct Creature
|
|||
int gold;
|
||||
}; // 96 bytes
|
||||
|
||||
struct AIDTstruct
|
||||
{
|
||||
// These are probabilities
|
||||
char hello, u1, fight, flee, alarm, u2, u3, u4;
|
||||
// The last u's might be the skills that this NPC can train you
|
||||
// in?
|
||||
int services; // See the NPC::Services enum
|
||||
}; // 12 bytes
|
||||
|
||||
NPDTstruct data;
|
||||
|
||||
int flags;
|
||||
|
|
|
@ -42,6 +42,16 @@ void NPC::load(ESMReader &esm, const std::string& id)
|
|||
else
|
||||
hasAI = false;
|
||||
|
||||
while (esm.isNextSub("DODT") || esm.isNextSub("DNAM")) {
|
||||
if (esm.retSubName() == 0x54444f44) { // DODT struct
|
||||
Dest dodt;
|
||||
esm.getHExact(&dodt.pos, 24);
|
||||
dest.push_back(dodt);
|
||||
} else if (esm.retSubName() == 0x4d414e44) { // DNAM struct
|
||||
dest.back().cellName = esm.getHString();
|
||||
}
|
||||
}
|
||||
aiPack.load(esm);
|
||||
esm.skipRecord();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "esm_reader.hpp"
|
||||
#include "loadcont.hpp"
|
||||
#include "defs.hpp"
|
||||
#include "defs_ai.hpp"
|
||||
|
||||
namespace ESM {
|
||||
|
||||
|
@ -71,18 +72,14 @@ struct NPC
|
|||
unknown1, unknown2, unknown3;
|
||||
int gold; // ?? not certain
|
||||
}; // 12 bytes
|
||||
|
||||
struct AIDTstruct
|
||||
{
|
||||
// These are probabilities
|
||||
char hello, u1, fight, flee, alarm, u2, u3, u4;
|
||||
// The last u's might be the skills that this NPC can train you
|
||||
// in?
|
||||
int services; // See the Services enum
|
||||
}; // 12 bytes
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct Dest
|
||||
{
|
||||
Position pos;
|
||||
std::string cellName;
|
||||
};
|
||||
|
||||
NPDTstruct52 npdt52;
|
||||
NPDTstruct12 npdt12; // Use this if npdt52.gold == -10
|
||||
|
||||
|
@ -94,6 +91,9 @@ struct NPC
|
|||
AIDTstruct AI;
|
||||
bool hasAI;
|
||||
|
||||
std::vector<Dest> dest;
|
||||
AIPackageList aiPack;
|
||||
|
||||
std::string name, model, race, cls, faction, script,
|
||||
hair, head; // body parts
|
||||
|
||||
|
|
Loading…
Reference in a new issue