Skip to content

Commit

Permalink
display aspects
Browse files Browse the repository at this point in the history
  • Loading branch information
jube committed Sep 14, 2024
1 parent e5a95a9 commit 8f7ad13
Show file tree
Hide file tree
Showing 17 changed files with 437 additions and 1 deletion.
24 changes: 24 additions & 0 deletions code/bits/Aspect.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "Aspect.h"

#include <cassert>

#include "Colors.h"

namespace akgr {

gf::Color aspect_color(Aspect aspect) {
switch (aspect) {
case Aspect::Health:
return HealthColor;
case Aspect::Magic:
return MagicColor;
case Aspect::Vitality:
return VitalityColor;
}

assert(false);
return gf::Black;
}

}

20 changes: 20 additions & 0 deletions code/bits/Aspect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef AKGR_ASPECT_H
#define AKGR_ASPECT_H

#include <cstdint>

#include <gf2/core/Color.h>

namespace akgr {

enum class Aspect : uint8_t {
Health,
Magic,
Vitality,
};

gf::Color aspect_color(Aspect aspect);

}

#endif // AKGR_ASPECT_H
109 changes: 109 additions & 0 deletions code/bits/AspectRenderer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "AspectRenderer.h"

#include <fmt/core.h>

#include "Akagoria.h"
#include "fmt/format.h"
#include "gf2/core/Color.h"
#include "gf2/core/TextData.h"

namespace akgr {

AspectRenderer::AspectRenderer(Akagoria* game, const WorldResources& resources)
: m_game(game)
, m_atlas({ 512, 512 }, game->render_manager())
, m_default_text_data(resources.aspect_text.data)
, m_hp_entity(&m_atlas, resources.aspect_text, game->render_manager(), game->resource_manager())
, m_mp_entity(&m_atlas, resources.aspect_text, game->render_manager(), game->resource_manager())
, m_vp_entity(&m_atlas, resources.aspect_text, game->render_manager(), game->resource_manager())
, m_background_shape(compute_shape_buffer(), game->render_manager())
{
m_background_shape.set_location({ 10.0f, 10.0f });
m_hp_entity.set_location({ 30.0f, 20.0f });
m_mp_entity.set_location({ 30.0f, 45.0f });
m_vp_entity.set_location({ 30.0f, 70.0f });
}

void AspectRenderer::update([[maybe_unused]] gf::Time time)
{
const auto& aspects = m_game->world_state()->hero.aspects;

m_background_shape.shape_group().update(compute_shape_buffer(), m_game->render_manager());

gf::TextData hp_text = m_default_text_data;
hp_text.content = fmt::format("HP: {}/{}", aspects.hp.value.as_int(), aspects.hp.max.as_int());
m_hp_entity.text().update(hp_text, m_game->render_manager());

gf::TextData mp_text = m_default_text_data;
mp_text.content = fmt::format("MP: {}/{}", aspects.mp.value.as_int(), aspects.mp.max.as_int());
m_mp_entity.text().update(mp_text, m_game->render_manager());

gf::TextData vp_text = m_default_text_data;
vp_text.content = fmt::format("VP: {}/{}", aspects.vp.value.as_int(), aspects.vp.max.as_int());
m_vp_entity.text().update(vp_text, m_game->render_manager());
}

void AspectRenderer::render(gf::RenderRecorder& recorder)
{
m_background_shape.render(recorder);
m_hp_entity.render(recorder);
m_mp_entity.render(recorder);
m_vp_entity.render(recorder);
}

gf::ShapeGroupBuffer AspectRenderer::compute_shape_buffer()
{
const auto& aspects = m_game->world_state()->hero.aspects;

gf::ShapeGroupBuffer buffer;

gf::ShapeBuffer frame = gf::ShapeBuffer::make_rectangle(gf::RectF::from_size({ 300.0f, 90.0f }));
frame.color = gf::Gray * gf::opaque(0.8f);
buffer.shapes.push_back(std::move(frame));

// hp

const float hp = 280.0f * aspects.hp.value.as_float() / aspects.hp.max.as_float();

gf::ShapeBuffer hp_background = gf::ShapeBuffer::make_rectangle(gf::RectF::from_position_size({ 10.0f, 10.0f }, { 280.0f, 15.0f }));
hp_background.color = gf::Transparent;
hp_background.outline_color = aspect_color(Aspect::Health);
hp_background.outline_thickness = 1.0f;
buffer.shapes.push_back(std::move(hp_background));

gf::ShapeBuffer hp_foreground = gf::ShapeBuffer::make_rectangle(gf::RectF::from_position_size({ 10.0f, 10.0f }, { hp, 15.0f }));
hp_foreground.color = aspect_color(Aspect::Health);
buffer.shapes.push_back(std::move(hp_foreground));

// mp

const float mp = 280.0f * aspects.mp.value.as_float() / aspects.mp.max.as_float();

gf::ShapeBuffer mp_background = gf::ShapeBuffer::make_rectangle(gf::RectF::from_position_size({ 10.0f, 35.0f }, { 280.0f, 15.0f }));
mp_background.color = gf::Transparent;
mp_background.outline_color = aspect_color(Aspect::Magic);
mp_background.outline_thickness = 1.0f;
buffer.shapes.push_back(std::move(mp_background));

gf::ShapeBuffer mp_foreground = gf::ShapeBuffer::make_rectangle(gf::RectF::from_position_size({ 10.0f, 35.0f }, { mp, 15.0f }));
mp_foreground.color = aspect_color(Aspect::Magic);
buffer.shapes.push_back(std::move(mp_foreground));

// vp

const float vp = 280.0f * aspects.vp.value.as_float() / aspects.vp.max.as_float();

gf::ShapeBuffer vp_background = gf::ShapeBuffer::make_rectangle(gf::RectF::from_position_size({ 10.0f, 60.0f }, { 280.0f, 15.0f }));
vp_background.color = gf::Transparent;
vp_background.outline_color = aspect_color(Aspect::Vitality);
vp_background.outline_thickness = 1.0f;
buffer.shapes.push_back(std::move(vp_background));

gf::ShapeBuffer vp_foreground = gf::ShapeBuffer::make_rectangle(gf::RectF::from_position_size({ 10.0f, 60.0f }, { vp, 15.0f }));
vp_foreground.color = aspect_color(Aspect::Vitality);
buffer.shapes.push_back(std::move(vp_foreground));

return buffer;
}

}
40 changes: 40 additions & 0 deletions code/bits/AspectRenderer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef AKGR_ASPECT_RENDERER_H
#define AKGR_ASPECT_RENDERER_H

#include <cstdint>
#include <gf2/core/Id.h>
#include <gf2/core/TextStyle.h>

#include <gf2/graphics/Entity.h>
#include <gf2/graphics/ShapeEntity.h>
#include <gf2/graphics/TextEntity.h>

#include "WorldResources.h"
#include "gf2/core/ShapeBuffer.h"

namespace akgr {
class Akagoria;

class AspectRenderer : public gf::Entity {
public:
AspectRenderer(Akagoria* game, const WorldResources& resources);

void update(gf::Time time) override;
void render(gf::RenderRecorder& recorder) override;

private:

gf::ShapeGroupBuffer compute_shape_buffer();

Akagoria* m_game = nullptr;
gf::FontAtlas m_atlas;
gf::TextData m_default_text_data;
gf::TextEntity m_hp_entity;
gf::TextEntity m_mp_entity;
gf::TextEntity m_vp_entity;
gf::ShapeGroupEntity m_background_shape;
};

}

#endif // AKGR_ASPECT_RENDERER_H
46 changes: 46 additions & 0 deletions code/bits/AspectState.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "AspectState.h"

#include <cassert>

namespace akgr {

bool AspectValue::increase(gf::Time time) {
value += (max / 20) * time.as_seconds();

if (value > max) {
value = max;
return false;
}

return true;
}

void AspectValue::update(gf::Time time, gf::Time max_period) {
period += time;

while (period > max_period) {
if (value < max) {
value += 1;
} else {
value = max;
}

period -= max_period;
}
}

AspectValue& AspectState::operator[](Aspect aspect) {
switch (aspect) {
case Aspect::Health:
return hp;
case Aspect::Magic:
return mp;
case Aspect::Vitality:
return vp;
}

assert(false);
return hp;
}

}
41 changes: 41 additions & 0 deletions code/bits/AspectState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef AKGR_ASPECT_STATE_H
#define AKGR_ASPECT_STATE_H

#include <gf2/core/Time.h>
#include <gf2/core/TypeTraits.h>

#include "Aspect.h"
#include "Value.h"

namespace akgr {

struct AspectValue {
Value value = 75;
Value max = 100;
gf::Time period;

bool increase(gf::Time time);
void update(gf::Time time, gf::Time max_period);
};

template<typename Archive>
Archive& operator|(Archive& ar, gf::MaybeConst<AspectValue, Archive>& aspect) {
return ar | aspect.value | aspect.max | aspect.period;
}

struct AspectState {
AspectValue hp;
AspectValue mp;
AspectValue vp;

AspectValue& operator[](Aspect aspect);
};

template<typename Archive>
Archive& operator|(Archive& ar, gf::MaybeConst<AspectState, Archive>& state) {
return ar | state.hp | state.mp | state.vp;
}

}

#endif // AKGR_ASPECT_STATE_H
1 change: 1 addition & 0 deletions code/bits/Attribute.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "Attribute.h"
18 changes: 18 additions & 0 deletions code/bits/Attribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef AKGR_ATTRIBUTE_H
#define AKGR_ATTRIBUTE_H

#include <cstdint>

namespace akgr {

enum class Attribute : uint8_t {
Strength,
Dexterity,
Intelligence,
Wisdom,
Knowledge,
};

}

#endif // AKGR_ATTRIBUTE_H
64 changes: 64 additions & 0 deletions code/bits/AttributeState.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "AttributeState.h"

#include <cassert>

namespace akgr {

void AttributeValue::increase(Value gain, AttributeValue& anti1, AttributeValue& anti2) {
Value loss1 = gain / 2;
Value loss2 = gain / 2;

if (loss1 > anti1.value) {
loss1 = anti1.value;
}

if (loss2 > anti2.value) {
loss2 = anti2.value;
}

gain = loss1 + loss2;

value += gain;
anti1.value -= loss1;
anti2.value -= loss2;
}

void AttributeState::increase(Attribute kind, Value gain) {
switch (kind) {
case Attribute::Strength:
strength.increase(gain, intelligence, wisdom);
break;
case Attribute::Dexterity:
dexterity.increase(gain, wisdom, knowledge);
break;
case Attribute::Intelligence:
intelligence.increase(gain, knowledge, strength);
break;
case Attribute::Wisdom:
wisdom.increase(gain, strength, dexterity);
break;
case Attribute::Knowledge:
knowledge.increase(gain, dexterity, intelligence);
break;
}
}

AttributeValue& AttributeState::operator[](Attribute attribute) {
switch (attribute) {
case Attribute::Strength:
return strength;
case Attribute::Dexterity:
return dexterity;
case Attribute::Intelligence:
return intelligence;
case Attribute::Wisdom:
return wisdom;
case Attribute::Knowledge:
return knowledge;
}

assert(false);
return strength;
}

}
Loading

0 comments on commit 8f7ad13

Please sign in to comment.