interactions
This commit is contained in:
@ -16,8 +16,15 @@ entity_t ENTITIES[ENTITY_COUNT_MAX] = {0};
|
|||||||
|
|
||||||
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
||||||
{NULL}, // ENTITY_TYPE_NULL
|
{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) {
|
void entityInit(entity_t *entity, const entitytype_t type) {
|
||||||
|
@ -47,6 +47,7 @@ typedef struct _entity_t {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
void (*init) (entity_t *entity);
|
void (*init) (entity_t *entity);
|
||||||
void (*update) (entity_t *entity);
|
void (*update) (entity_t *entity);
|
||||||
|
void (*interact)(entity_t *player, entity_t *self);
|
||||||
} entitycallback_t;
|
} entitycallback_t;
|
||||||
|
|
||||||
extern entity_t ENTITIES[ENTITY_COUNT_MAX];
|
extern entity_t ENTITIES[ENTITY_COUNT_MAX];
|
||||||
@ -66,3 +67,11 @@ void entityInit(entity_t *entity, const entitytype_t type);
|
|||||||
* @param entity Pointer to the entity to update.
|
* @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);
|
@ -14,3 +14,7 @@ void npcInit(entity_t *entity) {
|
|||||||
void npcUpdate(entity_t *entity) {
|
void npcUpdate(entity_t *entity) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void npcInteract(entity_t *player, entity_t *self) {
|
||||||
|
printf("I am being interacted with!\n");
|
||||||
|
}
|
@ -21,3 +21,11 @@ void npcInit(entity_t *entity);
|
|||||||
* @param entity The entity to update.
|
* @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,6 +82,7 @@ void playerNPCUpdate(entity_t *entity) {
|
|||||||
} else {
|
} else {
|
||||||
entity->vx = 0;
|
entity->vx = 0;
|
||||||
entity->vy = 0;
|
entity->vy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Interact
|
// Interact
|
||||||
if(inputPressed(INPUT_BIND_ACTION)) {
|
if(inputPressed(INPUT_BIND_ACTION)) {
|
||||||
@ -92,29 +93,53 @@ void playerNPCUpdate(entity_t *entity) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is the other entity interactable?
|
||||||
|
if(ENTITY_CALLBACKS[other->type].interact == NULL) {
|
||||||
|
other++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
fixed248_t distanceX = fx248Subfx248(other->x, entity->x);
|
fixed248_t distanceX = fx248Subfx248(other->x, entity->x);
|
||||||
fixed248_t distanceY = fx248Subfx248(other->y, entity->y);
|
fixed248_t distanceY = fx248Subfx248(other->y, entity->y);
|
||||||
fixed248_t distance = fx248Sqrt(
|
fixed248_t distance = fx248Sqrt(fx248Addfx248(
|
||||||
fx248Addfx248(
|
|
||||||
fx248Mulfx248(distanceX, distanceX),
|
fx248Mulfx248(distanceX, distanceX),
|
||||||
fx248Mulfx248(distanceY, distanceY)
|
fx248Mulfx248(distanceY, distanceY)
|
||||||
)
|
));
|
||||||
);
|
|
||||||
|
|
||||||
if(other->id == 102) {
|
|
||||||
printf("Distance to entity %u: %f\n", other->id, fx248Tof32(distance));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(distance > PLAYER_INTERACT_RANGE) {
|
if(distance > PLAYER_INTERACT_RANGE) {
|
||||||
other++;
|
other++;
|
||||||
continue;
|
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;
|
||||||
|
|
||||||
printf("Interacting with entity %u\n", other->id);
|
// 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++;
|
other++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTITY_CALLBACKS[other->type].interact(entity, other);
|
||||||
|
entity->vx = 0;
|
||||||
|
entity->vy = 0;
|
||||||
|
other++;
|
||||||
} while(other != ENTITIES + ENTITY_COUNT_MAX);
|
} 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_ENTITY_ID (UINT32_MAX-1)
|
||||||
#define PLAYER_MOVE_SPEED FIXED248(1, 0)
|
#define PLAYER_MOVE_SPEED FIXED248(1, 0)
|
||||||
#define PLAYER_MOVE_SPEED_XY FIXED248(0, 80)
|
#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.
|
* Initializes the player and all player-related entities.
|
||||||
|
@ -199,3 +199,59 @@ fixed248_t fx248Clamp(
|
|||||||
) {
|
) {
|
||||||
return (a < min) ? min : (a > max) ? max : a;
|
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_ONE (FIXED248(1, 0))
|
||||||
#define FIXED248_ZERO (FIXED248(0, 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.
|
* Convert an int32_t value to a fixed248_t value.
|
||||||
@ -351,3 +355,25 @@ fixed248_t fx248Clamp(
|
|||||||
const fixed248_t min,
|
const fixed248_t min,
|
||||||
const fixed248_t max
|
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