20 fin.
read(
reinterpret_cast<int32_t&
>(queueId));
22 fin.
read(
reinterpret_cast<uint8_t&
>(tr[i]));
27 fout.
write(int32_t(queueId));
29 fout.
write(uint8_t(tr[i]));
39 if(fillQueue(owner,ai.my_w_strafe))
47 if(fillQueue(owner,ai.enemy_stormprehit))
49 if(fillQueue(owner,ai.enemy_prehit))
56 if(fillQueue(owner,ai.my_w_runto))
59 if(fillQueue(owner,ai.my_w_focus))
61 if(fillQueue(owner,ai.my_w_nofocus))
67 if(fillQueue(owner,ai.my_g_runto))
70 if(fillQueue(owner,ai.my_g_focus))
77 if(fillQueue(owner,ai.my_fk_focus_mag))
79 if(fillQueue(owner,ai.my_fk_nofocus_mag))
84 if(fillQueue(owner,ai.my_fk_focus_far))
86 if(fillQueue(owner,ai.my_fk_nofocus_far))
89 fillQueue(owner,ai.my_w_nofocus);
92bool FightAlgo::fillQueue(
GameScript& owner,
const zenkit::IFightAi& src) {
94 for(
size_t i=0; i<zenkit::IFightAi::move_count; ++i){
95 if(src.move[i]==zenkit::FightAiMove::NOP)
101 queueId = zenkit::FightAiMove(src.move[owner.
rand(sz)]);
102 return queueId!=zenkit::FightAiMove::NOP;
106 using zenkit::FightAiMove;
110 case FightAiMove::TURN:
115 case FightAiMove::RUN:{
121 case FightAiMove::RUN_BACK:{
125 case FightAiMove::JUMP_BACK:{
129 case FightAiMove::STRAFE:{
134 case FightAiMove::ATTACK:{
138 case FightAiMove::ATTACK_SIDE:{
143 case FightAiMove::ATTACK_FRONT:{
148 case FightAiMove::ATTACK_TRIPLE:{
160 case FightAiMove::ATTACK_WHIRL:{
167 case FightAiMove::ATTACK_MASTER:{
176 case FightAiMove::TURN_TO_HIT:{
180 case FightAiMove::PARRY:{
184 case FightAiMove::STAND_UP:{
187 case FightAiMove::WAIT:
188 case FightAiMove::WAIT_EXT:{
192 case FightAiMove::WAIT_LONGER:{
197 static std::set<FightAiMove> inst;
198 if(inst.find(queueId)==inst.end()) {
199 Tempest::Log::d(
"unrecognized FAI instruction: ",
int(queueId));
200 inst.insert(queueId);
204 queueId = FightAiMove::NOP;
214 fillQueue(npc,tg,owner);
215 if(queueId==zenkit::FightAiMove::NOP)
222 for(
size_t i=1;i<
MV_MAX;++i)
228 queueId = zenkit::FightAiMove::NOP;
240 float baseTg = float(gv.fight_range_base[tg .
guild()]);
241 float baseNpc = float(gv.fight_range_base[npc.
guild()]);
242 return baseTg + baseNpc;
247 float baseTg = float(gv.fight_range_base[tg .
guild()]);
248 float baseNpc = float(gv.fight_range_base[npc.
guild()]);
249 return baseTg + baseNpc + weaponRange(owner,npc);
253 auto gl = npc.
guild();
255 float baseTg = float(gv.fight_range_base[tg .
guild()]);
256 float baseNpc = float(gv.fight_range_base[npc.
guild()]);
257 return float(baseTg + baseNpc +
float(gv.fight_range_g[gl])) + weaponRange(owner,npc);
261 float NPC_ATTACK_FINISH_DISTANCE = 180;
262 if(
auto var = owner.
findSymbol(
"NPC_ATTACK_FINISH_DISTANCE")) {
263 if(var->type()==zenkit::DaedalusDataType::INT)
264 NPC_ATTACK_FINISH_DISTANCE = float(var->get_int());
265 else if(var->type()==zenkit::DaedalusDataType::FLOAT)
266 NPC_ATTACK_FINISH_DISTANCE = var->get_float();
268 return NPC_ATTACK_FINISH_DISTANCE;
277 static float padding = 0;
280 return (dist<=pd*pd);
286 return (dist<=pd*pd);
292 return (dist<=pd*pd);
298 return (dist<=pd*pd);
302 static const float maxAngle = std::cos(
float(30.0*M_PI/180.0));
305 const float plAng = npc.
rotationRad()+float(M_PI/2);
307 const float da = plAng-std::atan2(dpos.z,dpos.x);
308 const float c = std::cos(da);
315float FightAlgo::weaponRange(
GameScript &owner,
const Npc &npc) {
316 auto gl = npc.
guild();
319 int add = w ? w->swordLength() : 0;
324 return float(gv.fight_range_1ha[gl] + add);
326 return float(gv.fight_range_2ha[gl] + add);
329 return float(gv.fight_range_fist[gl]);
void load(Serialize &fin)
Action nextFromQueue(Npc &npc, Npc &tg, GameScript &owner)
bool isInWRange(const Npc &npc, const Npc &tg, GameScript &owner) const
float prefferedGDistance(const Npc &npc, const Npc &tg, GameScript &owner) const
float prefferedAttackDistance(const Npc &npc, const Npc &tg, GameScript &owner) const
bool hasInstructions() const
float baseDistance(const Npc &npc, const Npc &tg, GameScript &owner) const
void save(Serialize &fout)
bool fetchInstructions(Npc &npc, Npc &tg, GameScript &owner)
float attackFinishDistance(GameScript &owner) const
bool isInAttackRange(const Npc &npc, const Npc &tg, GameScript &owner) const
bool isInFinishRange(const Npc &npc, const Npc &tg, GameScript &owner) const
bool isInGRange(const Npc &npc, const Npc &tg, GameScript &owner) const
bool isInFocusAngle(const Npc &npc, const Npc &tg) const
zenkit::DaedalusSymbol * findSymbol(std::string_view s)
const zenkit::IGuildValues & guildVal() const
uint32_t rand(uint32_t max)
static const FightAi & fai()
auto version() const -> const VersionInfo &
float qDistTo(const Tempest::Vec3 pos) const
auto weaponState() const -> WeaponState
float rotationRad() const
bool hasState(BodyState s) const
auto inventory() const -> const Inventory &
auto centerPosition() const -> Tempest::Vec3
BodyState bodyStateMasked() const
void write(const Arg &... a)