Files
ld58/code/game/impl/npc.c

68 lines
2.4 KiB
C
Raw Normal View History

#include "game/npc.h"
#include "game/world.h"
#include "core/types.h"
2025-10-05 15:32:57 +01:00
#include "core/math.h"
2025-10-05 21:05:29 +01:00
void UpdateNPC(F32 delta, NPC *npc, World *world) {
2025-10-06 21:07:55 +01:00
for(int i = 0; i < world->portalCount; i++) {
if(AABB_Collide(world->portals[0].box, npc->collision)) {
npc->currentArea = world->portals[0].area;
}
}
2025-10-05 00:25:37 +01:00
switch (npc->mode) {
case NPC_ACTION_WAITING:
npc->waitTime+=delta;
if(npc->waitTime > npc->maxWaitTime) {
npc->mode = NPC_ACTION_WALKING;
2025-10-05 15:32:57 +01:00
// TODO change targets to poi's rather than just random nodes
2025-10-05 18:28:58 +01:00
// TODO choose either global POI's or use NPC custom poi if
// customPOI is true
2025-10-05 18:05:01 +01:00
do {
npc->targetNavNode = Random_U32(&world->random, 0, world->navMesh->nodeCount);
} while(npc->targetNavNode == npc->currentNavNode);
2025-10-05 00:25:37 +01:00
npc->path = Nav_Path(world->navMesh, npc->currentNavNode, npc->targetNavNode);
npc->walkTimer = 0;
}
break;
case NPC_ACTION_WALKING:
npc->walkTimer+=delta;
if(npc->walkTimer >= NPC_SPEED){
npc->walkTimer = 0;
if(npc->path.nodeCount == npc->pathIndex+1){
npc->mode = NPC_ACTION_WAITING;
2025-10-05 18:28:58 +01:00
npc->maxWaitTime = Random_F32(&world->random, 20, 140);
2025-10-05 00:25:37 +01:00
npc->waitTime = 0;
2025-10-05 16:49:18 +01:00
npc->currentNavNode = npc->targetNavNode;
2025-10-05 00:25:37 +01:00
npc->pathIndex = 0;
return;
}
npc->currentNavNode = npc->path.indexes[npc->pathIndex];
2025-10-05 16:49:18 +01:00
npc->pathIndex+=1;
2025-10-05 00:25:37 +01:00
}
NavNode cNav = world->navMesh->nodes[npc->currentNavNode];
2025-10-05 16:49:18 +01:00
NavNode tNav = world->navMesh->nodes[npc->path.indexes[npc->pathIndex]];
2025-10-05 00:25:37 +01:00
npc->collision.pos.x = cNav.pos.x * (1 - npc->walkTimer/NPC_SPEED) + tNav.pos.x * npc->walkTimer/NPC_SPEED;
npc->collision.pos.y = cNav.pos.y * (1 - npc->walkTimer/NPC_SPEED) + tNav.pos.y * npc->walkTimer/NPC_SPEED;
break;
}
}
void NPCDraw(D_Context *draw, NPC *npc)
{
G_Outfit *outfit = &npc->outfit;
R2f pframe = D_AnimationFrame(&outfit->state);
for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it)
{
U32 flipped = (outfit->dir & G_OUTFIT_DIR_FLIPPED) != 0;
U32 dir = (outfit->dir & ~G_OUTFIT_DIR_FLIPPED);
U32 tid = outfit->e[dir].e[it];
if (tid != 0)
{
U32 flags = D_RECT_UV_ASPECT | (flipped ? D_RECT_FLIP_X : 0);
D_Rect(draw, npc->collision.pos.x, npc->collision.pos.y, .texture = tid, .uv = pframe, .flags = flags);
}
}
}