runeeffects.cpp

main 113 lines · 3.4 KB Raw
Alex Alex Commit Server upload 18/10/2026 23:38
1#include "otpch.h"
2
3#include "runeeffects.h"
4
5#include "pugicast.h"
6#include "tools.h"
7
8bool RuneEffects::reload()
9{
10 runeEffects.clear();
11 return loadFromXml();
12}
13
14bool RuneEffects::loadFromXml()
15{
16 pugi::xml_document doc;
17 pugi::xml_parse_result result = doc.load_file("data/XML/runeffects.xml");
18 if (!result) {
19 printXMLError("Error - RuneEffects::loadFromXml", "data/XML/runeffects.xml", result);
20 return false;
21 }
22
23 for (auto node : doc.child("runeffects").children()) {
24 RuneEffect re(
25 static_cast<uint8_t>(pugi::cast<uint16_t>(node.attribute("id").value())),
26 node.attribute("name").as_string(),
27 node.attribute("image").as_string(),
28 static_cast<uint16_t>(pugi::cast<uint16_t>(node.attribute("effectId").value())),
29 node.attribute("speed").as_float(0.5f),
30 node.attribute("scale").as_float(1.0f),
31 node.attribute("opacity").as_float(0.8f),
32 node.attribute("color").as_string("#ffffff"),
33 node.attribute("layer").as_string("back"),
34 node.attribute("glow").as_float(1.0f),
35 node.attribute("colorShift").as_float(0.0f),
36 node.attribute("noise").as_float(0.0f),
37 node.attribute("scanlines").as_float(0.0f),
38 node.attribute("flicker").as_float(0.0f),
39 pugi::cast<int32_t>(node.attribute("bonusLoot").value()),
40 pugi::cast<int32_t>(node.attribute("bonusDamage").value()),
41 pugi::cast<int32_t>(node.attribute("bonusSpeed").value()),
42 pugi::cast<int32_t>(node.attribute("bonusXp").value()),
43 node.attribute("damageInterval").as_int(2000),
44 node.attribute("damageDelay").as_int(200),
45 node.attribute("premium").as_bool()
46 );
47
48 // Parse <layer> children for multi-layer support
49 for (auto layerNode : node.children("layer")) {
50 std::string texture = layerNode.attribute("texture").as_string("");
51 uint16_t layerEffectId = static_cast<uint16_t>(pugi::cast<uint16_t>(layerNode.attribute("effectId").value()));
52
53 // If no texture and no effectId, try legacy single-image fallback
54 if (texture.empty() && layerEffectId == 0) {
55 continue;
56 }
57
58 re.layers.emplace_back(
59 texture,
60 layerEffectId,
61 layerNode.attribute("offsetX").as_float(0.0f),
62 layerNode.attribute("offsetY").as_float(0.0f),
63 layerNode.attribute("speed").as_float(re.speed),
64 layerNode.attribute("scale").as_float(re.scale),
65 layerNode.attribute("opacity").as_float(re.opacity),
66 layerNode.attribute("color").as_string(re.color.c_str()),
67 layerNode.attribute("flicker").as_float(re.flicker),
68 layerNode.attribute("colorShift").as_float(re.colorShift),
69 layerNode.attribute("drawOrder").as_int(0),
70 layerNode.attribute("behind").as_bool(true)
71 );
72 }
73
74 // Backward compat: if no <layer> children but has image/effectId, create implicit single layer
75 if (re.layers.empty() && (!re.image.empty() || re.effectId > 0)) {
76 re.layers.emplace_back(
77 re.image,
78 re.effectId,
79 0.0f, 0.0f,
80 re.speed, re.scale, re.opacity, re.color,
81 re.flicker, re.colorShift,
82 0,
83 true
84 );
85 }
86
87 runeEffects.emplace_back(std::move(re));
88 }
89 runeEffects.shrink_to_fit();
90 return true;
91}
92
93RuneEffect* RuneEffects::getRuneEffectByID(uint8_t id)
94{
95 auto it = std::find_if(runeEffects.begin(), runeEffects.end(), [id](const RuneEffect& re) {
96 return re.id == id;
97 });
98
99 return it != runeEffects.end() ? &*it : nullptr;
100}
101
102RuneEffect* RuneEffects::getRuneEffectByName(const std::string& name)
103{
104 auto effectName = name.c_str();
105 for (auto& it : runeEffects) {
106 if (strcasecmp(effectName, it.name.c_str()) == 0) {
107 return &it;
108 }
109 }
110
111 return nullptr;
112}
113
Top