[IMapEnts] Correct map entities
This commit is contained in:
parent
c77cbf39b2
commit
654b2210ce
@ -8,7 +8,7 @@ namespace Assets
|
||||
Utils::String::Replace(name, "mp/", "");
|
||||
Utils::String::Replace(name, ".d3dbsp", "");
|
||||
|
||||
Components::FileSystem::File ents(Utils::String::VA("mapents/%s.ents", name.c_str()));
|
||||
Components::FileSystem::File ents(Utils::String::VA("mapents/%s.ents", name.data()));
|
||||
if (ents.exists())
|
||||
{
|
||||
Game::MapEnts* entites = builder->getAllocator()->allocate<Game::MapEnts>();
|
||||
@ -37,20 +37,31 @@ namespace Assets
|
||||
}
|
||||
else
|
||||
{
|
||||
entites->name = builder->getAllocator()->duplicateString(Utils::String::VA("maps/mp/%s.d3dbsp", name.data()));
|
||||
entites->stageCount = 1;
|
||||
entites->stages = builder->getAllocator()->allocate<Game::Stage>();
|
||||
entites->stages[0].stageName = "stage 0";
|
||||
entites->stages[0].flags = 0x10400;
|
||||
}
|
||||
|
||||
entites->entityString = builder->getAllocator()->duplicateString(ents.getBuffer());
|
||||
entites->numEntityChars = ents.getBuffer().size() + 1;
|
||||
std::string entityString = ents.getBuffer();
|
||||
|
||||
entites->name = builder->getAllocator()->duplicateString(Utils::String::VA("maps/mp/%s.d3dbsp", name.data()));
|
||||
entites->entityString = builder->getAllocator()->duplicateString(entityString);
|
||||
entites->numEntityChars = entityString.size() + 1;
|
||||
|
||||
header->mapEnts = entites;
|
||||
}
|
||||
}
|
||||
|
||||
void IMapEnts::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
Utils::Entities memEnts(header.mapEnts->entityString, header.mapEnts->numEntityChars);
|
||||
for(auto& model : memEnts.getModels())
|
||||
{
|
||||
builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_XMODEL, model, false);
|
||||
}
|
||||
}
|
||||
|
||||
void IMapEnts::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
AssertSize(Game::MapEnts, 44);
|
||||
|
@ -7,6 +7,7 @@ namespace Assets
|
||||
public:
|
||||
virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_MAP_ENTS; };
|
||||
|
||||
virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
virtual void load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) override;
|
||||
};
|
||||
|
@ -881,7 +881,7 @@ namespace Assets
|
||||
|
||||
clipMap->checksum = reader.read<int>();
|
||||
|
||||
clipMap->mapEnts = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MAP_ENTS, Utils::String::VA("maps/mp/%s.d3dbsp", name.c_str()), builder).mapEnts;
|
||||
clipMap->mapEnts = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_MAP_ENTS, Utils::String::VA("maps/mp/%s.d3dbsp", name.data()), builder).mapEnts;
|
||||
|
||||
// This mustn't be null and has to have at least 1 'valid' entry.
|
||||
if (!clipMap->smodelNodeCount || !clipMap->smodelNodes)
|
||||
|
@ -105,6 +105,7 @@ template <size_t S> class Sizer { };
|
||||
#include "Utils/String.hpp"
|
||||
#include "Utils/Hooking.hpp"
|
||||
#include "Utils/Library.hpp"
|
||||
#include "Utils/Entities.hpp"
|
||||
#include "Utils/InfoString.hpp"
|
||||
#include "Utils/Compression.hpp"
|
||||
#include "Utils/Cryptography.hpp"
|
||||
|
169
src/Utils/Entities.cpp
Normal file
169
src/Utils/Entities.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
std::string Entities::build()
|
||||
{
|
||||
std::string entityString;
|
||||
|
||||
for (auto& entity : this->entities)
|
||||
{
|
||||
entityString.append("{\n");
|
||||
|
||||
for (auto& property : entity)
|
||||
{
|
||||
entityString.push_back('"');
|
||||
entityString.append(property.first);
|
||||
entityString.append("\" \"");
|
||||
entityString.append(property.second);
|
||||
entityString.append("\"\n");
|
||||
}
|
||||
|
||||
entityString.append("}\n");
|
||||
}
|
||||
|
||||
return entityString;
|
||||
}
|
||||
|
||||
std::vector<std::string> Entities::getModels()
|
||||
{
|
||||
std::vector<std::string> models;
|
||||
|
||||
for (auto& entity : this->entities)
|
||||
{
|
||||
if(entity.find("model") != entity.end())
|
||||
{
|
||||
std::string model = entity["model"];
|
||||
|
||||
if(!model.empty() && model[0] != '*') // Skip brushmodels
|
||||
{
|
||||
if (std::find(models.begin(), models.end(), model) == models.end())
|
||||
{
|
||||
models.push_back(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return models;
|
||||
}
|
||||
|
||||
void Entities::deleteTriggers()
|
||||
{
|
||||
for(auto i = this->entities.begin(); i != this->entities.end();)
|
||||
{
|
||||
if(i->find("classname") != i->end())
|
||||
{
|
||||
std::string classname = (*i)["classname"];
|
||||
if(Utils::String::StartsWith(classname, "trigger_"))
|
||||
{
|
||||
i = this->entities.erase(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void Entities::convertTurrets()
|
||||
{
|
||||
for (auto& entity : this->entities)
|
||||
{
|
||||
if (entity.find("classname") != entity.end())
|
||||
{
|
||||
if (entity["classname"] == "misc_turret"s)
|
||||
{
|
||||
entity["weaponinfo"] = "turret_minigun_mp";
|
||||
entity["model"] = "weapon_minigun";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Entities::deleteWeapons(bool keepTurrets)
|
||||
{
|
||||
for (auto i = this->entities.begin(); i != this->entities.end();)
|
||||
{
|
||||
if (i->find("weaponinfo") != i->end())
|
||||
{
|
||||
if (!keepTurrets || i->find("classname") == i->end() || (*i)["classname"] != "misc_turret"s)
|
||||
{
|
||||
i = this->entities.erase(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void Entities::parse(std::string buffer)
|
||||
{
|
||||
int parseState = 0;
|
||||
std::string key;
|
||||
std::string value;
|
||||
std::unordered_map<std::string, std::string> entity;
|
||||
|
||||
for(unsigned int i = 0; i < buffer.size(); ++i)
|
||||
{
|
||||
char character = buffer[i];
|
||||
if(character == '{')
|
||||
{
|
||||
entity.clear();
|
||||
}
|
||||
|
||||
switch(character)
|
||||
{
|
||||
case '{':
|
||||
{
|
||||
entity.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
case '}':
|
||||
{
|
||||
this->entities.push_back(entity);
|
||||
entity.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
case '"':
|
||||
{
|
||||
if (parseState == PARSE_AWAIT_KEY)
|
||||
{
|
||||
key.clear();
|
||||
parseState = PARSE_READ_KEY;
|
||||
}
|
||||
else if (parseState == PARSE_READ_KEY)
|
||||
{
|
||||
parseState = PARSE_AWAIT_VALUE;
|
||||
}
|
||||
else if (parseState == PARSE_AWAIT_VALUE)
|
||||
{
|
||||
value.clear();
|
||||
parseState = PARSE_READ_VALUE;
|
||||
}
|
||||
else if (parseState == PARSE_READ_VALUE)
|
||||
{
|
||||
entity[Utils::String::ToLower(key)] = value;
|
||||
parseState = PARSE_AWAIT_KEY;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Parsing error!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if(parseState == PARSE_READ_KEY) key.push_back(character);
|
||||
else if (parseState == PARSE_READ_VALUE) value.push_back(character);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
src/Utils/Entities.hpp
Normal file
32
src/Utils/Entities.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
class Entities
|
||||
{
|
||||
public:
|
||||
Entities() {};
|
||||
Entities(const char* string, size_t lenPlusOne) : Entities(std::string(string, lenPlusOne - 1)) {}
|
||||
Entities(std::string buffer) : Entities() { this->parse(buffer); };
|
||||
Entities(const Entities &obj) : entities(obj.entities) {};
|
||||
|
||||
std::string build();
|
||||
|
||||
std::vector<std::string> getModels();
|
||||
void deleteTriggers();
|
||||
void deleteWeapons(bool keepTurrets);
|
||||
void convertTurrets();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
PARSE_AWAIT_KEY,
|
||||
PARSE_READ_KEY,
|
||||
PARSE_AWAIT_VALUE,
|
||||
PARSE_READ_VALUE,
|
||||
};
|
||||
|
||||
std::vector<std::unordered_map<std::string, std::string>> entities;
|
||||
void parse(std::string buffer);
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user