diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.World/EnderDragon.h | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.World/EnderDragon.h')
| -rw-r--r-- | Minecraft.World/EnderDragon.h | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/Minecraft.World/EnderDragon.h b/Minecraft.World/EnderDragon.h new file mode 100644 index 00000000..8a12c08c --- /dev/null +++ b/Minecraft.World/EnderDragon.h @@ -0,0 +1,177 @@ +#pragma once +using namespace std; +#include "BossMob.h" + +class BossMobPart; +class EnderCrystal; +class Node; +class BinaryHeap; +class Path; + +class EnderDragon : public BossMob +{ +public: + eINSTANCEOF GetType() { return eTYPE_ENDERDRAGON; }; + static Entity *create(Level *level) { return new EnderDragon(level); } + +private: + static const int DATA_ID_SYNCHED_HEALTH = 16; + + // 4J Added for new behaviours + static const int DATA_ID_SYNCHED_ACTION = 17; + + static const int positionsLength = 64; // 4J Stu - Defined this so that we can keep the positions array as a basic type array +public: + double xTarget, yTarget, zTarget; + + double positions[positionsLength][3]; + int posPointer; + + //BossMobPart[] subEntities; + vector<shared_ptr<Entity> > subEntities; + shared_ptr<BossMobPart> head; + shared_ptr<BossMobPart> neck; // 4J Added + shared_ptr<BossMobPart> body; + shared_ptr<BossMobPart> tail1; + shared_ptr<BossMobPart> tail2; + shared_ptr<BossMobPart> tail3; + shared_ptr<BossMobPart> wing1; + shared_ptr<BossMobPart> wing2; + + float oFlapTime; + float flapTime; + bool newTarget; + bool inWall; + + // 4J Stu - Added for new dragon behaviour +private: + int m_fireballCharge; + float m_holdingPatternAngle; + bool m_holdingPatternClockwise; + int m_actionTicks; + int m_sittingDamageReceived; + int m_remainingCrystalsCount; + int m_flameAttacks; + + int m_iGrowlTimer; + + double m_headYRot; + AABB *m_acidArea; + + NodeArray *m_nodes; + int m_nodeAdjacency[24]; + BinaryHeap *openSet; + Path *m_currentPath; + + enum EEnderdragonAction + { + e_EnderdragonAction_HoldingPattern, + e_EnderdragonAction_StrafePlayer, + e_EnderdragonAction_LandingApproach, + e_EnderdragonAction_Landing, + e_EnderdragonAction_Takeoff, + e_EnderdragonAction_Sitting_Flaming, + e_EnderdragonAction_Sitting_Scanning, + e_EnderdragonAction_Sitting_Attacking, + }; + + static const int CRYSTAL_COUNT; + + static const int FLAME_TICKS; + static const float FLAME_ANGLE; + static const int FLAME_PASSES; + static const int FLAME_FREQUENCY; + static const int FLAME_RANGE; + + static const int ATTACK_TICKS; + + static const int SITTING_ATTACK_Y_VIEW_RANGE; + static const int SITTING_ATTACK_VIEW_RANGE; + static const int SITTING_ATTACK_RANGE; + static const int SITTING_POST_ATTACK_IDLE_TICKS; + static const int SITTING_SCANNING_IDLE_TICKS; + static const int SITTING_FLAME_ATTACKS_COUNT; + + // The percentage of max health that the dragon will take while in the "Sitting" states before flying away + static const float SITTING_ALLOWED_DAMAGE_PERCENTAGE; + + static const int PODIUM_X_POS = 0; + static const int PODIUM_Z_POS = 0; + +private: + shared_ptr<Entity> attackTarget; + +public: + int dragonDeathTime; + +public: + shared_ptr<EnderCrystal> nearestCrystal; + +private: + void _init(); + +public: + EnderDragon(Level *level); + virtual ~EnderDragon(); + +protected: + virtual void defineSynchedData(); + +public: + void getLatencyPos(doubleArray result, int step, float a); + virtual void aiStep(); + +private: + using BossMob::hurt; + + void checkCrystals(); + void checkAttack(); + void knockBack(vector<shared_ptr<Entity> > *entities); + void hurt(vector<shared_ptr<Entity> > *entities); + void findNewTarget(); + float rotWrap(double d); + bool checkWalls(AABB *bb); + +public: + virtual bool hurt(shared_ptr<BossMobPart> bossMobPart, DamageSource *source, int damage); + +protected: + virtual void tickDeath(); + +private: + void spawnExitPortal(int x, int z); + +protected: + virtual void checkDespawn(); + virtual int getHurtSound(); +public: + virtual vector<shared_ptr<Entity> > *getSubEntities(); + virtual bool isPickable(); + virtual int getSynchedHealth(); + +private: + // 4J added for new dragon behaviour + bool setSynchedAction(EEnderdragonAction action, bool force = false); + EEnderdragonAction getSynchedAction(); + int findClosestNode(double tX, double tY, double tZ); + int findClosestNode(); + Path *findPath(int startIndex, int endIndex, Node *finalNode = NULL); + Path *reconstruct_path(Node *from, Node *to); + + void strafeAttackTarget(); + void navigateToNextPathNode(); + +public: + virtual void addAdditonalSaveData(CompoundTag *entityTag); + virtual void readAdditionalSaveData(CompoundTag *tag); + +public: + void handleCrystalDestroyed(DamageSource *source); + + float getTilt(float a); + double getHeadYOffset(float a); + double getHeadYRotDiff(float a); + double getHeadPartYOffset(int partIndex, doubleArray bodyPos, doubleArray partPos); + double getHeadPartYRotDiff(int partIndex, doubleArray bodyPos, doubleArray partPos); + Vec3 *getHeadLookVector(float a); +}; |
