aozhiwei 64308c203d 1
2022-09-06 12:01:08 +08:00

360 lines
12 KiB
C++

#pragma once
#include "moveableentity.h"
#include "buff.h"
#include "trigger.h"
#include "ability.h"
#include "weapon.h"
#include "battledatacontext.h"
#include "cs_proto.pb.h"
enum CreatureStatus
{
CS_AlreadyLordMode = 1,
CS_Disable = 2,
CS_Collisioning = 3,
CS_DisableAttack = 8,
CS_ForceTeam = 9,
CS_End
};
namespace MetaData
{
class Skill;
class SkillPhase;
}
struct SkillCasterState
{
CreatureWeakPtr caster;
a8::Vec2 caster_pos;
int caster_skill_id = 0;
int caster_skill_target_id = 0;
a8::Vec2 caster_skill_dir;
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 hp_recover = 0.0f;
float atk = 0.0f;
float def = 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 xtimer_list;
class Skill;
class Obstacle;
class RoomObstacle;
class Hero;
class Team;
class Car;
class Trigger;
class Creature : public MoveableEntity
{
public:
long long hero_uniid = 0;
std::vector<Weapon> weapons;
long long last_shot_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;
a8::Vec2 shoot_offset;
int shot_hole = 0;
Creature* shot_passenger = nullptr;
a8::Vec2 target_pos;
std::function<bool ()> on_move_collision;
bool poisoning = false;
long long poisoning_time = 0;
bool playing_skill = false;
int power_idx = -1;
int hold_shield_hp = 0;
Weapon second_weapon;
a8::Vec2 context_pos;
a8::Vec2 context_dir;
std::shared_ptr<Ability> context_ability;
std::vector<std::tuple<int, int>> talent_list;
bool need_sync_active_player = false;
std::function<void ()> on_loading_bullet;
CreatureWeakPtr follow_target;
int turn_over_times = 0;
a8::Vec2 last_turn_over_pos;
Creature();
virtual ~Creature() override;
virtual void Initialize() override;
virtual void SetMoveDir(const a8::Vec2& move_dir) override;
virtual void AddToNewObjects(Entity* entity) {};
virtual void AddToPartObjects(Entity* entity) {};
virtual void RemovePartObjects(Entity* entity) {};
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;
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,
MetaData::Buff* buff_meta,
int skill_lv,
MetaData::Skill* buff_skill_meta = nullptr,
bool no_check_immune = false);
bool IsImmuneBuffEffect(int buff_effect);
int MustBeAddBuff(Creature* caster, int buff_id);
int TryAddBuff(Creature* caster, int buff_id);
int TryAddBuffWithTarget(Creature* caster, int buff_id);
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 FillBuffList(Human* hum, ::google::protobuf::RepeatedPtrField<::cs::MFBuff>* pb_buff_list);
void FillSkillList(::google::protobuf::RepeatedPtrField< cs::MFSkill >* pb_skill_list);
void TriggerBuff(Skill* skill, std::set<Creature*>& target_list, BuffTriggerType_e trigger_type);
Skill* GetSkill(int skill_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; }
bool IsProperTarget(Creature* target, bool no_teammate = false);
bool IsEnemy(Creature* target);
virtual void SelectSkillTargets(Skill* skill,
const a8::Vec2& target_pos,
std::set<Creature*>& target_list);
virtual bool CanUseSkill(int skill_id);
void DoSkill(int skill_id,
int target_id,
const a8::Vec2& skill_dir,
float skill_distance,
const a8::Vec2& target_pos
);
void ResetSkill();
Skill* CurrentSkill();
void ActiveAllSkill();
MetaData::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;
Human* AsHuman() { return IsHuman() ? (Human*)this : nullptr; };
Player* AsPlayer() { return IsPlayer() ? (Player*)this : nullptr; };
Car* AsCar() { return IsCar() ? (Car*)this : nullptr; };
virtual void DecHP(float dec_hp, int killer_id, const std::string& killer_name, int weapon_id) {};
void AddHp(float hp);
void SetHP(float hp);
void SetMaxHP(float max_hp);
RaceType_e GetRace() { return race_; }
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(a8::Vec2& target_dir, bool& shot_ok, float fly_distance);
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(int speed) {};
bool HasSpecMove();
void _UpdateSpecMove();
void CheckSpecObject();
bool CollisonDetection();
bool CollisonDetectionAndGetCollider(ColliderComponent** pickup_collider);
void SummonObstacle(Buff* buff, int id, const a8::Vec2& pos);
void SummonHero(Buff* buff, const a8::Vec2& pos, const a8::Vec2& dir);
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 GetDef();
void SetDef(float def);
void GetHitEnemys(std::set<Creature*>& enemys, float radius);
bool TryMove(const a8::Vec2& target_pos, a8::Vec2& out_pos);
void SetInfiniteBulletMode();
void FindLocation();
void FindLocationWithTarget(Entity* target, ColliderComponent* target_collider);
Entity* GetLastCollisionDoor() { return last_collision_door_; }
void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; }
bool CheckCollision();
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);
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 DoRecoilForce(int distance);
void WinSkillExp(int win_exp);
float GetAttrAbs(int attr_id);
float GetAttrRate(int attr_id);
void RecalcDtoAttr();
protected:
virtual void OnBuffRemove(Buff& buff);
private:
virtual void AddBuffPostProc(Creature* caster, Buff* buff);
virtual void DoSkillPreProc(int skill_id, int target_id, const a8::Vec2& target_pos);
virtual void DoSkillPostProc(bool used, int skill_id, int target_id, const a8::Vec2& target_pos);
void ProcSkillPhase(MetaData::SkillPhase* phase);
void ProcBuffEffect(Creature* caster, Buff* buff);
void TriggerOneObjectBuff(Skill* skill, Creature* target, BuffTriggerType_e trigger_type);
Skill* GetPassiveSkill(int skill_id);
void RemovePassiveSkill(int skill_id);
void RemoveSurplusHero(int buff_id, int id, int num);
void RemoveSurplusObstacle(int buff_id, int id, int num);
void CheckAbilityUsed();
void ProcOnceChgAttrBuff(MetaData::Buff* buff_meta);
bool TrySummonHero(MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos, bool through_wall);
Hero* InternalSummonHero(Buff* buff, MetaData::Player* hero_meta, a8::Vec2 dir, a8::Vec2 born_pos,
bool through_wall, int num, int life_time);
void AutoSwitchWeapon();
void CheckLoadingBullet();
protected:
RaceType_e race_ = kHumanRace;
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;
long long cell_flags_ = 0;
CircleCollider* self_collider_ = nullptr;
Entity* last_collision_door_ = nullptr;
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;
xtimer_list* follow_target_timer_ = nullptr;
private:
CreatureWeakPtr weak_ptr_;
Trigger* trigger_ = nullptr;
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, kCondBuffEnd> cond_buffs_ = {};
std::list<Buff> buff_list_;
std::list<std::tuple<int, Hero*>> slave_heros_;
std::list<std::tuple<int, RoomObstacle*>> slave_things_;
xtimer_list* auto_switch_weapon_timer_ = nullptr;
int follow_times_ = 0;
int disable_move_dir_times_ = 0;
a8::Vec2 skill_dir_;
float skill_param1 = 0;
size_t curr_skill_phase = 0;
Skill* curr_skill_ = nullptr;
int skill_target_id_ = 0;
a8::Vec2 skill_target_pos_;
float skill_distance_ = 0.0f;
std::map<int, Skill*> skill_hash_;
std::map<int, Skill*> passive_skill_hash_;
std::map<int, long long> buff_interval_hash_;
std::array<Inventory, IS_END> inventory_ = {};
friend class Skill;
friend class Trigger;
};
void InternalShot(Creature* sender,
MetaData::Equip* weapon_meta,
MetaData::EquipUpgrade* weapon_upgrade_meta,
MetaData::Equip* bullet_meta,
int weapon_lv,
int skill_id,
float fly_distance,
bool is_tank_skin,
long long weapon_uniid);