Trigger types on areas
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
#include "maparea.h"
|
#include "maparea.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/math.h"
|
#include "util/math.h"
|
||||||
|
#include "util/memory.h"
|
||||||
#include "rpg/overworld/map.h"
|
#include "rpg/overworld/map.h"
|
||||||
|
|
||||||
maparea_t MAP_AREAS[MAP_AREA_COUNT_MAX];
|
maparea_t MAP_AREAS[MAP_AREA_COUNT_MAX];
|
||||||
@@ -17,7 +18,8 @@ void mapAreaInit(
|
|||||||
const worldpos_t min,
|
const worldpos_t min,
|
||||||
const worldpos_t max,
|
const worldpos_t max,
|
||||||
const mapareacallback_t callback,
|
const mapareacallback_t callback,
|
||||||
const mapareanotify_t notify
|
const uint8_t notify,
|
||||||
|
const uint8_t trigger
|
||||||
) {
|
) {
|
||||||
assertNotNull(area, "Map area pointer cannot be NULL");
|
assertNotNull(area, "Map area pointer cannot be NULL");
|
||||||
assertNotNull(callback, "Map area callback cannot be NULL");
|
assertNotNull(callback, "Map area callback cannot be NULL");
|
||||||
@@ -32,6 +34,9 @@ void mapAreaInit(
|
|||||||
|
|
||||||
area->callback = callback;
|
area->callback = callback;
|
||||||
area->notify = notify;
|
area->notify = notify;
|
||||||
|
area->trigger = trigger;
|
||||||
|
|
||||||
|
memorySet(area->entities, 0, sizeof(area->entities));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t mapAreaIsInside(const maparea_t *area, const worldpos_t position) {
|
bool_t mapAreaIsInside(const maparea_t *area, const worldpos_t position) {
|
||||||
@@ -94,11 +99,12 @@ uint8_t mapAreaAdd(
|
|||||||
const worldpos_t min,
|
const worldpos_t min,
|
||||||
const worldpos_t max,
|
const worldpos_t max,
|
||||||
const mapareacallback_t callback,
|
const mapareacallback_t callback,
|
||||||
const mapareanotify_t notify
|
const uint8_t notify,
|
||||||
|
const uint8_t trigger
|
||||||
) {
|
) {
|
||||||
for(uint8_t i = 0; i < MAP_AREA_COUNT_MAX; i++) {
|
for(uint8_t i = 0; i < MAP_AREA_COUNT_MAX; i++) {
|
||||||
if(MAP_AREAS[i].callback != NULL) continue;
|
if(MAP_AREAS[i].callback != NULL) continue;
|
||||||
mapAreaInit(&MAP_AREAS[i], min, max, callback, notify);
|
mapAreaInit(&MAP_AREAS[i], min, max, callback, notify, trigger);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,8 +123,23 @@ void mapAreaCheckEntity(entity_t *entity) {
|
|||||||
for(uint8_t i = 0; i < MAP_AREA_COUNT_MAX; i++) {
|
for(uint8_t i = 0; i < MAP_AREA_COUNT_MAX; i++) {
|
||||||
maparea_t *area = &MAP_AREAS[i];
|
maparea_t *area = &MAP_AREAS[i];
|
||||||
if(area->callback == NULL) continue;
|
if(area->callback == NULL) continue;
|
||||||
if(!mapAreaIsInside(area, entity->position)) continue;
|
|
||||||
if(!mapAreaShouldNotify(area, entity)) continue;
|
if(!mapAreaShouldNotify(area, entity)) continue;
|
||||||
area->callback(entity);
|
|
||||||
|
bool_t wasInside = area->entities[entity->id] != 0;
|
||||||
|
bool_t isInside = mapAreaIsInside(area, entity->position);
|
||||||
|
uint8_t trigger = 0;
|
||||||
|
|
||||||
|
if(isInside && !wasInside) {
|
||||||
|
area->entities[entity->id] = 1;
|
||||||
|
trigger = MAP_TRIGGER_ENTER;
|
||||||
|
} else if(isInside && wasInside) {
|
||||||
|
trigger = MAP_TRIGGER_STEP;
|
||||||
|
} else if(!isInside && wasInside) {
|
||||||
|
area->entities[entity->id] = 0;
|
||||||
|
trigger = MAP_TRIGGER_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(trigger == 0 || !(area->trigger & trigger)) continue;
|
||||||
|
area->callback(entity, trigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,39 +7,44 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "worldpos.h"
|
#include "worldpos.h"
|
||||||
|
#include "rpg/entity/entity.h"
|
||||||
|
|
||||||
typedef struct chunk_s chunk_t;
|
typedef struct chunk_s chunk_t;
|
||||||
typedef struct entity_s entity_t;
|
|
||||||
typedef struct maparea_s maparea_t;
|
typedef struct maparea_s maparea_t;
|
||||||
|
|
||||||
#define MAP_AREA_COUNT_MAX 32
|
#define MAP_AREA_COUNT_MAX 32
|
||||||
|
|
||||||
typedef uint8_t mapareanotify_t;
|
#define MAP_AREA_NOTIFY_PLAYER (1 << 0)
|
||||||
|
#define MAP_AREA_NOTIFY_NPC (1 << 1)
|
||||||
|
#define MAP_AREA_NOTIFY_ALL (MAP_AREA_NOTIFY_PLAYER | MAP_AREA_NOTIFY_NPC)
|
||||||
|
|
||||||
#define MAP_AREA_NOTIFY_PLAYER ((mapareanotify_t)(1 << 0))
|
#define MAP_TRIGGER_STEP (1 << 0)
|
||||||
#define MAP_AREA_NOTIFY_NPC ((mapareanotify_t)(1 << 1))
|
#define MAP_TRIGGER_ENTER (1 << 1)
|
||||||
#define MAP_AREA_NOTIFY_ALL ((mapareanotify_t)( \
|
#define MAP_TRIGGER_EXIT (1 << 2)
|
||||||
MAP_AREA_NOTIFY_PLAYER | MAP_AREA_NOTIFY_NPC \
|
#define MAP_TRIGGER_ALL (MAP_TRIGGER_STEP | MAP_TRIGGER_ENTER | MAP_TRIGGER_EXIT)
|
||||||
))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback invoked for a map area.
|
* Callback invoked for a map area.
|
||||||
*
|
*
|
||||||
* @param entity Pointer to the entity associated with the callback.
|
* @param entity Pointer to the entity associated with the callback.
|
||||||
|
* @param trigger Which MAP_TRIGGER_* condition invoked the callback.
|
||||||
*/
|
*/
|
||||||
typedef void (*mapareacallback_t)(entity_t *entity);
|
typedef void (*mapareacallback_t)(entity_t *entity, const uint8_t trigger);
|
||||||
|
|
||||||
typedef struct maparea_s {
|
typedef struct maparea_s {
|
||||||
worldpos_t min;
|
worldpos_t min;
|
||||||
worldpos_t max;
|
worldpos_t max;
|
||||||
mapareacallback_t callback;
|
mapareacallback_t callback;
|
||||||
mapareanotify_t notify;
|
uint8_t notify;
|
||||||
|
uint8_t trigger;
|
||||||
|
uint8_t entities[ENTITY_COUNT];
|
||||||
} maparea_t;
|
} maparea_t;
|
||||||
|
|
||||||
extern maparea_t MAP_AREAS[MAP_AREA_COUNT_MAX];
|
extern maparea_t MAP_AREAS[MAP_AREA_COUNT_MAX];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a map area with the given bounds, callback and notify flags.
|
* Initializes a map area with the given bounds, callback, notify flags
|
||||||
|
* and trigger flags.
|
||||||
*
|
*
|
||||||
* @param area Pointer to the map area to initialize.
|
* @param area Pointer to the map area to initialize.
|
||||||
* @param min The minimum world position of the area.
|
* @param min The minimum world position of the area.
|
||||||
@@ -47,13 +52,16 @@ extern maparea_t MAP_AREAS[MAP_AREA_COUNT_MAX];
|
|||||||
* @param callback The callback to invoke for this area. Must not be NULL.
|
* @param callback The callback to invoke for this area. Must not be NULL.
|
||||||
* @param notify Bitwise MAP_AREA_NOTIFY_* flags for which entity types
|
* @param notify Bitwise MAP_AREA_NOTIFY_* flags for which entity types
|
||||||
* should trigger the callback.
|
* should trigger the callback.
|
||||||
|
* @param trigger Bitwise MAP_TRIGGER_* flags for which conditions should
|
||||||
|
* invoke the callback.
|
||||||
*/
|
*/
|
||||||
void mapAreaInit(
|
void mapAreaInit(
|
||||||
maparea_t *area,
|
maparea_t *area,
|
||||||
const worldpos_t min,
|
const worldpos_t min,
|
||||||
const worldpos_t max,
|
const worldpos_t max,
|
||||||
const mapareacallback_t callback,
|
const mapareacallback_t callback,
|
||||||
const mapareanotify_t notify
|
const uint8_t notify,
|
||||||
|
const uint8_t trigger
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,13 +114,16 @@ bool_t mapAreaShouldNotify(const maparea_t *area, const entity_t *entity);
|
|||||||
* @param callback The callback to invoke for this area. Must not be NULL.
|
* @param callback The callback to invoke for this area. Must not be NULL.
|
||||||
* @param notify Bitwise MAP_AREA_NOTIFY_* flags for which entity types
|
* @param notify Bitwise MAP_AREA_NOTIFY_* flags for which entity types
|
||||||
* should trigger the callback.
|
* should trigger the callback.
|
||||||
|
* @param trigger Bitwise MAP_TRIGGER_* flags for which conditions should
|
||||||
|
* invoke the callback.
|
||||||
* @returns The ID of the newly added map area.
|
* @returns The ID of the newly added map area.
|
||||||
*/
|
*/
|
||||||
uint8_t mapAreaAdd(
|
uint8_t mapAreaAdd(
|
||||||
const worldpos_t min,
|
const worldpos_t min,
|
||||||
const worldpos_t max,
|
const worldpos_t max,
|
||||||
const mapareacallback_t callback,
|
const mapareacallback_t callback,
|
||||||
const mapareanotify_t notify
|
const uint8_t notify,
|
||||||
|
const uint8_t trigger
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,8 +136,10 @@ void mapAreaRemove(const uint8_t id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks every active map area against an entity's current position,
|
* Checks every active map area against an entity's current position,
|
||||||
* invoking each matching area's callback if the entity is inside it and
|
* for areas whose notify flags include the entity's type. Invokes the
|
||||||
* its type is included in that area's notify flags.
|
* area's callback with MAP_TRIGGER_ENTER the frame the entity first
|
||||||
|
* becomes inside, MAP_TRIGGER_STEP on every subsequent frame it remains
|
||||||
|
* inside, and MAP_TRIGGER_EXIT the frame it leaves.
|
||||||
*
|
*
|
||||||
* @param entity Pointer to the entity to check.
|
* @param entity Pointer to the entity to check.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+4
-3
@@ -20,8 +20,8 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
|
|
||||||
void rpgTestAreaCallback(entity_t *entity) {
|
void rpgTestAreaCallback(entity_t *entity, const uint8_t trigger) {
|
||||||
consolePrint("rpgTestAreaCallback");
|
consolePrint("rpgTestAreaCallback: trigger=%u", trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t rpgInit(void) {
|
errorret_t rpgInit(void) {
|
||||||
@@ -53,7 +53,8 @@ errorret_t rpgInit(void) {
|
|||||||
(worldpos_t){ 11, 3, 0 },
|
(worldpos_t){ 11, 3, 0 },
|
||||||
(worldpos_t){ 16, 9, 10 },
|
(worldpos_t){ 16, 9, 10 },
|
||||||
rpgTestAreaCallback,
|
rpgTestAreaCallback,
|
||||||
MAP_AREA_NOTIFY_ALL
|
MAP_AREA_NOTIFY_ALL,
|
||||||
|
MAP_TRIGGER_ENTER | MAP_TRIGGER_EXIT
|
||||||
);
|
);
|
||||||
assertTrue(areaIndex != 0xFF, "No available map area slots!.");
|
assertTrue(areaIndex != 0xFF, "No available map area slots!.");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user