Bullets do not die immediately when view goes offscreen anymore. Initial jump states and setup for Slime King are now implemented.

pull/28/head
sigonasr2 1 year ago
parent efdf696d2c
commit 942e8e0ef7
  1. 1
      Crawler/Animation.cpp
  2. 3
      Crawler/Crawler.cpp
  3. 2
      Crawler/Crawler.h
  4. 36
      Crawler/Monster.cpp
  5. 13
      Crawler/Monster.h
  6. 9
      Crawler/MonsterAttribute.h
  7. 30
      Crawler/Player.cpp
  8. 6
      Crawler/Player.h
  9. 8
      Crawler/RunTowards.cpp
  10. 18
      Crawler/ShootAfar.cpp
  11. 45
      Crawler/SlimeKing.cpp
  12. 36
      Crawler/State.h
  13. 2
      Crawler/Version.h
  14. 3
      Crawler/assets/config/MonsterStrategies.txt
  15. 1
      Crawler/assets/config/gfx/gfx.txt
  16. BIN
      Crawler/assets/range_indicator.png
  17. 4
      Crawler/utils.cpp
  18. 1
      Crawler/utils.h

@ -206,6 +206,7 @@ void sig::Animation::InitializeAnimations(){
CreateStillAnimation(game->GFX_Arrow,{24,24},"ARROW");
CreateStillAnimation(game->GFX_ChargedArrow,{48,48},"CHARGED_ARROW");
CreateStillAnimation(game->GFX_Laser,{5,1},"LASER");
CreateStillAnimation(game->GFX_RangeIndicator,{24,24},"RANGE_INDICATOR");
}
void sig::Animation::SetupPlayerAnimations(){

@ -116,6 +116,7 @@ bool Crawler::OnUserCreate(){
LOADIMG(GFX_Arrow)
LOADIMG(GFX_Laser)
LOADIMG(GFX_ChargedArrow)
LOADIMG(GFX_RangeIndicator)
Monster::InitializeStrategies();
//Animations
@ -451,7 +452,7 @@ void Crawler::UpdateBullets(float fElapsedTime){
} else {
b->pos+=b->vel*fElapsedTime;
}
if(b->pos.x+b->radius<view.GetWorldTL().x||b->pos.x-b->radius>view.GetWorldBR().x||b->pos.y+b->radius<view.GetWorldTL().y||b->pos.y-b->radius>view.GetWorldBR().y){
if(b->pos.x+b->radius<view.GetWorldTL().x-WINDOW_SIZE.x||b->pos.x-b->radius>view.GetWorldBR().x+WINDOW_SIZE.x||b->pos.y+b->radius<view.GetWorldTL().y-WINDOW_SIZE.y||b->pos.y-b->radius>view.GetWorldBR().y+WINDOW_SIZE.y){
b->dead=true;
continue;
}

@ -29,7 +29,7 @@ class Crawler : public olc::PixelGameEngine
GFX_Splash_Effect,GFX_LightningBolt,GFX_LightningBoltParticle1,
GFX_LightningBoltParticle2,GFX_LightningBoltParticle3,GFX_LightningBoltParticle4,
GFX_ChainLightning,GFX_LightningSplash,GFX_Meteor,GFX_Arrow,
GFX_Laser,GFX_ChargedArrow;
GFX_Laser,GFX_ChargedArrow,GFX_RangeIndicator;
public:
Renderable GFX_BulletCircle,GFX_BulletCircleOutline,GFX_EnergyBolt,GFX_Circle;
Pathfinding pathfinder;

@ -129,11 +129,11 @@ bool Monster::Update(float fElapsedTime){
if(!HasIframes()){
for(Monster&m:MONSTER_LIST){
if(&m==this)continue;
if(!m.HasIframes()&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){
if(!m.HasIframes()&&OnUpperLevel()==m.OnUpperLevel()&&abs(m.GetZ()-GetZ())<=1&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){
m.Collision(*this);
geom2d::line line(pos,m.GetPos());
float dist = line.length();
m.SetPosition(line.rpoint(dist*1.1));
m.SetPos(line.rpoint(dist*1.1));
if(m.IsAlive()){
vel=line.vector().norm()*-128;
}
@ -142,7 +142,7 @@ bool Monster::Update(float fElapsedTime){
if(!game->GetPlayer()->HasIframes()&&game->GetPlayer()->OnUpperLevel()==OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(game->GetPlayer()->GetPos(),12*game->GetPlayer()->GetSizeMult()/2))){
geom2d::line line(pos,game->GetPlayer()->GetPos());
float dist = line.length();
SetPosition(line.rpoint(-0.1));
SetPos(line.rpoint(-0.1));
vel=line.vector().norm()*-128;
}
}
@ -183,6 +183,7 @@ Key Monster::GetFacingDirection(){
return facingDirection;
}
void Monster::Draw(){
strategyDraw(game);
if(GetZ()>0){
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},game->GFX_Circle.Decal(),shadowScale,BLACK);
@ -204,14 +205,14 @@ void Monster::Collision(Monster&m){
Collision();
}
void Monster::Collision(){
if(strategy==0&&GetState()==MOVE_TOWARDS){//The run towards strategy causes state to return to normal upon a collision.
SetState(NORMAL);
if(strategy==0&&GetState()==State::MOVE_TOWARDS){//The run towards strategy causes state to return to normal upon a collision.
SetState(State::NORMAL);
}
}
void Monster::SetVelocity(vf2d vel){
this->vel=vel;
}
bool Monster::SetPosition(vf2d pos){
bool Monster::SetPos(vf2d pos){
bool resultX=SetX(pos.x);
bool resultY=SetY(pos.y);
if(resultY&&!resultX){
@ -301,7 +302,7 @@ void Monster::AddBuff(BuffType type,float duration,float intensity){
}
void Monster::StartPathfinding(float pathingTime){
SetState(PATH_AROUND);
SetState(State::PATH_AROUND);
path=game->pathfinder.Solve_AStar(pos,target,12,OnUpperLevel());
if(path.size()>0){
pathIndex=0;
@ -315,7 +316,7 @@ void Monster::PathAroundBehavior(float fElapsedTime){
//Move towards the new path.
geom2d::line moveTowardsLine=geom2d::line(pos,path[pathIndex]*24);
if(moveTowardsLine.length()>2){
SetPosition(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult());
SetPos(pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult());
if(moveTowardsLine.vector().x>0){
facingDirection=RIGHT;
} else {
@ -341,11 +342,11 @@ std::vector<Buff>Monster::GetBuffs(BuffType buff){
return filteredBuffs;
}
State Monster::GetState(){
State::State Monster::GetState(){
return state;
}
void Monster::SetState(State newState){
void Monster::SetState(State::State newState){
state=newState;
}
@ -407,4 +408,19 @@ bool&Monster::GetBool(Attribute a){
attributes[a]=false;
}
return std::get<bool>(attributes[a]);
}
vf2d&Monster::GetVf2d(Attribute a){
if(attributes.count(a)==0){
attributes[a]=vf2d{};
}
return std::get<vf2d>(attributes[a]);
}
void Monster::SetZ(float z){
this->z=z;
}
void Monster::SetStrategyDrawFunction(std::function<void(Crawler*)>func){
strategyDraw=func;
}

@ -9,6 +9,7 @@
#include "MonsterAttribute.h"
struct Player;
class Crawler;
enum MonsterAnimation{
IDLE,
@ -72,7 +73,7 @@ private:
float iframe_timer=0;
Key facingDirection;
int strategy;
State state=State::NORMAL;
State::State state=State::NORMAL;
Animate2D::Animation<std::string>animation;
Animate2D::AnimationState internal_animState;
float randomFrameOffset=0.f;
@ -91,6 +92,7 @@ private:
bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die.
float targetSize=0;
std::map<Attribute,std::variant<VARIANTS>>attributes;
std::function<void(Crawler*)>strategyDraw=[](Crawler*pge){};
protected:
public:
Monster()=delete;
@ -115,7 +117,7 @@ public:
void Collision();
void SetVelocity(vf2d vel);
//Returns false if the monster could not be moved to the requested location due to collision.
bool SetPosition(vf2d pos);
bool SetPos(vf2d pos);
//Returns false if the monster could not be moved to the requested location due to collision.
bool SetX(float x);
//Returns false if the monster could not be moved to the requested location due to collision.
@ -129,17 +131,20 @@ public:
void PathAroundBehavior(float fElapsedTime);
void AddBuff(BuffType type,float duration,float intensity);
std::vector<Buff>GetBuffs(BuffType buff);
State GetState();
void SetState(State newState);
State::State GetState();
void SetState(State::State newState);
static void InitializeStrategies();
bool HasIframes();
float GetZ();
void SetZ(float z);
std::string GetStrategy();
void SetSize(float newSize,bool immediate=true);
float&GetFloat(Attribute a);
int&GetInt(Attribute a);
std::string&GetString(Attribute a);
bool&GetBool(Attribute a);
vf2d&GetVf2d(Attribute a);
void SetStrategyDrawFunction(std::function<void(Crawler*)>func);
private:
struct STRATEGY{
static int _GetInt(Monster&m,std::string param,int strategyNumber,int index=0);

@ -1,10 +1,11 @@
#pragma once
#define VARIANTS float,int,std::string,bool
#define VARIANTS float,int,std::string,bool,vf2d
#include <string>
#define F(attr) GetFloat(attr)
#define I(attr) GetInt(attr)
#define S(attr) GetString(attr)
#define B(attr) GetBool(attr)
#define V(attr) GetVf2d(attr)
enum class Attribute{
IFRAME_TIME_UPON_HIT,
@ -13,4 +14,10 @@ enum class Attribute{
SHOOT_RING_COUNTER,
SHOOT_RING_RIGHT,
SHOOT_RING_OFFSET,
PATTERN_REPEAT_COUNT,
JUMP_ORIGINAL_LANDING_TIMER,
JUMP_LANDING_TIMER,
JUMP_TARGET_POS,
JUMP_ORIGINAL_POS,
RECOVERY_TIME,
};

@ -160,7 +160,7 @@ float Player::GetSpinAngle(){
return spin_angle;
}
State Player::GetState(){
State::State Player::GetState(){
return state;
}
@ -207,7 +207,7 @@ void Player::Update(float fElapsedTime){
//Class-specific update events.
OnUpdate(fElapsedTime);
switch(state){
case SPIN:{
case State::SPIN:{
switch(facingDirection){
case UP:{
if(lastAnimationFlip==0){
@ -233,7 +233,7 @@ void Player::Update(float fElapsedTime){
z="Warrior.Ability 2.SpinMaxHeight"_I*sin(3.3*(GROUND_SLAM_SPIN_TIME-spin_attack_timer)/GROUND_SLAM_SPIN_TIME);
spin_attack_timer=std::max(0.f,spin_attack_timer-fElapsedTime);
} else {
SetState(NORMAL);
SetState(State::NORMAL);
spin_angle=0;
z=0;
float numb=4;
@ -245,14 +245,14 @@ void Player::Update(float fElapsedTime){
}
animation.UpdateState(internal_animState,fElapsedTime);
}break;
case BLOCK:{
case State::BLOCK:{
if(blockTimer<=0){
SetState(NORMAL);
SetState(State::NORMAL);
}
}break;
case SWING_SONIC_SWORD:{
case State::SWING_SONIC_SWORD:{
if(ability3.COOLDOWN_TIME-ability3.cooldown>0.5){
SetState(NORMAL);
SetState(State::NORMAL);
switch(facingDirection){
case DOWN:{
UpdateAnimation("WARRIOR_IDLE_S");
@ -270,11 +270,11 @@ void Player::Update(float fElapsedTime){
}
animation.UpdateState(internal_animState,fElapsedTime);
}break;
case TELEPORT:{
case State::TELEPORT:{
teleportAnimationTimer=std::max(0.f,teleportAnimationTimer-fElapsedTime);
if(teleportAnimationTimer<=0){
SetPos(teleportTarget);
SetState(NORMAL);
SetState(State::NORMAL);
}
animation.UpdateState(internal_animState,fElapsedTime);
}break;
@ -304,13 +304,13 @@ void Player::Update(float fElapsedTime){
ability4.cooldown=0;
}
for(Monster&m:MONSTER_LIST){
if(!HasIframes()&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){
if(!HasIframes()&&abs(m.GetZ()-GetZ())<=1&&OnUpperLevel()==m.OnUpperLevel()&&geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){
if(m.IsAlive()){
m.Collision(this);
}
geom2d::line line(pos,m.GetPos());
float dist = line.length();
m.SetPosition(line.rpoint(dist*1.1));
m.SetPos(line.rpoint(dist*1.1));
if(m.IsAlive()){
vel=line.vector().norm()*-128;
}
@ -382,7 +382,7 @@ void Player::Update(float fElapsedTime){
#pragma region Warrior
switch(GetState()){
case SWING_SWORD:{
case State::SWING_SWORD:{
switch(GetFacingDirection()){
case UP:{
UpdateAnimation("WARRIOR_SWINGSWORD_N");
@ -407,9 +407,9 @@ void Player::Update(float fElapsedTime){
#pragma endregion
#pragma region Ranger
if(GetState()==SHOOT_ARROW){
if(GetState()==State::SHOOT_ARROW){
if(attack_cooldown_timer<=ARROW_ATTACK_COOLDOWN-0.3){
SetState(NORMAL);
SetState(State::NORMAL);
}
}
if(retreatTimer>0){
@ -467,7 +467,7 @@ void Player::SetSwordSwingTimer(float val){
swordSwingTimer=val;
}
void Player::SetState(State newState){
void Player::SetState(State::State newState){
if(GetState()==State::BLOCK){
RemoveAllBuffs(BuffType::BLOCK_SLOWDOWN);
}

@ -41,7 +41,7 @@ private:
float manaTickTimer=0;
std::pair<std::string,float> notEnoughManaDisplay={"",0};
float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive.
State state=State::NORMAL;
State::State state=State::NORMAL;
Animate2D::Animation<std::string>animation;
Animate2D::AnimationState internal_animState;
Key lastReleasedMovementKey;
@ -58,7 +58,7 @@ protected:
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
float ARROW_ATTACK_COOLDOWN="Ranger.Auto Attack.Cooldown"_F;
void SetSwordSwingTimer(float val);
void SetState(State newState);
void SetState(State::State newState);
void SetFacingDirection(Key direction);
void SetLastReleasedMovementKey(Key k);
void Spin(float duration,float spinSpd);
@ -120,7 +120,7 @@ public:
float GetSizeMult();
float GetAttackRangeMult();
float GetSpinAngle();
State GetState();
State::State GetState();
Key GetFacingDirection();
vf2d GetVelocity();
bool HasIframes();

@ -18,11 +18,11 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,int strategyNum
} else {
m.target=desiredTargetLine.upoint(1.2);
}
m.SetState(MOVE_TOWARDS);
m.SetState(State::MOVE_TOWARDS);
m.hasHitPlayer=false;
}
switch(m.state){
case MOVE_TOWARDS:{
case State::MOVE_TOWARDS:{
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
vf2d newPos=m.pos+geom2d::line(m.pos,m.target).vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
if(!m.SetX(newPos.x)||!m.SetY(newPos.y)){
@ -30,11 +30,11 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,int strategyNum
}
m.PerformJumpAnimation();
} else {
m.SetState(NORMAL);//Revert state once we've finished moving towards target.
m.SetState(State::NORMAL);//Revert state once we've finished moving towards target.
m.UpdateAnimation(MONSTER_DATA[m.id].GetIdleAnimation());
}
}break;
case PATH_AROUND:{
case State::PATH_AROUND:{
m.PathAroundBehavior(fElapsedTime);
}break;
default:{

@ -24,23 +24,23 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb
if(line.length()<24.f*ConfigInt("Range")/100.f){
m.target=line.upoint(-1.2);
if(m.canMove){
m.SetState(MOVE_AWAY);
m.SetState(State::MOVE_AWAY);
} else {
m.SetState(NORMAL);
m.SetState(State::NORMAL);
}
} else
if(line.length()>24.f*ConfigInt("CloseInRange")/100.0f){
m.target=line.upoint(1.2);
m.SetState(MOVE_TOWARDS);
m.SetState(State::MOVE_TOWARDS);
} else {
m.SetState(NORMAL);
m.SetState(State::NORMAL);
}
}
m.canMove=true;
geom2d::line moveTowardsLine=geom2d::line(m.pos,m.target);
bool pathfindingDecision=false;
switch(m.state){
case MOVE_TOWARDS:{
case State::MOVE_TOWARDS:{
if(moveTowardsLine.length()>1){
vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
bool movedX=m.SetX(newPos.x);
@ -52,7 +52,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb
m.StartPathfinding(2.5);
}else
if(line.length()<=24.f*ConfigInt("CloseInRange")/100.0f){
m.SetState(NORMAL);
m.SetState(State::NORMAL);
}
if(moveTowardsLine.vector().x>0){
m.facingDirection=RIGHT;
@ -61,7 +61,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb
}
m.PerformJumpAnimation();
}break;
case MOVE_AWAY:{
case State::MOVE_AWAY:{
if(moveTowardsLine.length()>1){
vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
bool movedX=m.SetX(newPos.x);
@ -73,7 +73,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb
m.StartPathfinding(2.5);
}else
if(line.length()>=24.f*ConfigInt("Range")/100.f){
m.SetState(NORMAL);
m.SetState(State::NORMAL);
}
if(moveTowardsLine.vector().x>0){
m.facingDirection=RIGHT;
@ -82,7 +82,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumb
}
m.PerformJumpAnimation();
}break;
case PATH_AROUND:{
case State::PATH_AROUND:{
m.PathAroundBehavior(fElapsedTime);
}break;
default:{

@ -3,9 +3,11 @@
#include "DEFINES.h"
#include "Crawler.h"
#include "utils.h"
#include "safemap.h"
INCLUDE_game
INCLUDE_BULLET_LIST
INCLUDE_ANIMATION_DATA
typedef Attribute A;
@ -15,6 +17,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
m.F(A::SHOOT_RING_TIMER)=std::max(0.f,m.F(A::SHOOT_RING_TIMER)-fElapsedTime);
m.F(A::SHOOT_RING_DELAY)=std::max(0.f,m.F(A::SHOOT_RING_DELAY)-fElapsedTime);
m.F(A::JUMP_LANDING_TIMER)=std::max(0.f,m.F(A::JUMP_LANDING_TIMER)-fElapsedTime);
auto ShootBulletRing=[&](float angleOffset){
int bulletCount=ConfigInt("Phase1.RingBulletCount");
@ -23,6 +26,42 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
}
};
auto StartJump=[&](float jumpDuration,vf2d targetPos,float recoveryTime){
m.V(A::JUMP_ORIGINAL_POS)=m.GetPos();
m.F(A::JUMP_ORIGINAL_LANDING_TIMER)=m.F(A::JUMP_LANDING_TIMER)=jumpDuration;
m.V(A::JUMP_TARGET_POS)=targetPos;
m.F(A::RECOVERY_TIME)=recoveryTime;
m.state=State::JUMP;
};
if(m.state==State::RECOVERY){
m.F(A::RECOVERY_TIME)=std::max(0.f,m.F(A::RECOVERY_TIME)-fElapsedTime);
if(m.F(A::RECOVERY_TIME)==0){
m.state=State::NORMAL;
}
return;
}
if(m.state==State::JUMP){
float jumpLandingTimerRatio=m.F(A::JUMP_LANDING_TIMER)/m.F(A::JUMP_ORIGINAL_LANDING_TIMER);
m.SetPos(m.V(A::JUMP_ORIGINAL_POS).lerp(m.V(A::JUMP_TARGET_POS),1-jumpLandingTimerRatio));
if(m.F(A::JUMP_LANDING_TIMER)>=m.F(A::JUMP_ORIGINAL_LANDING_TIMER)/2){
m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),1-jumpLandingTimerRatio*2));
}else{
m.SetZ(util::lerp(0,ConfigInt("JumpHeight"),jumpLandingTimerRatio*2));
}
if(m.F(A::JUMP_LANDING_TIMER)==0){
m.state=State::RECOVERY;
m.SetStrategyDrawFunction([](Crawler*game){});
} else
if(m.F(A::JUMP_LANDING_TIMER)<=ConfigFloat("JumpWarningIndicatorTime")){
m.SetStrategyDrawFunction([&](Crawler*game){
Decal*dec=ANIMATION_DATA["RANGE_INDICATOR"].GetFrame(game->GetElapsedTime()).GetSourceImage()->Decal();
game->view.DrawRotatedDecal(m.GetPos(),dec,0,dec->sprite->Size()/2,vf2d{m.GetSizeMult(),m.GetSizeMult()}/2,RED);
});
}
return;
}
switch(m.phase){
case 0:{
@ -38,11 +77,17 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
m.SetSize(ConfigFloat("Phase2.Size")/100,false);
}
if(m.F(A::SHOOT_RING_TIMER)==0){
if(m.I(A::PATTERN_REPEAT_COUNT)>=ConfigInt("Phase1.JumpAfter")){
StartJump(ConfigFloat("Phase1.AirborneTime"),game->GetPlayer()->GetPos(),ConfigFloat("Phase1.LandingRecoveryTime"));
m.I(A::PATTERN_REPEAT_COUNT)=0;
return;
}
m.I(A::SHOOT_RING_COUNTER)=ConfigInt("Phase1.ShootRingCount")-1;
m.F(A::SHOOT_RING_DELAY)=ConfigFloat("Phase1.ShootRingDelay");
ShootBulletRing(m.F(A::SHOOT_RING_OFFSET));
m.F(A::SHOOT_RING_TIMER)=ConfigFloat("Phase1.ShootRepeatTime");
m.B(A::SHOOT_RING_RIGHT)=bool(rand()%2);
m.I(A::PATTERN_REPEAT_COUNT)++;
}
if(m.I(A::SHOOT_RING_COUNTER)>0){
if(m.F(A::SHOOT_RING_DELAY)==0){

@ -1,18 +1,22 @@
#pragma once
enum State{
NORMAL,
SWING_SWORD,
SWING_SONIC_SWORD,
SPIN,
MOVE_TOWARDS,
MOVE_AWAY,
BLOCK,
TELEPORT,
PATH_AROUND,
CASTING,
PREP_CAST,
SHOOT_ARROW,
RETREAT,
ANIMATION_LOCK,
};
namespace State{
enum State{
NORMAL,
SWING_SWORD,
SWING_SONIC_SWORD,
SPIN,
MOVE_TOWARDS,
MOVE_AWAY,
BLOCK,
TELEPORT,
PATH_AROUND,
CASTING,
PREP_CAST,
SHOOT_ARROW,
RETREAT,
ANIMATION_LOCK,
JUMP,
RECOVERY,
};
}

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 0
#define VERSION_BUILD 1119
#define VERSION_BUILD 1138
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -75,7 +75,7 @@ MonsterStrategy
# How much time a jump will be pre-telegraphed.
JumpWarningIndicatorTime = 1.0
# Distance to jump up into the sky. A higher value causes it to launch up and down seemingly faster.
JumpHeight = 1500
JumpHeight = 300
ProjectileDamage = 10
JumpAttackDamage = 20
@ -93,7 +93,6 @@ MonsterStrategy
RingOffset = 10.0
JumpAfter = 4 shots
AirborneTime = 3.0
LandingRingCount = 1
LandingRecoveryTime = 2.0
}
Phase2

@ -29,4 +29,5 @@ Images
GFX_Arrow = arrow.png
GFX_Laser = laser.png
GFX_ChargedArrow = charged_shot_arrow.png
GFX_RangeIndicator = range_indicator.png
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

@ -14,4 +14,8 @@ float util::degToRad(float deg){
float util::radToDeg(float rad){
return rad*57.2957795130823208767;
}
float util::lerp(float n1,float n2,double t){
return n1*(1-t)+n2*t;
}

@ -8,4 +8,5 @@ namespace util{
vf2d pointTo(vf2d posFrom,vf2d posTo);
float degToRad(float deg);
float radToDeg(float rad);
float lerp(float n1,float n2,double t);
}
Loading…
Cancel
Save