1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-26 02:03:48 +00:00
Aquaria/Aquaria/Game.h

551 lines
14 KiB
C++

/*
Copyright (C) 2007, 2010 - Bit-Blot
This file is part of Aquaria.
Aquaria is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef GAME_H
#define GAME_H
#include "../BBGE/DebugFont.h"
#include "DSQ.h"
#include "AquariaMenuItem.h"
#include "ScriptedEntity.h"
#include "TileVector.h"
#include "SceneEditor.h"
#include "TileMgr.h"
#include <tinyxml2.h>
using namespace tinyxml2;
class Avatar;
class Gradient;
class CurrentRender;
class SteamRender;
class SongLineRender;
class AutoMap;
class DebugButton;
class WorldMapRender;
class Shot;
class InGameMenu;
// FIXME: this should be made dynamic, or at least a power of 2
const int MAX_GRID = 2222;
const char CHAR_DOWN = 'd';
const char CHAR_UP = 'u';
const char CHAR_LEFT = 'l';
const char CHAR_RIGHT = 'r';
const float MIN_SIZE = 0.1f;
class GridRender;
class MiniMapRender;
class WaterSurfaceRender;
class ToolTip;
class Ingredient;
class ManaBall;
class Beam;
#include "Path.h"
// impl is in Minimap.cpp
struct MinimapIcon
{
MinimapIcon();
bool setTexture(std::string);
void update(float dt);
CountedPtr<Texture> tex;
InterpolatedVector color, alpha, size;
float throbMult;
bool scaleWithDistance;
static const Vector defaultSize;
};
typedef std::list<Ingredient*> Ingredients;
class ObsRow
{
public:
inline ObsRow(unsigned tx, unsigned ty, unsigned len)
: tx(tx), ty(ty), len(len) {}
inline ObsRow(const ObsRow& o)
: tx(o.tx), ty(o.ty), len(o.len) {}
const unsigned tx, ty, len;
};
enum FlagCheckType
{
NO_TYPE =-1,
AND =0,
OR =1
};
class EntityClass
{
public:
EntityClass(std::string name, bool script=false, int idx=-1, std::string prevGfx="", float prevScale=1)
: name(name), prevScale(prevScale), prevGfx(prevGfx), script(script), idx(idx) {}
std::string name;
float prevScale;
std::string prevGfx;
bool script;
int idx;
};
struct EntitySaveData
{
public:
EntitySaveData() : id(0), x(0), y(0), rot(0), idx(0) {}
EntitySaveData(int id, int x, int y, int rot, int idx, const std::string &name) : name(name), id(id), x(x), y(y), rot(rot), idx(idx) {}
std::string name;
int id, x, y, rot, idx;
};
class Game : public StateObject
{
public:
Game();
~Game();
void applyState();
void removeState();
void update(float dt);
Avatar *avatar;
Entity *li;
ObsType getGrid(const TileVector &tile) const;
ObsType getGridRaw(const TileVector &tile) const;
unsigned char *getGridColumn(int tileX);
void setGrid(const TileVector &tile, ObsType v);
void addGrid(const TileVector &tile, ObsType v);
bool isObstructed(const TileVector &tile, int t = OT_BLOCKING) const;
bool isObstructedRaw(const TileVector &tile, int t) const;
void trimGrid();
void dilateGrid(unsigned int radius, ObsType test, ObsType set, ObsType allowOverwrite);
void transitionToScene(std::string scene);
bool loadScene(std::string scene);
void clearGrid(int v = 0);
void clearDynamicGrid(unsigned char maskbyte = OT_MASK_BLACK);
void toggleWorldMap();
void action(int id, int state, int source, InputDevice device);
InGameMenu *getInGameMenu() { return themenu; }
// pass usedIdx == NULL to preload all textures from tileset
// pass usedIdx != NULL to preload only textures where usedIdx[i] != 0
void updateParticlePause();
void reconstructGrid(bool force=false);
void reconstructEntityGrid();
void registerSporeDrop(const Vector &pos, int t);
bool collideCircleWithGrid(const Vector& position, float r);
bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, float radius, float perc=0, int *colSegment=0);
bool collideCircleVsCircle(Entity *a, Entity *b);
Bone *collideSkeletalVsCircle(Entity *skeletal, CollideQuad *circle);
Bone *collideSkeletalVsLine(Entity *skeletal, Vector start, Vector end, float radius);
bool collideCircleVsLine(CollideQuad *r, Vector start, Vector end, float radius);
bool collideCircleVsLineAngle(CollideQuad *r, float angle, float startLen, float endLen, float radius, Vector basePos);
Bone *collideSkeletalVsCircle(Entity *skeletal, Vector pos, float radius);
void handleShotCollisions(Entity *e, bool hasShield=false);
void handleShotCollisionsSkeletal(Entity *e);
void handleShotCollisionsHair(Entity *e, int num = 0, float perc = 0);
std::string sceneName, sceneDisplayName;
bool saveScene(std::string scene);
void postInitEntities();
EntityClass *getEntityClassForEntityType(const std::string &type);
InterpolatedVector sceneColor, sceneColor2, sceneColor3;
Vector getCameraPositionFor(const Vector &vec);
bool isActive();
bool isPaused();
void togglePause(bool v);
Ingredient* spawnIngredient(const std::string &ing, const Vector &pos, int times=1, int out=0);
void spawnIngredientFromEntity(Entity *ent, IngredientData *data);
Ingredient *getNearestIngredient(const Vector &pos, float radius);
Entity *getNearestEntity(const Vector &pos, float radius, Entity *ignore = 0, EntityType et=ET_NOTYPE, DamageType dt=DT_NONE, int lrStart=-1, int lrEnd=-1);
Script *cookingScript;
void spawnManaBall(Vector pos, float a);
bool updateMusic();
std::string overrideMusic;
void resetFromTitle();
float maxLookDistance;
XMLDocument *saveFile;
Vector positionToAvatar;
Vector getWallNormal(Vector pos, int sampleArea = 5, int obs = -1);
EntitySaveData *getEntitySaveDataForEntity(Entity *e);
Entity *createEntityOnMap(const EntitySaveData& sav); // when loading from save (saved to map). Caller must postInit().
Entity *createEntityOnMap(const char *type, Vector pos); // when spawning in the editor (saved to map). Caller must postInit().
Entity *createEntityTemp(const char *type, Vector pos, bool doPostInit); // when spawning via script (not saved to map). Never does postInit() if we're currently loading a map.
void establishEntity(Entity *e, int id, Vector startPos);
Entity *getEntityByID(int id) const;
int findUnusedEntityID(bool temporary) const; // pass temporary=true for script-spawned entities, false for entities that are spawned on the map
void setCameraFollow(RenderObject *r);
void setCameraFollowEntity(Entity *e);
bool removeEntityAtCursor();
void toggleOverrideZoom(bool on);
bool useWaterLevel;
InterpolatedVector waterLevel;
int saveWaterLevel;
void warpCameraTo(RenderObject *r);
void addObsRow(unsigned tx, unsigned ty, unsigned len);
void clearObsRows();
Entity *getEntityAtCursor();
Vector cameraMin, cameraMax;
bool removeEntity(Entity *e);
void removeIngredient(Ingredient *i);
void bindIngredients();
protected:
std::vector<Path*> paths;
Path *firstPathOfType[PATH_MAX];
public:
void addPath(Path *p);
void removePath(size_t idx);
void clearPaths();
size_t getNumPaths() const {return paths.size();}
Path *getPath(size_t idx) const {return idx < paths.size() ? paths[idx] : NULL;}
Path *getFirstPathOfType(PathType type) const {return firstPathOfType[type];}
Path *getPathByName(std::string name);
size_t getIndexOfPath(Path *p);
Path *getPathAtCursor();
Path *getScriptedPathAtCursor(bool withAct=false);
Path *getNearestPath(const Vector &pos, const std::string &name="", const Path *ignore=0);
Path *getNearestPath(const Vector &pos, PathType pathType=PATH_NONE);
Path *getNearestPath(Path *p, std::string name);
Path *getWaterbubbleAt(const Vector& pos, float rad = 0) const;
UnderWaterResult isUnderWater(const Vector& pos, float rad = 0) const;
SceneEditor sceneEditor;
bool isSceneEditorActive() {return sceneEditor.isOn();}
bool isInGameMenu();
typedef std::vector<EntityClass> EntityTypeList;
EntityTypeList entityTypeList;
void loadEntityTypeList();
std::vector<EntitySaveData> entitySaveData;
int getIdxForEntityType(std::string type);
void setCameraFollow(Vector *position);
Shot *fireShot(const std::string &bankShot, Entity *firer, Entity *target=0, const Vector &pos=Vector(0,0,0), const Vector &aim=Vector(0,0,0), bool playSfx=true);
void playBurstSound(bool wallJump=false);
void toggleMiniMapRender();
void toggleMiniMapRender(int v);
bool runGameOverScript;
void setTimerTextAlpha(float a, float t);
void setTimerText(float time);
void generateCollisionMask(Bone *q, float overrideCollideRadius=0);
std::string fromScene, toNode;
int toFlip;
char fromWarpType;
void warpToSceneFromNode(Path *p);
Vector fromPosition;
PauseQuad *damageSprite;
void toggleDamageSprite(bool on);
ObsType lastCollideTileType;
void fillGrid(const GridFiller& gf);
void fillGridFromQuad(Quad *q, ObsType ot=OT_INVISIBLEIN, bool trim=true);
bool isDamageTypeAvatar(DamageType dt);
bool isDamageTypeEnemy(DamageType dt);
bool isEntityCollideWithShot(Entity *e, Shot *shot);
void setControlHint(const std::string &hint, bool left, bool right, bool middle, float time, std::string image="", bool ignoreClear=false, int songType=0, float scale=1);
void clearControlHint();
bool trace(Vector start, Vector target);
BitmapText *timerText;
float cameraLerpDelay;
Vector gradTop, gradBtm;
bool isValidTarget(Entity *e, Entity *me);
Gradient *grad;
std::string bgSfxLoop, airSfxLoop;
void constrainCamera();
void setElementLayerVisible(int bgLayer, bool v);
bool isElementLayerVisible(int bgLayer);
bool isControlHint();
int getNumberOfEntitiesNamed(const std::string &name);
MiniMapRender *miniMapRender;
WorldMapRender *worldMapRender;
bool loadingScene;
bool doScreenTrans;
bool noSceneTransitionFadeout;
bool fullTilesetReload;
WaterSurfaceRender *waterSurfaceRender;
EntityGroups entityGroups;
std::string getNoteName(int n, const std::string &pre="");
InterpolatedVector cameraInterp;
float getWaterLevel();
void setMusicToPlay(const std::string &musicToPlay);
Vector lastCollidePosition;
void switchBgLoop(int v);
CurrentRender *currentRender;
SteamRender *steamRender;
SongLineRender *songLineRender;
void showImage(const std::string &image);
void hideImage();
bool bNatural;
std::string sceneToLoad;
void snapCam();
void updateBgSfxLoop();
void preLocalWarp(LocalWarpType localWarpType);
void postLocalWarp();
void entityDied(Entity *e);
bool isShuttingDownGameState() { return shuttingDownGameState; }
void warpToSceneNode(std::string scene, std::string node);
void ensureLimit(Entity *e, int num, int state=0);
float getTimer(float mod=1);
float getHalfTimer(float mod=1);
std::string bgSfxLoopPlaying2;
void createInGameMenu();
Entity *currentPet;
Entity* setActivePet(int flag);
void spawnAllIngredients(const Vector &position);
void createGradient();
std::string saveMusic;
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt, *gridRenderUser1, *gridRenderUser2;
void toggleGridRender();
bool invinciblity;
bool isApplyingState() { return applyingState; }
bool activation;
void overrideZoom(float z, float t=1);
void learnedRecipe(Recipe *r, bool effects=true);
bool firstSchoolFish;
bool invincibleOnNested;
bool hasPlayedLow;
void pickupIngredientEffects(IngredientData *data);
void bindInput();
bool cameraOffBounds;
void toggleHelpScreen();
void setWorldPaused(bool b) { worldPaused = b; }
bool isWorldPaused() const { return worldPaused; }
void setIgnoreAction(AquariaActions ac, bool ignore);
bool isIgnoreAction(AquariaActions ac) const;
void onContinuityReset();
protected:
unsigned highestLoadedEntityID;
void toggleHelpScreen(bool on, const std::string &label="");
void onToggleHelpScreen();
void onHelpUp();
void onHelpDown();
bool helpWasPaused;
PauseQuad *helpBG, *helpBG2;
AquariaMenuItem *helpUp, *helpDown, *helpCancel;
TTFText *helpText;
bool inHelpScreen;
float ingOffY;
float ingOffYTimer;
std::vector<RenderObject*> controlHintNotes;
bool active;
bool applyingState;
int lastBgSfxLoop;
float timer, halfTimer;
void warpPrep();
bool shuttingDownGameState;
Quad *image;
float controlHintTimer;
bool cameraConstrained;
void updateCursor(float dt);
Quad *controlHint_mouseLeft, *controlHint_mouseRight, *controlHint_mouseBody, *controlHint_mouseMiddle, *controlHint_image;
Quad *controlHint_shine;
PauseQuad *controlHint_bg;
bool controlHint_ignoreClear;
BitmapText *controlHint_text;
void createLi();
void createPets();
void findMaxCameraValues();
std::vector<ObsRow> obsRows;
std::string musicToPlay;
float deathTimer;
void onPressEscape(int source, InputDevice device);
bool paused;
bool worldPaused;
Vector getClosestPointOnTriangle(Vector a, Vector b, Vector c, Vector p);
Vector getClosestPointOnLine(Vector a, Vector b, Vector p);
Vector *cameraFollow;
RenderObject *cameraFollowObject;
Entity *cameraFollowEntity;
bool loadSceneXML(std::string scene);
void spawnEntities(const EntitySaveData *sav, size_t n);
void toggleSceneEditor();
void warpCameraTo(Vector position);
std::vector<int> ignoredActions;
private:
Ingredients ingredients;
InGameMenu *themenu;
static unsigned char grid[MAX_GRID][MAX_GRID];
};
extern Game *game;
// INLINE FUNCTIONS
inline
ObsType Game::getGridRaw(const TileVector &tile) const
{
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
? ObsType(grid[tile.x][tile.y])
: OT_OUTOFBOUNDS;
}
inline
ObsType Game::getGrid(const TileVector &tile) const
{
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
? ObsType(grid[tile.x][tile.y] & OT_BLOCKING)
: OT_INVISIBLE;
}
inline
unsigned char *Game::getGridColumn(int tileX)
{
if (tileX < 0)
return grid[0];
else if (tileX >= MAX_GRID)
return grid[MAX_GRID-1];
else
return grid[tileX];
}
inline
void Game::setGrid(const TileVector &tile, ObsType v)
{
if (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
grid[tile.x][tile.y] = v;
}
inline
void Game::addGrid(const TileVector &tile, ObsType v)
{
if (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
grid[tile.x][tile.y] |= v;
}
inline
bool Game::isObstructed(const TileVector &tile, int t /* = OT_BLOCKING */) const
{
return (getGrid(tile) & t);
}
inline
bool Game::isObstructedRaw(const TileVector &tile, int t) const
{
return (getGridRaw(tile) & t);
}
#endif