-
-
Save brokenprogrammer/66f94a741422fdaa67ab7ff64ab7eba3 to your computer and use it in GitHub Desktop.
This file contains hidden or 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