interactions
This commit is contained in:
@ -16,8 +16,15 @@ entity_t ENTITIES[ENTITY_COUNT_MAX] = {0};
|
||||
|
||||
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
||||
{NULL}, // ENTITY_TYPE_NULL
|
||||
{playerNPCInit, playerNPCUpdate}, // ENTITY_TYPE_PLAYER
|
||||
{npcInit, npcUpdate} // ENTITY_TYPE_NPC
|
||||
{
|
||||
.init = playerNPCInit,
|
||||
.update = playerNPCUpdate,
|
||||
},
|
||||
{
|
||||
.init = npcInit,
|
||||
.update = npcUpdate,
|
||||
.interact = npcInteract,
|
||||
},
|
||||
};
|
||||
|
||||
void entityInit(entity_t *entity, const entitytype_t type) {
|
||||
|
@ -47,6 +47,7 @@ typedef struct _entity_t {
|
||||
typedef struct {
|
||||
void (*init) (entity_t *entity);
|
||||
void (*update) (entity_t *entity);
|
||||
void (*interact)(entity_t *player, entity_t *self);
|
||||
} entitycallback_t;
|
||||
|
||||
extern entity_t ENTITIES[ENTITY_COUNT_MAX];
|
||||
@ -65,4 +66,12 @@ void entityInit(entity_t *entity, const entitytype_t type);
|
||||
*
|
||||
* @param entity Pointer to the entity to update.
|
||||
*/
|
||||
void entityUpdate(entity_t *entity);
|
||||
void entityUpdate(entity_t *entity);
|
||||
|
||||
/**
|
||||
* Converts an entity direction to an angle in fixed248_t format.
|
||||
*
|
||||
* @param dir The entity direction to convert.
|
||||
* @return The angle corresponding to the entity direction.
|
||||
*/
|
||||
fixed248_t entityDirToAngle(const entitydir_t dir);
|
@ -13,4 +13,8 @@ void npcInit(entity_t *entity) {
|
||||
|
||||
void npcUpdate(entity_t *entity) {
|
||||
|
||||
}
|
||||
|
||||
void npcInteract(entity_t *player, entity_t *self) {
|
||||
printf("I am being interacted with!\n");
|
||||
}
|
@ -20,4 +20,12 @@ void npcInit(entity_t *entity);
|
||||
*
|
||||
* @param entity The entity to update.
|
||||
*/
|
||||
void npcUpdate(entity_t *entity);
|
||||
void npcUpdate(entity_t *entity);
|
||||
|
||||
/**
|
||||
* Handles interaction between the player and the NPC.
|
||||
*
|
||||
* @param player The player entity interacting with the NPC.
|
||||
* @param self The NPC entity being interacted with.
|
||||
*/
|
||||
void npcInteract(entity_t *player, entity_t *self);
|
@ -82,39 +82,64 @@ void playerNPCUpdate(entity_t *entity) {
|
||||
} else {
|
||||
entity->vx = 0;
|
||||
entity->vy = 0;
|
||||
}
|
||||
|
||||
// Interact
|
||||
if(inputPressed(INPUT_BIND_ACTION)) {
|
||||
entity_t *other = ENTITIES;
|
||||
do {
|
||||
if(other == entity || other->type == ENTITY_TYPE_NULL) {
|
||||
other++;
|
||||
continue;
|
||||
}
|
||||
|
||||
fixed248_t distanceX = fx248Subfx248(other->x, entity->x);
|
||||
fixed248_t distanceY = fx248Subfx248(other->y, entity->y);
|
||||
fixed248_t distance = fx248Sqrt(
|
||||
fx248Addfx248(
|
||||
fx248Mulfx248(distanceX, distanceX),
|
||||
fx248Mulfx248(distanceY, distanceY)
|
||||
)
|
||||
);
|
||||
|
||||
if(other->id == 102) {
|
||||
printf("Distance to entity %u: %f\n", other->id, fx248Tof32(distance));
|
||||
}
|
||||
|
||||
if(distance > PLAYER_INTERACT_RANGE) {
|
||||
other++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
printf("Interacting with entity %u\n", other->id);
|
||||
// Interact
|
||||
if(inputPressed(INPUT_BIND_ACTION)) {
|
||||
entity_t *other = ENTITIES;
|
||||
do {
|
||||
if(other == entity || other->type == ENTITY_TYPE_NULL) {
|
||||
other++;
|
||||
continue;
|
||||
}
|
||||
|
||||
} while(other != ENTITIES + ENTITY_COUNT_MAX);
|
||||
}
|
||||
// Is the other entity interactable?
|
||||
if(ENTITY_CALLBACKS[other->type].interact == NULL) {
|
||||
other++;
|
||||
continue;
|
||||
}
|
||||
|
||||
fixed248_t distanceX = fx248Subfx248(other->x, entity->x);
|
||||
fixed248_t distanceY = fx248Subfx248(other->y, entity->y);
|
||||
fixed248_t distance = fx248Sqrt(fx248Addfx248(
|
||||
fx248Mulfx248(distanceX, distanceX),
|
||||
fx248Mulfx248(distanceY, distanceY)
|
||||
));
|
||||
|
||||
if(distance > PLAYER_INTERACT_RANGE) {
|
||||
other++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get angle
|
||||
fixed248_t angle = fx248Atan2(distanceY, distanceX);
|
||||
while(angle < 0) angle += FX248_PI;
|
||||
fixed248_t selfAngle = entityDirToAngle(entity->dir);
|
||||
while(selfAngle < 0) selfAngle += FX248_PI;
|
||||
|
||||
// Check if angle is within range
|
||||
fixed248_t angleDiff = fx248Subfx248(angle, selfAngle);
|
||||
if(angleDiff > FX248_HALF_PI) angleDiff -= FX248_PI;
|
||||
if(angleDiff < -FX248_HALF_PI) angleDiff += FX248_PI;
|
||||
if(fx248Abs(angleDiff) > PLAYER_INTERACT_ANGLE) {
|
||||
other++;
|
||||
continue;
|
||||
}
|
||||
|
||||
ENTITY_CALLBACKS[other->type].interact(entity, other);
|
||||
entity->vx = 0;
|
||||
entity->vy = 0;
|
||||
other++;
|
||||
} while(other != ENTITIES + ENTITY_COUNT_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
fixed248_t entityDirToAngle(const entitydir_t dir) {
|
||||
switch(dir) {
|
||||
case ENTITY_DIR_NORTH: return FX248_HALF_PI;
|
||||
case ENTITY_DIR_SOUTH: return -FX248_HALF_PI;
|
||||
case ENTITY_DIR_EAST: return 0;
|
||||
case ENTITY_DIR_WEST: return FX248_PI;
|
||||
default: return 0; // Should never happen
|
||||
}
|
||||
}
|
@ -18,7 +18,10 @@ typedef struct {
|
||||
#define PLAYER_ENTITY_ID (UINT32_MAX-1)
|
||||
#define PLAYER_MOVE_SPEED FIXED248(1, 0)
|
||||
#define PLAYER_MOVE_SPEED_XY FIXED248(0, 80)
|
||||
#define PLAYER_INTERACT_RANGE FIXED248((TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3)), 0)
|
||||
#define PLAYER_INTERACT_RANGE FIXED248( \
|
||||
(TILE_WIDTH_HEIGHT + (TILE_WIDTH_HEIGHT / 3)), 0 \
|
||||
)
|
||||
#define PLAYER_INTERACT_ANGLE ((fixed248_t)175)
|
||||
|
||||
/**
|
||||
* Initializes the player and all player-related entities.
|
||||
|
@ -198,4 +198,60 @@ fixed248_t fx248Clamp(
|
||||
const fixed248_t max
|
||||
) {
|
||||
return (a < min) ? min : (a > max) ? max : a;
|
||||
}
|
||||
|
||||
fixed248_t fx248Abs(const fixed248_t a) {
|
||||
return (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
fixed248_t fx248Atan2(
|
||||
const fixed248_t y,
|
||||
const fixed248_t x
|
||||
) {
|
||||
// Handle special cases
|
||||
if (x == 0) {
|
||||
if (y > 0) return FX248_HALF_PI;
|
||||
if (y < 0) return -FX248_HALF_PI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Use absolute values for quadrant correction
|
||||
fixed248_t abs_y = y;
|
||||
if (abs_y < 0) abs_y = -abs_y;
|
||||
|
||||
fixed248_t angle;
|
||||
if (abs_y < fx248Abs(x)) {
|
||||
fixed248_t z = fx248Divfx248(y, x);
|
||||
fixed248_t z2 = fx248Mulfx248(z, z);
|
||||
fixed248_t z3 = fx248Mulfx248(z2, z);
|
||||
fixed248_t z5 = fx248Mulfx248(z3, z2);
|
||||
angle = fx248Subfx248(
|
||||
fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))),
|
||||
fx248Divfx248(z3, fx248Fromi32(3))
|
||||
);
|
||||
if (x < 0) {
|
||||
if (y < 0) {
|
||||
angle -= FX248_PI;
|
||||
} else {
|
||||
angle += FX248_PI;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fixed248_t z = fx248Divfx248(x, y);
|
||||
fixed248_t z2 = fx248Mulfx248(z, z);
|
||||
fixed248_t z3 = fx248Mulfx248(z2, z);
|
||||
fixed248_t z5 = fx248Mulfx248(z3, z2);
|
||||
angle = fx248Subfx248(
|
||||
fx248Addfx248(z, fx248Divfx248(z5, fx248Fromi32(5))),
|
||||
fx248Divfx248(z3, fx248Fromi32(3))
|
||||
);
|
||||
if (y > 0) {
|
||||
angle = FX248_HALF_PI - angle;
|
||||
} else {
|
||||
angle = -FX248_HALF_PI - angle;
|
||||
}
|
||||
}
|
||||
return angle;
|
||||
}
|
@ -20,6 +20,10 @@ typedef int32_t fixed248_t;
|
||||
))
|
||||
#define FIXED248_ONE (FIXED248(1, 0))
|
||||
#define FIXED248_ZERO (FIXED248(0, 0))
|
||||
#define FX248_PI 804
|
||||
#define FX248_HALF_PI 402
|
||||
#define FX248_3PI_4 603
|
||||
#define FX248_NEG_PI -804
|
||||
|
||||
/**
|
||||
* Convert an int32_t value to a fixed248_t value.
|
||||
@ -350,4 +354,26 @@ fixed248_t fx248Clamp(
|
||||
const fixed248_t a,
|
||||
const fixed248_t min,
|
||||
const fixed248_t max
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a fixed248_t value.
|
||||
*
|
||||
* @param a The fixed248_t value to calculate the absolute value of.
|
||||
* @return The absolute value as a fixed248_t value.
|
||||
*/
|
||||
fixed248_t fx248Abs(const fixed248_t a);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the arctangent of a fixed248_t value.
|
||||
*
|
||||
* @param y Y coordinate value.
|
||||
* @param x X coordinate value.
|
||||
* @return The arctangent of the value as a fixed248_t value.
|
||||
*/
|
||||
fixed248_t fx248Atan2(
|
||||
const fixed248_t y,
|
||||
const fixed248_t x
|
||||
);
|
Reference in New Issue
Block a user