Finish implementing Pirate Captain and Parrot behaviors. Refactor monster phase system to be per-strategy instead of a global phase for all strategies. Release Build 11666.
//The bear slam attack indicator will move with the bear, and the LOCKON_POS variable will hold a polar coordinate indicating distance and angle for where it should be attacking relative to its position.
if(m.F(A::FLYING_HEIGHT)<m.F(A::TARGET_FLYING_HEIGHT))m.F(A::FLYING_HEIGHT)=std::min(m.F(A::TARGET_FLYING_HEIGHT),m.F(A::FLYING_HEIGHT)+ConfigFloat("Attack Z Speed")*fElapsedTime);
voidMoveForward(constvf2d&moveForwardVec,constfloatfElapsedTime);//Moves the monster forward in given vector direction (will be auto-normalized) applying speeed boosts and other proper movement requirements as if you wanted to move on a frame-by-frame basis.
//NOTE: Marking a monster for deletion does not trigger any death events. It just simply removes the monster from the field!!
// The way this works is that monsters marked for deletion will cause the monster update loop to detect there's at least one or more monsters that must be deleted and will call erase_if on the list at the end of the iteration loop.
@ -273,7 +277,7 @@ private:
floatspriteRot=0;
std::shared_ptr<DamageNumber>damageNumberPtr;
std::shared_ptr<DamageNumber>dotNumberPtr;
intphase=0;
std::unordered_map<StrategyName,int>phase{};//NOTE: THIS SHOULD NOT BE MODIFIED DIRECTLY!!! Use SetPhase(), GetPhase() / PHASE() SETPHASE() macros!
booldiesNormally=true;//If set to false, the monster death is handled in a special way. Set it to true when it's time to die.
DaggerStab::DirectionOffsets{ConfigVec("Dagger Up Offset"),ConfigVec("Dagger Down Offset"),ConfigVec("Dagger Right Offset"),ConfigVec("Dagger Left Offset")})EndBullet;
m.F(A::NEXT_HEALTH_PCT_PILLAR_PHASE)=ConfigFloat("Pillar Respawns.Start HP Threshold")/100.f;
m.I(A::SHOCKWAVE_COLOR)=ConfigPixel("Shockwave.Danger Area Color").n;
m.phase=SPAWN_PILLAR_PREPARE;
SETPHASE(SPAWN_PILLAR_PREPARE);
if(ConfigIntArr("Pillar Respawns.Respawn Count",0)<ConfigIntArr("Pillar Respawns.Respawn Count",1))ERR(std::format("WARNING! {} Stone golem pillars were declared damaged when only {} will spawn. Please make sure the number is the same or equal to the total spawned pillars! (\"Pillar Respawns.Respawn Count\" strategy property)",ConfigIntArr("Pillar Respawns.Respawn Count",1),ConfigIntArr("Pillar Respawns.Respawn Count",0)));
if(StoneThrowRollSucceeds){//The intent is one or the other attack is supposed to happen. We can't do the slam and a throw, rerolling repeatedly each tick is unncessary.
if(m.SIZET(A::PREVIOUS_MONSTER_COUNT)!=MONSTER_LIST.size()){//The monster list has changed...Whether it's a pillar getting added or removed, it's important we recalculate safe areas proper.
m.phase=FIX_SAFE_AREAS;//HACK ALERT! Since spawning/removing monsters doesn't immediately occur in the MONSTER_LIST structure, we must defer the safe areas until the next tick and then recalculate them. To do this, we put the monster into another state and pause the shockwave attack for a frame to fix the new spawn areas on the next tick.
SETPHASE(FIX_SAFE_AREAS);//HACK ALERT! Since spawning/removing monsters doesn't immediately occur in the MONSTER_LIST structure, we must defer the safe areas until the next tick and then recalculate them. To do this, we put the monster into another state and pause the shockwave attack for a frame to fix the new spawn areas on the next tick.
//Extending the bear script's variables to read the state of it...
constboolSlamHasFinished=m.I(A::ATTACK_COUNT)!=m.I(A::BEAR_STOMP_COUNT);//The bear script uses the internal phase variable to determine the state of things.