817 lines
24 KiB
C++
817 lines
24 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2010 - Frictional Games
|
|
*
|
|
* This file is part of HPL1 Engine.
|
|
*/
|
|
|
|
#include "hpl1/engine/scene/World2D.h"
|
|
|
|
#include "hpl1/engine/graphics/Graphics.h"
|
|
#include "hpl1/engine/graphics/ImageEntityData.h"
|
|
#include "hpl1/engine/graphics/Mesh2d.h"
|
|
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
|
|
#include "hpl1/engine/math/Math.h"
|
|
#include "hpl1/engine/math/MathTypes.h"
|
|
#include "hpl1/engine/physics/Body2D.h"
|
|
#include "hpl1/engine/physics/Collider2D.h"
|
|
#include "hpl1/engine/resources/FileSearcher.h"
|
|
#include "hpl1/engine/resources/ParticleManager.h"
|
|
#include "hpl1/engine/resources/Resources.h"
|
|
#include "hpl1/engine/resources/ScriptManager.h"
|
|
#include "hpl1/engine/resources/TileSetManager.h"
|
|
#include "hpl1/engine/scene/Area2D.h"
|
|
#include "hpl1/engine/scene/Camera.h"
|
|
#include "hpl1/engine/scene/GridMap2D.h"
|
|
#include "hpl1/engine/scene/ImageEntity.h"
|
|
#include "hpl1/engine/scene/Light2DPoint.h"
|
|
#include "hpl1/engine/scene/Node2D.h"
|
|
#include "hpl1/engine/scene/SoundSource.h"
|
|
#include "hpl1/engine/scene/TileMap.h"
|
|
#include "hpl1/engine/system/MemoryManager.h"
|
|
#include "hpl1/engine/system/Script.h"
|
|
#include "hpl1/engine/system/String.h"
|
|
#include "hpl1/engine/system/low_level_system.h"
|
|
|
|
#include "hpl1/engine/graphics/Renderer2D.h"
|
|
|
|
namespace hpl {
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CONSTRUCTORS
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cWorld2D::cWorld2D(tString asName, cGraphics *apGraphics, cResources *apResources, cSound *apSound, cCollider2D *apCollider) {
|
|
mpGraphics = apGraphics;
|
|
mpResources = apResources;
|
|
mpSound = apSound;
|
|
mpCollider = apCollider;
|
|
|
|
mpRootNode = hplNew(cNode2D, ());
|
|
mpMapLights = NULL;
|
|
mpMapImageEntities = NULL;
|
|
mpMapBodies = NULL;
|
|
mpTileMap = NULL;
|
|
|
|
mpScript = NULL;
|
|
|
|
msName = asName;
|
|
|
|
mfLightZ = 10;
|
|
mAmbientColor = cColor(0, 0);
|
|
|
|
mlBodyIDCount = 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cWorld2D::~cWorld2D() {
|
|
if (mpTileMap)
|
|
hplDelete(mpTileMap);
|
|
|
|
if (mpMapLights)
|
|
hplDelete(mpMapLights);
|
|
if (mpMapImageEntities)
|
|
hplDelete(mpMapImageEntities);
|
|
if (mpMapBodies)
|
|
hplDelete(mpMapBodies);
|
|
if (mpMapParticles)
|
|
hplDelete(mpMapParticles);
|
|
if (mpMapAreas)
|
|
hplDelete(mpMapAreas);
|
|
|
|
tSoundSourceListIt it = mlstSoundSources.begin();
|
|
while (it != mlstSoundSources.end()) {
|
|
hplDelete(*it);
|
|
it++;
|
|
}
|
|
mlstSoundSources.clear();
|
|
|
|
if (mpScript) {
|
|
mpResources->GetScriptManager()->Destroy(mpScript);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// PUBLIC METHODS
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::Render(cCamera2D *apCamera) {
|
|
mpTileMap->Render(apCamera);
|
|
RenderImagesEntities(apCamera);
|
|
RenderParticles(apCamera);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::Update(float afTimeStep) {
|
|
UpdateEntities();
|
|
UpdateBodies();
|
|
UpdateParticles();
|
|
UpdateSoundSources();
|
|
UpdateLights();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cLight2DPoint *cWorld2D::CreateLightPoint(tString asName) {
|
|
if (mpMapLights == NULL)
|
|
return NULL;
|
|
|
|
cLight2DPoint *pLight = hplNew(cLight2DPoint, (asName));
|
|
|
|
mpMapLights->AddEntity(pLight);
|
|
|
|
// Add the light to the base node awell...
|
|
|
|
return pLight;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::DestroyLight(iLight2D *apLight) {
|
|
if (mpMapLights == NULL)
|
|
return;
|
|
|
|
mpMapLights->RemoveEntity(apLight);
|
|
hplDelete(apLight);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cGridMap2D *cWorld2D::GetGridMapLights() {
|
|
return mpMapLights;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
iLight2D *cWorld2D::GetLight(const tString &asName) {
|
|
tGrid2DObjectMap *pGridMap = mpMapLights->GetAllMap();
|
|
tGrid2DObjectMapIt it = pGridMap->begin();
|
|
for (; it != pGridMap->end(); it++) {
|
|
cGrid2DObject *pObj = it->second;
|
|
if (pObj->GetEntity()->GetName() == asName) {
|
|
return static_cast<iLight2D *>(pObj->GetEntity());
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cSoundSource *cWorld2D::CreateSoundSource(const tString &asName, const tString &asSoundName,
|
|
bool abVolatile) {
|
|
cSoundSource *pSoundSource = hplNew(cSoundSource, (asName, asSoundName, mpSound, abVolatile));
|
|
mlstSoundSources.push_back(pSoundSource);
|
|
|
|
return pSoundSource;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::DestroySoundSource(cSoundSource *apSound) {
|
|
mlstSoundSources.remove(apSound);
|
|
hplDelete(apSound);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cImageEntity *cWorld2D::CreateImageEntity(tString asName, tString asDataName) {
|
|
cImageEntity *pEntity = hplNew(cImageEntity, (asName, mpResources, mpGraphics));
|
|
|
|
if (pEntity == NULL)
|
|
return NULL;
|
|
|
|
if (pEntity->LoadEntityData(asDataName)) {
|
|
mpMapImageEntities->AddEntity(pEntity);
|
|
} else {
|
|
hplDelete(pEntity);
|
|
}
|
|
|
|
return pEntity;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::DestroyImageEntity(cImageEntity *apEntity) {
|
|
if (mpMapImageEntities == NULL)
|
|
return;
|
|
|
|
mpMapImageEntities->RemoveEntity(apEntity);
|
|
hplDelete(apEntity);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cImageEntity *cWorld2D::GetImageEntity(const tString &asName) {
|
|
tGrid2DObjectMap *pGridMap = mpMapImageEntities->GetAllMap();
|
|
tGrid2DObjectMapIt it = pGridMap->begin();
|
|
for (; it != pGridMap->end(); it++) {
|
|
cGrid2DObject *pObj = it->second;
|
|
if (pObj->GetEntity()->GetName() == asName) {
|
|
return static_cast<cImageEntity *>(pObj->GetEntity());
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
iParticleSystem2D *cWorld2D::CreateParticleSystem(const tString &asName, const cVector3f &avSize) {
|
|
/*iParticleSystem2D* pPS = mpResources->GetParticleManager()->CreatePS2D(asName, avSize);
|
|
if(pPS == NULL){
|
|
Error("Couldn't create particle system '%s'\n",asName.c_str());
|
|
}
|
|
|
|
mpMapParticles->AddEntity(pPS);
|
|
|
|
return pPS;*/
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::DestroyParticleSystem(iParticleSystem2D *apPS) {
|
|
/*if(apPS==NULL)return;
|
|
|
|
mpMapParticles->RemoveEntity(apPS);
|
|
hplDelete(apPS);*/
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cBody2D *cWorld2D::CreateBody2D(const tString &asName, cMesh2D *apMesh, cVector2f avSize) {
|
|
cBody2D *pBody = hplNew(cBody2D, (asName, apMesh, avSize, mpCollider, mlBodyIDCount++));
|
|
|
|
mpMapBodies->AddEntity(pBody);
|
|
|
|
return pBody;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cArea2D *cWorld2D::GetArea(const tString &asName, const tString &asType) {
|
|
tGrid2DObjectMap *GridMap = mpMapAreas->GetAllMap();
|
|
tGrid2DObjectMapIt it = GridMap->begin();
|
|
while (it != GridMap->end()) {
|
|
cArea2D *pArea = static_cast<cArea2D *>(it->second->GetEntity());
|
|
|
|
if (asName == "" || pArea->GetName() == asName) {
|
|
if (asType == "" || pArea->GetType() == asType) {
|
|
return pArea;
|
|
}
|
|
}
|
|
|
|
it++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool cWorld2D::CreateFromFile(tString asFile) {
|
|
|
|
// Load the document
|
|
asFile = cString::SetFileExt(asFile, "hpl");
|
|
tString sPath = mpResources->GetFileSearcher()->GetFilePath(asFile);
|
|
|
|
if (sPath == "") {
|
|
error("Couldn't find map '%s'", asFile.c_str());
|
|
return false;
|
|
}
|
|
|
|
TiXmlDocument *pDoc = hplNew(TiXmlDocument, (sPath.c_str()));
|
|
if (!pDoc->LoadFile()) {
|
|
error("Couldn't load map '%s'", asFile.c_str());
|
|
return false;
|
|
}
|
|
|
|
// Load the script
|
|
asFile = cString::SetFileExt(asFile, "hps");
|
|
mpScript = mpResources->GetScriptManager()->CreateScript(asFile);
|
|
if (mpScript == NULL) {
|
|
Error("Couldn't load script '%s'", asFile.c_str());
|
|
}
|
|
|
|
TiXmlElement *pHplMapElem = pDoc->RootElement();
|
|
|
|
cVector2l vMapSize;
|
|
msMapName = pHplMapElem->Attribute("Name");
|
|
vMapSize.x = cString::ToInt(pHplMapElem->Attribute("Width"), 0);
|
|
vMapSize.y = cString::ToInt(pHplMapElem->Attribute("Height"), 0);
|
|
float fTileSize = (float)cString::ToInt(pHplMapElem->Attribute("TileSize"), 0);
|
|
mfLightZ = cString::ToFloat(pHplMapElem->Attribute("LightZ"), 0);
|
|
mAmbientColor.r = cString::ToFloat(pHplMapElem->Attribute("AmbColR"), 0) / 255.0f;
|
|
mAmbientColor.g = cString::ToFloat(pHplMapElem->Attribute("AmbColG"), 0) / 255.0f;
|
|
mAmbientColor.b = cString::ToFloat(pHplMapElem->Attribute("AmbColB"), 0) / 255.0f;
|
|
mAmbientColor.a = 0;
|
|
// Log("Amb: %f : %f : %f : %f\n",mAmbientColor.r,mAmbientColor.g,mAmbientColor.b,mAmbientColor.a);
|
|
|
|
mpGraphics->GetRenderer2D()->SetAmbientLight(mAmbientColor);
|
|
mpGraphics->GetRenderer2D()->SetShadowZ(mfLightZ);
|
|
|
|
// Set up data for objects.
|
|
cVector2l vWorldSize = vMapSize * (int)fTileSize;
|
|
mvWorldSize = cVector2f((float)vWorldSize.x, (float)vWorldSize.y);
|
|
|
|
mpMapLights = hplNew(cGridMap2D, (vWorldSize, cVector2l(200, 200), cVector2l(5, 5)));
|
|
mpMapImageEntities = hplNew(cGridMap2D, (vWorldSize, cVector2l(150, 150), cVector2l(5, 5)));
|
|
mpMapBodies = hplNew(cGridMap2D, (vWorldSize, cVector2l(150, 150), cVector2l(5, 5)));
|
|
mpMapParticles = hplNew(cGridMap2D, (vWorldSize, cVector2l(300, 300), cVector2l(3, 3)));
|
|
mpMapAreas = hplNew(cGridMap2D, (vWorldSize, cVector2l(300, 300), cVector2l(3, 3)));
|
|
|
|
TiXmlElement *pHplMapChildElem = pHplMapElem->FirstChildElement();
|
|
while (pHplMapChildElem) {
|
|
tString sChildName = pHplMapChildElem->Value();
|
|
|
|
/////////////////
|
|
/// LIGHTS //////
|
|
/////////////////
|
|
if (sChildName == "Lights") {
|
|
TiXmlElement *pLightChildElem = pHplMapChildElem->FirstChildElement();
|
|
while (pLightChildElem) {
|
|
cVector3f vPos;
|
|
cColor Col(0, 1);
|
|
cLight2DPoint *pLight = CreateLightPoint(pLightChildElem->Attribute("Name"));
|
|
vPos.x = cString::ToFloat(pLightChildElem->Attribute("X"), 0);
|
|
vPos.y = cString::ToFloat(pLightChildElem->Attribute("Y"), 0);
|
|
vPos.z = cString::ToFloat(pLightChildElem->Attribute("Z"), 0);
|
|
pLight->SetPosition(vPos);
|
|
Col.r = cString::ToFloat(pLightChildElem->Attribute("ColR"), 0) / 255.0f;
|
|
Col.g = cString::ToFloat(pLightChildElem->Attribute("ColG"), 0) / 255.0f;
|
|
Col.b = cString::ToFloat(pLightChildElem->Attribute("ColB"), 0) / 255.0f;
|
|
Col.a = cString::ToFloat(pLightChildElem->Attribute("Specular"), 1);
|
|
pLight->SetDiffuseColor(Col);
|
|
pLight->SetFarAttenuation(cString::ToFloat(pLightChildElem->Attribute("Radius"), 0));
|
|
pLight->SetActive(cString::ToBool(pLightChildElem->Attribute("Active"), true));
|
|
/*LOad some more stuff*/
|
|
pLight->SetAffectMaterial(cString::ToBool(pLightChildElem->Attribute("AffectMaterial"), true));
|
|
pLight->SetCastShadows(cString::ToBool(pLightChildElem->Attribute("CastShadows"), true));
|
|
|
|
pLightChildElem = pLightChildElem->NextSiblingElement();
|
|
}
|
|
}
|
|
////////////////////////
|
|
/// ENTITIES ///////////
|
|
////////////////////////
|
|
else if (sChildName == "Entities") {
|
|
TiXmlElement *pEntityElem = pHplMapChildElem->FirstChildElement();
|
|
while (pEntityElem) {
|
|
tString sRenderType = cString::ToString(pEntityElem->Attribute("RenderType"), "Image");
|
|
|
|
if (sRenderType == "Image") {
|
|
cImageEntity *pEntity = hplNew(cImageEntity, (cString::ToString(
|
|
pEntityElem->Attribute("Name"), "Image"),
|
|
mpResources, mpGraphics));
|
|
// The the main data
|
|
cVector3f vPos;
|
|
vPos.x = cString::ToFloat(pEntityElem->Attribute("X"), 0);
|
|
vPos.y = cString::ToFloat(pEntityElem->Attribute("Y"), 0);
|
|
vPos.z = cString::ToFloat(pEntityElem->Attribute("Z"), 0);
|
|
pEntity->SetPosition(vPos);
|
|
pEntity->SetActive(cString::ToBool(pEntityElem->Attribute("Active"), true));
|
|
|
|
if (pEntity->LoadData(pEntityElem)) {
|
|
mpMapImageEntities->AddEntity(pEntity);
|
|
|
|
iEntity2DLoader *pLoader = mpResources->GetEntity2DLoader(
|
|
pEntity->GetEntityData()->GetType());
|
|
|
|
if (pLoader) {
|
|
pLoader->Load(pEntity);
|
|
} else {
|
|
/*Maybe delete entity if no type found? */
|
|
}
|
|
} else {
|
|
Error("Couldn't load data for entity '%s'", pEntity->GetName().c_str());
|
|
hplDelete(pEntity);
|
|
}
|
|
} else {
|
|
error("No other Render mode for entity exist!!");
|
|
}
|
|
|
|
pEntityElem = pEntityElem->NextSiblingElement();
|
|
}
|
|
}
|
|
/////////////////////////////
|
|
/// SOUND SOURCES ///////////
|
|
/////////////////////////////
|
|
else if (sChildName == "SoundSources") {
|
|
TiXmlElement *pSoundElem = pHplMapChildElem->FirstChildElement();
|
|
while (pSoundElem) {
|
|
cSoundSource *pSound = hplNew(cSoundSource, (
|
|
cString::ToString(pSoundElem->Attribute("Name"), ""),
|
|
cString::ToString(pSoundElem->Attribute("SoundName"), ""),
|
|
mpSound, false));
|
|
|
|
pSound->LoadData(pSoundElem);
|
|
|
|
mlstSoundSources.push_back(pSound);
|
|
|
|
pSoundElem = pSoundElem->NextSiblingElement();
|
|
}
|
|
}
|
|
/////////////////////////////
|
|
/// PARTICLE SYSTEMS ///////////
|
|
/////////////////////////////
|
|
/*else if(sChildName == "ParticleSystems")
|
|
{
|
|
TiXmlElement* pPartElem = pHplMapChildElem->FirstChildElement();
|
|
while(pPartElem)
|
|
{
|
|
iParticleSystem2D* pPS;
|
|
|
|
tString sName = cString::ToString(pPartElem->Attribute("Name"),"");
|
|
tString sPartName = cString::ToString(pPartElem->Attribute("PartName"),"");
|
|
cVector3f vSize;
|
|
cVector3f vPos;
|
|
vSize.x = cString::ToFloat(pPartElem->Attribute("SizeX"),0);
|
|
vSize.y = cString::ToFloat(pPartElem->Attribute("SizeY"),0);
|
|
vSize.z = cString::ToFloat(pPartElem->Attribute("SizeZ"),0);
|
|
|
|
vPos.x = cString::ToFloat(pPartElem->Attribute("X"),0);
|
|
vPos.y = cString::ToFloat(pPartElem->Attribute("Y"),0);
|
|
vPos.z = cString::ToFloat(pPartElem->Attribute("Z"),0);
|
|
|
|
pPS = mpResources->GetParticleManager()->CreatePS2D(sPartName,vSize);
|
|
|
|
if(pPS==NULL){
|
|
Error("Couldn't load particle system '%s'!\n",sPartName.c_str());
|
|
}
|
|
else {
|
|
pPS->SetName(sName);
|
|
pPS->SetPosition(vPos);
|
|
|
|
mpMapParticles->AddEntity(pPS);
|
|
}
|
|
|
|
pPartElem = pPartElem->NextSiblingElement();
|
|
}
|
|
}*/
|
|
/////////////////////////////
|
|
/// AREAS ///////////////////
|
|
/////////////////////////////
|
|
else if (sChildName == "Areas") {
|
|
TiXmlElement *pAreaElem = pHplMapChildElem->FirstChildElement();
|
|
while (pAreaElem) {
|
|
cArea2D *pArea;
|
|
|
|
tString sName = cString::ToString(pAreaElem->Attribute("Name"), "");
|
|
tString sAreaType = cString::ToString(pAreaElem->Attribute("AreaType"), "");
|
|
cVector3f vPos;
|
|
|
|
vPos.x = cString::ToFloat(pAreaElem->Attribute("X"), 0);
|
|
vPos.y = cString::ToFloat(pAreaElem->Attribute("Y"), 0);
|
|
vPos.z = cString::ToFloat(pAreaElem->Attribute("Z"), 0);
|
|
|
|
pArea = hplNew(cArea2D, (sName, sAreaType, mpCollider));
|
|
|
|
pArea->LoadData(pAreaElem);
|
|
|
|
pArea->SetName(sName);
|
|
pArea->SetPosition(vPos);
|
|
|
|
if (pArea->GetType() != "Script") {
|
|
iArea2DLoader *pAreaLoader = mpResources->GetArea2DLoader(pArea->GetType());
|
|
if (pAreaLoader) {
|
|
pAreaLoader->Load(pArea);
|
|
}
|
|
}
|
|
|
|
mpMapAreas->AddEntity(pArea);
|
|
|
|
pAreaElem = pAreaElem->NextSiblingElement();
|
|
}
|
|
}
|
|
/////////////////
|
|
/// TILEMAP /////
|
|
/////////////////
|
|
else if (sChildName == "TileMap") {
|
|
mpTileMap = hplNew(cTileMap, (vMapSize, fTileSize, mpGraphics, mpResources));
|
|
int lShadowLayer = cString::ToInt(pHplMapChildElem->Attribute("ShadowLayer"), 0);
|
|
|
|
TiXmlElement *pTileMapChildElem = pHplMapChildElem->FirstChildElement();
|
|
while (pTileMapChildElem) {
|
|
tString sTileMapChildName = pTileMapChildElem->Value();
|
|
|
|
// Log("Tilemap: %s\n",sTileMapChildName.c_str());
|
|
////////////////////////
|
|
/// TILE SETS //////////
|
|
////////////////////////
|
|
|
|
if (sTileMapChildName == "TileSets") {
|
|
TiXmlElement *pTileSetChildElem = pTileMapChildElem->FirstChildElement();
|
|
while (pTileSetChildElem) {
|
|
tString sName = pTileSetChildElem->Attribute("Name");
|
|
|
|
cTileSet *pTileSet = mpResources->GetTileSetManager()->CreateTileSet(sName);
|
|
mpTileMap->AddTileSet(pTileSet);
|
|
|
|
pTileSetChildElem = pTileSetChildElem->NextSiblingElement();
|
|
}
|
|
}
|
|
////////////////////////
|
|
/// TILE LAYERS ////////
|
|
///////////////////////
|
|
else if (sTileMapChildName == "Layers") {
|
|
// Log("Layers\n");
|
|
TiXmlElement *pLayerChildElem = pTileMapChildElem->FirstChildElement();
|
|
while (pLayerChildElem) {
|
|
// Log("Layer Children\n");
|
|
|
|
if (pLayerChildElem->Attribute("Width") == NULL)
|
|
error("Can't Load Width");
|
|
int lW = cString::ToInt(pLayerChildElem->Attribute("Width"), 0);
|
|
|
|
if (pLayerChildElem->Attribute("Height") == NULL)
|
|
error("Can't Load Height");
|
|
int lH = cString::ToInt(pLayerChildElem->Attribute("Height"), 0);
|
|
bool bCollide = cString::ToBool(pLayerChildElem->Attribute("Collide"), true);
|
|
bool bLit = cString::ToBool(pLayerChildElem->Attribute("Lit"), true);
|
|
float fZ = cString::ToFloat(pLayerChildElem->Attribute("Z"), 0);
|
|
|
|
cTileLayer *pTileLayer = hplNew(cTileLayer, (lW, lH,
|
|
bCollide, bLit, eTileLayerType_Normal));
|
|
pTileLayer->SetZ(fZ);
|
|
|
|
mpTileMap->AddTileLayerFront(pTileLayer);
|
|
|
|
//// THE TILES ////////
|
|
TiXmlElement *pTileRowElem = pLayerChildElem->FirstChildElement();
|
|
|
|
int lRowCount = 0;
|
|
while (pTileRowElem) {
|
|
// Log("Tile Row: ");
|
|
int lColCount = 0;
|
|
tString sData = pTileRowElem->Attribute("Data");
|
|
int lDataCount = 0;
|
|
while (lDataCount < (int)sData.size()) {
|
|
cTile *pTile = hplNew(cTile, (NULL, eTileRotation_0,
|
|
cVector3f((float)lColCount * fTileSize, (float)lRowCount * fTileSize, fZ),
|
|
cVector2f(fTileSize, fTileSize), NULL));
|
|
|
|
lDataCount = LoadTileData(pTile, &sData, lDataCount);
|
|
|
|
if (pTile->GetTileData()) {
|
|
|
|
// Create the collision mesh
|
|
if (pTileLayer->HasCollision()) {
|
|
cCollisionMesh2D *pCollMesh = NULL;
|
|
cTileDataNormal *pTData;
|
|
pTData = static_cast<cTileDataNormal *>(pTile->GetTileData());
|
|
|
|
if (pTData->GetCollideMesh()) {
|
|
pCollMesh = pTData->GetCollideMesh()->CreateCollisonMesh(
|
|
cVector2f(pTile->GetPosition().x,
|
|
pTile->GetPosition().y),
|
|
cVector2f(2),
|
|
pTile->GetAngle());
|
|
}
|
|
|
|
pTile->SetCollisionMesh(pCollMesh);
|
|
}
|
|
|
|
// Add tile to the layer
|
|
pTileLayer->SetTile(lColCount, lRowCount, pTile);
|
|
} else {
|
|
hplDelete(pTile);
|
|
}
|
|
|
|
lColCount++;
|
|
}
|
|
// Log("\n");
|
|
|
|
lRowCount++;
|
|
pTileRowElem = pTileRowElem->NextSiblingElement();
|
|
}
|
|
|
|
pLayerChildElem = pLayerChildElem->NextSiblingElement();
|
|
}
|
|
}
|
|
pTileMapChildElem = pTileMapChildElem->NextSiblingElement();
|
|
}
|
|
|
|
// Set the inverse shadow layer.
|
|
mpTileMap->SetShadowLayer(mpTileMap->GetTileLayerNum() - lShadowLayer - 1);
|
|
}
|
|
|
|
pHplMapChildElem = pHplMapChildElem->NextSiblingElement();
|
|
}
|
|
|
|
hplDelete(pDoc);
|
|
|
|
return true;
|
|
}
|
|
//-----------------------------------------------------------------------
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// PRIVATE METHODS
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::UpdateSoundSources() {
|
|
tSoundSourceListIt it = mlstSoundSources.begin();
|
|
while (it != mlstSoundSources.end()) {
|
|
(*it)->UpdateLogic(0);
|
|
|
|
if ((*it)->IsDead()) {
|
|
it = mlstSoundSources.erase(it);
|
|
} else {
|
|
it++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::UpdateParticles() {
|
|
/*tGrid2DObjectMapIt it = mpMapParticles->GetAllMap()->begin();
|
|
|
|
while(it != mpMapParticles->GetAllMap()->end())
|
|
{
|
|
iParticleSystem2D *pEntity = static_cast<iParticleSystem2D*>(it->second->GetEntity());
|
|
|
|
pEntity->UpdateLogic(0);
|
|
|
|
it++;
|
|
|
|
//Check if the system is alive, else destroy
|
|
if(pEntity->IsDead()){
|
|
DestroyParticleSystem(pEntity);
|
|
}
|
|
}*/
|
|
}
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::RenderParticles(cCamera2D *apCamera) {
|
|
/*cRect2f ClipRect;
|
|
apCamera->GetClipRect(ClipRect);
|
|
|
|
iGridMap2DIt* pEntityIt = mpMapParticles->GetRectIterator(ClipRect);
|
|
|
|
while(pEntityIt->HasNext())
|
|
{
|
|
iParticleSystem2D* pEntity = static_cast<iParticleSystem2D*>(pEntityIt->Next());
|
|
|
|
pEntity->Render();
|
|
}
|
|
|
|
|
|
hplDelete(pEntityIt);*/
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::UpdateEntities() {
|
|
tGrid2DObjectMapIt it = mpMapImageEntities->GetAllMap()->begin();
|
|
|
|
while (it != mpMapImageEntities->GetAllMap()->end()) {
|
|
iEntity2D *pEntity = static_cast<cImageEntity *>(it->second->GetEntity());
|
|
|
|
if (pEntity->IsActive())
|
|
pEntity->UpdateLogic(0);
|
|
|
|
it++;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::UpdateBodies() {
|
|
tGrid2DObjectMapIt it = mpMapBodies->GetAllMap()->begin();
|
|
|
|
while (it != mpMapBodies->GetAllMap()->end()) {
|
|
cBody2D *pBody = static_cast<cBody2D *>(it->second->GetEntity());
|
|
|
|
if (pBody->IsActive())
|
|
pBody->UpdateLogic(0);
|
|
|
|
it++;
|
|
}
|
|
}
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::UpdateLights() {
|
|
tGrid2DObjectMapIt it = mpMapLights->GetAllMap()->begin();
|
|
|
|
while (it != mpMapLights->GetAllMap()->end()) {
|
|
iLight2D *pLight = static_cast<iLight2D *>(it->second->GetEntity());
|
|
|
|
if (pLight->IsActive())
|
|
pLight->UpdateLogic(0);
|
|
|
|
it++;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cWorld2D::RenderImagesEntities(cCamera2D *apCamera) {
|
|
cRect2f ClipRect;
|
|
apCamera->GetClipRect(ClipRect);
|
|
|
|
iGridMap2DIt *pEntityIt = mpMapImageEntities->GetRectIterator(ClipRect);
|
|
|
|
while (pEntityIt->HasNext()) {
|
|
cImageEntity *pEntity = static_cast<cImageEntity *>(pEntityIt->Next());
|
|
|
|
if (pEntity->IsActive()) {
|
|
pEntity->Render();
|
|
}
|
|
}
|
|
|
|
hplDelete(pEntityIt);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
int cWorld2D::LoadTileData(cTile *apTile, tString *asData, int alStart) {
|
|
int lCount = alStart;
|
|
int lStart = lCount;
|
|
int lValType = 0;
|
|
int lSet = 0;
|
|
int lNum;
|
|
|
|
while (true) {
|
|
if (asData->c_str()[lCount] == ':' || asData->c_str()[lCount] == '|') {
|
|
if (lStart != lCount) {
|
|
tString sVal = asData->substr(lStart, lCount - lStart);
|
|
int lVal = cString::ToInt(sVal.c_str(), -1);
|
|
|
|
cTileSet *pSet = NULL;
|
|
cTileDataNormal *pData = NULL;
|
|
switch (lValType) {
|
|
case 0:
|
|
lSet = lVal;
|
|
break;
|
|
case 1:
|
|
lNum = lVal;
|
|
if (lSet < 0)
|
|
break;
|
|
if (lNum < 0)
|
|
break;
|
|
|
|
pSet = mpTileMap->GetTileSet(lSet);
|
|
if (pSet == NULL)
|
|
error("Error getting tileset%d", lSet);
|
|
pData = static_cast<cTileDataNormal *>(pSet->Get(lNum));
|
|
|
|
apTile->SetTileData(pData);
|
|
|
|
break;
|
|
case 2:
|
|
apTile->SetAngle((eTileRotation)lVal);
|
|
break;
|
|
case 3:
|
|
apTile->SetFlags(eTileFlag_Breakable);
|
|
}
|
|
lValType++;
|
|
}
|
|
|
|
if (asData->c_str()[lCount] == '|') {
|
|
/*if(apTile->GetTileData())
|
|
Log("%d,%d,%d|",lSet,lNum,apTile->GetAngle());
|
|
else
|
|
Log("N|");*/
|
|
break;
|
|
}
|
|
lStart = lCount + 1;
|
|
}
|
|
|
|
lCount++;
|
|
}
|
|
|
|
return lCount + 1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
} // namespace hpl
|