-
-
Save brokenprogrammer/66f94a741422fdaa67ab7ff64ab7eba3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
STN_INTERNAL void | |
PerformMove(entity *Entity, event_queue *EventQueue, vector2i CurrentTile, | |
move_direction MoveDirection, world *World) | |
{ | |
Assert(Entity->Type == ENTITY_TYPE_BRAINROLL); | |
u32 TemporaryArenaSize = Maraton->FrameArena.MemoryLeft / 2.0f; | |
memory_arena Arena = MemoryArenaInit(MemoryArenaAllocate(&Maraton->FrameArena, TemporaryArenaSize), | |
TemporaryArenaSize); | |
STNDefer { MemoryArenaFreeBytes(&Maraton->FrameArena, TemporaryArenaSize); }; | |
if (Entity->Brainroll.HasBeenAmended) | |
{ | |
return; | |
} | |
b32 NextTileIsOutOfBounds = false; | |
b32 DidAlterDestination = false; | |
vector2i MovementVector = MoveDirectionToVector(MoveDirection); | |
vector2i Destination = Vector2Add(CurrentTile, MovementVector); | |
rope_list_build_order RopeBuildOrder = ROPE_LIST_BUILD_ORDER_BACKWARDS; | |
if (MoveFromCurrentTileIsBlocked(World, CurrentTile)) | |
{ | |
EventQueuePushWallCollision(EventQueue, Entity, CurrentTile, MoveDirection); | |
return; | |
} | |
NextTileIsOutOfBounds = WorldTileIsOufOfBounds(World, Destination); | |
if (Entity->HasRopeConnection) | |
{ | |
if (EntityIsFirstInRope(Entity, World)) | |
{ | |
RopeBuildOrder = ROPE_LIST_BUILD_ORDER_FORWARDS; | |
} | |
rope_list RopeList = RopeListCreate(Entity, World, &Arena, RopeBuildOrder); | |
if (!RopeInAdjacentTile(RopeList.Next, World, Destination)) | |
{ | |
rope_transaction_list *TransactionList = RopeCreateTransactionList(&Arena); | |
if (!RopeTryMove(RopeList.Next, World, &Arena, MoveDirection, EventQueue, Entity, TransactionList)) | |
{ | |
Destination = Vector2Minus(Destination, MovementVector); | |
EventQueuePushWallCollision(EventQueue, Entity, Destination, MoveDirection); | |
} | |
else | |
{ | |
entity *NextTile = WorldGetStaticEntityAt(World, Destination); | |
entity *NextObject = WorldGetDynamicEntityAt(World, Destination); | |
if ((NextTile == NULL && NextObject == NULL) || | |
(NextObject != NULL && NextObject->Type == ENTITY_TYPE_ROPE && RopeListContainsEntity(RopeList.Next, World, NextObject)) || | |
(NextObject == NULL && NextTile != NULL && NextTile->Type == ENTITY_TYPE_PRESSURE_PLATE) || | |
(NextObject == NULL && NextTile != NULL && NextTile->Type == ENTITY_TYPE_SLIME)) | |
{ | |
if (IsMovingTowardsRope(MoveDirection, CurrentTile, RopeList.Next->Tile)) | |
{ | |
RopeTransactionsCommit(TransactionList, World, EventQueue); | |
MoveManagePressurePlateOnMove(EventQueue, Entity, World, CurrentTile, Destination); | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
WorldSwapTiles(World, CurrentTile, Destination); | |
if (NextTile != NULL && NextTile->Type == ENTITY_TYPE_PRESSURE_PLATE) | |
{ | |
EventQueuePushEnterPressurePlate(EventQueue, Entity, NextTile); | |
} | |
CurrentTile = Destination; | |
Destination = Vector2Add(Destination, MovementVector); | |
DidAlterDestination = true; | |
} | |
else | |
{ | |
MoveManagePressurePlateOnMove(EventQueue, Entity, World, CurrentTile, Destination); | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
WorldSwapTiles(World, CurrentTile, Destination); | |
if (NextTile != NULL && NextTile->Type == ENTITY_TYPE_PRESSURE_PLATE) | |
{ | |
EventQueuePushEnterPressurePlate(EventQueue, Entity, NextTile); | |
} | |
CurrentTile = Destination; | |
Destination = Vector2Add(Destination, MovementVector); | |
RopeTransactionsCommit(TransactionList, World, EventQueue); | |
DidAlterDestination = true; | |
} | |
} | |
} | |
} | |
} | |
entity *NextTile = WorldGetStaticEntityAt(World, Destination); | |
entity *NextObject = WorldGetDynamicEntityAt(World, Destination); | |
b32 RopeCollisionManaged = false; | |
while (NextTile == NULL && | |
NextObject == NULL && | |
NextTileIsOutOfBounds == false && | |
RopeCollisionManaged == false) | |
{ | |
if (!DidAlterDestination) | |
{ | |
Destination = Vector2Add(Destination, MovementVector); | |
} | |
else | |
{ | |
DidAlterDestination = false; | |
} | |
NextTileIsOutOfBounds = WorldTileIsOufOfBounds(World, Destination); | |
if (NextTileIsOutOfBounds) | |
{ | |
break; | |
} | |
NextTile = WorldGetStaticEntityAt(World, Destination); | |
NextObject = WorldGetDynamicEntityAt(World, Destination); | |
if (Entity->HasRopeConnection) | |
{ | |
rope_list RopeList = RopeListCreate(Entity, World, &Arena, RopeBuildOrder); | |
if (!RopeInAdjacentTile(RopeList.Next, World, Destination)) | |
{ | |
rope_transaction_list *TransactionList = RopeCreateTransactionList(&Arena); | |
if (!RopeTryMove(RopeList.Next, World, &Arena, MoveDirection, EventQueue, Entity, TransactionList)) | |
{ | |
RopeCollisionManaged = true; | |
Destination = Vector2Minus(Destination, MovementVector); | |
if (Destination.X != 0 || Destination.Y != 0) | |
{ | |
MoveManagePressurePlateOnMove(EventQueue, Entity, World, CurrentTile, Destination); | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
WorldSwapTiles(World, CurrentTile, Destination); | |
EventQueuePushWallCollision(EventQueue, Entity, Destination, MoveDirection); | |
} | |
} | |
else | |
{ | |
entity *NextTile = WorldGetStaticEntityAt(World, Destination); | |
entity *NextObject = WorldGetDynamicEntityAt(World, Destination); | |
if ((NextTile == NULL && NextObject == NULL) || | |
(NextObject != NULL && NextObject->Type == ENTITY_TYPE_ROPE && RopeListContainsEntity(RopeList.Next, World, NextObject)) || | |
(NextObject == NULL && NextTile != NULL && NextTile->Type == ENTITY_TYPE_PRESSURE_PLATE) || | |
(NextObject == NULL && NextTile != NULL && NextTile->Type == ENTITY_TYPE_SLIME)) | |
{ | |
if (IsMovingTowardsRope(MoveDirection, CurrentTile, RopeList.Next->Tile)) | |
{ | |
RopeTransactionsCommit(TransactionList, World, EventQueue); | |
MoveManagePressurePlateOnMove(EventQueue, Entity, World, CurrentTile, Destination); | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
WorldSwapTiles(World, CurrentTile, Destination); | |
CurrentTile = Destination; | |
} | |
else | |
{ | |
MoveManagePressurePlateOnMove(EventQueue, Entity, World, CurrentTile, Destination); | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
WorldSwapTiles(World, CurrentTile, Destination); | |
CurrentTile = Destination; | |
RopeTransactionsCommit(TransactionList, World, EventQueue); | |
} | |
} | |
NextTile = WorldGetStaticEntityAt(World, Destination); | |
NextObject = WorldGetDynamicEntityAt(World, Destination); | |
} | |
} | |
else | |
{ | |
NextTile = WorldGetStaticEntityAt(World, Destination); | |
NextObject = WorldGetDynamicEntityAt(World, Destination); | |
} | |
} | |
} | |
if (DidAlterDestination) | |
{ | |
Destination = Vector2Minus(Destination, MovementVector); | |
NextTile = WorldGetStaticEntityAt(World, Destination); | |
NextObject = WorldGetDynamicEntityAt(World, Destination); | |
} | |
if (!RopeCollisionManaged) | |
{ | |
if (NextTileIsOutOfBounds) | |
{ | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
EventQueuePushOutOfBounds(EventQueue, Entity); | |
} | |
else | |
{ | |
if (NextObject) | |
{ | |
if (NextObject == Entity) | |
{ | |
return; | |
} | |
MoveCheckDynamicCollision(Entity, EventQueue, CurrentTile, Destination, MoveDirection, World, NextObject); | |
} | |
else if (NextTile) | |
{ | |
MoveCheckStaticCollision(Entity, EventQueue, CurrentTile, Destination, MoveDirection, World, NextTile); | |
} | |
else | |
{ | |
if (Destination.X != 0 || Destination.Y != 0) | |
{ | |
EventQueuePushMove(EventQueue, Entity, CurrentTile, Destination, MoveDirection); | |
WorldSwapTiles(World, CurrentTile, Destination); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment