mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 18:32:44 +01:00
Merge pull request #266 from danhedron/map-zones-1
Add zone queries and load save zones
This commit is contained in:
commit
1308342f8f
@ -1,15 +1,16 @@
|
|||||||
#pragma once
|
#ifndef RWENGINE_DATA_ZONEDATA_HPP
|
||||||
#ifndef _ZONEDATA_HPP_
|
#define RWENGINE_DATA_ZONEDATA_HPP
|
||||||
#define _ZONEDATA_HPP_
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define ZONE_GANG_COUNT 13
|
#define ZONE_GANG_COUNT 13
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class Zone
|
* Zone Data loaded from IPL/zon files
|
||||||
* A Zone entry
|
|
||||||
*/
|
*/
|
||||||
struct ZoneData {
|
struct ZoneData {
|
||||||
/**
|
/**
|
||||||
@ -37,30 +38,87 @@ struct ZoneData {
|
|||||||
/**
|
/**
|
||||||
* Text of the zone?
|
* Text of the zone?
|
||||||
*/
|
*/
|
||||||
std::string Text;
|
std::string text = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gang spawn density for daytime (8:00-19:00)
|
* Gang spawn density for daytime (8:00-19:00)
|
||||||
*/
|
*/
|
||||||
unsigned int gangDensityDay[ZONE_GANG_COUNT];
|
unsigned int gangDensityDay[ZONE_GANG_COUNT] = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gang spawn density for nighttime (19:00-8:00)
|
* Gang spawn density for nighttime (19:00-8:00)
|
||||||
*/
|
*/
|
||||||
unsigned int gangDensityNight[ZONE_GANG_COUNT];
|
unsigned int gangDensityNight[ZONE_GANG_COUNT] = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gang car spawn density for daytime (8:00-19:00)
|
* Gang car spawn density for daytime (8:00-19:00)
|
||||||
*/
|
*/
|
||||||
unsigned int gangCarDensityDay[ZONE_GANG_COUNT];
|
unsigned int gangCarDensityDay[ZONE_GANG_COUNT] = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gang car spawn density for nighttime (19:00-8:00)
|
* Gang car spawn density for nighttime (19:00-8:00)
|
||||||
*/
|
*/
|
||||||
unsigned int gangCarDensityNight[ZONE_GANG_COUNT];
|
unsigned int gangCarDensityNight[ZONE_GANG_COUNT] = {};
|
||||||
|
|
||||||
unsigned int pedGroupDay;
|
unsigned int pedGroupDay = 0;
|
||||||
unsigned int pedGroupNight;
|
unsigned int pedGroupNight = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to parent zone in zone array
|
||||||
|
*/
|
||||||
|
ZoneData* parent_ = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Totally contained zones
|
||||||
|
*/
|
||||||
|
std::vector<ZoneData*> children_ = {};
|
||||||
|
|
||||||
|
static bool isZoneContained(const ZoneData& inner, const ZoneData& outer) {
|
||||||
|
return glm::all(glm::greaterThanEqual(inner.min, outer.min)) &&
|
||||||
|
glm::all(glm::lessThanEqual(inner.max, outer.max));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsPoint(const glm::vec3& point) const {
|
||||||
|
return glm::all(glm::greaterThanEqual(point, min)) &&
|
||||||
|
glm::all(glm::lessThanEqual(point, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneData* findLeafAtPoint(const glm::vec3& point) {
|
||||||
|
for (ZoneData* child : children_) {
|
||||||
|
auto descendent = child->findLeafAtPoint(point);
|
||||||
|
if (descendent) {
|
||||||
|
return descendent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return containsPoint(point) ? this : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insertZone(ZoneData& inner) {
|
||||||
|
if (!isZoneContained(inner, *this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ZoneData* child : children_) {
|
||||||
|
if (child->insertZone(inner)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// inner is a child of outer
|
||||||
|
|
||||||
|
// Move any zones that are really within inner to inner
|
||||||
|
auto it = std::stable_partition(
|
||||||
|
children_.begin(), children_.end(),
|
||||||
|
[&](ZoneData* a) { return !inner.insertZone(*a); });
|
||||||
|
children_.erase(it, children_.end());
|
||||||
|
|
||||||
|
children_.push_back(&inner);
|
||||||
|
inner.parent_ = this;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
using ZoneDataList = std::vector<ZoneData>;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -56,6 +56,10 @@ void GameData::load() {
|
|||||||
|
|
||||||
loadIFP("ped.ifp");
|
loadIFP("ped.ifp");
|
||||||
|
|
||||||
|
// Clear existing zones
|
||||||
|
gamezones = ZoneDataList{
|
||||||
|
{"CITYZON", 0, {-4000.f, -4000.f, -500.f}, {4000.f, 4000.f, 500.f}, 0}};
|
||||||
|
|
||||||
loadLevelFile("data/default.dat");
|
loadLevelFile("data/default.dat");
|
||||||
loadLevelFile("data/gta3.dat");
|
loadLevelFile("data/gta3.dat");
|
||||||
}
|
}
|
||||||
@ -164,20 +168,24 @@ void GameData::loadIPL(const std::string& path) {
|
|||||||
bool GameData::loadZone(const std::string& path) {
|
bool GameData::loadZone(const std::string& path) {
|
||||||
LoaderIPL ipll;
|
LoaderIPL ipll;
|
||||||
|
|
||||||
if (ipll.load(path)) {
|
// Load the zones
|
||||||
if (ipll.zones.size() > 0) {
|
if (!ipll.load(path)) {
|
||||||
for (auto& z : ipll.zones) {
|
|
||||||
zones.insert({z.name, z});
|
|
||||||
}
|
|
||||||
logger->info("Data", "Loaded " + std::to_string(ipll.zones.size()) +
|
|
||||||
" zones from " + path);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger->error("Data", "Failed to load zones from " + path);
|
logger->error("Data", "Failed to load zones from " + path);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
gamezones.insert(gamezones.end(), ipll.zones.begin(), ipll.zones.end());
|
||||||
|
|
||||||
|
// Build zone hierarchy
|
||||||
|
for (ZoneData& zone : gamezones) {
|
||||||
|
zone.children_.clear();
|
||||||
|
if (&zone == &gamezones.front()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
gamezones[0].insertZone(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ColSection {
|
enum ColSection {
|
||||||
|
@ -43,6 +43,7 @@ private:
|
|||||||
|
|
||||||
Logger* logger;
|
Logger* logger;
|
||||||
LoaderDFF dffLoader;
|
LoaderDFF dffLoader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* ctor
|
* ctor
|
||||||
@ -193,10 +194,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::map<std::string, LoaderIMG> archives;
|
std::map<std::string, LoaderIMG> archives;
|
||||||
|
|
||||||
/**
|
ZoneDataList gamezones;
|
||||||
* Map Zones
|
|
||||||
*/
|
ZoneDataList mapzones;
|
||||||
std::map<std::string, ZoneData> zones;
|
|
||||||
|
ZoneData* findZone(const std::string& name) {
|
||||||
|
auto it =
|
||||||
|
std::find_if(gamezones.begin(), gamezones.end(),
|
||||||
|
[&](const ZoneData& a) { return a.name == name; });
|
||||||
|
return it != gamezones.end() ? &(*it) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneData* findZoneAt(const glm::vec3& pos) {
|
||||||
|
RW_CHECK(!gamezones.empty(), "No game zones loaded");
|
||||||
|
ZoneData* zone = gamezones[0].findLeafAtPoint(pos);
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
std::unordered_map<ModelID, std::unique_ptr<BaseModelInfo>> modelinfo;
|
std::unordered_map<ModelID, std::unique_ptr<BaseModelInfo>> modelinfo;
|
||||||
|
|
||||||
|
@ -371,9 +371,11 @@ struct Block11Zone {
|
|||||||
};
|
};
|
||||||
struct Block11ZoneInfo {
|
struct Block11ZoneInfo {
|
||||||
BlockWord density;
|
BlockWord density;
|
||||||
// This will likely be the gang
|
BlockWord unknown1[16];
|
||||||
// car and ped densities +more
|
BlockWord peddensity;
|
||||||
uint8_t unknown1[56];
|
BlockWord copdensity;
|
||||||
|
BlockWord gangpeddensity[9];
|
||||||
|
BlockWord pedgroup;
|
||||||
};
|
};
|
||||||
struct Block11AudioZone {
|
struct Block11AudioZone {
|
||||||
BlockWord zoneId;
|
BlockWord zoneId;
|
||||||
@ -890,6 +892,10 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
|||||||
Block11ZoneInfo& info = zoneData.dayNightInfo[z];
|
Block11ZoneInfo& info = zoneData.dayNightInfo[z];
|
||||||
READ_VALUE(info.density)
|
READ_VALUE(info.density)
|
||||||
READ_VALUE(info.unknown1)
|
READ_VALUE(info.unknown1)
|
||||||
|
READ_VALUE(info.peddensity)
|
||||||
|
READ_VALUE(info.copdensity)
|
||||||
|
READ_VALUE(info.gangpeddensity)
|
||||||
|
READ_VALUE(info.pedgroup);
|
||||||
}
|
}
|
||||||
READ_VALUE(zoneData.numNavZones);
|
READ_VALUE(zoneData.numNavZones);
|
||||||
READ_VALUE(zoneData.numZoneInfos);
|
READ_VALUE(zoneData.numZoneInfos);
|
||||||
@ -919,6 +925,31 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
|||||||
for (int z = 0; z < zoneData.numNavZones; ++z) {
|
for (int z = 0; z < zoneData.numNavZones; ++z) {
|
||||||
Block11Zone& zone = zoneData.navZones[z];
|
Block11Zone& zone = zoneData.navZones[z];
|
||||||
std::cout << " " << zone.name << std::endl;
|
std::cout << " " << zone.name << std::endl;
|
||||||
|
auto& dayinfo = zoneData.dayNightInfo[zone.dayZoneInfo];
|
||||||
|
std::cout << " DAY " << dayinfo.density << " " << dayinfo.peddensity
|
||||||
|
<< " " << dayinfo.copdensity << " "
|
||||||
|
<< " [";
|
||||||
|
for (BlockDword gang : dayinfo.gangpeddensity) {
|
||||||
|
std::cout << " " << gang;
|
||||||
|
}
|
||||||
|
std::cout << "] " << dayinfo.pedgroup << std::endl;
|
||||||
|
for (BlockDword dw : dayinfo.unknown1) {
|
||||||
|
std::cout << " " << dw;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
auto& nightinfo = zoneData.dayNightInfo[zone.nightZoneInfo];
|
||||||
|
std::cout << " NIGHT " << nightinfo.density << " "
|
||||||
|
<< nightinfo.peddensity << " " << nightinfo.copdensity << " "
|
||||||
|
<< " [";
|
||||||
|
for (BlockDword gang : nightinfo.gangpeddensity) {
|
||||||
|
std::cout << " " << gang;
|
||||||
|
}
|
||||||
|
std::cout << "] " << nightinfo.pedgroup << std::endl;
|
||||||
|
for (BlockDword dw : nightinfo.unknown1) {
|
||||||
|
std::cout << " " << dw;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
for (int z = 0; z < zoneData.numMapZones; ++z) {
|
for (int z = 0; z < zoneData.numMapZones; ++z) {
|
||||||
Block11Zone& zone = zoneData.mapZones[z];
|
Block11Zone& zone = zoneData.mapZones[z];
|
||||||
@ -926,6 +957,33 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Clear existing zone data
|
||||||
|
auto& gamezones = state.world->data->gamezones;
|
||||||
|
gamezones.clear();
|
||||||
|
for (int z = 0; z < zoneData.numNavZones; ++z) {
|
||||||
|
Block11Zone& zone = zoneData.navZones[z];
|
||||||
|
Block11ZoneInfo& day = zoneData.dayNightInfo[zone.dayZoneInfo];
|
||||||
|
Block11ZoneInfo& night = zoneData.dayNightInfo[zone.nightZoneInfo];
|
||||||
|
ZoneData zd;
|
||||||
|
zd.name = zone.name;
|
||||||
|
zd.type = zone.type;
|
||||||
|
zd.min = zone.coordA;
|
||||||
|
zd.max = zone.coordB;
|
||||||
|
zd.island = zone.level;
|
||||||
|
// @toodo restore gang density
|
||||||
|
zd.pedGroupDay = day.pedgroup;
|
||||||
|
zd.pedGroupNight = night.pedgroup;
|
||||||
|
gamezones.push_back(zd);
|
||||||
|
}
|
||||||
|
// Re-build zone hierarchy
|
||||||
|
for (ZoneData& zone : gamezones) {
|
||||||
|
if (&zone == &gamezones[0]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gamezones[0].insertZone(zone);
|
||||||
|
}
|
||||||
|
|
||||||
// Block 12
|
// Block 12
|
||||||
BlockSize gangBlockSize;
|
BlockSize gangBlockSize;
|
||||||
BLOCK_HEADER(gangBlockSize)
|
BLOCK_HEADER(gangBlockSize)
|
||||||
|
@ -124,4 +124,4 @@ bool LoaderIPL::load(const std::string& filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
std::vector<std::shared_ptr<InstanceData>> m_instances;
|
std::vector<std::shared_ptr<InstanceData>> m_instances;
|
||||||
|
|
||||||
/// List of Zones
|
/// List of Zones
|
||||||
std::vector<ZoneData> zones;
|
ZoneDataList zones;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LoaderIPL_h__
|
#endif // LoaderIPL_h__
|
||||||
|
@ -108,11 +108,11 @@ inline bool objectInRadiusNear(const ScriptArguments& args, GameObject* object,
|
|||||||
|
|
||||||
template <class Tobj>
|
template <class Tobj>
|
||||||
inline bool objectInZone(const ScriptArguments& args, Tobj object,
|
inline bool objectInZone(const ScriptArguments& args, Tobj object,
|
||||||
const ScriptString zone) {
|
const ScriptString name) {
|
||||||
auto zfind = args.getWorld()->data->zones.find(zone);
|
auto zone = args.getWorld()->data->findZone(name);
|
||||||
if (zfind != args.getWorld()->data->zones.end()) {
|
if (zone) {
|
||||||
auto& min = zfind->second.min;
|
auto& min = zone->min;
|
||||||
auto& max = zfind->second.max;
|
auto& max = zone->max;
|
||||||
return objectInBounds(object, min, max);
|
return objectInBounds(object, min, max);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3694,12 +3694,11 @@ void opcode_0152(const ScriptArguments& args, const ScriptString arg1, const Scr
|
|||||||
RW_UNUSED(arg15);
|
RW_UNUSED(arg15);
|
||||||
RW_UNUSED(arg16);
|
RW_UNUSED(arg16);
|
||||||
RW_UNUSED(arg17);
|
RW_UNUSED(arg17);
|
||||||
auto& zones = args.getWorld()->data->zones;
|
auto zone = args.getWorld()->data->findZone(arg1);
|
||||||
auto it = zones.find(arg1);
|
if (zone) {
|
||||||
if (it != zones.end()) {
|
auto density = (zone->gangCarDensityNight);
|
||||||
auto density = (it->second.gangCarDensityNight);
|
if (arg2) {
|
||||||
if (arg1) {
|
density = zone->gangCarDensityDay;
|
||||||
density = it->second.gangCarDensityDay;
|
|
||||||
}
|
}
|
||||||
auto count = args.getParameters().size();
|
auto count = args.getParameters().size();
|
||||||
for (auto g = 0u; g < count - 2; ++g) {
|
for (auto g = 0u; g < count - 2; ++g) {
|
||||||
@ -3824,12 +3823,11 @@ void opcode_015c(const ScriptArguments& args, const ScriptString areaName, const
|
|||||||
RW_UNUSED(arg9);
|
RW_UNUSED(arg9);
|
||||||
RW_UNUSED(arg10);
|
RW_UNUSED(arg10);
|
||||||
RW_UNUSED(arg11);
|
RW_UNUSED(arg11);
|
||||||
auto& zones = args.getWorld()->data->zones;
|
auto zone = args.getWorld()->data->findZone(areaName);
|
||||||
auto it = zones.find(areaName);
|
if (zone) {
|
||||||
if (it != zones.end()) {
|
auto density = (zone->gangCarDensityNight);
|
||||||
auto density = (it->second.gangCarDensityNight);
|
|
||||||
if (arg2) {
|
if (arg2) {
|
||||||
density = it->second.gangCarDensityDay;
|
density = zone->gangCarDensityDay;
|
||||||
}
|
}
|
||||||
auto count = args.getParameters().size();
|
auto count = args.getParameters().size();
|
||||||
for (auto g = 0u; g < count - 2; ++g) {
|
for (auto g = 0u; g < count - 2; ++g) {
|
||||||
@ -8101,13 +8099,12 @@ void opcode_02dd(const ScriptArguments& args, const ScriptString areaName, Scrip
|
|||||||
RW_UNIMPLEMENTED_OPCODE(0x02dd);
|
RW_UNIMPLEMENTED_OPCODE(0x02dd);
|
||||||
RW_UNUSED(areaName);
|
RW_UNUSED(areaName);
|
||||||
RW_UNUSED(character);
|
RW_UNUSED(character);
|
||||||
const auto& zones = args.getWorld()->data->zones;
|
|
||||||
|
|
||||||
std::string zname(args[0].string);
|
std::string zname(args[0].string);
|
||||||
|
|
||||||
// Only try to find a character if this is a known zone
|
// Only try to find a character if this is a known zone
|
||||||
auto zfind = zones.find(zname);
|
auto zone = args.getWorld()->data->findZone(areaName);
|
||||||
if(zfind != zones.end()) {
|
if(zone) {
|
||||||
|
|
||||||
// Create a list of candidate characters by iterating and checking if the char is in this zone
|
// Create a list of candidate characters by iterating and checking if the char is in this zone
|
||||||
std::vector<std::pair<GameObjectID, GameObject*>> candidates;
|
std::vector<std::pair<GameObjectID, GameObject*>> candidates;
|
||||||
@ -8122,8 +8119,8 @@ void opcode_02dd(const ScriptArguments& args, const ScriptString areaName, Scrip
|
|||||||
|
|
||||||
// Check if character is in this zone
|
// Check if character is in this zone
|
||||||
auto cp = character->getPosition();
|
auto cp = character->getPosition();
|
||||||
auto& min = zfind->second.min;
|
auto& min = zone->min;
|
||||||
auto& max = zfind->second.max;
|
auto& max = zone->max;
|
||||||
if (cp.x > min.x && cp.y > min.y && cp.z > min.z &&
|
if (cp.x > min.x && cp.y > min.y && cp.z > min.z &&
|
||||||
cp.x < max.x && cp.y < max.y && cp.z < max.z) {
|
cp.x < max.x && cp.y < max.y && cp.z < max.z) {
|
||||||
candidates.push_back(p);
|
candidates.push_back(p);
|
||||||
@ -9246,17 +9243,17 @@ void opcode_0324(const ScriptArguments& args, const ScriptString arg1, const Scr
|
|||||||
RW_UNUSED(arg1);
|
RW_UNUSED(arg1);
|
||||||
RW_UNUSED(arg2);
|
RW_UNUSED(arg2);
|
||||||
RW_UNUSED(arg3);
|
RW_UNUSED(arg3);
|
||||||
auto it = args.getWorld()->data->zones.find(args[0].string);
|
auto zone = args.getWorld()->data->findZone(arg1);
|
||||||
if( it != args.getWorld()->data->zones.end() )
|
if (zone)
|
||||||
{
|
{
|
||||||
auto day = args[1].integer == 1;
|
auto day = args[1].integer == 1;
|
||||||
if( day )
|
if( day )
|
||||||
{
|
{
|
||||||
it->second.pedGroupDay = args[2].integer;
|
zone->pedGroupDay = args[2].integer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
it->second.pedGroupNight = args[2].integer;
|
zone->pedGroupNight = args[2].integer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,9 @@ void DebugState::tick(float dt) {
|
|||||||
void DebugState::draw(GameRenderer* r) {
|
void DebugState::draw(GameRenderer* r) {
|
||||||
// Draw useful information like camera position.
|
// Draw useful information like camera position.
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Camera Position: " << glm::to_string(_debugCam.position);
|
ss << "Camera Position: " << glm::to_string(_debugCam.position) << "\n";
|
||||||
|
auto zone = getWorld()->data->findZoneAt(_debugCam.position);
|
||||||
|
ss << (zone ? zone->name : "No Zone") << "\n";
|
||||||
|
|
||||||
TextRenderer::TextInfo ti;
|
TextRenderer::TextInfo ti;
|
||||||
ti.text = GameStringUtil::fromString(ss.str());
|
ti.text = GameStringUtil::fromString(ss.str());
|
||||||
|
@ -28,6 +28,7 @@ set(TEST_SOURCES
|
|||||||
"test_Input.cpp"
|
"test_Input.cpp"
|
||||||
"test_lifetime.cpp"
|
"test_lifetime.cpp"
|
||||||
"test_loaderdff.cpp"
|
"test_loaderdff.cpp"
|
||||||
|
"test_LoaderIPL.cpp"
|
||||||
"test_Logger.cpp"
|
"test_Logger.cpp"
|
||||||
"test_menu.cpp"
|
"test_menu.cpp"
|
||||||
"test_object.cpp"
|
"test_object.cpp"
|
||||||
@ -45,6 +46,7 @@ set(TEST_SOURCES
|
|||||||
"test_VisualFX.cpp"
|
"test_VisualFX.cpp"
|
||||||
"test_weapon.cpp"
|
"test_weapon.cpp"
|
||||||
"test_world.cpp"
|
"test_world.cpp"
|
||||||
|
"test_ZoneData.cpp"
|
||||||
|
|
||||||
# Hack in rwgame sources until there's a per-target test suite
|
# Hack in rwgame sources until there's a per-target test suite
|
||||||
"${CMAKE_SOURCE_DIR}/rwgame/GameConfig.cpp"
|
"${CMAKE_SOURCE_DIR}/rwgame/GameConfig.cpp"
|
||||||
|
21
tests/test_LoaderIPL.cpp
Normal file
21
tests/test_LoaderIPL.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <loaders/LoaderIPL.hpp>
|
||||||
|
#include "test_globals.hpp"
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(LoaderIPLTests)
|
||||||
|
|
||||||
|
#if RW_TEST_WITH_DATA
|
||||||
|
BOOST_AUTO_TEST_CASE(test_load_zones) {
|
||||||
|
LoaderIPL loader;
|
||||||
|
const auto& gdpath = Global::get().getGamePath();
|
||||||
|
BOOST_REQUIRE(loader.load(gdpath + "/data/gta3.zon"));
|
||||||
|
|
||||||
|
BOOST_REQUIRE(loader.zones.size() > 2);
|
||||||
|
|
||||||
|
auto& zone1 = loader.zones[0];
|
||||||
|
BOOST_CHECK_EQUAL(zone1.name, "ROADBR1");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
33
tests/test_ZoneData.cpp
Normal file
33
tests/test_ZoneData.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <data/ZoneData.hpp>
|
||||||
|
#include "test_globals.hpp"
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(ZoneDataTests)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_contains_point) {
|
||||||
|
ZoneData zone;
|
||||||
|
zone.min = glm::vec3(10.f, 10.f, -5.f);
|
||||||
|
zone.max = glm::vec3(30.f, 40.f, 5.f);
|
||||||
|
|
||||||
|
BOOST_CHECK(zone.containsPoint({15.f, 15.f, 0.f}));
|
||||||
|
BOOST_CHECK(zone.containsPoint({10.f, 10.f, 0.f}));
|
||||||
|
BOOST_CHECK(zone.containsPoint({30.f, 35.f, 0.f}));
|
||||||
|
BOOST_CHECK(!zone.containsPoint({35.f, 30.f, 0.f}));
|
||||||
|
BOOST_CHECK(!zone.containsPoint({0.f, 0.f, 0.f}));
|
||||||
|
BOOST_CHECK(!zone.containsPoint({-15.f, -15.f, 0.f}));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_hierarchy) {
|
||||||
|
ZoneData zone;
|
||||||
|
zone.min = glm::vec3(-10.f,-10.f,-5.f);
|
||||||
|
zone.max = glm::vec3( 10.f, 10.f, 5.f);
|
||||||
|
ZoneData leaf;
|
||||||
|
leaf.min = glm::vec3(0.f, 0.f,-5.f);
|
||||||
|
leaf.max = glm::vec3(10.f,10.f, 5.f);
|
||||||
|
BOOST_CHECK(zone.insertZone(leaf));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(zone.findLeafAtPoint({-5.f, 0.f, 0.f}), &zone);
|
||||||
|
BOOST_CHECK_EQUAL(zone.findLeafAtPoint({ 5.f, 5.f, 0.f}), &leaf);
|
||||||
|
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue
Block a user