#include "simulation.h" #include "consts.h" #include "level.h" Simulation::Simulation( const Level& level) : level_(level) { id_type player = emplaceEntity(); Entity& entity = getEntity(player); entity.size = TILE_SIZE; entity.speed = 3.0; entity.controllable = true; entity.colliderType = ColliderType::player; entity.colorVal = 180; entity.gridPos = vec2s { 1, 5 }; id_type crateId = emplaceEntity(); Entity& crate = getEntity(crateId); crate.size = TILE_SIZE; crate.speed = static_cast(schedule_.getBPM()) / 30.0; crate.colliderType = ColliderType::crate; crate.canBePushedBy.insert(ColliderType::player); crate.canBePushedBy.insert(ColliderType::crate); crate.canBePushedBy.insert(ColliderType::train); crate.gridPos = vec2s { 4, 5 }; id_type crateId2 = emplaceEntity(); Entity& crate2 = getEntity(crateId2); crate2.size = TILE_SIZE; crate2.speed = static_cast(schedule_.getBPM()) / 30.0; crate2.colliderType = ColliderType::crate; crate2.canBePushedBy.insert(ColliderType::player); crate2.canBePushedBy.insert(ColliderType::crate); crate2.canBePushedBy.insert(ColliderType::train); crate2.gridPos = vec2s { 6, 7 }; id_type trainId = emplaceEntity(); Entity& train = getEntity(trainId); train.size = TILE_SIZE; train.speed = static_cast(schedule_.getBPM()) / 30.0; train.colliderType = ColliderType::train; train.scheduled = true; train.colorVal = 90; train.gridPos = vec2s { 6, 1 }; for (id_type id : active_) { Entity& entity = entities_.at(id); posCache_.set(id, entity.gridPos); } } void Simulation::tick( double dt, const Uint8* keystate) { // Control for (id_type id : active_) { Entity& entity = entities_.at(id); if (entity.controllable && !entity.moving) { if (keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]) { Direction lookDir = Direction::none; if (keystate[SDL_SCANCODE_LEFT]) { lookDir = Direction::left; } else if (keystate[SDL_SCANCODE_UP]) { lookDir = Direction::up; } else if (keystate[SDL_SCANCODE_RIGHT]) { lookDir = Direction::right; } else if (keystate[SDL_SCANCODE_DOWN]) { lookDir = Direction::down; } vec2s lookPos = posInDir(entity.gridPos, lookDir); for (id_type blockId : posCache_.at(lookPos)) { Entity& block = entities_.at(blockId); if (!block.moving && block.canBePushedBy.count(ColliderType::player)) { moveEntityOnGrid(blockId, lookDir); } } } else { if (keystate[SDL_SCANCODE_LEFT] && moveEntityOnGrid(id, Direction::left, true)) { entity.shouldMoveTo = Direction::left; } else if (keystate[SDL_SCANCODE_UP] && moveEntityOnGrid(id, Direction::up, true)) { entity.shouldMoveTo = Direction::up; } else if (keystate[SDL_SCANCODE_RIGHT] && moveEntityOnGrid(id, Direction::right, true)) { entity.shouldMoveTo = Direction::right; } else if (keystate[SDL_SCANCODE_DOWN] && moveEntityOnGrid(id, Direction::down, true)) { entity.shouldMoveTo = Direction::down; } else { entity.shouldMoveTo = Direction::none; } if (entity.shouldMoveTo != Direction::none) { moveEntityOnGrid(id, entity.shouldMoveTo); } } } } // Schedule schedule_.accumulate(dt); if (schedule_.step()) { for (id_type id
from dataclasses import dataclass

from Options import PerGameCommonOptions, Toggle


class ShuffleDoors(Toggle):
    """If enabled, most doors will open from receiving an item rather than fulfilling the in-game requirements."""
    display_name = "Shuffle Doors"


@dataclass
class Lingo2Options(PerGameCommonOptions):
    shuffle_doors: ShuffleDoors