📄 featurehandler.cpp
字号:
#include "StdAfx.h"
#include "FeatureHandler.h"
#include "Feature.h"
#include "QuadField.h"
#include "FileSystem/FileHandler.h"
#include "Game/Camera.h"
#include "Game/Game.h"
#include "LoadSaveInterface.h"
#include "LogOutput.h"
#include "LosHandler.h"
#include "Lua/LuaCallInHandler.h"
#include "Lua/LuaParser.h"
#include "Lua/LuaRules.h"
#include "Map/Ground.h"
#include "myMath.h"
#include "Rendering/Env/BaseTreeDrawer.h"
#include "Rendering/Env/BaseWater.h"
#include "Rendering/FartextureHandler.h"
#include "Rendering/GL/myGL.h"
#include "Rendering/GL/VertexArray.h"
#include "Rendering/ShadowHandler.h"
#include "Rendering/UnitModels/3DOParser.h"
#include "Rendering/UnitModels/UnitDrawer.h"
#include "Sim/Units/UnitHandler.h"
#include "System/TimeProfiler.h"
#include <GL/glu.h> // after myGL.h
#include "mmgr.h"
#include "creg/STL_List.h"
#include "creg/STL_Set.h"
using namespace std;
CFeatureHandler* featureHandler = NULL;
/******************************************************************************/
CR_BIND(FeatureDef, );
CR_REG_METADATA(FeatureDef, (
CR_MEMBER(myName),
CR_MEMBER(description),
CR_MEMBER(metal),
CR_MEMBER(id),
CR_MEMBER(energy),
CR_MEMBER(maxHealth),
CR_MEMBER(reclaimTime),
CR_MEMBER(mass),
CR_MEMBER(upright),
CR_MEMBER(drawType),
//CR_MEMBER(model), FIXME
CR_MEMBER(modelname),
CR_MEMBER(modelType),
CR_MEMBER(destructable),
CR_MEMBER(blocking),
CR_MEMBER(burnable),
CR_MEMBER(floating),
CR_MEMBER(geoThermal),
CR_MEMBER(deathFeature),
CR_MEMBER(xsize),
CR_MEMBER(ysize)
));
CR_BIND_DERIVED(CFeatureHandler,CObject, );
CR_REG_METADATA(CFeatureHandler, (
// CR_MEMBER(featureDefs),
// CR_MEMBER(featureDefsVector),
CR_MEMBER(nextFreeID),
CR_MEMBER(freeIDs),
CR_MEMBER(toBeFreedIDs),
CR_MEMBER(activeFeatures),
CR_MEMBER(toBeRemoved),
CR_MEMBER(updateFeatures),
// CR_MEMBER(drawQuads),
// CR_MEMBER(drawQuadsX),
// CR_MEMBER(drawQuadsY),
CR_RESERVED(128),
CR_SERIALIZER(Serialize),
CR_POSTLOAD(PostLoad)
));
CR_BIND(CFeatureHandler::DrawQuad, );
CR_REG_METADATA_SUB(CFeatureHandler,DrawQuad,(
CR_MEMBER(features)
));
/******************************************************************************/
CFeatureHandler::CFeatureHandler() : nextFreeID(0)
{
PrintLoadMsg("Loading feature definitions");
drawQuadsX = gs->mapx/DRAW_QUAD_SIZE;
drawQuadsY = gs->mapy/DRAW_QUAD_SIZE;
drawQuads.resize(drawQuadsX * drawQuadsY);
treeDrawer = CBaseTreeDrawer::GetTreeDrawer();
const LuaTable rootTable = game->defsParser->GetRoot().SubTable("FeatureDefs");
if (!rootTable.IsValid()) {
throw content_error("Error loading FeatureDefs");
}
// get most of the feature defs (missing trees and geovent from the map)
vector<string> keys;
rootTable.GetKeys(keys);
for (int i = 0; i < (int)keys.size(); i++) {
const string& name = keys[i];
const LuaTable fdTable = rootTable.SubTable(name);
CreateFeatureDef(fdTable, name);
}
}
CFeatureHandler::~CFeatureHandler()
{
for(CFeatureSet::iterator fi=activeFeatures.begin(); fi != activeFeatures.end(); ++fi)
delete *fi;
activeFeatures.clear();
while(!featureDefs.empty()){
std::map<std::string, const FeatureDef*>::iterator fi=featureDefs.begin();
delete fi->second;
featureDefs.erase(fi);
}
delete treeDrawer;
}
void CFeatureHandler::Serialize(creg::ISerializer *s)
{
}
void CFeatureHandler::PostLoad()
{
drawQuadsX=gs->mapx/DRAW_QUAD_SIZE;
drawQuadsY=gs->mapy/DRAW_QUAD_SIZE;
drawQuads.clear();
drawQuads.resize(drawQuadsX * drawQuadsY);
for (CFeatureSet::const_iterator it = activeFeatures.begin(); it != activeFeatures.end(); ++it)
if ((*it)->drawQuad >= 0)
drawQuads[(*it)->drawQuad].features.insert(*it);
}
void CFeatureHandler::AddFeatureDef(const std::string& name, FeatureDef* fd)
{
std::map<std::string, const FeatureDef*>::const_iterator it = featureDefs.find(name);
if (it != featureDefs.end()) {
featureDefsVector[it->second->id] = fd;
} else {
fd->id = featureDefsVector.size();
featureDefsVector.push_back(fd);
}
featureDefs[name] = fd;
}
const FeatureDef* CFeatureHandler::CreateFeatureDef(const LuaTable& fdTable,
const string& mixedCase)
{
const string name = StringToLower(mixedCase);
std::map<std::string, const FeatureDef*>::iterator fi = featureDefs.find(name);
if (fi != featureDefs.end()) {
return fi->second;
}
FeatureDef* fd = SAFE_NEW FeatureDef;
fd->myName = name;
fd->filename = fdTable.GetString("filename", "unknown");
fd->description = fdTable.GetString("description", "");
fd->blocking = fdTable.GetBool("blocking", true);
fd->burnable = fdTable.GetBool("flammable", false);
fd->destructable = !fdTable.GetBool("indestructible", false);
fd->reclaimable = fdTable.GetBool("reclaimable", fd->destructable);
//this seem to be the closest thing to floating that ta wreckage contains
fd->floating = fdTable.GetBool("nodrawundergray", true);
if (fd->floating && !fd->blocking) {
fd->floating = false;
}
fd->noSelect = fdTable.GetBool("noselect", false);
fd->deathFeature = fdTable.GetString("featureDead", "");
fd->metal = fdTable.GetFloat("metal", 0.0f);
fd->energy = fdTable.GetFloat("energy", 0.0f);
fd->maxHealth = fdTable.GetFloat("damage", 0.0f);
fd->reclaimTime = fdTable.GetFloat("reclaimTime", (fd->metal + fd->energy));
fd->drawType = DRAWTYPE_3DO;
fd->modelname = fdTable.GetString("object", "");
if (!fd->modelname.empty()) {
fd->modelname=string("objects3d/") + fd->modelname;
}
fd->collisionSphereScale = fdTable.GetFloat("collisionSphereScale", 1.0f);
fd->collisionSphereOffset = fdTable.GetFloat3("collisionSphereOffset", ZeroVector);
fd->useCSOffset = (fd->collisionSphereOffset != ZeroVector);
fd->upright = fdTable.GetBool("upright", false);
// our resolution is double TA's
fd->xsize = fdTable.GetInt("footprintX", 1) * 2;
fd->ysize = fdTable.GetInt("footprintZ", 1) * 2;
const float defMass = (fd->metal * 0.4f) + (fd->maxHealth * 0.1f);
fd->mass = fdTable.GetFloat("mass", defMass);
fd->mass = max(0.001f, fd->mass);
AddFeatureDef(name, fd);
fi = featureDefs.find(name);
return fi->second;
}
const FeatureDef* CFeatureHandler::GetFeatureDef(const std::string mixedCase)
{
const string name = StringToLower(mixedCase);
std::map<std::string, const FeatureDef*>::iterator fi = featureDefs.find(name);
if (fi != featureDefs.end()) {
return fi->second;
}
logOutput.Print("Couldnt find wreckage info %s", name.c_str());
return NULL;
}
const FeatureDef* CFeatureHandler::GetFeatureDefByID(int id)
{
if ((id < 0) || (id >= (int) featureDefsVector.size())) {
return NULL;
}
return featureDefsVector[id];
}
void CFeatureHandler::LoadFeaturesFromMap(bool onlyCreateDefs)
{
PrintLoadMsg("Initializing map features");
int numType = readmap->GetNumFeatureTypes ();
for (int a = 0; a < numType; ++a) {
const string name = StringToLower(readmap->GetFeatureType(a));
if (name.find("treetype") != string::npos) {
FeatureDef* fd = SAFE_NEW FeatureDef;
fd->blocking = 1;
fd->burnable = true;
fd->destructable = 1;
fd->reclaimable = true;
fd->drawType = DRAWTYPE_TREE;
fd->modelType = atoi(name.substr(8).c_str());
fd->energy = 250;
fd->metal = 0;
fd->reclaimTime = 250;
fd->maxHealth = 5;
fd->xsize = 2;
fd->ysize = 2;
fd->myName = name;
fd->description = "Tree";
fd->mass = 20;
AddFeatureDef(name, fd);
}
else if (name.find("geovent") != string::npos) {
FeatureDef* fd = SAFE_NEW FeatureDef;
fd->blocking = 0;
fd->burnable = 0;
fd->destructable = 0;
fd->reclaimable = false;
fd->geoThermal = 1;
fd->drawType = DRAWTYPE_NONE; //geos are drawn into the ground texture and emit smoke to be visible
fd->modelType = 0;
fd->energy = 0;
fd->metal = 0;
fd->reclaimTime = 0;
fd->maxHealth = 0;
fd->xsize = 0;
fd->ysize = 0;
fd->myName = name;
fd->mass = 100000;
AddFeatureDef(name, fd);
}
else {
if (GetFeatureDef(name) == NULL) {
logOutput.Print("Unknown map feature type %s", name.c_str());
}
}
}
if (!onlyCreateDefs) {
const int numFeatures = readmap->GetNumFeatures();
MapFeatureInfo* mfi = SAFE_NEW MapFeatureInfo[numFeatures];
readmap->GetFeatureInfo(mfi);
for(int a = 0; a < numFeatures; ++a) {
const string name = StringToLower(readmap->GetFeatureType(mfi[a].featureType));
std::map<std::string, const FeatureDef*>::iterator def = featureDefs.find(name);
if (def == featureDefs.end()) {
logOutput.Print("Unknown feature named '%s'", name.c_str());
continue;
}
const float ypos = ground->GetHeight2(mfi[a].pos.x, mfi[a].pos.z);
(SAFE_NEW CFeature)->Initialize (float3(mfi[a].pos.x, ypos, mfi[a].pos.z),
featureDefs[name], (short int)mfi[a].rotation,
0, -1, "");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -