139 lines
4.2 KiB
C
139 lines
4.2 KiB
C
#include "Enemy.h"
|
|
#include "Layers.h"
|
|
#include "debug.h"
|
|
#include "game_world.h"
|
|
#include "physics.h"
|
|
#include "physics_world.h"
|
|
#include "sprite.h"
|
|
|
|
START_REFLECT(Enemy)
|
|
REFLECT_TYPECLASS(Enemy, Transformable)
|
|
REFLECT_TYPECLASS(Enemy, Drop)
|
|
REFLECT_TYPECLASS(Enemy, PhysicsEntity)
|
|
REFLECT_TYPECLASS(Enemy, BehaviourEntity)
|
|
REFLECT_TYPECLASS(Enemy, Damagable)
|
|
END_REFLECT(Enemy)
|
|
|
|
impl_Transformable_for(Enemy,
|
|
EnemyGetTransform
|
|
)
|
|
|
|
impl_Drop_for(Enemy,
|
|
EnemyDestroy
|
|
)
|
|
|
|
impl_BehaviourEntity_for(Enemy,
|
|
EnemyStart,
|
|
EnemyUpdate,
|
|
EnemyDraw,
|
|
EnemyGetDepth
|
|
)
|
|
|
|
impl_PhysicsEntity_for(Enemy,
|
|
EnemyGetRigidBody,
|
|
EnemyOnCollision,
|
|
EnemyOnOverlap
|
|
)
|
|
|
|
impl_Damagable_for(Enemy,
|
|
EnemyDamage
|
|
)
|
|
|
|
Enemy* MakeEnemy() {
|
|
Enemy* self = malloc(sizeof(Enemy));
|
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate Enemy");
|
|
*self = (Enemy){
|
|
.transform = IdentityTransform,
|
|
.behaviour = NULL,
|
|
.rigidbody = NULL,
|
|
.collider = NULL,
|
|
.hitbox = NULL,
|
|
.sprite = sprite_new_empty(),
|
|
.facing = 1,
|
|
.stun_time = 0.f,
|
|
.idleAnim = NULL,
|
|
.walkAnim = NULL,
|
|
.hurtAnim = NULL,
|
|
.currentAnimation = NULL,
|
|
.health = 15,
|
|
};
|
|
|
|
self->rigidbody = rigidbody_make(Enemy_as_PhysicsEntity(self));
|
|
self->collider = collider_new(Enemy_as_PhysicsEntity(self), shape_new_square(MakeVector(0.2f, 0.05f)), 0,
|
|
PHYSICS_LAYER_DEFAULT, PHYSICS_LAYER_DEFAULT);
|
|
self->collider = collider_new(Enemy_as_PhysicsEntity(self), shape_new((Vector[]){
|
|
MakeVector(-0.2f, -0.95f),
|
|
MakeVector( 0.2f, -0.95f),
|
|
MakeVector( 0.2f, 0.0f),
|
|
MakeVector(-0.2f, 0.0f),
|
|
}, 4), 1, PHYSICS_LAYER_COMBAT, 0x0);
|
|
PhysicsEntity pe = Enemy_as_PhysicsEntity(self);
|
|
LOG_INFO("enemy instantiated mirroring as: %s", pe.mirror->get_typestring(pe.data));
|
|
|
|
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
|
|
|
self->idleAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
|
|
self->walkAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
|
|
self->hurtAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Hurt.png", IVectorFrom(512)), 5.f, LoopMode_Stop);
|
|
|
|
return self;
|
|
}
|
|
|
|
Enemy* SpawnEnemy(Vector location, const State* entryState) {
|
|
Enemy* self = MakeEnemy();
|
|
self->behaviour = state_machine_init(self, entryState);
|
|
rigidbody_get_transform(self->rigidbody)->position = location;
|
|
game_world_add_entity(Enemy_as_BehaviourEntity(self));
|
|
physics_world_add_entity(Enemy_as_PhysicsEntity(self));
|
|
return self;
|
|
}
|
|
|
|
void EnemyStart(Enemy* self) {}
|
|
|
|
void EnemyUpdate(Enemy* self, float deltaTime) {
|
|
state_machine_update(self->behaviour, deltaTime);
|
|
if(self->stun_time > 0.0f)
|
|
self->stun_time -= deltaTime;
|
|
}
|
|
|
|
void EnemyDraw(Enemy* self) {
|
|
sprite_flip_horizontal(self->sprite, self->facing == -1);
|
|
animation_sprite_draw(self->currentAnimation, &self->transform);
|
|
}
|
|
|
|
void EnemyDestroy(Enemy* self) {
|
|
state_machine_destroy(self->behaviour);
|
|
collider_destroy(self->collider);
|
|
rigidbody_destroy(self->rigidbody);
|
|
sprite_destroy(self->sprite);
|
|
|
|
physics_world_remove_entity(Enemy_as_PhysicsEntity(self));
|
|
free(self);
|
|
}
|
|
|
|
void EnemyOnCollision(Enemy* self, Collision collision) {}
|
|
void EnemyOnOverlap(Enemy* self, Collider* other) {}
|
|
|
|
Transform* EnemyGetTransform(Enemy* self) {
|
|
return &self->transform;
|
|
}
|
|
|
|
RigidBody* EnemyGetRigidBody(Enemy* self) {
|
|
return self->rigidbody;
|
|
}
|
|
|
|
int EnemyDamage(Enemy* self, DamageEventData* data) {
|
|
self->health -= data->damageAmount;
|
|
LOG_INFO("Damage received");
|
|
if(self->health <= 0) {
|
|
game_world_destroy_entity(Enemy_as_BehaviourEntity(self));
|
|
return 1;
|
|
} else {
|
|
self->stun_time = data->stun;
|
|
float direction = ((data->origin.x - self->transform.position.x) > 0) * 2 - 1;
|
|
self->facing = direction;
|
|
rigidbody_get_transform(self->rigidbody)->position = vaddf(self->transform.position, MakeVector(-direction * data->knockback, 0));
|
|
return 0;
|
|
}
|
|
}
|