Implement Pirate Marauder AI. Release Build 11609.
This commit is contained in:
parent
9509f317c3
commit
d6c2b6c87f
@ -169,11 +169,16 @@ void Monster::PerformAnimation(const std::string_view animationName){
|
|||||||
if(HasFourWaySprites())animation.ChangeState(internal_animState,std::format("{}_{}",animationName,int(facingDirection)));
|
if(HasFourWaySprites())animation.ChangeState(internal_animState,std::format("{}_{}",animationName,int(facingDirection)));
|
||||||
else animation.ChangeState(internal_animState,std::string(animationName));
|
else animation.ChangeState(internal_animState,std::string(animationName));
|
||||||
}
|
}
|
||||||
//Performs an animation, optionally changes the facing direction of this monster.
|
|
||||||
void Monster::PerformAnimation(const std::string_view animationName,const Direction facingDir){
|
void Monster::PerformAnimation(const std::string_view animationName,const Direction facingDir){
|
||||||
facingDirection=facingDir;
|
facingDirection=facingDir;
|
||||||
PerformAnimation(animationName);
|
PerformAnimation(animationName);
|
||||||
}
|
}
|
||||||
|
void Monster::PerformAnimation(const std::string_view animationName,const vf2d targetFacingDir){
|
||||||
|
facingDirection=GetFacingDirectionToTarget(targetFacingDir);
|
||||||
|
PerformAnimation(animationName);
|
||||||
|
}
|
||||||
|
|
||||||
bool Monster::_SetX(float x,const bool monsterInvoked){
|
bool Monster::_SetX(float x,const bool monsterInvoked){
|
||||||
vf2d newPos={x,pos.y};
|
vf2d newPos={x,pos.y};
|
||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
@ -1637,3 +1642,7 @@ void Monster::ResetCurseOfDeathDamage(){
|
|||||||
void Monster::AddAddedVelocity(vf2d vel){
|
void Monster::AddAddedVelocity(vf2d vel){
|
||||||
this->addedVel+=vel;
|
this->addedVel+=vel;
|
||||||
}
|
}
|
||||||
|
void Monster::MoveForward(const vf2d&moveForwardVec,const float fElapsedTime){
|
||||||
|
if(moveForwardVec.mag()==0.f)ERR("WARNING! Passed a zero length vector into Move Forward! THIS IS NOT ALLOWED!");
|
||||||
|
SetPos(pos+moveForwardVec.norm()*100.f*fElapsedTime*GetMoveSpdMult());
|
||||||
|
}
|
@ -128,7 +128,8 @@ public:
|
|||||||
void PerformNPCLeftAnimation();
|
void PerformNPCLeftAnimation();
|
||||||
void PerformNPCRightAnimation();
|
void PerformNPCRightAnimation();
|
||||||
void PerformAnimation(const std::string_view animationName);
|
void PerformAnimation(const std::string_view animationName);
|
||||||
void PerformAnimation(const std::string_view animationName,const Direction facingDir);
|
void PerformAnimation(const std::string_view animationName,const Direction facingDir); //Performs an animation, optionally changes the facing direction of this monster.
|
||||||
|
void PerformAnimation(const std::string_view animationName,const vf2d targetFacingDir); //Faces a target vector while performing an animation.
|
||||||
const Animate2D::FrameSequence&GetCurrentAnimation()const;
|
const Animate2D::FrameSequence&GetCurrentAnimation()const;
|
||||||
const Animate2D::FrameSequence&GetAnimation(const std::string_view animationName)const;
|
const Animate2D::FrameSequence&GetAnimation(const std::string_view animationName)const;
|
||||||
const bool OnUpperLevel()const;
|
const bool OnUpperLevel()const;
|
||||||
@ -162,8 +163,8 @@ public:
|
|||||||
const std::function<void(Monster&,float,std::string)>&GetStrategy()const;
|
const std::function<void(Monster&,float,std::string)>&GetStrategy()const;
|
||||||
void SetSize(float newSize,bool immediate=true);
|
void SetSize(float newSize,bool immediate=true);
|
||||||
geom2d::circle<float>BulletCollisionHitbox();
|
geom2d::circle<float>BulletCollisionHitbox();
|
||||||
void SetStrategyDrawFunction(std::function<void(AiL*,Monster&,const std::string&)>func);
|
void SetStrategyDrawFunction(std::function<void(AiL*game,Monster&monster,const std::string&strategy)>func);
|
||||||
void SetStrategyDrawOverlayFunction(std::function<void(AiL*,Monster&,const std::string&)>func);
|
void SetStrategyDrawOverlayFunction(std::function<void(AiL*game,Monster&monster,const std::string&strategy)>func);
|
||||||
std::function<void(AiL*,Monster&,const std::string&)>strategyDraw=[](AiL*pge,Monster&m,const std::string&strategy){};
|
std::function<void(AiL*,Monster&,const std::string&)>strategyDraw=[](AiL*pge,Monster&m,const std::string&strategy){};
|
||||||
std::function<void(AiL*,Monster&,const std::string&)>strategyDrawOverlay=[](AiL*pge,Monster&m,const std::string&strategy){};
|
std::function<void(AiL*,Monster&,const std::string&)>strategyDrawOverlay=[](AiL*pge,Monster&m,const std::string&strategy){};
|
||||||
const ItemAttributable&GetStats()const;
|
const ItemAttributable&GetStats()const;
|
||||||
@ -227,6 +228,7 @@ public:
|
|||||||
const bool FadeoutWhenStandingBehind()const;
|
const bool FadeoutWhenStandingBehind()const;
|
||||||
const bool FaceTarget()const;
|
const bool FaceTarget()const;
|
||||||
void ResetCurseOfDeathDamage();
|
void ResetCurseOfDeathDamage();
|
||||||
|
void MoveForward(const vf2d&moveForwardVec,const float fElapsedTime); //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.
|
||||||
private:
|
private:
|
||||||
//NOTE: Marking a monster for deletion does not trigger any death events. It just simply removes the monster from the field!!
|
//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.
|
// 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.
|
||||||
@ -280,7 +282,7 @@ private:
|
|||||||
NPCData npcData;
|
NPCData npcData;
|
||||||
float lastPathfindingCooldown=0.f;
|
float lastPathfindingCooldown=0.f;
|
||||||
std::function<bool(GameEvent&,Monster&,const std::string&)>strategyDeathFunc{};
|
std::function<bool(GameEvent&,Monster&,const std::string&)>strategyDeathFunc{};
|
||||||
void SetStrategyDeathFunction(std::function<bool(GameEvent&,Monster&,const std::string&)>func);
|
void SetStrategyDeathFunction(std::function<bool(GameEvent&event,Monster&monster,const std::string&strategyName)>func);
|
||||||
//If you are trying to change a Get() stat, use the STAT_UP buff (and the optional argument) to supply an attribute you want to apply.
|
//If you are trying to change a Get() stat, use the STAT_UP buff (and the optional argument) to supply an attribute you want to apply.
|
||||||
const ItemAttribute&GetBonusStat(std::string_view attr)const;
|
const ItemAttribute&GetBonusStat(std::string_view attr)const;
|
||||||
//Returns false if the monster could not be moved to the requested location due to collision.
|
//Returns false if the monster could not be moved to the requested location due to collision.
|
||||||
|
@ -48,19 +48,64 @@ INCLUDE_game
|
|||||||
|
|
||||||
void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string strategy){
|
void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string strategy){
|
||||||
enum PhaseName{
|
enum PhaseName{
|
||||||
|
INIT,
|
||||||
MOVE,
|
MOVE,
|
||||||
WINDUP,
|
WINDUP,
|
||||||
RECOVERY,
|
RECOVERY,
|
||||||
};
|
LEAP,
|
||||||
|
PREPARE_WHIRLWIND,
|
||||||
enum AttackType{
|
WHIRLWIND,
|
||||||
STAB,
|
|
||||||
SLASH
|
|
||||||
};
|
};
|
||||||
|
|
||||||
switch(m.phase){
|
switch(m.phase){
|
||||||
|
case INIT:{
|
||||||
|
m.F(A::CHASE_TIMER)=ConfigFloat("Ability Choose Timer");
|
||||||
|
m.phase=MOVE;
|
||||||
|
}break;
|
||||||
case MOVE:{
|
case MOVE:{
|
||||||
float distToPlayer=m.GetDistanceFrom(game->GetPlayer()->GetPos());
|
float distToPlayer=m.GetDistanceFrom(game->GetPlayer()->GetPos());
|
||||||
|
|
||||||
|
m.F(A::CHASE_TIMER)-=fElapsedTime;
|
||||||
|
if(m.F(A::CHASE_TIMER)<=0.f){
|
||||||
|
m.I(A::ABILITY_COUNT)++;
|
||||||
|
m.F(A::CHASE_TIMER)=ConfigFloat("Ability Choose Timer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m.I(A::ABILITY_COUNT)>0){
|
||||||
|
float roll{util::random_range(0.f,100.f)};
|
||||||
|
float distanceToPlayer{util::distance(m.GetPos(),game->GetPlayer()->GetPos())};
|
||||||
|
std::pair<float,float>jumpAttackRollRange{0.f,ConfigFloat("Jump Attack Chance")};
|
||||||
|
std::pair<float,float>whirlwindAttackRollRange{jumpAttackRollRange.second,jumpAttackRollRange.second+ConfigFloat("Whirlwind Attack Chance")};
|
||||||
|
|
||||||
|
if(roll<jumpAttackRollRange.second&&distanceToPlayer>=ConfigFloatArr("Jump Attack Ranges",0)/100.f*24.f&&distanceToPlayer<=ConfigFloatArr("Jump Attack Ranges",1)/100.f*24.f){
|
||||||
|
m.phase=LEAP;
|
||||||
|
m.V(A::JUMP_TARGET_POS)=game->GetPlayer()->GetPos();
|
||||||
|
m.I(A::ABILITY_COUNT)--;
|
||||||
|
const float impactArea{ConfigFloat("Jump Attack Impact Area")};
|
||||||
|
m.SetStrategyDrawFunction([impactArea](AiL*game,Monster&monster,const std::string&strategy){
|
||||||
|
game->view.DrawRotatedDecal(monster.V(A::JUMP_TARGET_POS),GFX["range_indicator.png"].Decal(),0.f,GFX["range_indicator.png"].Sprite()->Size()/2.f,vf2d{1,1}*(impactArea/100.f),{255,0,0,96});
|
||||||
|
});
|
||||||
|
m.F(A::JUMP_MOVE_TO_TARGET_TIMER)=0.f;
|
||||||
|
m.V(A::PREV_POS)=m.GetPos();
|
||||||
|
m.PerformAnimation("LEAPING",m.V(A::JUMP_TARGET_POS));
|
||||||
|
break;
|
||||||
|
}else
|
||||||
|
if(roll>=whirlwindAttackRollRange.first&&roll<whirlwindAttackRollRange.second
|
||||||
|
&&distanceToPlayer>=ConfigFloatArr("Whirlwind Attack Ranges",0)/100.f*24.f&&distanceToPlayer<=ConfigFloatArr("Whirlwind Attack Ranges",1)/100.f*24.f){
|
||||||
|
m.phase=PREPARE_WHIRLWIND;
|
||||||
|
m.I(A::ABILITY_COUNT)--;
|
||||||
|
vf2d aimingTarget{game->GetPlayer()->GetPos()};
|
||||||
|
if(aimingTarget==m.GetPos()){ //Handle edge case.
|
||||||
|
aimingTarget=m.GetPos()+vf2d{1.f,util::random(2*PI)}.cart();
|
||||||
|
}
|
||||||
|
m.V(A::PATH_DIR)=util::pointTo(m.GetPos(),aimingTarget);
|
||||||
|
m.PerformAnimation("SPIN",m.V(A::LOCKON_POS));
|
||||||
|
m.F(A::CASTING_TIMER)=ConfigFloat("Whirlwind Chargeup Time");
|
||||||
|
m.AddBuff(BuffType::SPEEDBOOST,ConfigFloat("Whirlwind Spin Time"),ConfigFloat("Whirlwind Bonus Movespd")/100.f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NormalBehavior:
|
||||||
if(distToPlayer>ConfigFloat("Attack Spacing")/100.f*24){
|
if(distToPlayer>ConfigFloat("Attack Spacing")/100.f*24){
|
||||||
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
||||||
}else{
|
}else{
|
||||||
@ -86,5 +131,45 @@ void Monster::STRATEGY::PIRATE_MARAUDER(Monster&m,float fElapsedTime,std::string
|
|||||||
if(m.F(A::CASTING_TIMER)<=0){m.PerformIdleAnimation(m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos()));}
|
if(m.F(A::CASTING_TIMER)<=0){m.PerformIdleAnimation(m.GetFacingDirectionToTarget(game->GetPlayer()->GetPos()));}
|
||||||
if(m.F(A::RECOVERY_TIME)<=0)m.phase=MOVE;
|
if(m.F(A::RECOVERY_TIME)<=0)m.phase=MOVE;
|
||||||
}break;
|
}break;
|
||||||
|
case LEAP:{
|
||||||
|
m.F(A::JUMP_MOVE_TO_TARGET_TIMER)+=fElapsedTime;
|
||||||
|
const float halfJumpTime{ConfigFloat("Jump Attack Duration")/2.f};
|
||||||
|
if(m.F(A::JUMP_MOVE_TO_TARGET_TIMER)<halfJumpTime)m.SetZ(util::smoothstep(0,ConfigFloat("Jump Attack Height"),m.F(A::JUMP_MOVE_TO_TARGET_TIMER)/halfJumpTime));
|
||||||
|
else m.SetZ(util::smoothstep(ConfigFloat("Jump Attack Height"),0,(m.F(A::JUMP_MOVE_TO_TARGET_TIMER)-halfJumpTime)/halfJumpTime));
|
||||||
|
m.SetPos(m.V(A::PREV_POS).lerp(m.V(A::JUMP_TARGET_POS),m.F(A::JUMP_MOVE_TO_TARGET_TIMER)/ConfigFloat("Jump Attack Duration")));
|
||||||
|
if(m.F(A::JUMP_MOVE_TO_TARGET_TIMER)>=ConfigFloat("Jump Attack Duration")){
|
||||||
|
SoundEffect::PlaySFX("Leap Land",m.GetPos());
|
||||||
|
game->Hurt(m.GetPos(),ConfigFloat("Jump Attack Impact Area")/100.f*24.f,m.GetAttack(),m.OnUpperLevel(),m.GetZ(),HurtType::PLAYER);
|
||||||
|
game->ProximityKnockback(m.GetPos(),ConfigFloat("Jump Attack Impact Area")/100.f*24.f,ConfigFloat("Jump Attack Knockback Amount"),HurtType::MONSTER|HurtType::PLAYER);
|
||||||
|
m.SetZ(0.f);
|
||||||
|
m.SetPos(m.V(A::JUMP_TARGET_POS));
|
||||||
|
m.phase=MOVE;
|
||||||
|
m.PerformIdleAnimation();
|
||||||
|
m.SetStrategyDrawFunction([](AiL*game,Monster&monster,const std::string&strategy){});
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case PREPARE_WHIRLWIND:{
|
||||||
|
m.F(A::CASTING_TIMER)-=fElapsedTime;
|
||||||
|
if(m.F(A::CASTING_TIMER)<=0.f){
|
||||||
|
m.phase=WHIRLWIND;
|
||||||
|
m.F(A::CHASE_TIMER)=0.f;
|
||||||
|
m.PerformAnimation("SPINNING");
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case WHIRLWIND:{
|
||||||
|
m.F(A::CHASE_TIMER)+=fElapsedTime;
|
||||||
|
if(m.F(A::CHASE_TIMER)>=ConfigFloat("Whirlwind Spin Time")){
|
||||||
|
m.phase=MOVE;
|
||||||
|
m.PerformIdleAnimation();
|
||||||
|
}
|
||||||
|
m.MoveForward(m.V(A::PATH_DIR),fElapsedTime);
|
||||||
|
const HurtList hurtTargets{game->Hurt(m.GetPos(),ConfigFloat("Whirlwind Radius")/100.f*24.f,m.GetAttack(),m.OnUpperLevel(),m.GetZ(),HurtType::PLAYER)};
|
||||||
|
for(auto&[target,isHurt]:hurtTargets){
|
||||||
|
if(std::holds_alternative<Player*>(target)){
|
||||||
|
(std::get<Player*>(target))->ApplyIframes(0.5f);
|
||||||
|
}else ERR("WARNING! Somehow ended up with a non-player entity for whirlwind damage check! THIS SHOULD NOT BE HAPPENING!")
|
||||||
|
}
|
||||||
|
game->ProximityKnockback(m.GetPos(),ConfigFloat("Whirlwind Radius")/100.f*24.f,ConfigFloat("Whirlwind Knockback Amount"),HurtType::MONSTER|HurtType::PLAYER);
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 11602
|
#define VERSION_BUILD 11609
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="335" height="165" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="9">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="335" height="165" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="13">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Background Music" propertytype="BGM" value="mountain"/>
|
<property name="Background Music" propertytype="BGM" value="mountain"/>
|
||||||
<property name="Level Type" type="int" propertytype="LevelType" value="0"/>
|
<property name="Level Type" type="int" propertytype="LevelType" value="0"/>
|
||||||
@ -9,6 +9,7 @@
|
|||||||
<tileset firstgid="4533" source="../maps/palm_trees.tsx"/>
|
<tileset firstgid="4533" source="../maps/palm_trees.tsx"/>
|
||||||
<tileset firstgid="4617" source="../maps/objects.tsx"/>
|
<tileset firstgid="4617" source="../maps/objects.tsx"/>
|
||||||
<tileset firstgid="5400" source="../maps/24x24_Waterfall.tsx"/>
|
<tileset firstgid="5400" source="../maps/24x24_Waterfall.tsx"/>
|
||||||
|
<tileset firstgid="5480" source="../maps/Monsters.tsx"/>
|
||||||
<layer id="2" name="Layer 1" width="335" height="165">
|
<layer id="2" name="Layer 1" width="335" height="165">
|
||||||
<data encoding="csv">
|
<data encoding="csv">
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2312,1736,1785,1785,1785,1735,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,1736,1785,1785,1785,1785,1785,1785,1785,1735,2312,2312,2312,2312,2312,2312,2312,2312,1734,2298,2298,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1732,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2164,2165,2113,2113,2165,2112,2113,2164,2312,2312,2312,2312,2312,2312,2312,2312,2312,1734,2298,2298,2298,2298,2298,2298,1732,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2312,1736,1785,1785,1785,1735,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,1736,1785,1785,1785,1785,1785,1785,1785,1735,2312,2312,2312,2312,2312,2312,2312,2312,1734,2298,2298,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1732,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2164,2165,2113,2113,2165,2112,2113,2164,2312,2312,2312,2312,2312,2312,2312,2312,2312,1734,2298,2298,2298,2298,2298,2298,1732,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,2312,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
@ -861,13 +862,28 @@
|
|||||||
<property name="Upper?" type="bool" value="false"/>
|
<property name="Upper?" type="bool" value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="5" template="../maps/Monsters/Pirate.tx" x="492" y="1452">
|
<object id="8" name="Spawn Zone" type="SpawnGroup" x="180" y="1326" width="426" height="306">
|
||||||
|
<ellipse/>
|
||||||
|
</object>
|
||||||
|
<object id="9" template="../maps/Monsters/Pirate Marauder.tx" x="474" y="1398">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="spawner" type="object" value="8"/>
|
<property name="spawner" type="object" value="8"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="8" name="Spawn Zone" type="SpawnGroup" x="180" y="1326" width="426" height="306">
|
<object id="10" template="../maps/Monsters/Pirate Marauder.tx" x="474" y="1350">
|
||||||
<ellipse/>
|
<properties>
|
||||||
|
<property name="spawner" type="object" value="8"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
|
<object id="11" template="../maps/Monsters/Pirate Marauder.tx" x="456" y="1494">
|
||||||
|
<properties>
|
||||||
|
<property name="spawner" type="object" value="8"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
|
<object id="12" template="../maps/Monsters/Pirate Marauder.tx" x="480" y="1566">
|
||||||
|
<properties>
|
||||||
|
<property name="spawner" type="object" value="8"/>
|
||||||
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -1032,6 +1032,29 @@ MonsterStrategy
|
|||||||
}
|
}
|
||||||
Pirate Marauder
|
Pirate Marauder
|
||||||
{
|
{
|
||||||
|
# How long before adding an ability choice charge to perform abilities with.
|
||||||
|
Ability Choose Timer = 8s
|
||||||
|
|
||||||
|
Jump Attack Chance = 25%
|
||||||
|
Whirlwind Attack Chance = 25%
|
||||||
|
|
||||||
|
Whirlwind Chargeup Time = 0.2s
|
||||||
|
|
||||||
|
Whirlwind Bonus Movespd = 60%
|
||||||
|
# Spin time derived from 200% movespd (60% bonus movespd + 125% base movespd)
|
||||||
|
Whirlwind Spin Time = 1.5s
|
||||||
|
Whirlwind Knockback Amount = 140
|
||||||
|
Whirlwind Radius = 200
|
||||||
|
# Min, Max Range
|
||||||
|
Whirlwind Attack Ranges = 400, 700
|
||||||
|
|
||||||
|
Jump Attack Height = 12
|
||||||
|
Jump Attack Duration = 0.4s
|
||||||
|
Jump Attack Impact Area = 150
|
||||||
|
Jump Attack Knockback Amount = 120
|
||||||
|
# Min, Max Range
|
||||||
|
Jump Attack Ranges = 400, 9999
|
||||||
|
|
||||||
# Distance from player to run to before swinging weapon.
|
# Distance from player to run to before swinging weapon.
|
||||||
Attack Spacing = 50
|
Attack Spacing = 50
|
||||||
|
|
||||||
|
@ -1249,6 +1249,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 33
|
XP = 33
|
||||||
|
|
||||||
|
Collision Radius = 12
|
||||||
|
|
||||||
Strategy = Goblin Dagger
|
Strategy = Goblin Dagger
|
||||||
|
|
||||||
#### Script Override ####
|
#### Script Override ####
|
||||||
@ -1327,6 +1329,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 39
|
XP = 39
|
||||||
|
|
||||||
|
Collision Radius = 12
|
||||||
|
|
||||||
Strategy = Pirate Marauder
|
Strategy = Pirate Marauder
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1338,6 +1342,17 @@ Monsters
|
|||||||
# Setting this to true means every four rows indicates one animation, the ordering of the directions is: NORTH, EAST, SOUTH, WEST
|
# Setting this to true means every four rows indicates one animation, the ordering of the directions is: NORTH, EAST, SOUTH, WEST
|
||||||
4-Way Spritesheet = True
|
4-Way Spritesheet = True
|
||||||
|
|
||||||
|
#### Script Override ####
|
||||||
|
# Distance from player to run to before swinging weapon.
|
||||||
|
Attack Spacing = 100
|
||||||
|
|
||||||
|
# Slash Attack windup time
|
||||||
|
Slash Windup Time = 0.2s
|
||||||
|
|
||||||
|
Dagger Slash Image = "pirate_slash.png"
|
||||||
|
|
||||||
|
#########################
|
||||||
|
|
||||||
Animations
|
Animations
|
||||||
{
|
{
|
||||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse,ReverseOneShot)
|
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse,ReverseOneShot)
|
||||||
@ -1372,6 +1387,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 59
|
XP = 59
|
||||||
|
|
||||||
|
Collision Radius = 12
|
||||||
|
|
||||||
Strategy = Pirate Captain
|
Strategy = Pirate Captain
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1419,6 +1436,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 37
|
XP = 37
|
||||||
|
|
||||||
|
Collision Radius = 12
|
||||||
|
|
||||||
Strategy = Pirate Buccaneer
|
Strategy = Pirate Buccaneer
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1461,6 +1480,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 37
|
XP = 37
|
||||||
|
|
||||||
|
Collision Radius = 10
|
||||||
|
|
||||||
Strategy = Crab
|
Strategy = Crab
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1502,6 +1523,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 61
|
XP = 61
|
||||||
|
|
||||||
|
Collision Radius = 10
|
||||||
|
|
||||||
Strategy = Crab
|
Strategy = Crab
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1543,6 +1566,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 6
|
XP = 6
|
||||||
|
|
||||||
|
Collision Radius = 9
|
||||||
|
|
||||||
Strategy = Seagull
|
Strategy = Seagull
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1584,6 +1609,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 24
|
XP = 24
|
||||||
|
|
||||||
|
Collision Radius = 10
|
||||||
|
|
||||||
Strategy = Sandworm
|
Strategy = Sandworm
|
||||||
|
|
||||||
# Wait time override for Run Towards strategy.
|
# Wait time override for Run Towards strategy.
|
||||||
@ -1627,6 +1654,8 @@ Monsters
|
|||||||
|
|
||||||
XP = 0
|
XP = 0
|
||||||
|
|
||||||
|
Collision Radius = 7
|
||||||
|
|
||||||
Strategy = Parrot
|
Strategy = Parrot
|
||||||
|
|
||||||
# Instead of the monster dying, it gets knocked unconscious
|
# Instead of the monster dying, it gets knocked unconscious
|
||||||
|
@ -237,6 +237,12 @@ Events
|
|||||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
File[0] = rockbreak.ogg, 90%, 40%, 50%
|
File[0] = rockbreak.ogg, 90%, 40%, 50%
|
||||||
}
|
}
|
||||||
|
Leap Land
|
||||||
|
{
|
||||||
|
CombatSound = True
|
||||||
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
|
File[0] = rockbreak.ogg, 80%
|
||||||
|
}
|
||||||
Level Up
|
Level Up
|
||||||
{
|
{
|
||||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||||
|
@ -191,6 +191,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
#ifndef OLC_V2D_TYPE
|
#ifndef OLC_V2D_TYPE
|
||||||
#define OLC_V2D_TYPE
|
#define OLC_V2D_TYPE
|
||||||
@ -246,6 +247,7 @@ namespace olc
|
|||||||
inline v_2d norm() const
|
inline v_2d norm() const
|
||||||
{
|
{
|
||||||
auto r = 1 / mag();
|
auto r = 1 / mag();
|
||||||
|
if(!std::isfinite(r))ERR("WARNING! Passing a value that creates an unusable infinite value while normalizing! THIS SHOULD NOT BE HAPPENING!");
|
||||||
return v_2d(x * r, y * r);
|
return v_2d(x * r, y * r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,12 @@ namespace olc::util{
|
|||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
template<class T,class U>
|
||||||
|
inline auto smoothstep(const T val1,const U val2,const float t){
|
||||||
|
auto x{decltype(val1+val2)(1-pow(1-t,3))};
|
||||||
|
return val1*(1-x)+val2*x;
|
||||||
|
}
|
||||||
|
|
||||||
std::string timerStr(float time);
|
std::string timerStr(float time);
|
||||||
std::string WrapText(PixelGameEngine*pge,std::string str,int width,bool proportional,vd2d scale);
|
std::string WrapText(PixelGameEngine*pge,std::string str,int width,bool proportional,vd2d scale);
|
||||||
std::u32string WrapText(PixelGameEngine*pge,std::u32string str,int width,Font&font,vd2d scale);
|
std::u32string WrapText(PixelGameEngine*pge,std::u32string str,int width,Font&font,vd2d scale);
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user