// Copyright (c) 2014 Alex Diener. All rights reserved. #ifndef __LevelModel_H__ #define __LevelModel_H__ #ifdef __cplusplus extern "C" { #endif typedef struct LevelModel LevelModel; #include "stemobject/StemObject.h" #include "gamemath/FixedPoint.h" #include "gamemath/Vector2i.h" #include "watertowerclassic/PlayerModel.h" #include "watertowerclassic/SharedDefinitions.h" #define LEVEL_BLOCK_COUNT_X 32 #define LEVEL_BLOCK_COUNT_Y 30 #define LEVEL_BLOCK_SIZE 16 #define LEVEL_POWERUP_COUNT_MAX 40 #define SWITCH_ID_COUNT_MAX 12 #define WATER_LEVEL_MAX 480.0f enum LevelBlockType { BLOCK_TYPE_EMPTY, BLOCK_TYPE_STONE, BLOCK_TYPE_DRY_SOLID, BLOCK_TYPE_WET_SOLID, BLOCK_TYPE_CRUMBLE, BLOCK_TYPE_SWITCHABLE, BLOCK_TYPE_DEATH, BLOCK_TYPE_MOVING, BLOCK_TYPE_FLOATING, BLOCK_TYPE_PHASING, BLOCK_TYPE_LOCK, BLOCK_TYPE_LADDER, BLOCK_TYPE_LEVER, BLOCK_TYPE_PUSHABLE, BLOCK_TYPE_TRAMPOLINE, BLOCK_TYPE_TELEPORT, BLOCK_TYPE_FIRE, BLOCK_TYPE_ICE, BLOCK_TYPE_SAND, BLOCK_TYPE_STICKY, BLOCK_TYPE_FALLING }; enum LevelPowerupType { POWERUP_TYPE_KEY = 1, POWERUP_TYPE_HEART, POWERUP_TYPE_GEM }; struct LevelBlock { enum LevelBlockType type; union { struct { unsigned int switchIDs[SWITCH_ID_COUNT_MAX]; bool on; } switchable; struct { direction4 direction; fixed16_16 speed; Vector2f position; } moving; struct { unsigned int initialDelay; unsigned int onPeriod; unsigned int offPeriod; bool initiallyOn; } phasing; struct { unsigned int id; } lever; struct { unsigned int id; } teleport; struct { fixed8_8 yVelocity; Vector2f position; } pushable; struct { bool isUnsteady; unsigned int framesUntilFalling; bool isFalling; fixed8_8 yVelocity; Vector2f position; } falling; } properties; Vector2i tilePosition; char alreadyCarried; bool markedForRemoval; }; struct LevelPowerup { enum LevelPowerupType type; Vector2i tilePosition; }; #define LevelModel_structContents(self_type) \ StemObject_structContents(self_type) \ \ Vector2i playerStartPosition; \ struct LevelBlock blocks[LEVEL_BLOCK_COUNT_X * LEVEL_BLOCK_COUNT_Y]; \ unsigned int powerupCount; \ struct LevelPowerup powerups[LEVEL_POWERUP_COUNT_MAX]; \ float waterLevel; \ float waterSpeed; \ unsigned int pointsToUnlockNextLevel; \ int lastBlockWaterLevel; stemobject_struct_definition(LevelModel) LevelModel * LevelModel_create(); LevelModel * LevelModel_copy(LevelModel * self); bool LevelModel_init(LevelModel * self); bool LevelModel_initCopy(LevelModel * self, LevelModel * copy); void LevelModel_dispose(LevelModel * self); void LevelModel_update(LevelModel * self, PlayerModel * playerModel, unsigned int frameIndex); void LevelModel_switchBlocks(LevelModel * self, unsigned int id); unsigned int LevelModel_getPowerupByLocation(LevelModel * self, int tileX, int tileY); void LevelModel_removePowerupAtIndex(LevelModel * self, unsigned int powerupIndex); blockRef * LevelModel_getBlockRefsOccupyingTilePosition(LevelModel * self, unsigned int tileX, unsigned int tileY); unsigned int getPowerupPointValue(enum LevelPowerupType type); #ifdef __cplusplus } #endif #endif