[RELEASE] u22-v03
This version is submitted to U22 breau.
This commit is contained in:
16
core/loentity/CMakeLists.txt
Normal file
16
core/loentity/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
add_library(loentity
|
||||
bullet.c
|
||||
character.c
|
||||
entity.c
|
||||
store.c
|
||||
)
|
||||
target_link_libraries(loentity
|
||||
msgpackc
|
||||
|
||||
coly2d
|
||||
container
|
||||
math
|
||||
memory
|
||||
|
||||
locommon
|
||||
)
|
43
core/loentity/bullet.c
Normal file
43
core/loentity/bullet.c
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "./bullet.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/coly2d/shape.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
bool loentity_bullet_affect(
|
||||
loentity_bullet_t* bullet, loentity_character_t* chara) {
|
||||
assert(bullet != NULL);
|
||||
assert(chara != NULL);
|
||||
|
||||
assert(bullet->vtable.affect != NULL);
|
||||
return bullet->vtable.affect(bullet, chara);
|
||||
}
|
||||
|
||||
bool loentity_bullet_hittest(
|
||||
const loentity_bullet_t* bullet,
|
||||
const locommon_position_t* point,
|
||||
const vec2_t* velocity,
|
||||
float dt) {
|
||||
assert(bullet != NULL);
|
||||
assert(locommon_position_valid(point));
|
||||
assert(vec2_valid(velocity));
|
||||
assert(MATH_FLOAT_VALID(dt));
|
||||
|
||||
vec2_t st;
|
||||
locommon_position_sub(&st, point, &bullet->super.pos);
|
||||
|
||||
vec2_t ed;
|
||||
vec2_sub(&ed, velocity, &bullet->velocity);
|
||||
vec2_muleq(&ed, dt);
|
||||
vec2_addeq(&ed, &st);
|
||||
|
||||
return coly2d_shape_hittest_lineseg(&bullet->shape, &st, &ed);
|
||||
}
|
45
core/loentity/bullet.h
Normal file
45
core/loentity/bullet.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "util/coly2d/shape.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./entity.h"
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
typedef struct {
|
||||
bool
|
||||
(*affect)(
|
||||
loentity_bullet_t* bullet,
|
||||
loentity_character_t* chara
|
||||
);
|
||||
} loentity_bullet_vtable_t;
|
||||
|
||||
struct loentity_bullet_t {
|
||||
loentity_t super;
|
||||
|
||||
loentity_bullet_vtable_t vtable;
|
||||
|
||||
loentity_id_t owner;
|
||||
vec2_t velocity;
|
||||
|
||||
coly2d_shape_t shape;
|
||||
};
|
||||
|
||||
bool
|
||||
loentity_bullet_affect(
|
||||
loentity_bullet_t* bullet,
|
||||
loentity_character_t* chara
|
||||
);
|
||||
|
||||
bool
|
||||
loentity_bullet_hittest(
|
||||
const loentity_bullet_t* bullet,
|
||||
const locommon_position_t* point,
|
||||
const vec2_t* velocity,
|
||||
float dt
|
||||
);
|
28
core/loentity/character.c
Normal file
28
core/loentity/character.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "./character.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "core/loeffect/effect.h"
|
||||
|
||||
#include "./entity.h"
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
void loentity_character_apply_effect(
|
||||
loentity_character_t* chara, const loeffect_t* effect) {
|
||||
assert(chara != NULL);
|
||||
assert(effect != NULL);
|
||||
|
||||
assert(chara->vtable.apply_effect != NULL);
|
||||
chara->vtable.apply_effect(chara, effect);
|
||||
}
|
||||
|
||||
void loentity_character_knockback(
|
||||
loentity_character_t* chara, const vec2_t* v) {
|
||||
assert(chara != NULL);
|
||||
assert(v != NULL);
|
||||
|
||||
assert(chara->vtable.knockback != NULL);
|
||||
chara->vtable.knockback(chara, v);
|
||||
}
|
40
core/loentity/character.h
Normal file
40
core/loentity/character.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/loeffect/effect.h"
|
||||
|
||||
#include "./entity.h"
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
typedef struct {
|
||||
void
|
||||
(*apply_effect)(
|
||||
loentity_character_t* chara,
|
||||
const loeffect_t* effect
|
||||
);
|
||||
void
|
||||
(*knockback)(
|
||||
loentity_character_t* chara,
|
||||
const vec2_t* v
|
||||
);
|
||||
} loentity_character_vtable_t;
|
||||
|
||||
struct loentity_character_t {
|
||||
loentity_t super;
|
||||
|
||||
loentity_character_vtable_t vtable;
|
||||
};
|
||||
|
||||
void
|
||||
loentity_character_apply_effect(
|
||||
loentity_character_t* chara,
|
||||
const loeffect_t* effect
|
||||
);
|
||||
|
||||
void
|
||||
loentity_character_knockback(
|
||||
loentity_character_t* chara,
|
||||
const vec2_t* v
|
||||
);
|
13
core/loentity/decl.private.h
Normal file
13
core/loentity/decl.private.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
struct loentity_t;
|
||||
typedef struct loentity_t loentity_t;
|
||||
|
||||
struct loentity_ground_t;
|
||||
typedef struct loentity_ground_t loentity_ground_t;
|
||||
|
||||
struct loentity_bullet_t;
|
||||
typedef struct loentity_bullet_t loentity_bullet_t;
|
||||
|
||||
struct loentity_character_t;
|
||||
typedef struct loentity_character_t loentity_character_t;
|
44
core/loentity/entity.c
Normal file
44
core/loentity/entity.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "./entity.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
void loentity_delete(loentity_t* entity) {
|
||||
assert(entity != NULL);
|
||||
|
||||
assert(entity->vtable.delete != NULL);
|
||||
entity->vtable.delete(entity);
|
||||
}
|
||||
|
||||
void loentity_die(loentity_t* entity) {
|
||||
assert(entity != NULL);
|
||||
|
||||
assert(entity->vtable.die != NULL);
|
||||
entity->vtable.die(entity);
|
||||
}
|
||||
|
||||
bool loentity_update(loentity_t* entity) {
|
||||
assert(entity != NULL);
|
||||
|
||||
assert(entity->vtable.update != NULL);
|
||||
return entity->vtable.update(entity);
|
||||
}
|
||||
|
||||
void loentity_draw(loentity_t* entity, const locommon_position_t* basepos) {
|
||||
assert(entity != NULL);
|
||||
assert(locommon_position_valid(basepos));
|
||||
|
||||
assert(entity->vtable.draw != NULL);
|
||||
entity->vtable.draw(entity, basepos);
|
||||
}
|
||||
|
||||
void loentity_pack(const loentity_t* entity, msgpack_packer* packer) {
|
||||
assert(entity != NULL);
|
||||
assert(packer != NULL);
|
||||
|
||||
assert(entity->vtable.pack != NULL);
|
||||
entity->vtable.pack(entity, packer);
|
||||
}
|
88
core/loentity/entity.h
Normal file
88
core/loentity/entity.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
typedef struct {
|
||||
void
|
||||
(*delete)(
|
||||
loentity_t* entity
|
||||
);
|
||||
|
||||
void
|
||||
(*die)(
|
||||
loentity_t* entity
|
||||
);
|
||||
|
||||
bool
|
||||
(*update)(
|
||||
loentity_t* entity
|
||||
);
|
||||
void
|
||||
(*draw)(
|
||||
loentity_t* entity,
|
||||
const locommon_position_t* basepos
|
||||
);
|
||||
|
||||
void
|
||||
(*pack)(
|
||||
const loentity_t* entity,
|
||||
msgpack_packer* packer
|
||||
);
|
||||
} loentity_vtable_t;
|
||||
|
||||
typedef enum {
|
||||
LOENTITY_SUBCLASS_NONE,
|
||||
LOENTITY_SUBCLASS_GROUND,
|
||||
LOENTITY_SUBCLASS_BULLET,
|
||||
LOENTITY_SUBCLASS_CHARACTER,
|
||||
} loentity_subclass_t;
|
||||
|
||||
typedef uint64_t loentity_id_t;
|
||||
|
||||
struct loentity_t {
|
||||
loentity_vtable_t vtable;
|
||||
loentity_subclass_t subclass;
|
||||
|
||||
loentity_id_t id;
|
||||
|
||||
locommon_position_t pos;
|
||||
|
||||
bool dont_save;
|
||||
};
|
||||
|
||||
void
|
||||
loentity_delete(
|
||||
loentity_t* entity /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loentity_die(
|
||||
loentity_t* entity
|
||||
);
|
||||
|
||||
bool
|
||||
loentity_update(
|
||||
loentity_t* entity
|
||||
);
|
||||
|
||||
void
|
||||
loentity_draw(
|
||||
loentity_t* entity,
|
||||
const locommon_position_t* basepos
|
||||
);
|
||||
|
||||
void
|
||||
loentity_pack(
|
||||
const loentity_t* entity,
|
||||
msgpack_packer* packer
|
||||
);
|
18
core/loentity/ground.h
Normal file
18
core/loentity/ground.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./entity.h"
|
||||
|
||||
#include "./decl.private.h"
|
||||
|
||||
typedef struct {
|
||||
} loentity_ground_vtable_t;
|
||||
|
||||
struct loentity_ground_t {
|
||||
loentity_t super;
|
||||
|
||||
loentity_ground_vtable_t vtable;
|
||||
|
||||
vec2_t size;
|
||||
};
|
211
core/loentity/store.c
Normal file
211
core/loentity/store.c
Normal file
@@ -0,0 +1,211 @@
|
||||
#include "./store.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/container/array.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "core/locommon/physics.h"
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./bullet.h"
|
||||
#include "./character.h"
|
||||
#include "./entity.h"
|
||||
#include "./ground.h"
|
||||
|
||||
struct loentity_store_t {
|
||||
CONTAINER_ARRAY loentity_t** items;
|
||||
};
|
||||
|
||||
static void loentity_store_iterator_assign_by_index_(
|
||||
loentity_store_t* store, loentity_store_iterator_t* itr) {
|
||||
assert(store != NULL);
|
||||
assert(itr != NULL);
|
||||
assert(itr->index < container_array_get_length(store->items));
|
||||
|
||||
itr->entity = NULL;
|
||||
itr->ground = NULL;
|
||||
itr->bullet = NULL;
|
||||
itr->character = NULL;
|
||||
|
||||
itr->entity = store->items[itr->index];
|
||||
switch (itr->entity->subclass) {
|
||||
case LOENTITY_SUBCLASS_GROUND:
|
||||
itr->ground = (loentity_ground_t*) itr->entity;
|
||||
break;
|
||||
case LOENTITY_SUBCLASS_BULLET:
|
||||
itr->bullet = (loentity_bullet_t*) itr->entity;
|
||||
break;
|
||||
case LOENTITY_SUBCLASS_CHARACTER:
|
||||
itr->character = (loentity_character_t*) itr->entity;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
loentity_store_t* loentity_store_new(size_t reserve) {
|
||||
loentity_store_t* store = memory_new(sizeof(*store));
|
||||
*store = (typeof(*store)) {0};
|
||||
|
||||
container_array_reserve(store->items, reserve);
|
||||
return store;
|
||||
}
|
||||
|
||||
void loentity_store_delete(loentity_store_t* store) {
|
||||
if (store == NULL) return;
|
||||
|
||||
container_array_delete(store->items);
|
||||
memory_delete(store);
|
||||
}
|
||||
|
||||
void loentity_store_add(
|
||||
loentity_store_t* store, loentity_t* entity) {
|
||||
assert(store != NULL);
|
||||
assert(entity != NULL);
|
||||
|
||||
const size_t len = container_array_get_length(store->items);
|
||||
size_t index = 0;
|
||||
for (; index < len; ++index) {
|
||||
if (store->items[index] == NULL) break;
|
||||
}
|
||||
if (index == len) container_array_insert(store->items, index);
|
||||
store->items[index] = entity;
|
||||
}
|
||||
|
||||
loentity_t* loentity_store_remove(
|
||||
loentity_store_t* store, const loentity_store_iterator_t* itr) {
|
||||
assert(store != NULL);
|
||||
assert(itr != NULL);
|
||||
|
||||
assert(itr->index < container_array_get_length(store->items));
|
||||
assert(itr->entity != NULL);
|
||||
assert(itr->entity == store->items[itr->index]);
|
||||
|
||||
store->items[itr->index] = NULL;
|
||||
return itr->entity;
|
||||
}
|
||||
|
||||
void loentity_store_clear(loentity_store_t* store) {
|
||||
assert(store != NULL);
|
||||
|
||||
const size_t len = container_array_get_length(store->items);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
loentity_t** e = &store->items[i];
|
||||
if (*e == NULL) continue;
|
||||
loentity_delete(*e);
|
||||
*e = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool loentity_store_iterate_next(
|
||||
loentity_store_t* store, loentity_store_iterator_t* itr) {
|
||||
assert(store != NULL);
|
||||
assert(itr != NULL);
|
||||
|
||||
++itr->index;
|
||||
if (itr->entity == NULL) {
|
||||
itr->index = 0;
|
||||
}
|
||||
itr->entity = NULL;
|
||||
itr->ground = NULL;
|
||||
itr->bullet = NULL;
|
||||
itr->character = NULL;
|
||||
|
||||
const size_t len = container_array_get_length(store->items);
|
||||
for (; itr->index < len; ++itr->index) {
|
||||
if (store->items[itr->index] != NULL) break;
|
||||
}
|
||||
if (itr->index >= len) return false;
|
||||
|
||||
loentity_store_iterator_assign_by_index_(store, itr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loentity_store_find_item_by_id(
|
||||
loentity_store_t* store, loentity_store_iterator_t* itr, loentity_id_t id) {
|
||||
assert(store != NULL);
|
||||
assert(itr != NULL);
|
||||
|
||||
const size_t len = container_array_get_length(store->items);
|
||||
for (itr->index = 0; itr->index < len; ++itr->index) {
|
||||
loentity_t* e = store->items[itr->index];
|
||||
if (e != NULL && e->id == id) {
|
||||
loentity_store_iterator_assign_by_index_(store, itr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool loentity_store_solve_collision_between_ground(
|
||||
loentity_store_t* store,
|
||||
locommon_physics_entity_t* e,
|
||||
float dt) {
|
||||
assert(store != NULL);
|
||||
assert(e != NULL);
|
||||
|
||||
bool solved = false;
|
||||
|
||||
loentity_store_iterator_t itr = {0};
|
||||
while (loentity_store_iterate_next(store, &itr)) {
|
||||
if (itr.ground == NULL) continue;
|
||||
|
||||
const locommon_physics_entity_t g = {
|
||||
.pos = itr.entity->pos,
|
||||
.velocity = vec2(0, 0),
|
||||
.size = itr.ground->size,
|
||||
};
|
||||
if (locommon_physics_solve_collision_with_fixed_one(e, &g, dt)) {
|
||||
solved = true;
|
||||
}
|
||||
}
|
||||
return solved;
|
||||
}
|
||||
|
||||
bool loentity_store_affect_bullets_shot_by_others(
|
||||
loentity_store_t* store,
|
||||
loentity_character_t* chara,
|
||||
const vec2_t* velocity,
|
||||
float dt) {
|
||||
assert(store != NULL);
|
||||
assert(chara != NULL);
|
||||
assert(vec2_valid(velocity));
|
||||
assert(MATH_FLOAT_VALID(dt));
|
||||
|
||||
loentity_store_iterator_t itr = {0};
|
||||
while (loentity_store_iterate_next(store, &itr)) {
|
||||
if (itr.bullet == NULL || itr.bullet->owner == chara->super.id) continue;
|
||||
|
||||
if (loentity_bullet_hittest(itr.bullet, &chara->super.pos, velocity, dt)) {
|
||||
if (loentity_bullet_affect(itr.bullet, chara)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool loentity_store_affect_bullets_shot_by_one(
|
||||
loentity_store_t* store,
|
||||
loentity_character_t* chara,
|
||||
loentity_id_t shooter,
|
||||
const vec2_t* velocity,
|
||||
float dt) {
|
||||
assert(store != NULL);
|
||||
assert(chara != NULL);
|
||||
assert(vec2_valid(velocity));
|
||||
assert(MATH_FLOAT_VALID(dt));
|
||||
|
||||
loentity_store_iterator_t itr = {0};
|
||||
while (loentity_store_iterate_next(store, &itr)) {
|
||||
if (itr.bullet == NULL || itr.bullet->owner != shooter) continue;
|
||||
|
||||
if (loentity_bullet_hittest(itr.bullet, &chara->super.pos, velocity, dt)) {
|
||||
if (loentity_bullet_affect(itr.bullet, chara)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
90
core/loentity/store.h
Normal file
90
core/loentity/store.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/locommon/physics.h"
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./bullet.h"
|
||||
#include "./character.h"
|
||||
#include "./entity.h"
|
||||
#include "./ground.h"
|
||||
|
||||
struct loentity_store_t;
|
||||
typedef struct loentity_store_t loentity_store_t;
|
||||
|
||||
typedef struct {
|
||||
loentity_t* entity;
|
||||
loentity_ground_t* ground;
|
||||
loentity_bullet_t* bullet;
|
||||
loentity_character_t* character;
|
||||
|
||||
size_t index;
|
||||
} loentity_store_iterator_t;
|
||||
|
||||
loentity_store_t* /* OWNERSHIP */
|
||||
loentity_store_new(
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loentity_store_delete(
|
||||
loentity_store_t* store /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loentity_store_add(
|
||||
loentity_store_t* store,
|
||||
loentity_t* entity /* OWNERSHIP */
|
||||
);
|
||||
|
||||
loentity_t* /* OWNERSHIP */
|
||||
loentity_store_remove(
|
||||
loentity_store_t* store,
|
||||
const loentity_store_iterator_t* itr
|
||||
);
|
||||
|
||||
void
|
||||
loentity_store_clear(
|
||||
loentity_store_t* store
|
||||
);
|
||||
|
||||
bool
|
||||
loentity_store_iterate_next(
|
||||
loentity_store_t* store,
|
||||
loentity_store_iterator_t* itr
|
||||
);
|
||||
|
||||
bool
|
||||
loentity_store_find_item_by_id(
|
||||
loentity_store_t* store,
|
||||
loentity_store_iterator_t* itr,
|
||||
loentity_id_t id
|
||||
);
|
||||
|
||||
bool /* whether the entitiy was collided */
|
||||
loentity_store_solve_collision_between_ground(
|
||||
loentity_store_t* store,
|
||||
locommon_physics_entity_t* e,
|
||||
float dt
|
||||
);
|
||||
|
||||
bool
|
||||
loentity_store_affect_bullets_shot_by_others(
|
||||
loentity_store_t* store,
|
||||
loentity_character_t* chara,
|
||||
const vec2_t* velocity,
|
||||
float dt
|
||||
);
|
||||
|
||||
bool
|
||||
loentity_store_affect_bullets_shot_by_one(
|
||||
loentity_store_t* store,
|
||||
loentity_character_t* chara,
|
||||
loentity_id_t shooter,
|
||||
const vec2_t* velocity,
|
||||
float dt
|
||||
);
|
Reference in New Issue
Block a user