mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-26 04:12:41 +01:00
Merge pull request #265 from danhedron/ped-improvements
Ped improvements
This commit is contained in:
commit
66dd55620d
@ -39,6 +39,8 @@ set(RWENGINE_SOURCES
|
||||
src/data/ModelData.cpp
|
||||
src/data/ModelData.hpp
|
||||
src/data/PathData.hpp
|
||||
src/data/PedData.cpp
|
||||
src/data/PedData.hpp
|
||||
src/data/Skeleton.cpp
|
||||
src/data/Skeleton.hpp
|
||||
src/data/WeaponData.hpp
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <ai/AIGraphNode.hpp>
|
||||
#include <ai/CharacterController.hpp>
|
||||
#include <core/Logger.hpp>
|
||||
#include <engine/GameData.hpp>
|
||||
#include <engine/GameState.hpp>
|
||||
#include <engine/GameWorld.hpp>
|
||||
#include <objects/CharacterObject.hpp>
|
||||
@ -127,11 +128,19 @@ std::vector<GameObject*> TrafficDirector::populateNearby(
|
||||
}
|
||||
|
||||
/// Hardcoded cop Pedestrian
|
||||
std::vector<uint16_t> validPeds = {1};
|
||||
validPeds.insert(validPeds.end(), {20, 11, 19, 5});
|
||||
std::vector<uint16_t> peds = {1};
|
||||
// Determine which zone the viewpoint is in
|
||||
auto zone = world->data->findZoneAt(camera.position);
|
||||
bool day = (world->state->basic.gameHour >= 8 &&
|
||||
world->state->basic.gameHour <= 19);
|
||||
int groupid = zone ? (day ? zone->pedGroupDay : zone->pedGroupNight) : 0;
|
||||
const auto& group = world->data->pedgroups.at(groupid);
|
||||
peds.insert(peds.end(), group.cbegin(), group.cend());
|
||||
|
||||
std::random_device rd;
|
||||
std::default_random_engine re(rd());
|
||||
std::uniform_int_distribution<> d(0, validPeds.size() - 1);
|
||||
std::uniform_int_distribution<> d(0, peds.size() - 1);
|
||||
const glm::vec3 kSpawnOffset{0.f, 0.f, 1.f};
|
||||
|
||||
int counter = availablePeds;
|
||||
// maxSpawn can be -1 for "as many as possible"
|
||||
@ -151,8 +160,8 @@ std::vector<GameObject*> TrafficDirector::populateNearby(
|
||||
}
|
||||
|
||||
// Spawn a pedestrian from the available pool
|
||||
auto ped = world->createPedestrian(
|
||||
validPeds[d(re)], spawn->position + glm::vec3(0.f, 0.f, 1.f));
|
||||
auto ped = world->createPedestrian(peds[d(re)],
|
||||
spawn->position + kSpawnOffset);
|
||||
ped->setLifetime(GameObject::TrafficLifetime);
|
||||
ped->controller->setGoal(CharacterController::TrafficWander);
|
||||
created.push_back(ped);
|
||||
|
@ -346,7 +346,7 @@ public:
|
||||
PLAYER1 = 0,
|
||||
PLAYER2,
|
||||
PLAYER3,
|
||||
PLAYER_4,
|
||||
PLAYER4,
|
||||
CIVMALE,
|
||||
CIVFEMALE,
|
||||
COP,
|
||||
@ -365,11 +365,11 @@ public:
|
||||
_UNNAMED,
|
||||
PROSTITUTE,
|
||||
SPECIAL,
|
||||
_NUM_PEDTYPE
|
||||
};
|
||||
|
||||
PedType pedtype_ = PLAYER1;
|
||||
/// @todo this should be an index
|
||||
std::string behaviour_;
|
||||
int statindex_ = 0;
|
||||
/// @todo this should be an index
|
||||
std::string animgroup_;
|
||||
/// The mask of vehicle classes this ped can drive
|
||||
@ -381,7 +381,7 @@ public:
|
||||
{"PLAYER1", PLAYER1},
|
||||
{"PLAYER2", PLAYER2},
|
||||
{"PLAYER3", PLAYER3},
|
||||
{"PLAYER_4", PLAYER_4},
|
||||
{"PLAYER4", PLAYER4},
|
||||
{"CIVMALE", CIVMALE},
|
||||
{"CIVFEMALE", CIVFEMALE},
|
||||
{"COP", COP},
|
||||
@ -397,7 +397,6 @@ public:
|
||||
{"EMERGENCY", EMERGENCY},
|
||||
{"FIREMAN", FIREMAN},
|
||||
{"CRIMINAL", CRIMINAL},
|
||||
{"_UNNAMED", _UNNAMED},
|
||||
{"PROSTITUTE", PROSTITUTE},
|
||||
{"SPECIAL", SPECIAL},
|
||||
};
|
||||
|
35
rwengine/src/data/PedData.cpp
Normal file
35
rwengine/src/data/PedData.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "PedData.hpp"
|
||||
#include <unordered_map>
|
||||
|
||||
uint32_t PedRelationship::threatFromName(const std::string &name) {
|
||||
static const std::unordered_map<std::string, uint32_t> kThreatMap{
|
||||
{"PLAYER1", THREAT_PLAYER1}, // Player
|
||||
{"PLAYER2", THREAT_PLAYER2}, // Unused
|
||||
{"PLAYER3", THREAT_PLAYER3}, // Unused
|
||||
{"PLAYER4", THREAT_PLAYER4}, // Unused
|
||||
{"CIVMALE", THREAT_CIVMALE}, // Civilan
|
||||
{"CIVFEMALE", THREAT_CIVFEMALE}, // Civilan
|
||||
{"COP", THREAT_COP}, // Police
|
||||
{"GANG1", THREAT_GANG1}, // Mafia
|
||||
{"GANG2", THREAT_GANG2}, // Triad
|
||||
{"GANG3", THREAT_GANG3}, // Diablo
|
||||
{"GANG4", THREAT_GANG4}, // Yakuza
|
||||
{"GANG5", THREAT_GANG5}, // Yardie
|
||||
{"GANG6", THREAT_GANG6}, // Columbian
|
||||
{"GANG7", THREAT_GANG7}, // Hood
|
||||
{"GANG8", THREAT_GANG8}, // Unused
|
||||
{"GANG9", THREAT_GANG9}, // Unused
|
||||
{"EMERGENCY", THREAT_EMERGENCY}, // Emergency services
|
||||
{"PROSTITUTE", THREAT_PROSTITUTE}, // ...
|
||||
{"CRIMINAL", THREAT_CRIMINAL}, // Criminals
|
||||
{"SPECIAL", THREAT_SPECIAL}, // SPECIAL
|
||||
{"GUN", THREAT_GUN}, // Not sure
|
||||
{"COP_CAR", THREAT_COP_CAR},
|
||||
{"FAST_CAR", THREAT_FAST_CAR},
|
||||
{"EXPLOSION", THREAT_EXPLOSION}, // Explosions
|
||||
{"FIREMAN", THREAT_FIREMAN}, // Firemen?
|
||||
{"DEADPEDS", THREAT_DEADPEDS}, // Dead bodies
|
||||
};
|
||||
|
||||
return kThreatMap.at(name);
|
||||
}
|
73
rwengine/src/data/PedData.hpp
Normal file
73
rwengine/src/data/PedData.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef RWENGINE_DATA_PEDDATA_HPP
|
||||
#define RWENGINE_DATA_PEDDATA_HPP
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class PedStats {
|
||||
public:
|
||||
int id_;
|
||||
std::string name_;
|
||||
|
||||
float fleedistance_;
|
||||
float rotaterate_;
|
||||
float fear_;
|
||||
float temper_;
|
||||
float lawful_;
|
||||
float sexy_;
|
||||
float attackstrength_;
|
||||
float defendweakness_;
|
||||
uint32_t flags_;
|
||||
};
|
||||
using PedStatsList = std::vector<PedStats>;
|
||||
|
||||
class PedRelationship {
|
||||
public:
|
||||
enum {
|
||||
THREAT_PLAYER1 = 1, // Player
|
||||
THREAT_PLAYER2 = 2, // Unused
|
||||
THREAT_PLAYER3 = 3, // Unused
|
||||
THREAT_PLAYER4 = 4, // Unused
|
||||
THREAT_CIVMALE = 16, // Civilan
|
||||
THREAT_CIVFEMALE = 32, // Civilan
|
||||
THREAT_COP = 64, // Police
|
||||
THREAT_GANG1 = 128, // Mafia
|
||||
THREAT_GANG2 = 256, // Triad
|
||||
THREAT_GANG3 = 512, // Diablo
|
||||
THREAT_GANG4 = 1024, // Yakuza
|
||||
THREAT_GANG5 = 2048, // Yardie
|
||||
THREAT_GANG6 = 4096, // Columbian
|
||||
THREAT_GANG7 = 8192, // Hood
|
||||
THREAT_GANG8 = 16384, // Unused
|
||||
THREAT_GANG9 = 32768, // Unused
|
||||
THREAT_EMERGENCY = 65536, // Emergency services
|
||||
THREAT_PROSTITUTE = 131072, // ...
|
||||
THREAT_CRIMINAL = 262144, // Criminals
|
||||
THREAT_SPECIAL = 524288, // SPECIAL
|
||||
THREAT_GUN = 1048576, // Not sure
|
||||
THREAT_COP_CAR = 2097152,
|
||||
THREAT_FAST_CAR = 4194304,
|
||||
THREAT_EXPLOSION = 8388608, // Explosions
|
||||
THREAT_FIREMAN = 16777216, // Firemen?
|
||||
THREAT_DEADPEDS = 33554432, // Dead bodies
|
||||
};
|
||||
|
||||
uint32_t id_ = 0;
|
||||
|
||||
// Unknown values
|
||||
float a_ = 0.f;
|
||||
float b_ = 0.f;
|
||||
float c_ = 0.f;
|
||||
float d_ = 0.f;
|
||||
float e_ = 0.f;
|
||||
|
||||
uint32_t threatflags_ = 0;
|
||||
uint32_t avoidflags_ = 0;
|
||||
|
||||
static uint32_t threatFromName(const std::string& name);
|
||||
};
|
||||
|
||||
using PedGroup = std::vector<uint16_t>;
|
||||
using PedGroupList = std::vector<PedGroup>;
|
||||
|
||||
#endif
|
@ -53,6 +53,8 @@ void GameData::load() {
|
||||
loadHandling("data/handling.cfg");
|
||||
loadWaterpro("data/waterpro.dat");
|
||||
loadWeaponDAT("data/weapon.dat");
|
||||
loadPedStats("data/pedstats.dat");
|
||||
loadPedRelations("data/ped.dat");
|
||||
|
||||
loadIFP("ped.ifp");
|
||||
|
||||
@ -62,6 +64,9 @@ void GameData::load() {
|
||||
|
||||
loadLevelFile("data/default.dat");
|
||||
loadLevelFile("data/gta3.dat");
|
||||
|
||||
// Load ped groups after IDEs so they can resolve
|
||||
loadPedGroups("data/pedgrp.dat");
|
||||
}
|
||||
|
||||
void GameData::loadLevelFile(const std::string& path) {
|
||||
@ -116,7 +121,7 @@ void GameData::loadIDE(const std::string& path) {
|
||||
auto systempath = index.findFilePath(path).string();
|
||||
LoaderIDE idel;
|
||||
|
||||
if (idel.load(systempath)) {
|
||||
if (idel.load(systempath, pedstats)) {
|
||||
std::move(idel.objects.begin(), idel.objects.end(),
|
||||
std::inserter(modelinfo, modelinfo.end()));
|
||||
} else {
|
||||
@ -492,6 +497,115 @@ void GameData::loadWeaponDAT(const std::string& path) {
|
||||
l.loadWeapons(syspath, weaponData);
|
||||
}
|
||||
|
||||
void GameData::loadPedStats(const std::string& path) {
|
||||
auto syspath = index.findFilePath(path).string();
|
||||
std::ifstream fs(syspath.c_str());
|
||||
if (!fs.is_open()) {
|
||||
throw std::runtime_error("Failed to open " + path);
|
||||
}
|
||||
|
||||
std::string line;
|
||||
for (int i = 0; std::getline(fs, line);) {
|
||||
if (line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
// The name should be ignored, but we will use it anyway
|
||||
PedStats stats;
|
||||
stats.id_ = i++;
|
||||
std::stringstream ss(line);
|
||||
ss >> stats.name_;
|
||||
ss >> stats.fleedistance_;
|
||||
ss >> stats.rotaterate_;
|
||||
ss >> stats.fear_;
|
||||
ss >> stats.temper_;
|
||||
ss >> stats.lawful_;
|
||||
ss >> stats.sexy_;
|
||||
ss >> stats.attackstrength_;
|
||||
ss >> stats.defendweakness_;
|
||||
ss >> stats.flags_;
|
||||
|
||||
pedstats.push_back(stats);
|
||||
}
|
||||
}
|
||||
|
||||
void GameData::loadPedRelations(const std::string& path) {
|
||||
auto syspath = index.findFilePath(path).string();
|
||||
std::ifstream fs(syspath.c_str());
|
||||
if (!fs.is_open()) {
|
||||
throw std::runtime_error("Failed to open " + path);
|
||||
}
|
||||
|
||||
std::string line;
|
||||
for (int index = 0; std::getline(fs, line);) {
|
||||
if (line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
std::stringstream ss(line);
|
||||
if (isspace(line[0])) {
|
||||
// Add this flags to the last index
|
||||
ss >> line;
|
||||
if (line == "Avoid") {
|
||||
while (!ss.eof()) {
|
||||
ss >> line;
|
||||
auto flag = PedRelationship::threatFromName(line);
|
||||
pedrels[index].avoidflags_ |= flag;
|
||||
}
|
||||
}
|
||||
if (line == "Threat") {
|
||||
while (!ss.eof()) {
|
||||
ss >> line;
|
||||
auto flag = PedRelationship::threatFromName(line);
|
||||
pedrels[index].threatflags_ |= flag;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ss >> line;
|
||||
index = PedModelInfo::findPedType(line);
|
||||
PedRelationship& shp = pedrels[index];
|
||||
shp.id_ = PedRelationship::threatFromName(line);
|
||||
ss >> shp.a_;
|
||||
ss >> shp.b_;
|
||||
ss >> shp.c_;
|
||||
ss >> shp.d_;
|
||||
ss >> shp.e_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameData::loadPedGroups(const std::string& path) {
|
||||
auto syspath = index.findFilePath(path).string();
|
||||
std::ifstream fs(syspath.c_str());
|
||||
if (!fs.is_open()) {
|
||||
throw std::runtime_error("Failed to open " + path);
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while (std::getline(fs, line)) {
|
||||
if (line.empty() || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
std::stringstream ss(line);
|
||||
PedGroup group;
|
||||
while (ss >> line) {
|
||||
if (line.empty() || line[0] == '#') {
|
||||
break;
|
||||
}
|
||||
if (line.back() == ',') {
|
||||
line.resize(line.size()-1);
|
||||
}
|
||||
auto model = findModelObject(line);
|
||||
if (int16_t(model) == -1) {
|
||||
logger->error("Data", "Invalid model in ped group " + line);
|
||||
continue;
|
||||
}
|
||||
group.push_back(model);
|
||||
}
|
||||
if (!group.empty()) {
|
||||
pedgroups.emplace_back(std::move(group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GameData::loadAudioStream(const std::string& name) {
|
||||
auto systempath = index.findFilePath("audio/" + name).string();
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
class Logger;
|
||||
|
||||
#include <data/GameTexts.hpp>
|
||||
#include <data/PedData.hpp>
|
||||
#include <data/ZoneData.hpp>
|
||||
#include <loaders/LoaderDFF.hpp>
|
||||
#include <loaders/LoaderIDE.hpp>
|
||||
@ -159,6 +160,21 @@ public:
|
||||
*/
|
||||
void loadWeaponDAT(const std::string& path);
|
||||
|
||||
/**
|
||||
* Loads pedestrian stats from e.g. pedstats.dat
|
||||
*/
|
||||
void loadPedStats(const std::string& path);
|
||||
|
||||
/**
|
||||
* Loads pedestrian relations e.g. peds.dat
|
||||
*/
|
||||
void loadPedRelations(const std::string& path);
|
||||
|
||||
/**
|
||||
* Loads pedestrian groups e.g. pedgrp.dat for zone info
|
||||
*/
|
||||
void loadPedGroups(const std::string& path);
|
||||
|
||||
bool loadAudioStream(const std::string& name);
|
||||
bool loadAudioClip(const std::string& name, const std::string& fileName);
|
||||
|
||||
@ -272,6 +288,21 @@ public:
|
||||
|
||||
std::vector<std::shared_ptr<WeaponData>> weaponData;
|
||||
|
||||
/**
|
||||
* Pedstrian type stats
|
||||
*/
|
||||
std::vector<PedStats> pedstats;
|
||||
|
||||
/**
|
||||
* Pedestrian relationships
|
||||
*/
|
||||
std::array<PedRelationship, PedModelInfo::_NUM_PEDTYPE> pedrels;
|
||||
|
||||
/**
|
||||
* Pedestrian groups
|
||||
*/
|
||||
PedGroupList pedgroups;
|
||||
|
||||
/**
|
||||
* @struct WaterArea
|
||||
* Stores Water Rectangle Information
|
||||
|
@ -459,14 +459,14 @@ struct Block18Data {
|
||||
};
|
||||
|
||||
struct Block19PedType {
|
||||
BlockDword unknown1;
|
||||
BlockDword bitstring_;
|
||||
float unknown2;
|
||||
float unknown3;
|
||||
float unknown4;
|
||||
float unknown5;
|
||||
float unknown6;
|
||||
BlockDword unknown7;
|
||||
BlockDword unknown8;
|
||||
float fleedistance;
|
||||
float headingchangerate;
|
||||
BlockDword threatflags_;
|
||||
BlockDword avoidflags_;
|
||||
};
|
||||
struct Block19Data {
|
||||
Block19PedType types[23];
|
||||
@ -1190,11 +1190,16 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
|
||||
Block19Data pedTypeData;
|
||||
READ_VALUE(pedTypeData);
|
||||
|
||||
#if RW_DEBUG && 0 // Nor this
|
||||
#if RW_DEBUG
|
||||
for (int i = 0; i < 23; ++i) {
|
||||
if (pedTypeData.types[i].unknown1 & (0x1 << i) != 0) continue;
|
||||
std::cout << pedTypeData.types[i].unknown1 << " "
|
||||
<< pedTypeData.types[i].unknown7 << std::endl;
|
||||
printf("%08x: %f %f %f %f %f threat %08x avoid %08x\n", pedTypeData.types[i].bitstring_,
|
||||
pedTypeData.types[i].unknown2,
|
||||
pedTypeData.types[i].unknown3,
|
||||
pedTypeData.types[i].unknown4,
|
||||
pedTypeData.types[i].fleedistance,
|
||||
pedTypeData.types[i].headingchangerate,
|
||||
pedTypeData.types[i].threatflags_,
|
||||
pedTypeData.types[i].avoidflags_);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -8,11 +8,21 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
bool LoaderIDE::load(const std::string &filename) {
|
||||
bool LoaderIDE::load(const std::string &filename, const PedStatsList &stats) {
|
||||
std::ifstream str(filename);
|
||||
|
||||
if (!str.is_open()) return false;
|
||||
|
||||
auto find_stat_id = [&](const std::string &name) {
|
||||
auto it =
|
||||
std::find_if(stats.begin(), stats.end(),
|
||||
[&](const PedStats &a) { return a.name_ == name; });
|
||||
if (it == stats.end()) {
|
||||
return -1;
|
||||
}
|
||||
return it->id_;
|
||||
};
|
||||
|
||||
SectionTypes section = NONE;
|
||||
while (!str.eof()) {
|
||||
std::string line;
|
||||
@ -155,7 +165,9 @@ bool LoaderIDE::load(const std::string &filename) {
|
||||
getline(strstream, buff, ',');
|
||||
peds->pedtype_ = PedModelInfo::findPedType(buff);
|
||||
|
||||
getline(strstream, peds->behaviour_, ',');
|
||||
std::string behaviour;
|
||||
getline(strstream, behaviour, ',');
|
||||
peds->statindex_ = find_stat_id(behaviour);
|
||||
getline(strstream, peds->animgroup_, ',');
|
||||
|
||||
getline(strstream, buff, ',');
|
||||
@ -232,7 +244,7 @@ bool LoaderIDE::load(const std::string &filename) {
|
||||
}
|
||||
|
||||
auto &object = objects[path.ID];
|
||||
auto simple = dynamic_cast<SimpleModelInfo*>(object.get());
|
||||
auto simple = dynamic_cast<SimpleModelInfo *>(object.get());
|
||||
simple->paths.push_back(path);
|
||||
|
||||
break;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <data/ModelData.hpp>
|
||||
#include <data/PathData.hpp>
|
||||
#include <data/PedData.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
@ -22,7 +23,7 @@ public:
|
||||
};
|
||||
|
||||
// Load the IDE data into memory
|
||||
bool load(const std::string& filename);
|
||||
bool load(const std::string& filename, const PedStatsList& stats);
|
||||
|
||||
/**
|
||||
* @brief objects loaded during the call to load()
|
||||
|
@ -525,7 +525,10 @@ void RWGame::tick(float dt) {
|
||||
currentCam.getView());
|
||||
// Use the current camera position to spawn pedestrians.
|
||||
world->cleanupTraffic(currentCam);
|
||||
world->createTraffic(currentCam);
|
||||
// Only create new traffic outside cutscenes
|
||||
if (!state.currentCutscene) {
|
||||
world->createTraffic(currentCam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,77 @@ BOOST_AUTO_TEST_CASE(test_object_data) {
|
||||
BOOST_CHECK_EQUAL(def->flags, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_ped_stats) {
|
||||
GameData gd(&Global::get().log, Global::getGamePath());
|
||||
gd.load();
|
||||
|
||||
BOOST_REQUIRE(gd.pedstats.size() > 2);
|
||||
|
||||
auto& stat1 = gd.pedstats[0];
|
||||
auto& stat2 = gd.pedstats[1];
|
||||
|
||||
BOOST_CHECK_EQUAL(stat1.id_, 0);
|
||||
BOOST_CHECK_EQUAL(stat1.fleedistance_, 0.0f);
|
||||
BOOST_CHECK_EQUAL(stat1.defendweakness_, 0.4f);
|
||||
BOOST_CHECK_EQUAL(stat1.flags_, 6);
|
||||
|
||||
BOOST_CHECK_EQUAL(stat2.id_, 1);
|
||||
BOOST_CHECK_EQUAL(stat2.fleedistance_, 20.0f);
|
||||
BOOST_CHECK_EQUAL(stat2.defendweakness_, 1.0f);
|
||||
BOOST_CHECK_EQUAL(stat2.flags_, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_ped_stat_info) {
|
||||
GameData gd(&Global::get().log, Global::getGamePath());
|
||||
gd.load();
|
||||
|
||||
BOOST_REQUIRE(gd.pedstats.size() > 2);
|
||||
BOOST_REQUIRE(gd.modelinfo.find(1) != gd.modelinfo.end());
|
||||
auto it = gd.modelinfo.find(1);
|
||||
auto cop = static_cast<PedModelInfo*>(it->second.get());
|
||||
|
||||
auto& stat_cop = gd.pedstats[1];
|
||||
|
||||
BOOST_CHECK_EQUAL(cop->statindex_, stat_cop.id_);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_ped_relations) {
|
||||
GameData gd(&Global::get().log, Global::getGamePath());
|
||||
gd.load();
|
||||
|
||||
auto& rel_cop = gd.pedrels[PedModelInfo::COP];
|
||||
auto& rel_crim = gd.pedrels[PedModelInfo::CRIMINAL];
|
||||
|
||||
BOOST_CHECK_EQUAL(rel_cop.id_, PedRelationship::THREAT_COP);
|
||||
BOOST_CHECK_EQUAL(rel_cop.threatflags_,
|
||||
PedRelationship::THREAT_GUN |
|
||||
PedRelationship::THREAT_EXPLOSION |
|
||||
PedRelationship::THREAT_DEADPEDS);
|
||||
BOOST_CHECK_EQUAL(rel_crim.id_, PedRelationship::THREAT_CRIMINAL);
|
||||
BOOST_CHECK_EQUAL(rel_crim.threatflags_,
|
||||
PedRelationship::THREAT_GUN |
|
||||
PedRelationship::THREAT_COP |
|
||||
PedRelationship::THREAT_COP_CAR |
|
||||
PedRelationship::THREAT_EXPLOSION);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_ped_groups) {
|
||||
GameData gd(&Global::get().log, Global::getGamePath());
|
||||
gd.load();
|
||||
|
||||
BOOST_REQUIRE(gd.pedgroups.size() > 2);
|
||||
|
||||
const auto& def = gd.pedgroups[0];
|
||||
const auto& red = gd.pedgroups[1];
|
||||
|
||||
BOOST_REQUIRE_GE(def.size(), 8);
|
||||
BOOST_CHECK_EQUAL(def[0], 30);
|
||||
|
||||
BOOST_REQUIRE_GE(red.size(), 8);
|
||||
BOOST_CHECK_EQUAL(red[0], 34);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -9,7 +9,7 @@ BOOST_AUTO_TEST_CASE(test_object_data) {
|
||||
{
|
||||
LoaderIDE l;
|
||||
|
||||
l.load(Global::get().getGamePath() + "/data/maps/generic.ide");
|
||||
l.load(Global::get().getGamePath() + "/data/maps/generic.ide", {});
|
||||
|
||||
BOOST_ASSERT(l.objects.find(1100) != l.objects.end());
|
||||
|
||||
@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(test_object_data) {
|
||||
{
|
||||
LoaderIDE l;
|
||||
|
||||
l.load(Global::get().getGamePath() + "/data/default.ide");
|
||||
l.load(Global::get().getGamePath() + "/data/default.ide", {});
|
||||
|
||||
BOOST_ASSERT(l.objects.find(90) != l.objects.end());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user