Skip to content

Commit ff6e446

Browse files
committed
Merge remote-tracking branch 'origin/all-in-one-vs2022-wpo' into Scope-fix
2 parents 7d0497d + 6b6d05b commit ff6e446

File tree

14 files changed

+258
-55
lines changed

14 files changed

+258
-55
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

gamedata/gamedata/scripts/aaaa_script_fixes_mp.script

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ function ui_pda_npc_tab.use_view(obj)
4747
end
4848
end
4949

50+
-- NLTP_ASHES: Fix for ActorMenu_on_item_after_move callback sending nil values
51+
ui_inventory_UIInventory_Action_Move = ui_inventory.UIInventory.Action_Move
52+
function ui_inventory.UIInventory:Action_Move(obj, bag)
53+
obj = self:CheckItem(obj,"Action_Move")
54+
if obj then
55+
ui_inventory_UIInventory_Action_Move(self, obj, bag)
56+
end
57+
end
58+
5059
-- Additional params for callbacks
5160
-- Called on CHudItem Motion Mark
5261
_G.CHudItem__OnMotionMark = function(state, mark, obj, owner)

gamedata/gamedata/scripts/callbacks_gameobject.script

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,16 @@ function anomaly_on_before_activate(zone, obj, flags)
273273
end
274274
end
275275

276+
-- NLTP_ASHES: Trigger actor_on_item_put_in_box callback when moving item to stash from slot
277+
function ActorMenu_on_item_after_move(npc_id, obj, mode, bag_from)
278+
local box = level.object_by_id(npc_id)
279+
if box and IsInvbox(box) and mode == "loot" and bag_from == 1 then
280+
SendScriptCallback("actor_on_item_put_in_box", box, obj)
281+
end
282+
end
283+
276284
function on_game_start()
285+
RegisterScriptCallback("ActorMenu_on_item_after_move", ActorMenu_on_item_after_move)
277286
RegisterScriptCallback("anomaly_on_before_activate", anomaly_on_before_activate)
278287
RegisterScriptCallback("game_object_on_net_spawn", game_object_on_net_spawn)
279288
RegisterScriptCallback("game_object_on_net_destroy", game_object_on_net_destroy)

src/xrCore/log.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,15 @@ void CloseLog(void)
305305
LogFile->clear();
306306
xr_delete(LogFile);
307307
}
308+
309+
shared_str FormatString(LPCSTR fmt, ...)
310+
{
311+
va_list mark;
312+
string2048 buf;
313+
va_start(mark, fmt);
314+
int sz = _vsnprintf(buf, sizeof(buf) - 1, fmt, mark);
315+
buf[sizeof(buf) - 1] = 0;
316+
va_end(mark);
317+
if (sz) return shared_str(buf);
318+
return shared_str(0);
319+
}

src/xrCore/log.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ void XRCORE_API FlushLog();
2424
extern XRCORE_API xr_vector<shared_str>* LogFile;
2525
extern XRCORE_API BOOL LogExecCB;
2626

27+
shared_str FormatString(LPCSTR fmt, ...);
28+
2729
#endif

src/xrGame/WeaponMagazined.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ void CWeaponMagazined::Load(LPCSTR section)
103103
m_sounds.LoadSound(section, "snd_shoot_actor", "sndShotActor", false, m_eSoundShot);
104104
//-Alundaio
105105

106+
// Cyclic fire sounds
107+
if (WeaponSoundExist(section, "snd_shoot_actor_first"))
108+
m_sounds.LoadSound(section, "snd_shoot_actor_first", "sndShotActorFirst", false, m_eSoundShot);
109+
106110
//misfire shot
107111
if (WeaponSoundExist(section, "snd_shot_misfire"))
108112
m_sounds.LoadSound(section, "snd_shot_misfire", "sndShotMisfire", false, m_eSoundShot);
@@ -153,6 +157,10 @@ void CWeaponMagazined::Load(LPCSTR section)
153157
m_sounds.LoadSound(section, "snd_silncer_shot_actor", "sndSilencerShotActor", false, m_eSoundShot);
154158
//-Alundaio
155159

160+
// Cyclic fire sounds w/ silencer
161+
if (WeaponSoundExist(section, "snd_silncer_shoot_actor_first"))
162+
m_sounds.LoadSound(section, "snd_silncer_shoot_actor_first", "sndSilencerShotActorFirst", false, m_eSoundShot);
163+
156164
//misfire shot
157165
if (WeaponSoundExist(section, "snd_silncer_shot_misfire"))
158166
m_sounds.LoadSound(section, "snd_silncer_shot_misfire", "sndSilencerShotMisfire", false, m_eSoundShot);
@@ -669,6 +677,8 @@ void CWeaponMagazined::UpdateSounds()
669677
m_sounds.SetPosition("sndShotMisfire", P);
670678
if (m_sounds.FindSoundItem("sndShotMisfireActor", false))
671679
m_sounds.SetPosition("sndShotMisfireActor", P);
680+
if (m_sounds.FindSoundItem("sndShotActorFirst", false))
681+
m_sounds.SetPosition("sndShotActorFirst", P);
672682
}
673683

674684
// demonized: check if cycle_down is enabled and shot num below max possible burst. Adds support for arbitrary burst shot at rpm_mode_2 with cycling down to rpm after maxBurstAmount
@@ -819,6 +829,14 @@ void CWeaponMagazined::PlaySoundShot()
819829
}
820830
}
821831

832+
string128 sndNameFirst;
833+
strconcat(sizeof(sndNameFirst), sndNameFirst, m_sSndShotCurrent.c_str(), "ActorFirst");
834+
if (m_iShotNum == 1 && m_sounds.FindSoundItem(sndNameFirst, false))
835+
{
836+
m_sounds.PlaySound(sndNameFirst, get_LastFP(), H_Root(), !!GetHUDmode(), false, (u8)-1);
837+
return;
838+
}
839+
822840
string128 sndName;
823841
strconcat(sizeof(sndName), sndName, m_sSndShotCurrent.c_str(), "Actor");
824842
if (m_sounds.FindSoundItem(sndName, false))

src/xrGame/ai_space.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ void CAI_Space::patrol_path_storage_raw(IReader& stream)
197197
xr_delete(m_patrol_path_storage);
198198
m_patrol_path_storage = xr_new<CPatrolPathStorage>();
199199
m_patrol_path_storage->load_raw(get_level_graph(), get_cross_table(), get_game_graph(), stream);
200+
m_patrol_path_storage->load_from_config();
200201
}
201202

202203
void CAI_Space::patrol_path_storage(IReader& stream)
@@ -207,6 +208,7 @@ void CAI_Space::patrol_path_storage(IReader& stream)
207208
xr_delete(m_patrol_path_storage);
208209
m_patrol_path_storage = xr_new<CPatrolPathStorage>();
209210
m_patrol_path_storage->load(stream);
211+
m_patrol_path_storage->load_from_config();
210212
}
211213

212214
void CAI_Space::set_alife(CALifeSimulator* alife_simulator)

src/xrGame/patrol_path.cpp

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,29 @@
66
// Description : Patrol path
77
////////////////////////////////////////////////////////////////////////////
88

9+
#include <regex>
910
#include "stdafx.h"
1011
#include "patrol_path.h"
1112
#include "levelgamedef.h"
13+
#include "../xrCore/mezz_stringbuffer.h"
1214

1315
LPCSTR TEST_PATROL_PATH_NAME = "val_dogs_nest4_centre";
1416

1517
CPatrolPath::CPatrolPath(shared_str name)
1618
{
1719
#ifdef DEBUG
18-
m_name = name;
20+
m_name = name;
1921
#endif
2022
}
2123

22-
CPatrolPath& CPatrolPath::load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross,
23-
const CGameGraph* game_graph, IReader& stream)
24+
CPatrolPath& CPatrolPath::load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross, const CGameGraph* game_graph, IReader& stream)
2425
{
2526
R_ASSERT(stream.find_chunk(WAYOBJECT_CHUNK_POINTS));
2627
u32 vertex_count = stream.r_u16();
2728
for (u32 i = 0; i < vertex_count; ++i)
29+
{
2830
add_vertex(CPatrolPoint(this).load_raw(level_graph, cross, game_graph, stream), i);
31+
}
2932

3033
R_ASSERT(stream.find_chunk(WAYOBJECT_CHUNK_LINKS));
3134
u32 edge_count = stream.r_u16();
@@ -40,17 +43,86 @@ CPatrolPath& CPatrolPath::load_raw(const CLevelGraph* level_graph, const CGameLe
4043
return (*this);
4144
}
4245

46+
CPatrolPath& CPatrolPath::load_from_config(CInifile* ini_paths, LPCSTR patrol_name)
47+
{
48+
R_ASSERT3(ini_paths->line_exist(patrol_name, "points"), "Missing key 'points' in patrol path", patrol_name);
49+
LPCSTR points_csv = ini_paths->r_string(patrol_name, "points");
50+
std::vector<std::string> points = splitStringMulti(points_csv, ",", false, true);
51+
52+
// Keep track of name <-> vertex_id association
53+
std::map<shared_str, u32> vertex_ids_by_name;
54+
55+
// Add patrol points
56+
for (int idx = 0; idx < points.size(); idx++)
57+
{
58+
LPCSTR point_name = points[idx].c_str();
59+
Msg("[PP] Reading point %s", point_name);
60+
add_vertex(CPatrolPoint(this).load_from_config(ini_paths, patrol_name, point_name), idx);
61+
vertex_ids_by_name.emplace(point_name, idx);
62+
}
63+
64+
// Link patrol points
65+
for (int idx = 0; idx < points.size(); idx++)
66+
{
67+
LPCSTR point_name = points[idx].c_str();
68+
69+
Msg("[PP] Linking point for %s", point_name);
70+
71+
// Verify if point has links (links are optional)
72+
shared_str links_csv_key = FormatString("%s:%s", point_name, "links");
73+
if (!ini_paths->line_exist(patrol_name, links_csv_key))
74+
{
75+
continue;
76+
}
77+
78+
// Get list of vertices to link to
79+
LPCSTR links_csv = ini_paths->r_string(patrol_name, links_csv_key.c_str());
80+
std::vector<std::string> links = splitStringMulti(links_csv, ",", false, true);
81+
82+
for (std::string link : links)
83+
{
84+
// Link current point to target points
85+
std::pair<u16, float> link_info = parse_point_link(patrol_name, link, vertex_ids_by_name);
86+
add_edge(idx, link_info.first, link_info.second);
87+
Msg("[PP] Linked %d to %d with a probability of %f", link_info.first, idx, link_info.second);
88+
}
89+
}
90+
91+
vertex_ids_by_name.clear();
92+
93+
return (*this);
94+
}
95+
96+
std::pair<u32, float> CPatrolPath::parse_point_link(LPCSTR patrol_name, std::string link, std::map<shared_str, u32> vertex_ids_by_name)
97+
{
98+
Msg("[PP] Linking %s", link.c_str());
99+
100+
std::regex pattern("(\\w+)\\((\\d+)\\)");
101+
std::smatch matches;
102+
103+
bool matched = std::regex_search(link, matches, pattern);
104+
R_ASSERT4(matched, "Bad format for patrol path link", patrol_name, link.c_str());
105+
106+
std::string target = matches[1].str();
107+
float prob = std::stof(matches[2].str());
108+
109+
auto I = vertex_ids_by_name.find(target.c_str());
110+
R_ASSERT4(I != vertex_ids_by_name.end(), "Patrol point link target does not exist", patrol_name, target.c_str());
111+
112+
return std::make_pair((*I).second, prob);
113+
}
114+
43115
CPatrolPath::~CPatrolPath()
44116
{
45117
}
46118

47119
#ifdef DEBUG
48-
void CPatrolPath::load (IReader &stream)
120+
void CPatrolPath::load(IReader &stream)
49121
{
50122
inherited::load (stream);
51123
vertex_iterator I = vertices().begin();
52124
vertex_iterator E = vertices().end();
53125
for ( ; I != E; ++I)
54-
(*I).second->data().path (this);
126+
(*I).second->data().path(this);
55127
}
56128
#endif

src/xrGame/patrol_path.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include "stdafx.h"
1112
#include "graph_abstract.h"
1213
#include "patrol_point.h"
1314

@@ -33,13 +34,16 @@ class CPatrolPath : public CGraphAbstractSerialize<CPatrolPoint, float, u32>
3334
public:
3435
CPatrolPath(shared_str name = "");
3536
virtual ~CPatrolPath();
36-
CPatrolPath& load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross,
37-
const CGameGraph* game_graph, IReader& stream);
37+
CPatrolPath& load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross, const CGameGraph* game_graph, IReader& stream);
38+
CPatrolPath& load_from_config(CInifile* ini_paths, LPCSTR patrol_name);
3839
IC const CVertex* point(shared_str name) const;
3940
template <typename T>
4041
IC const CVertex* point(const Fvector& position, const T& evaluator) const;
4142
IC const CVertex* point(const Fvector& position) const;
4243

44+
private:
45+
std::pair<u32, float> CPatrolPath::parse_point_link(LPCSTR patrol_name, std::string link, std::map<shared_str, u32> vertex_ids_by_name);
46+
4347
#ifdef DEBUG
4448
public:
4549
virtual void load (IReader &stream);

src/xrGame/patrol_path_storage.cpp

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,15 @@ CPatrolPathStorage::~CPatrolPathStorage()
1717
delete_data(m_registry);
1818
}
1919

20-
void CPatrolPathStorage::load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross,
21-
const CGameGraph* game_graph, IReader& stream)
20+
void CPatrolPathStorage::load_raw(const CLevelGraph* level_graph, const CGameLevelCrossTable* cross, const CGameGraph* game_graph, IReader& stream)
2221
{
2322
IReader* chunk = stream.open_chunk(WAY_PATROLPATH_CHUNK);
2423

2524
if (!chunk)
2625
return;
2726

2827
u32 chunk_iterator;
29-
for (IReader* sub_chunk = chunk->open_chunk_iterator(chunk_iterator); sub_chunk; sub_chunk = chunk->
30-
open_chunk_iterator(chunk_iterator, sub_chunk))
28+
for (IReader* sub_chunk = chunk->open_chunk_iterator(chunk_iterator); sub_chunk; sub_chunk = chunk->open_chunk_iterator(chunk_iterator, sub_chunk))
3129
{
3230
R_ASSERT(sub_chunk->find_chunk(WAYOBJECT_CHUNK_VERSION));
3331
R_ASSERT(sub_chunk->r_u16() == WAYOBJECT_VERSION);
@@ -40,14 +38,7 @@ void CPatrolPathStorage::load_raw(const CLevelGraph* level_graph, const CGameLev
4038
m_registry.insert(
4139
std::make_pair(
4240
patrol_name,
43-
&xr_new<CPatrolPath>(
44-
patrol_name
45-
)->load_raw(
46-
level_graph,
47-
cross,
48-
game_graph,
49-
*sub_chunk
50-
)
41+
&xr_new<CPatrolPath>(patrol_name)->load_raw(level_graph, cross, game_graph, *sub_chunk)
5142
)
5243
);
5344
}
@@ -88,7 +79,7 @@ void CPatrolPathStorage::load(IReader& stream)
8879
VERIFY3(I == m_registry.end(), "Duplicated patrol path found ", *pair.first);
8980

9081
#ifdef DEBUG
91-
pair.second->name (pair.first);
82+
pair.second->name(pair.first);
9283
#endif
9384

9485
m_registry.insert(pair);
@@ -97,6 +88,41 @@ void CPatrolPathStorage::load(IReader& stream)
9788
chunk->close();
9889
}
9990

91+
void CPatrolPathStorage::load_from_config()
92+
{
93+
// Open patrol_paths.ltx
94+
string_path fname;
95+
FS.update_path(fname, "$game_config$", "patrol_paths.ltx");
96+
CInifile* ini_paths = xr_new<CInifile>(fname, TRUE);
97+
98+
Msg("[PP] %s initialized", fname);
99+
100+
// Iterate sections. Each section is a unique patrol path
101+
CInifile::Root& paths = ini_paths->sections();
102+
for (CInifile::Root::iterator i = paths.begin(), ie = paths.end(); i != ie; ++i)
103+
{
104+
// Get patrol path name
105+
LPCSTR patrol_name = (*i)->Name.c_str();
106+
107+
Msg("[PP] Reading section %s", patrol_name);
108+
109+
// Assert unique
110+
const_iterator exists = m_registry.find(patrol_name);
111+
R_ASSERT3(exists == m_registry.end(), "Duplicated patrol path found", patrol_name);
112+
113+
// Build CPatrolPath object
114+
CPatrolPath* patrol_path = &xr_new<CPatrolPath>(patrol_name)->load_from_config(ini_paths, patrol_name);
115+
116+
// Insert in registry
117+
PATROL_REGISTRY::value_type pair = std::make_pair(patrol_name, patrol_path);
118+
m_registry.insert(pair);
119+
}
120+
121+
Msg("[PP] Done reading patrol paths from configs");
122+
123+
xr_delete(ini_paths);
124+
}
125+
100126
void CPatrolPathStorage::save(IWriter& stream)
101127
{
102128
stream.open_chunk(0);

0 commit comments

Comments
 (0)