Skip to content

Instantly share code, notes, and snippets.

@CedricGuillemet
Created November 28, 2017 05:50
Show Gist options
  • Save CedricGuillemet/8037096cb34479b60c6f00c17d6207a3 to your computer and use it in GitHub Desktop.
Save CedricGuillemet/8037096cb34479b60c6f00c17d6207a3 to your computer and use it in GitHub Desktop.
#include "ImApp.h"
inline void SpawnDust(EntityManager& manager, Entity& entity)
{
if (/*!entity.mStunned &&*/ entity.mCatchedBy != -1)
return;
float vel = zmax(entity.mVel, entity.mGroupForce.length());
if (vel < FLT_EPSILON)
return;
static int loc = 0;
loc++;
if ((loc % 10) == 0)
{
float ng = r01() * ZPI * 2.f;
float side = ((loc / 10) & 1) ? -1.f : 1.f;
if (entity.mBloodStain >= 5)
{
mSprites.PushEndScaleAlpha(1.5, 0.f);
mSprites.AddSprite("soulSplat.png", entity.mPos + entity.GetRight() * side * 0.2f , 300, 1, entity.mDir * 0.2f);
ImApp::ImApp::Instance()->PlayEvent("event:/Physic/Footsteps/Granson/Footsteps_wet");
}
else if (entity.mSlime > 0)
{
mSprites.PushEndScaleAlpha(1.5, 0.f);
mSprites.AddSprite("slime.png", entity.mPos + entity.GetRight() * side * 0.2f, 300, 1, entity.mDir * 0.2f);
ImApp::ImApp::Instance()->PlayEvent("event:/Physic/Footsteps/Granson/Footsteps_wet");
}
else
{
// classic footstep
const Sequence *response = sequences.GetByName("FootStep_00");
if (response)
manager.PlaySequence(entity, NULL, response, entity.mDir);
}
}
}
inline void PlayerBehavior(EntityManager& manager, Entity& entity, float dt)
{
ImGuiIO& io = ImGui::GetIO();
static const vec_t dirs[] = { vec_t(-1.f, 0.f) , vec_t(0.f, -1.f) , vec_t(1.f, 0.f) , vec_t(0.f, 1.f) };
bool moving = false;
vec_t desiredDir = vec_t(0.f, 0.f);
for (int i = 0; i < 4; i++)
{
if (io.KeysDown[0x25 + i])
{
desiredDir += dirs[i];
moving = true;
}
}
entity.mDesiredDir = desiredDir;
// catching must be prior to throwing test and action set otherwise, the catchable entity keeps being catched
if (entity.mCatching == -1 && !entity.mCurrentAction)
{
int catchable = manager.FindCatchable(&entity);
if (catchable != -1)
{
manager.mEntities[catchable].mCatchedBy = &entity - manager.mEntities.data();
entity.mCatching = catchable;
}
}
entity.mThrowDir = entity.mDir;
const Entity *throwTarget = manager.FindBestTarget(entity);
if (throwTarget)
entity.mThrowDir = (entity.mPos - throwTarget->mPos).normalize();
static bool kd = false;
static bool kdd = false;
entity.mInput.Reset();
if (io.KeysDown[0x41] && !kd)
{
entity.mInput.mSequence = true;
if (entity.mCatching != -1)
{
Entity& catchedEntity = manager.mEntities[entity.mCatching];
if (!throwTarget)
entity.mThrowDir = (entity.mPos - catchedEntity.mPos).normalize();
entity.SetAction("Player_Throw");
}
else
{
int abilityIndex = experience.OverAbilityCanAcquire(entity.mPos);
if (abilityIndex != -1)
{
const Ability& ability = experience.mAbilities[abilityIndex];
entity.mExperiencePoint -= ability.mCost;
entity.mAbilities.push_back(ability.mName);
entity.SetAction("Player_SpendSoul");
}
else
{
//entity.SetAction("Player_05_02");// "Player_04_02");// "Player_03_01");
entity.SetAction("Player_03_01");
}
}
kd = true;
}
if (io.KeysDown[0x5a] && !kdd && entity.mCatching == -1)
{
entity.SetAction("Player_Dash_01");
kdd = true;
}
if (!io.KeysDown[0x41])
kd = false;
if (!io.KeysDown[0x5a])
kdd = false;
if (!entity.mCurrentAction)
{
if (desiredDir.length() > 0.f)
{
entity.mDir = desiredDir;
entity.mDir.normalize();
}
}
float accel = .3f;
float deccel = .6f;
if (moving)
{
entity.mVel += accel;
}
else
{
entity.mVel -= deccel;
}
entity.mVel = zmin(entity.mVel, 4.f);
entity.mVel = zmax(entity.mVel, 0.f);
if (throwTarget && entity.mCatching != -1)
{
static float anim = 0;
anim += 0.1f;
mSprites.AddSprite("aimArrow.png", throwTarget->mPos + entity.mThrowDir * (1.f + cosf(anim) *0.1f), 2, 140, entity.mThrowDir);
}
entity.mExcite = zmax(entity.mExcite - 1, 0);
SpawnDust(manager, entity);
}
inline void WarriorBehavior(EntityManager& manager, Entity& entity, float dt)
{
Entity*player = manager.GetPlayer();
if (!player)
return;
if (entity.mStunned > 0)
return;
if (entity.mCatchedBy != -1)
return;
if (entity.IsDashing())
return;
vec_t posPlayer = player->mPos;
vec_t vect2Player = (posPlayer - entity.mPos);
vec_t vect2PlayerNotNormalized = vect2Player;
entity.mDir = vect2Player.normalize();
if (entity.mStun > 80 && !entity.mStunned)
{
entity.SetAction("ActionWarriorGotStunned", true);
}
if (entity.mSequenceToken >= 0)
{
entity.mExcite++;
if (entity.mDir.dot(player->mDir) >= 0.f)
entity.mExcite += 2;
}
if (entity.mExcite >= 500 && entity.mSequenceToken == manager.mSequenceToken && vect2Player.length() < 5.f)
{
for (auto& nentity : manager.mEntities)
{
nentity.mExcite = fastrand() % 100;
}
entity.SetAction("Warrior_01_02");
manager.mSequenceToken++;
}
if (!entity.mStunned && vect2PlayerNotNormalized.length() < 1.5f)
{
entity.SetAction("Warrior_StandBack");
}
if (entity.mLocalTime == 0)
{
if (fastrand() % 6 == 0)
{
float ng = r01() * ZPI * 2.f;
entity.mReplaceForce = vec_t(cosf(ng), sinf(ng));
}
else
{
entity.mReplaceForce = vec_t(0.f, 0.f);
}
entity.mLocalTime = (fastrand() % 60);
}
if (entity.mStunned)
entity.mReplaceForce = vec_t(0.f, 0.f);
SpawnDust(manager, entity);
}
inline void SoulBehavior(EntityManager& manager, Entity& entity, float dt)
{
Entity*player = manager.GetPlayer();
const vec_t& dest = (player && !experience.mInsideAbilityMap) ? player->mPos : vec_t(0.f, 0.f);
vec_t right(-entity.mDir.y, entity.mDir.x);
vec_t dif = dest - entity.mPos;
entity.mDir = Rotate2D(entity.mDir, SignOf(right.dot(dif)) * 0.4f * LERP(0.f, 1.f, zmin(entity.mLife, 1.f)));
entity.SetAction("Soul");
if (experience.mInsideAbilityMap && dif.length() < 0.8f)
{
const Sequence *response = sequences.GetByName("Soul_Used");
if (response)
manager.PlaySequence(entity, NULL, response, entity.mDir);
}
}
inline void BossMichelBehavior(EntityManager& manager, Entity& entity, float dt)
{
static const vec_t pts[4] = { vec_t(-7.f, -4.f), vec_t(7.f, -4.f), vec_t(7.f, 4.f), vec_t(-7.f, 4.f) };
static const vec_t dirs[] = { vec_t(1.f, 1.f), vec_t(-1.f, 1.f), vec_t(-1.f, -1.f), vec_t(1.f, -1.f) };
static int random = 0;
Entity*player = manager.GetPlayer();
if (!entity.mCurrentAction)
{
vec_t distToTarget = pts[random] - entity.mPos;
vec_t moveDir = normalized(distToTarget);
entity.mDir = moveDir;
entity.mVel = 4.0f;
if (player)
{
HitBox hitbox(&entity, entity.mPos, entity.mDir * 4.f, 2.0, 0, true);
if (hitbox.Contains(player->mPos))
{
entity.mDir = normalized(player->mPos - entity.mPos);
entity.SetAction("MichelDash", true);
}
}
if (distToTarget.length() < 0.1f)
{
entity.mDir = normalized(dirs[random]);
entity.SetAction("MichelBeam", true);
random = fastrand() % sizeof(pts) / sizeof(vec_t);
}
}
else if (entity.mExcite)
{
entity.mCurrentAction = NULL;
}
}
inline void SoulSphereBehavior(EntityManager& manager, Entity& entity, float dt)
{
const Arena &ar = manager.mArena;
vec_t normal;
bool bounce = false;
if (entity.mPos.x >= ar.mMax.x * 0.9f)
{
entity.mPos.x = ar.mMax.x * 0.9f;
bounce = true;
normal = vec_t(-1.f, 0.f);
}
if (entity.mPos.x <= ar.mMin.x * 0.9f)
{
entity.mPos.x = ar.mMin.x * 0.9f;
bounce = true;
normal = vec_t(1.f, 0.f);
}
if (entity.mPos.y >= ar.mMax.y * 0.9f)
{
entity.mPos.y = ar.mMax.y * 0.9f;
bounce = true;
normal = vec_t(0.f, -1.f);
}
if (entity.mPos.y <= ar.mMin.y * 0.9f)
{
entity.mPos.y = ar.mMin.y * 0.9f;
bounce = true;
normal = vec_t(0.f, 1.f);
}
if (bounce)
{
entity.mForce = Reflect(normalized(entity.mForce), normal) * entity.mForce.length();
const Sequence *response = sequences.GetByName("SoulSphereHitWall");
if (response)
manager.PlaySequence(entity, NULL, response, entity.mDir);
}
}
inline void SoccerBehavior(EntityManager& manager, Entity& entity, float dt)
{
const Entity *ball = manager.GetEntityByType("SoulBall");
if (!ball)
return;
if (Distance(ball->mPos, entity.mPos) < 2.0f)
{
entity.SetAction("ActionWarriorAttack");
}
else if (ball->mPos.x > 0.f)
{
vec_t distToTarget = ball->mPos - entity.mPos;
vec_t moveDir = normalized(distToTarget);
entity.mDir = moveDir;
entity.mVel = 5.f;
}
else
{
entity.mVel = 0.f;
}
}
inline void TickBehaviorBehavior(int behaviorIndex, EntityManager& manager, Entity& entity, float dt)
{
switch (behaviorIndex)
{
case 0:
PlayerBehavior(manager, entity, dt);
break;
case 1:
WarriorBehavior(manager, entity, dt);
break;
case 2:
SoulBehavior(manager, entity, dt);
break;
case 3:
BossMichelBehavior(manager, entity, dt);
break;
case 4:
SoulSphereBehavior(manager, entity, dt);
break;
case 5:
SoccerBehavior(manager, entity, dt);
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment