Skip to content

Commit 836435a

Browse files
committed
Loadout icons
1 parent 37911f1 commit 836435a

13 files changed

Lines changed: 434 additions & 132 deletions

CastingEssentials/CastingEssentials.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@
101101
<ClCompile Include="Modules\ConsoleTools.cpp" />
102102
<ClCompile Include="Modules\FOVOverride.cpp" />
103103
<ClCompile Include="Modules\Graphics.cpp" />
104+
<ClCompile Include="Modules\ItemSchema.cpp" />
104105
<ClCompile Include="Modules\Killfeed.cpp" />
105106
<ClCompile Include="Modules\Killstreaks.cpp" />
107+
<ClCompile Include="Modules\LoadoutIcons.cpp" />
106108
<ClCompile Include="Modules\LocalPlayer.cpp" />
107109
<ClCompile Include="Modules\MapConfigs.cpp" />
108110
<ClCompile Include="Modules\MapFlythroughs.cpp" />
@@ -148,8 +150,10 @@
148150
<ClInclude Include="Modules\FOVOverride.h" />
149151
<ClInclude Include="Modules\FreezeInfo.h" />
150152
<ClInclude Include="Modules\Graphics.h" />
153+
<ClInclude Include="Modules\ItemSchema.h" />
151154
<ClInclude Include="Modules\Killfeed.h" />
152155
<ClInclude Include="Modules\Killstreaks.h" />
156+
<ClInclude Include="Modules\LoadoutIcons.h" />
153157
<ClInclude Include="Modules\LocalPlayer.h" />
154158
<ClInclude Include="Modules\MapConfigs.h" />
155159
<ClInclude Include="Modules\MapFlythroughs.h" />

CastingEssentials/CastingEssentials.vcxproj.filters

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@
129129
<ClCompile Include="Misc\Polyhook.cpp">
130130
<Filter>Source Files</Filter>
131131
</ClCompile>
132+
<ClCompile Include="Modules\LoadoutIcons.cpp">
133+
<Filter>Source Files</Filter>
134+
</ClCompile>
135+
<ClCompile Include="Modules\ItemSchema.cpp">
136+
<Filter>Source Files</Filter>
137+
</ClCompile>
132138
</ItemGroup>
133139
<ItemGroup>
134140
<ClInclude Include="PluginBase\Plugin.h">
@@ -272,5 +278,11 @@
272278
<ClInclude Include="Hooking\GroupGlobalVirtualHook.h">
273279
<Filter>Header Files</Filter>
274280
</ClInclude>
281+
<ClInclude Include="Modules\LoadoutIcons.h">
282+
<Filter>Header Files</Filter>
283+
</ClInclude>
284+
<ClInclude Include="Modules\ItemSchema.h">
285+
<Filter>Header Files</Filter>
286+
</ClInclude>
275287
</ItemGroup>
276288
</Project>
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#include "ItemSchema.h"
2+
#include "PluginBase/Interfaces.h"
3+
4+
#include <filesystem.h>
5+
#include <KeyValues.h>
6+
7+
ItemSchema::ItemSchema()
8+
{
9+
LoadItemSchema();
10+
11+
PluginWarning("asdf");
12+
}
13+
14+
bool ItemSchema::CheckDependencies()
15+
{
16+
bool ready = true;
17+
18+
if (!Interfaces::GetFileSystem())
19+
{
20+
PluginWarning("Required interface IFileSystem for module %s not available!\n", GetModuleName());
21+
ready = false;
22+
}
23+
24+
return ready;
25+
}
26+
27+
int ItemSchema::GetBaseItemID(int specializedID) const
28+
{
29+
if (specializedID < 0 || (size_t)specializedID > m_MappingsSize)
30+
return specializedID;
31+
32+
return m_Mappings.get()[specializedID];
33+
}
34+
35+
void ItemSchema::LoadItemSchema()
36+
{
37+
KeyValues::AutoDelete basekv(new KeyValues("none"));
38+
39+
constexpr const char* FILENAME = "scripts/items/items_game.txt";
40+
if (!basekv->LoadFromFile(Interfaces::GetFileSystem(), FILENAME))
41+
{
42+
PluginWarning("Failed to load %s for module %s!\n", FILENAME, GetModuleName());
43+
return;
44+
}
45+
46+
KeyValues* items = basekv->FindKey("items");
47+
48+
KeyValues* item = items->GetFirstTrueSubKey();
49+
if (!item)
50+
{
51+
PluginWarning("No items found in the item schema???\n");
52+
return;
53+
}
54+
55+
size_t mappingCount = 0;
56+
57+
std::map<int, std::vector<int>> mappings;
58+
int maxItemID = 0;
59+
60+
do
61+
{
62+
const char* name = item->GetName();
63+
if (!isdigit(name[0]))
64+
continue;
65+
66+
const int itemID = atoi(name);
67+
68+
const char* prefabTypes = item->GetString("prefab", nullptr);
69+
if (!prefabTypes)
70+
continue;
71+
72+
char firstPrefabType[128];
73+
GetFirstPrefabType(item->GetString("prefab"), firstPrefabType, sizeof(firstPrefabType));
74+
75+
const int firstFoundPrefab = GetFirstItemUsingPrefab(items, firstPrefabType);
76+
77+
if (firstFoundPrefab < itemID)
78+
{
79+
mappings[firstFoundPrefab].push_back(itemID);
80+
maxItemID = max(maxItemID, itemID);
81+
mappingCount++;
82+
}
83+
84+
} while (item = item->GetNextTrueSubKey());
85+
86+
PluginMsg("Generated item schema mappings: %zu down to %zu.\n", mappingCount, mappings.size());
87+
88+
// Just allocate an array for O(1) lookup
89+
m_MappingsSize = maxItemID + 1;
90+
m_Mappings.reset(new int[m_MappingsSize]);
91+
92+
// Assign them to their index
93+
for (size_t i = 0; i < m_MappingsSize; i++)
94+
m_Mappings.get()[i] = (int)i;
95+
96+
for (const auto& mapping : mappings)
97+
{
98+
for (const auto& child : mapping.second)
99+
{
100+
Assert(child < m_MappingsSize);
101+
m_Mappings.get()[child] = mapping.first;
102+
}
103+
}
104+
}
105+
106+
void ItemSchema::GetFirstPrefabType(const char* prefabsGroup, char* prefabOut, size_t maxOutSize)
107+
{
108+
while (maxOutSize-- && *prefabsGroup && !isspace(*prefabsGroup))
109+
*prefabOut++ = *prefabsGroup++;
110+
111+
Assert(maxOutSize != (size_t)-1 && maxOutSize > 0);
112+
113+
*prefabOut = '\0';
114+
}
115+
116+
int ItemSchema::GetFirstItemUsingPrefab(KeyValues* items, const char* prefabName)
117+
{
118+
Assert(items);
119+
Assert(prefabName && prefabName[0]);
120+
121+
const size_t prefabNameLength = strlen(prefabName);
122+
123+
KeyValues* kv = items->GetFirstTrueSubKey();
124+
if (!kv)
125+
{
126+
Assert(false);
127+
return -1;
128+
}
129+
130+
do
131+
{
132+
const char* prefabTypes = kv->GetString("prefab");
133+
bool match = false;
134+
while (*prefabTypes)
135+
{
136+
const size_t wordLength = strcspn(prefabTypes, WHITESPACE_CHARS);
137+
if (wordLength == prefabNameLength)
138+
{
139+
if (!strnicmp(prefabTypes, prefabName, prefabNameLength))
140+
{
141+
match = true;
142+
break;
143+
}
144+
}
145+
146+
prefabTypes += wordLength;
147+
prefabTypes += strspn(prefabTypes, WHITESPACE_CHARS);
148+
}
149+
150+
if (!match)
151+
continue;
152+
153+
const char* name = kv->GetName();
154+
155+
return atoi(name);
156+
157+
} while (kv = kv->GetNextTrueSubKey());
158+
159+
return -1;
160+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
3+
#include "PluginBase/Modules.h"
4+
5+
#include <vector>
6+
7+
class ConCommand;
8+
class ConVar;
9+
class IConVar;
10+
class KeyValues;
11+
12+
class ItemSchema : public Module
13+
{
14+
public:
15+
ItemSchema();
16+
17+
static ItemSchema* GetModule() { return Modules().GetModule<ItemSchema>(); }
18+
static const char* GetModuleName() { return Modules().GetModuleName<ItemSchema>().c_str(); }
19+
20+
static bool CheckDependencies();
21+
22+
// Converts a "specialized" version of an item (a botkiller medigun, for example) into its
23+
// "base" item (a stock medigun)
24+
int GetBaseItemID(int specializedID) const;
25+
26+
private:
27+
void LoadItemSchema();
28+
29+
static void GetFirstPrefabType(const char* prefabsGroup, char* prefabOut, size_t maxOutSize);
30+
int GetFirstItemUsingPrefab(KeyValues* items, const char* prefabName);
31+
32+
// O(1) lookup
33+
std::unique_ptr<int> m_Mappings;
34+
size_t m_MappingsSize;
35+
};

0 commit comments

Comments
 (0)