init
This commit is contained in:
commit
87bff164f1
416 files changed
+279512
No files matched your search
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
// The contents of a flask or barrel: MaterialInventoryComponent holds how much of each material it has (count_per_material_type). A flask keeps its materials
|
||||
// apart (no reactions inside: do_reactions is 0 for potions), they react when they are poured out or spilled into the world.
|
||||
// Representation on the component: count_per_material_type.mix = "water:700;radioactive_liquid:300", plus the main material (the largest part) and the total count
|
||||
// under count_per_material_type.Material.material / .count (what scripts and the HUD read).
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lua/entity_api.h"
|
||||
|
||||
namespace ng {
|
||||
|
||||
struct MixPart { std::string mat; double n = 0; };
|
||||
|
||||
inline std::vector<MixPart> mix_get(IEntityWorld& w, int comp) {
|
||||
std::vector<MixPart> parts;
|
||||
const LVal mix = w.get_value(comp, "count_per_material_type.mix", false);
|
||||
if (mix.t == LVal::T::Str && !mix.s.empty()) {
|
||||
size_t pos = 0;
|
||||
while (pos < mix.s.size()) {
|
||||
size_t end = mix.s.find(';', pos);
|
||||
if (end == std::string::npos) end = mix.s.size();
|
||||
const std::string item = mix.s.substr(pos, end - pos);
|
||||
const size_t c = item.rfind(':');
|
||||
if (c != std::string::npos) parts.push_back({item.substr(0, c), std::atof(item.c_str() + c + 1)});
|
||||
pos = end + 1;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
const LVal m = w.get_value(comp, "count_per_material_type.Material.material", false), n = w.get_value(comp, "count_per_material_type.Material.count", false);
|
||||
if (m.t == LVal::T::Str && !m.s.empty() && n.t == LVal::T::Str && std::atof(n.s.c_str()) > 0) parts.push_back({m.s, std::atof(n.s.c_str())});
|
||||
return parts;
|
||||
}
|
||||
|
||||
inline double mix_total(const std::vector<MixPart>& p) { double t = 0; for (const MixPart& x : p) t += x.n; return t; }
|
||||
|
||||
inline void mix_set(IEntityWorld& w, int comp, std::vector<MixPart> parts) {
|
||||
parts.erase(std::remove_if(parts.begin(), parts.end(), [](const MixPart& x) { return x.n < 0.5; }), parts.end());
|
||||
std::stable_sort(parts.begin(), parts.end(), [](const MixPart& a, const MixPart& b) { return a.n > b.n; });
|
||||
std::string s;
|
||||
for (const MixPart& x : parts) s += (s.empty() ? "" : ";") + x.mat + ":" + std::to_string((long long)std::llround(x.n));
|
||||
w.set_value(comp, "count_per_material_type.mix", LVal::string(s));
|
||||
w.set_value(comp, "count_per_material_type.Material.material", LVal::string(parts.empty() ? std::string() : parts.front().mat));
|
||||
w.set_value(comp, "count_per_material_type.Material.count", LVal::string(std::to_string((long long)std::llround(mix_total(parts)))));
|
||||
}
|
||||
|
||||
inline void mix_add(std::vector<MixPart>& parts, const std::string& mat, double n) {
|
||||
for (MixPart& x : parts) if (x.mat == mat) { x.n += n; return; }
|
||||
parts.push_back({mat, n});
|
||||
}
|
||||
|
||||
} // namespace ng
|
||||
Reference in new issue
Block a user