This repository has been archived on 2022-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
LEFTONE/core/loplayer/player.c

289 lines
7.2 KiB
C
Raw Normal View History

#include "./player.h"
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <msgpack.h>
#include <msgpack/sbuffer.h>
#include "util/math/matrix.h"
#include "util/mpkutil/get.h"
#include "util/mpkutil/pack.h"
#include "core/lobullet/pool.h"
#include "core/locommon/input.h"
#include "core/locommon/position.h"
#include "core/locommon/ticker.h"
#include "core/loentity/entity.h"
#include "core/loentity/store.h"
#include "core/loshader/hud_bar.h"
#include "core/loshader/posteffect.h"
#include "core/loshader/set.h"
#include "./action.h"
#include "./camera.h"
#include "./combat.h"
#include "./controller.h"
#include "./entity.h"
#include "./event.h"
#include "./hud.h"
#include "./menu.h"
#include "./status.h"
#define LOPLAYER_COMBAT_ATTACK_RESERVE 32
void loplayer_initialize(
loplayer_t* player,
loentity_id_t id,
loresource_set_t* res,
loshader_set_t* shaders,
const locommon_ticker_t* ticker,
lobullet_pool_t* bullets,
loentity_store_t* entities,
const mat4_t* proj) {
assert(player != NULL);
assert(res != NULL);
assert(shaders != NULL);
assert(ticker != NULL);
assert(bullets != NULL);
assert(entities != NULL);
assert(mat4_valid(proj));
*player = (typeof(*player)) {
.shaders = shaders,
};
player->event = loplayer_event_new(
res,
shaders);
loplayer_status_initialize(&player->status, res, ticker);
loplayer_entity_initialize(
&player->entity,
id,
res->sound,
shaders->drawer.character,
ticker,
entities,
player->event,
&player->status);
loentity_store_add(entities, &player->entity.super.super);
player->combat = loplayer_combat_new(
res->sound,
shaders->drawer.combat_ring,
ticker,
entities,
&player->status,
&player->entity,
LOPLAYER_COMBAT_ATTACK_RESERVE);
loplayer_controller_initialize(&player->controller);
loplayer_camera_initialize(
&player->camera,
shaders,
ticker,
player->event,
&player->status,
&player->entity,
proj);
player->hud = loplayer_hud_new(
res,
shaders,
ticker,
player->event,
&player->status,
&player->entity);
player->menu = loplayer_menu_new(
res,
shaders,
ticker,
&player->status,
&player->controller);
player->action = loplayer_action_new(
res,
ticker,
bullets,
entities,
player->event,
&player->status,
&player->entity,
player->combat,
&player->controller,
&player->camera,
player->hud,
player->menu);
}
void loplayer_deinitialize(loplayer_t* player) {
assert(player != NULL);
loplayer_action_delete(player->action);
loplayer_menu_delete(player->menu);
loplayer_hud_delete(player->hud);
loplayer_camera_deinitialize(&player->camera);
loplayer_controller_deinitialize(&player->controller);
loplayer_combat_delete(player->combat);
loplayer_entity_deinitialize(&player->entity);
loplayer_status_deinitialize(&player->status);
loplayer_event_delete(player->event);
}
void loplayer_popup(loplayer_t* player, const char* title, const char* text) {
assert(player != NULL);
loplayer_action_start_menu_popup_state(player->action);
loplayer_menu_popup(player->menu, title, text);
}
bool loplayer_attack(
loplayer_t* player, const loplayer_combat_attack_t* attack) {
assert(player != NULL);
assert(attack != NULL);
return loplayer_combat_add_attack(player->combat, attack);
}
void loplayer_touch_encephalon(loplayer_t* player) {
assert(player != NULL);
loplayer_status_set_respawn_position(
&player->status, &player->entity.super.super.pos);
loplayer_status_reset(&player->status);
}
void loplayer_gain_stance(loplayer_t* player, loeffect_stance_id_t id) {
assert(player != NULL);
if (!loplayer_status_add_stance(&player->status, id)) return;
loplayer_action_start_menu_popup_state(player->action);
loplayer_menu_show_status_with_stance_highlighted(player->menu, id);
}
void loplayer_gain_faith(loplayer_t* player, float amount) {
assert(player != NULL);
player->status.recipient.faith += amount;
}
void loplayer_update(
loplayer_t* player,
const locommon_input_t* input,
const locommon_position_t* cursor) {
assert(player != NULL);
assert(input != NULL);
assert(locommon_position_valid(cursor));
loplayer_status_update(&player->status);
/* entity is updated through entity store. */
loplayer_combat_update(player->combat);
loplayer_camera_update(&player->camera);
loplayer_hud_update(player->hud);
loplayer_menu_update(player->menu);
loplayer_controller_update(&player->controller, input, cursor);
loplayer_action_execute(player->action);
}
void loplayer_draw(const loplayer_t* player) {
assert(player != NULL);
loplayer_camera_draw(&player->camera);
loplayer_event_draw(player->event);
loplayer_combat_draw_ui(player->combat);
loplayer_hud_draw_ui(player->hud);
loplayer_menu_draw_ui(player->menu);
}
void loplayer_pack(const loplayer_t* player, msgpack_packer* packer) {
assert(player != NULL);
assert(packer != NULL);
msgpack_pack_map(packer, 6);
mpkutil_pack_str(packer, "status");
loplayer_status_pack(&player->status, packer);
mpkutil_pack_str(packer, "entity");
loplayer_entity_pack(&player->entity, packer);
mpkutil_pack_str(packer, "combat");
loplayer_combat_pack(player->combat, packer);
mpkutil_pack_str(packer, "camera");
loplayer_camera_pack(&player->camera, packer);
mpkutil_pack_str(packer, "menu");
loplayer_menu_pack(player->menu, packer);
mpkutil_pack_str(packer, "action");
loplayer_action_pack(player->action, packer);
}
bool loplayer_unpack(loplayer_t* player, const msgpack_object* obj) {
assert(player != NULL);
if (obj == NULL) return false;
const msgpack_object_map* root = mpkutil_get_map(obj);
# define item_(v) mpkutil_get_map_item_by_str(root, v)
if (!loplayer_status_unpack(&player->status, item_("status")) ||
!loplayer_entity_unpack(&player->entity, item_("entity")) ||
!loplayer_combat_unpack( player->combat, item_("combat")) ||
!loplayer_camera_unpack(&player->camera, item_("camera")) ||
!loplayer_menu_unpack ( player->menu, item_("menu" )) ||
!loplayer_action_unpack( player->action, item_("action"))) {
return false;
}
# undef item_
return true;
}
void loplayer_test_packing(const loplayer_t* player) {
assert(player != NULL);
msgpack_sbuffer buf;
msgpack_sbuffer_init(&buf);
msgpack_packer pk;
msgpack_packer_init(&pk, &buf, msgpack_sbuffer_write);
loplayer_pack(player, &pk);
msgpack_unpacked upk;
msgpack_unpacked_init(&upk);
size_t off = 0;
const msgpack_unpack_return r =
msgpack_unpack_next(&upk, buf.data, buf.size, &off);
if (r != MSGPACK_UNPACK_SUCCESS) {
fprintf(stderr, "player: invalid msgpack format\n");
abort();
}
if (!loplayer_unpack((loplayer_t*) player, &upk.data)) {
fprintf(stderr, "player: failed to unpack\n");
abort();
}
printf("player: packing test passed\n");
msgpack_unpacked_destroy(&upk);
msgpack_sbuffer_destroy(&buf);
}