2023-04-11 15:01:34 +08:00

452 lines
16 KiB
C++

#pragma once
#include "moveableentity.h"
#include "weapon.h"
namespace cs
{
class MFCharacterImage;
}
enum CreatureStatus
{
CS_Disable,
CS_DisableAttack,
CS_ForceTeam,
CS_PreDieSuspended,
CS_DeadNoDrop,
CS_Reviving,
CS_End
};
struct SkillCasterState
{
CreatureWeakPtr caster;
Position caster_pos;
int caster_skill_id = 0;
int caster_skill_target_id = 0;
glm::vec3 caster_skill_dir = GlmHelper::ZERO;
float caster_skill_distance = 0.0f;
float caster_skill_param1 = 0.0f;
};
struct Inventory
{
int slot = 0;
int num = 0;
int itemid = 0;
};
struct HumanAbility
{
float hp = 0.0f;
float max_hp = 0.0f;
float speed = 0.0f;
float shot_range = 0.0f;
float shot_speed = 0.0f;
float reload_speed = 0.0f;
float fire_rate = 0.0f;
};
struct BattleDataContext;
class Buff;
class Effect;
class Ability;
class Skill;
class Obstacle;
class RoomObstacle;
class Hero;
class Team;
class Car;
class Trigger;
class DelayAddBuffHandle;
class Movement;
class Player;
class GunGrasp;
class Android;
class Creature : public MoveableEntity
{
public:
long long hero_uniid = 0;
std::vector<Weapon> weapons;
long long last_shot_frameno_ = 0;
long long last_receive_dmg_frameno = 0;
int status = 0;
bool downed = false;
bool dead = false;
bool real_dead = false;
int team_id = 0;
bool aiming = false;
std::list<int> aiming_buffs;
long long aiming_frameno = 0;
glm::vec3 shoot_offset;
int shot_hole = 0;
Creature* shot_passenger = nullptr;
Position target_pos;
bool poisoning = false;
long long poisoning_time = 0;
bool playing_skill = false;
int power_idx = -1;
std::function<void(Buff*)> on_add_buff;
int over_delay_time = 0;
int energy_shield = 0;
int max_energy_shield = 0;
int level = 1;
int hero_level = 1;
Weapon second_weapon;
glm::vec3 skill_pos;
Position context_pos;
glm::vec3 context_real_pos = GlmHelper::ZERO;
glm::vec3 context_dir = GlmHelper::ZERO;
std::shared_ptr<Ability> context_ability;
std::vector<std::tuple<int, int>> talent_list;
std::function<void ()> on_loading_bullet;
CreatureWeakPtr follow_target;
int turn_over_times = 0;
Position last_turn_over_pos;
int shield_hp_ = 0;
int shield_max_hp_ = 0;
int gemstone = 0;
bool shot_start = false;
bool shot_hold = false;
Creature();
virtual ~Creature() override;
virtual void Initialize() override;
virtual void SetMoveDir(const glm::vec3& move_dir) override;
virtual void AddToNewObjects(Entity* entity) {};
virtual void AddToPartObjects(Entity* entity) {};
virtual void RemovePartObjects(Entity* entity) {};
virtual void AddToImageObjects(Creature* c) {};
virtual bool InNewObjects(Entity* target) { return false; };
virtual bool InPartObjects(Entity* target) { return false; };
virtual int GetPartObjectsCount() { return 0; };
virtual void RemoveObjects(Entity* entity) {};
virtual void AddOutObjects(Entity* entity) {};
virtual void RemoveOutObjects(Entity* entity) {};
virtual bool Attackable(Room* room) override;
virtual bool ReceiveExplosionDmg(Explosion* explosion) override;
virtual bool IsCreature(Room* room) override { return true;};
virtual void OnBattleStart(Room* room) override;
virtual const mt::Hero* GetHeroMeta() { return nullptr; };
virtual void FillMFObjectImage(Room* room, Human* hum, cs::MFCharacterImage* image_data) {};
virtual void SetPos(Position pos) override;
virtual float GetSpeed();
std::shared_ptr<Movement> GetMovement() { return movement_; };
bool HasBuffEffect(int buff_effect_id);
Buff* GetBuffByEffectId(int effect_id);
Buff* GetBuffById(int buff_id);
Buff* GetBuffByUniId(int buff_uniid);
int GetBuffNum(int buff_id);
int AddBuff(Creature* caster,
const mt::Buff* buff_meta,
const mt::Skill* buff_skill_meta = nullptr,
bool no_check_immune = false,
std::shared_ptr<a8::Args> init_args = nullptr,
std::shared_ptr<std::vector<float>> buff_vars = nullptr);
bool IsImmuneBuffEffect(int buff_effect);
int MustBeAddBuff(Creature* caster,
int buff_id,
std::shared_ptr<a8::Args> init_args = nullptr,
std::shared_ptr<std::vector<float>> buff_vars = nullptr);
a8::XTimerWp TryDelayAddBuff
(
Creature* caster,
int buff_id,
int time,
DelayAddBuffHandle* handle = nullptr,
std::shared_ptr<a8::Args> init_args = nullptr,
std::shared_ptr<std::vector<float>> buff_vars = nullptr
);
int TryAddBuff(Creature* caster,
int buff_id,
const mt::Skill* skill_meta = nullptr,
std::shared_ptr<a8::Args> init_args = nullptr,
std::shared_ptr<std::vector<float>> buff_vars = nullptr);
int TryAddBuffAndSetTime(Creature* caster,
int buff_id,
int time,
const mt::Skill* skill_meta = nullptr,
std::shared_ptr<a8::Args> init_args = nullptr,
std::shared_ptr<std::vector<float>> buff_vars = nullptr);
int TryAddBuffWithTarget(Creature* caster,
int buff_id,
std::shared_ptr<a8::Args> init_args = nullptr,
std::shared_ptr<std::vector<float>> buff_vars = nullptr);
void RemoveBuffById(int buff_id);
void RemoveBuffByUniId(int buff_uniid);
void ClearBuffById(int buff_id);
void RecalcBuffAttr();
void RemoveBuffByEffectId(int buff_effect_id);
void ClearBuffList();
void TriggerBuff(Skill* skill, std::set<Creature*>& target_list, BuffTriggerType_e trigger_type);
Skill* GetSkill(int skill_id);
int GetSkillTargetId() { return skill_target_id_; };
void AddSkill(int skill_id);
void ClearSkill();
void AddPassiveSkill(int skill_id);
void ClearPassiveSkill();
void UpdatePoisoning();
Team* GetTeam() { return team_; }
void SetTeam(Team* team) { team_ = team; }
std::weak_ptr<Effect> AddEffect(int effect_id);
std::weak_ptr<Effect> AddEffectAndSetTime(int effect_id, int time);
void RemoveEffect(std::weak_ptr<Effect> effect);
void RemoveEffect(int effect_uniid);
void RemoveEffects(std::vector<int> effect_uniids);
void ClearEffect();
bool IsProperTarget(Creature* target, bool no_teammate = false);
bool IsEnemy(Creature* target);
virtual void SelectSkillTargets(Skill* skill,
const Position& target_pos,
std::set<Creature*>& target_list);
virtual bool CanUseSkill(int skill_id);
void DoSkill(int skill_id,
int target_id,
const glm::vec3& skill_dir,
float skill_distance
);
void ResetSkill();
Skill* CurrentSkill();
const mt::Skill* CurrentSkillMeta();
void ActiveAllSkill();
const mt::SkillPhase* GetCurrSkillPhase();
bool CanSee(const Creature* c) const;
virtual void SendDebugMsg(const std::string& debug_msg);
virtual void DropItems(Obstacle* obstacle) {};
bool IsPlayer() const;
bool IsAndroid() const;
bool IsHuman() const;
bool IsCar() const;
bool IsHero() const { return IsEntityType(ET_Hero); };
Human* AsHuman() { return IsHuman() ? (Human*)this : nullptr; };
Android* AsAndroid() { return IsAndroid() ? (Android*)this : nullptr; };
Player* AsPlayer() { return IsPlayer() ? (Player*)this : nullptr; };
Car* AsCar() { return IsCar() ? (Car*)this : nullptr; };
Hero* AsHero() { return IsHero() ? (Hero*)this : nullptr; };
virtual void DecHP(float dec_hp, int killer_id,
const std::string killer_name, int weapon_id,
int real_killer_id, const std::string real_killer_name,
float& real_dmg_out) {};
void AddHp(float hp);
void SetHP(float hp);
void SetMaxHP(float max_hp);
bool IsHpFull();
void AddEnergyShield(int value);
void ClearEnergyShield();
void StartAction(ActionType_e action_type,
int action_duration,
int item_id,
int target_id);
void CancelAction();
void ResetAction();
int GetActionType() { return action_type; }
int GetActionTargetId() { return action_target_id; }
void TraverseProperTargets(std::function<void (Creature*, bool&)> func);
void TraverseProperTargetsNoTeammate(std::function<void (Creature*, bool&)> func);
CreatureWeakPtrChunk* GetWeakPtrChunk() { return &weak_ptr_chunk_; };
void Shot(glm::vec3& target_dir, bool& shot_ok, float fly_distance, int trace_target_uniid);
void AutoLoadingBullet(bool manual = false);
int GetInventory(int slot_id);
void AddInventory(int slot_id, int num);
void DecInventory(int slot_id, int num);
std::array<Inventory, IS_END>& GetInventoryData() { return inventory_; };
virtual void UpdateMove();
virtual void ForwardMove(float distance);
virtual void SpecDirMove(glm::vec3 dir, float distance);
bool HasSpecMove();
void _UpdateSpecMove();
void CheckSpecObject(int new_poly_flags);
void SummonObstacle(Buff* buff, int id, const Position& target_pos);
Hero* SummonHero(Buff* buff, const glm::vec3& pos, const glm::vec3& dir);
void RemoveSurplusHero(int hero_id, int num);
Obstacle* SummonObstacle(Buff* buff, const glm::vec3& pos, const glm::vec3& dir);
void RemoveSurplusObstacle(int thing_id, int num);
void FillSkillCasterState(SkillCasterState* caster_state);
void RecoverSkillCasterState(SkillCasterState* caster_state);
CreatureWeakPtr AllocWeakPtr();
CreatureWeakPtr& GetWeakPtrRef();
Weapon* AutoChgWeapon();
Weapon* ChooseNextWeapon(int curr_weapon_slot_id, int begin_slot_id, int end_slot_id);
Weapon* ChooseNextSpecWeapon(int curr_weapon_slot_id);
Weapon* GetCurrWeapon() { return curr_weapon_; };
void SetCurrWeapon(Weapon* weapon);
void ResetAllSkillCd();
void UpdateSkill();
bool FreezeOperate();
void SlaveOnRemove(Entity* slave);
bool IsInvincible();
void ClearAimingBuffs();
float GetHP();
float GetMaxHP();
float GetHPRate();
void GetHitEnemys(std::set<Creature*>& enemys, float radius);
void GetHitEnemys(std::set<Creature*>& enemys, const glm::vec3 center, float radius);
void SetInfiniteBulletMode();
void FindLocation();
std::shared_ptr<Trigger> GetTrigger() { return trigger_; };
std::shared_ptr<Ability>& GetAbility() { return ability_; };
std::shared_ptr<BattleDataContext>& GetBattleContext() { return battle_context_; };
void SetBattleContext(std::shared_ptr<BattleDataContext> c);
void RefreshHP();
void TraverseBuff(std::function<void (Buff*, bool&)> func);
void TraverseEffect(std::function<void (Effect*, bool&)> func);
void TraverseSkill(std::function<void (Skill*, bool&)> func);
long long GetCollisionTimes() { return collision_times_; };
std::string DebugOutBuffList();
bool CanFollow(Creature* follower);
void FollowToTarget();
int GetFollowTimes() { return follow_times_; };
void IncFollowTimes() { ++follow_times_; };
void IncDisableMoveDirTimes() { ++disable_move_dir_times_ ; };
void DecDisableMoveDirTimes() { --disable_move_dir_times_ ; };
int GetDisableMoveDirTimes() { return disable_move_dir_times_ ; };
void SetDisableMoveDirTimes(int times) { disable_move_dir_times_ = times; };
void IncDisableAttackDirTimes() { ++disable_attack_dir_times_ ; };
void DecDisableAttackDirTimes() { --disable_attack_dir_times_ ; };
int GetDisableAttackDirTimes() { return disable_attack_dir_times_ ; };
void SetDisableAttackDirTimes(int times) { disable_attack_dir_times_ = times; };
void IncDisableMoveTimes() { ++disable_move_times_ ; };
void DecDisableMoveTimes() { --disable_move_times_ ; };
int GetDisableMoveTimes() { return disable_move_times_ ; };
void SetDisableMoveTimes(int times) { disable_move_times_ = times; };
void DoRecoilForce(int distance);
void WinSkillExp(int win_exp);
void RecalcDtoAttr();
void AutoNavigation(const glm::vec3& target_pos, float speed,
std::function<void (Creature*)> cb);
void LockAttackDir(int time);
void PullTarget(const glm::vec3& target_pos);
void MarkSyncActivePlayer(const char* file, int line, const char* func);
void CheckBulletHitHoldShield(IBullet* bullet, bool& eat);
void RemoveSkillObstacle(const mt::Skill* skill_meta);
void SetBuffTag(int tag, int val);
int GetBuffTag(int tag);
void IncBuffTag(int tag, int val);
void UnSetBuffTag(int tag);
void ShortFindPath();
float GetSkillRaycastDistance();
virtual void NetInitOk();
bool IsNearGas();
std::shared_ptr<std::set<int>> CalcReporterList(bool is_trace_bullet,
const mt::Equip* weapon_meta,
const mt::Equip* bullet_meta);
bool CanShot(bool try_reload);
void AdjustPos();
protected:
virtual void OnBuffRemove(Buff& buff);
private:
virtual void AddBuffPostProc(Creature* caster, Buff* buff);
virtual void DoSkillPreProc(int skill_id, int target_id);
virtual void DoSkillPostProc(bool used, int skill_id, int target_id);
void ProcSkillPhase(const mt::SkillPhase* phase);
void TriggerOneObjectBuff(Skill* skill, Creature* target, BuffTriggerType_e trigger_type);
Hero* InternalSummonHero(Buff* buff, const mt::Hero* hero_meta, glm::vec3 dir, const glm::vec3 born_pos);
Obstacle* InternalSummonObstacle(Buff* buff, const mt::MapThing* thing_meta,
glm::vec3 dir, const glm::vec3 born_pos);
Skill* GetPassiveSkill(int skill_id);
void RemovePassiveSkill(int skill_id);
void RemoveSurplusObstacle(int buff_id, int id, int num);
void CheckAbilityUsed();
void AutoSwitchWeapon();
void CheckLoadingBullet();
void OnLand();
protected:
bool need_sync_active_player_ = false;
std::list<std::any> on_dead_remove_objects_;
ActionType_e action_type = AT_None;
int action_duration = 0;
long long action_frameno = 0;
int action_item_id = 0;
int action_target_id = 0;
int poly_ext_flags_ = 0;
std::array<Inventory, IS_END> buff_inventory_ = {};
int camouflage_move_addition_ = 0;
int camouflage_aiming_addition_ = 0;
long long last_follow_move_frameno_ = 0;
int follow_target_last_chg_move_dir_times_ = -1;
a8::XTimerWp follow_target_timer_;
private:
CreatureWeakPtr weak_ptr_;
std::shared_ptr<Movement> movement_;
std::shared_ptr<Trigger> trigger_;
long long collision_times_ = 0;
Team* team_ = nullptr;
Weapon* curr_weapon_ = nullptr;
CreatureWeakPtrChunk weak_ptr_chunk_;
HumanAbility ability;
std::shared_ptr<Ability> ability_;
std::shared_ptr<BattleDataContext> battle_context_;
int buff_uniid_ = 1000;
std::array<list_head, kBET_End> buff_effect_ = {};
std::array<list_head, kBET_End> depend_effect_ = {};
std::array<list_head, kEventBuffEnd> cond_buffs_ = {};
std::list<std::shared_ptr<Buff>> buff_list_;
std::map<int, std::shared_ptr<Effect>> effect_hash_;
std::map<int, list_head> slave_heros_;
std::map<int, list_head> slave_things2_;
std::list<std::tuple<int, RoomObstacleWeakPtr>> slave_things_;
a8::XTimerWp auto_switch_weapon_timer_;
a8::XTimerWp reload_delay_timer_;
int follow_times_ = 0;
std::map<int, int> buff_tags_;
int disable_move_dir_times_ = 0;
int disable_attack_dir_times_ = 0;
int disable_move_times_ = 0;
glm::vec3 skill_dir_ = GlmHelper::ZERO;
float skill_param1 = 0;
size_t curr_skill_phase = 0;
Skill* curr_skill_ = nullptr;
int skill_target_id_ = 0;
float skill_distance_ = 0.0f;
std::map<int, std::shared_ptr<Skill>> skill_hash_;
std::map<int, std::shared_ptr<Skill>> passive_skill_hash_;
std::map<int, long long> buff_interval_hash_;
std::array<Inventory, IS_END> inventory_ = {};
std::shared_ptr<GunGrasp> gun_grasp_;
friend class Buff;
friend class AddInventoryBuff;
friend class BePullBuff;
friend class CamouflageBuff;
friend class CamouflageAdditionBuff;
friend class EventAddBuff;
friend class FlashMoveBuff;
friend class JumpBuff;
friend class JumpToBuff;
friend class Skill;
friend class Trigger;
friend class PBUtils;
friend class GunGrasp;
};