More cutscene stuff
This commit is contained in:
@@ -33,4 +33,22 @@ typedef struct cutscene_s {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = WAIT }
|
||||
|
||||
#define CUTSCENE_CUTSCENE(CUTSCENE) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CUTSCENE, .cutscene = CUTSCENE_REFERENCE(CUTSCENE) }
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_CUTSCENE, \
|
||||
.cutscene = CUTSCENE_REFERENCE(CUTSCENE) \
|
||||
}
|
||||
|
||||
#define CUTSCENE_CALLBACK(CALLBACK) \
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = CALLBACK }
|
||||
|
||||
#define CUTSCENE_ENTITY_TELEPORT(ENTITY_INDEX, X, Y, Z) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT, \
|
||||
.entityTeleport = { .entityIndex = ENTITY_INDEX, .target = { X, Y, Z } } \
|
||||
}
|
||||
|
||||
#define CUTSCENE_FADE(FROM, TO, DURATION, EASING) \
|
||||
{ \
|
||||
.type = CUTSCENE_ITEM_TYPE_FADE, \
|
||||
.fade = { .from = FROM, .to = TO, .duration = DURATION, .easing = EASING } \
|
||||
}
|
||||
|
||||
@@ -7,5 +7,4 @@
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
cutsceneitem.c
|
||||
cutsceneentitymove.c
|
||||
)
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cutsceneentitymove.h"
|
||||
#include "rpg/cutscene/cutscenesystem.h"
|
||||
#include "rpg/entity/entity.h"
|
||||
|
||||
void cutsceneEntityMoveStart(const cutsceneitem_t *item) {
|
||||
}
|
||||
|
||||
void cutsceneEntityMoveUpdate(const cutsceneitem_t *item) {
|
||||
entity_t *entity = &ENTITIES[item->entityMove.entityIndex];
|
||||
|
||||
if(worldPosIsEqual(entity->position, item->entityMove.target)) {
|
||||
cutsceneSystemNext();
|
||||
return;
|
||||
}
|
||||
|
||||
entitydir_t dir;
|
||||
if(entity->position.x != item->entityMove.target.x) {
|
||||
dir = entity->position.x < item->entityMove.target.x
|
||||
? ENTITY_DIR_EAST : ENTITY_DIR_WEST;
|
||||
} else {
|
||||
dir = entity->position.y < item->entityMove.target.y
|
||||
? ENTITY_DIR_SOUTH : ENTITY_DIR_NORTH;
|
||||
}
|
||||
|
||||
if(entityCanTurn(entity)) entityTurn(entity, dir);
|
||||
|
||||
if(item->entityMove.run) {
|
||||
if(entityCanRun(entity)) entityRun(entity, dir);
|
||||
} else {
|
||||
if(entityCanWalk(entity)) entityWalk(entity, dir);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "cutsceneitem.h"
|
||||
|
||||
/**
|
||||
* Handles the start of an entity move cutscene item.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
*/
|
||||
void cutsceneEntityMoveStart(const cutsceneitem_t *item);
|
||||
|
||||
/**
|
||||
* Updates an entity move cutscene item, steering the entity one step
|
||||
* per frame toward the target and advancing the cutscene on arrival.
|
||||
*
|
||||
* @param item The cutscene item.
|
||||
*/
|
||||
void cutsceneEntityMoveUpdate(const cutsceneitem_t *item);
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/color.h"
|
||||
#include "animation/easing.h"
|
||||
|
||||
typedef struct {
|
||||
color_t from;
|
||||
color_t to;
|
||||
float_t duration;
|
||||
easingtype_t easing;
|
||||
} cutscenefade_t;
|
||||
@@ -6,10 +6,11 @@
|
||||
*/
|
||||
|
||||
#include "rpg/cutscene/cutscenesystem.h"
|
||||
#include "cutsceneentitymove.h"
|
||||
#include "input/input.h"
|
||||
#include "ui/overlay/uifullbox.h"
|
||||
#include "time/time.h"
|
||||
#include "ui/rpg/uitextboxmain.h"
|
||||
#include "rpg/entity/entity.h"
|
||||
|
||||
void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
||||
switch(item->type) {
|
||||
@@ -29,8 +30,21 @@ void cutsceneItemStart(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
||||
if(item->cutscene != NULL) cutsceneSystemStartCutscene(item->cutscene);
|
||||
break;
|
||||
|
||||
case CUTSCENE_ITEM_TYPE_ENTITY_MOVE:
|
||||
cutsceneEntityMoveStart(item);
|
||||
case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT:
|
||||
entityPositionSet(
|
||||
&ENTITIES[item->entityTeleport.entityIndex],
|
||||
item->entityTeleport.target
|
||||
);
|
||||
break;
|
||||
|
||||
case CUTSCENE_ITEM_TYPE_FADE:
|
||||
uiFullboxTransition(
|
||||
&UI_FULLBOX_OVER,
|
||||
item->fade.from,
|
||||
item->fade.to,
|
||||
item->fade.duration,
|
||||
item->fade.easing
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -50,8 +64,16 @@ void cutsceneItemUpdate(const cutsceneitem_t *item, cutsceneitemdata_t *data) {
|
||||
if(data->wait <= 0) cutsceneSystemNext();
|
||||
break;
|
||||
|
||||
case CUTSCENE_ITEM_TYPE_ENTITY_MOVE:
|
||||
cutsceneEntityMoveUpdate(item);
|
||||
case CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT:
|
||||
cutsceneSystemNext();
|
||||
break;
|
||||
|
||||
case CUTSCENE_ITEM_TYPE_FADE:
|
||||
if(
|
||||
UI_FULLBOX_OVER.duration > 0.0f &&
|
||||
UI_FULLBOX_OVER.time < UI_FULLBOX_OVER.duration
|
||||
) return;
|
||||
cutsceneSystemNext();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "cutscenewait.h"
|
||||
#include "cutscenecallback.h"
|
||||
#include "cutscenetext.h"
|
||||
#include "cutscenefade.h"
|
||||
#include "rpg/overworld/worldpos.h"
|
||||
|
||||
typedef struct cutscene_s cutscene_t;
|
||||
@@ -19,7 +20,8 @@ typedef enum {
|
||||
CUTSCENE_ITEM_TYPE_CALLBACK,
|
||||
CUTSCENE_ITEM_TYPE_WAIT,
|
||||
CUTSCENE_ITEM_TYPE_CUTSCENE,
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_MOVE
|
||||
CUTSCENE_ITEM_TYPE_ENTITY_TELEPORT,
|
||||
CUTSCENE_ITEM_TYPE_FADE
|
||||
} cutsceneitemtype_t;
|
||||
|
||||
typedef struct cutsceneitem_s {
|
||||
@@ -34,8 +36,8 @@ typedef struct cutsceneitem_s {
|
||||
struct {
|
||||
uint8_t entityIndex;
|
||||
worldpos_t target;
|
||||
bool_t run;
|
||||
} entityMove;
|
||||
} entityTeleport;
|
||||
cutscenefade_t fade;
|
||||
};
|
||||
} cutsceneitem_t;
|
||||
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
|
||||
#pragma once
|
||||
#include "rpg/cutscene/cutscene.h"
|
||||
#include "rpg/cutscene/cutscenesystem.h"
|
||||
|
||||
CUTSCENE(TEST_ONE, DEFAULT,
|
||||
CUTSCENE_TEXT("This is a test cutscene."),
|
||||
CUTSCENE_WAIT(0.5f),
|
||||
CUTSCENE_TEXT("It has multiple lines of text.\nAnd waits in between.")
|
||||
CUTSCENE_TEXT("Test One."),
|
||||
);
|
||||
|
||||
CUTSCENE(TEST_TWO, DEFAULT,
|
||||
CUTSCENE_WAIT(0.1f),
|
||||
CUTSCENE_CUTSCENE(TEST_ONE),
|
||||
CUTSCENE_TEXT("Test Two."),
|
||||
CUTSCENE_FADE(COLOR_TRANSPARENT_BLACK, COLOR_BLACK, 1.0f, EASING_LINEAR),
|
||||
CUTSCENE_ENTITY_TELEPORT(0, 20, 0, 0),
|
||||
CUTSCENE_WAIT(1.0f),
|
||||
CUTSCENE_FADE(COLOR_BLACK, COLOR_TRANSPARENT_BLACK, 1.0f, EASING_LINEAR),
|
||||
);
|
||||
@@ -244,6 +244,15 @@ uint8_t entityGetAvailable() {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void entityPositionSet(entity_t *entity, const worldpos_t pos) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
entity->lastPosition = pos;
|
||||
entity->position = pos;
|
||||
entity->animation = ENTITY_ANIM_IDLE;
|
||||
entity->animTime = 0;
|
||||
entity->walkEndCooldown = 0;
|
||||
}
|
||||
|
||||
void entitySetChunk(entity_t *entity, const uint8_t chunkIndex) {
|
||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||
|
||||
|
||||
@@ -122,4 +122,12 @@ uint8_t entityGetAvailable();
|
||||
* @param entity Pointer to the entity.
|
||||
* @param chunkIndex Index of the chunk to assign to, or 0xFF for none.
|
||||
*/
|
||||
void entitySetChunk(entity_t *entity, const uint8_t chunkIndex);
|
||||
void entitySetChunk(entity_t *entity, const uint8_t chunkIndex);
|
||||
|
||||
/**
|
||||
* Instantly moves an entity to a world position, resetting movement state.
|
||||
*
|
||||
* @param entity Pointer to the entity to move.
|
||||
* @param pos The world position to place the entity at.
|
||||
*/
|
||||
void entityPositionSet(entity_t *entity, const worldpos_t pos);
|
||||
+2
-2
@@ -33,7 +33,7 @@ errorret_t rpgInit(void) {
|
||||
assertTrue(entIndex != 0xFF, "No available entity slots!.");
|
||||
entity_t *ent = &ENTITIES[entIndex];
|
||||
entityInit(ent, ENTITY_TYPE_PLAYER);
|
||||
ent->position = (worldpos_t){ 10, 2, 0 };
|
||||
entityPositionSet(ent, (worldpos_t){ 10, 2, 0 });
|
||||
RPG_CAMERA.mode = RPG_CAMERA_MODE_FOLLOW_ENTITY;
|
||||
RPG_CAMERA.followEntity.followEntityId = ent->id;
|
||||
{
|
||||
@@ -47,7 +47,7 @@ errorret_t rpgInit(void) {
|
||||
entity_t *npc = &ENTITIES[npcIndex];
|
||||
entityInit(npc, ENTITY_TYPE_NPC);
|
||||
npcSetMoveType(npc, NPC_MOVE_TYPE_PATH);
|
||||
npc->position = (worldpos_t){ 8, 8, 1 };
|
||||
entityPositionSet(npc, (worldpos_t){ 8, 8, 1 });
|
||||
npc->interact.type = ENTITY_INTERACT_CUTSCENE;
|
||||
npc->interact.data.cutscene = CUTSCENE_REFERENCE(TEST_TWO);
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user