forked from themrdemonized/xray-monolith
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpatrol_path.cpp
More file actions
127 lines (103 loc) · 3.62 KB
/
patrol_path.cpp
File metadata and controls
127 lines (103 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
////////////////////////////////////////////////////////////////////////////
// Module : patrol_path.cpp
// Created : 15.06.2004
// Modified : 15.06.2004
// Author : Dmitriy Iassenev
// Description : Patrol path
////////////////////////////////////////////////////////////////////////////
#include <regex>
#include "stdafx.h"
#include "patrol_path.h"
#include "levelgamedef.h"
#include "../xrCore/mezz_stringbuffer.h"
LPCSTR TEST_PATROL_PATH_NAME = "val_dogs_nest4_centre";
CPatrolPath::CPatrolPath(shared_str name)
{
#ifdef DEBUG
m_name = name;
#endif
}
CPatrolPath& CPatrolPath::load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross, const CGameGraph* game_graph, IReader& stream)
{
R_ASSERT(stream.find_chunk(WAYOBJECT_CHUNK_POINTS));
u32 vertex_count = stream.r_u16();
for (u32 i = 0; i < vertex_count; ++i)
{
add_vertex(CPatrolPoint(this).load_raw(level_graph, cross, game_graph, stream), i);
}
R_ASSERT(stream.find_chunk(WAYOBJECT_CHUNK_LINKS));
u32 edge_count = stream.r_u16();
for (u32 i = 0; i < edge_count; ++i)
{
u16 vertex0 = stream.r_u16();
u16 vertex1 = stream.r_u16();
float probability = stream.r_float();
add_edge(vertex0, vertex1, probability);
}
return (*this);
}
CPatrolPath& CPatrolPath::load_from_config(CInifile* ini_paths, LPCSTR patrol_name)
{
LPCSTR points_csv = ini_paths->r_string(patrol_name, "points");
std::vector<std::string> points = splitStringMulti(points_csv, ",", false, true);
// Keep track of name <-> vertex_id association
std::map<shared_str, u32> vertex_ids_by_name;
// Add patrol points
for (int idx = 0; idx < points.size(); idx++)
{
LPCSTR point_name = points[idx].c_str();
Msg("[ASHES] Reading point %s", point_name);
add_vertex(CPatrolPoint(this).load_from_config(ini_paths, patrol_name, point_name), idx);
vertex_ids_by_name.emplace(point_name, idx);
}
// Link patrol points
for (int idx = 0; idx < points.size(); idx++)
{
LPCSTR point_name = points[idx].c_str();
Msg("[ASHES] Linking point for %s", point_name);
// Verify if point has links (links are optional)
shared_str links_csv_key = FormatString("%s:%s", point_name, "links");
if (!ini_paths->line_exist(patrol_name, links_csv_key))
{
continue;
}
// Get list of vertices to link to
LPCSTR links_csv = ini_paths->r_string(patrol_name, links_csv_key.c_str());
std::vector<std::string> links = splitStringMulti(links_csv, ",", false, true);
for (std::string link : links)
{
// Link current point to target points
std::pair<u16, float> link_info = parse_point_link(link, vertex_ids_by_name);
add_edge(idx, link_info.first, link_info.second);
Msg("[ASHES] Linked %d to %d with a probability of %f", link_info.first, idx, link_info.second);
}
}
vertex_ids_by_name.clear();
return (*this);
}
std::pair<u32, float> CPatrolPath::parse_point_link(std::string link, std::map<shared_str, u32> vertex_ids_by_name)
{
Msg("[ASHES] Linking %s", link.c_str());
std::regex pattern("(\\w+)\\((\\d+)\\)");
std::smatch matches;
bool matched = std::regex_search(link, matches, pattern);
R_ASSERT2(matched, "Bad format for patrol path link", link);
std::string target = matches[1].str();
float prob = std::stof(matches[2].str());
auto I = vertex_ids_by_name.find(target.c_str());
R_ASSERT2(I != vertex_ids_by_name.end(), "Patrol point link target does not exist", str);
return std::make_pair((*I).second, prob);
}
CPatrolPath::~CPatrolPath()
{
}
#ifdef DEBUG
void CPatrolPath::load(IReader &stream)
{
inherited::load (stream);
vertex_iterator I = vertices().begin();
vertex_iterator E = vertices().end();
for ( ; I != E; ++I)
(*I).second->data().path(this);
}
#endif