osb/source/game/items/StarArmors.cpp

229 lines
7.9 KiB
C++
Raw Normal View History

2023-06-20 04:33:09 +00:00
#include "StarArmors.hpp"
#include "StarAssets.hpp"
#include "StarJsonExtra.hpp"
#include "StarImageProcessing.hpp"
#include "StarHumanoid.hpp"
#include "StarRoot.hpp"
#include "StarStoredFunctions.hpp"
#include "StarPlayer.hpp"
2023-06-24 12:49:47 +00:00
#include "StarDirectives.hpp"
2023-06-20 04:33:09 +00:00
namespace Star {
ArmorItem::ArmorItem(Json const& config, String const& directory, Json const& data) : Item(config, directory, data), SwingableItem(config) {
2023-06-20 04:33:09 +00:00
refreshStatusEffects();
m_effectSources = jsonToStringSet(instanceValue("effectSources", JsonArray()));
m_techModule = instanceValue("techModule", "").toString();
if (m_techModule->empty())
m_techModule = {};
else
m_techModule = AssetPath::relativeTo(directory, *m_techModule);
m_directives = instanceValue("directives", "").toString();
m_colorOptions = colorDirectivesFromConfig(config.getArray("colorOptions", JsonArray{""}));
2023-06-24 15:16:40 +00:00
if (!m_directives)
2023-06-20 04:33:09 +00:00
m_directives = "?" + m_colorOptions.wrap(instanceValue("colorIndex", 0).toUInt());
refreshIconDrawables();
m_hideBody = config.getBool("hideBody", false);
}
List<PersistentStatusEffect> ArmorItem::statusEffects() const {
return m_statusEffects;
}
StringSet ArmorItem::effectSources() const {
return m_effectSources;
}
List<Drawable> ArmorItem::drawables() const {
auto drawables = iconDrawables();
Drawable::scaleAll(drawables, 1.0f / TilePixels);
Drawable::translateAll(drawables, -handPosition() / TilePixels);
return drawables;
}
float ArmorItem::getAngle(float) {
return -25.0f * Constants::deg2rad;
}
void ArmorItem::fire(FireMode, bool, bool) {}
void ArmorItem::fireTriggered() {}
2023-06-20 04:33:09 +00:00
List<String> const& ArmorItem::colorOptions() {
return m_colorOptions;
}
2023-06-24 12:49:47 +00:00
Directives const& ArmorItem::directives() const {
2023-06-20 04:33:09 +00:00
return m_directives;
}
bool ArmorItem::hideBody() const {
return m_hideBody;
}
Maybe<String> const& ArmorItem::techModule() const {
return m_techModule;
}
void ArmorItem::refreshIconDrawables() {
auto drawables = iconDrawables();
for (auto& drawable : drawables) {
if (drawable.isImage()) {
drawable.imagePart().removeDirectives(true);
drawable.imagePart().addDirectives(m_directives, true);
}
}
setIconDrawables(std::move(drawables));
2023-06-20 04:33:09 +00:00
}
void ArmorItem::refreshStatusEffects() {
m_statusEffects = instanceValue("statusEffects", JsonArray()).toArray().transformed(jsonToPersistentStatusEffect);
if (auto leveledStatusEffects = instanceValue("leveledStatusEffects", Json())) {
auto functionDatabase = Root::singleton().functionDatabase();
float level = instanceValue("level", 1).toFloat();
for (auto effectConfig : leveledStatusEffects.iterateArray()) {
float levelFunctionFactor = functionDatabase->function(effectConfig.getString("levelFunction"))->evaluate(level);
auto statModifier = jsonToStatModifier(effectConfig);
if (auto p = statModifier.ptr<StatBaseMultiplier>())
p->baseMultiplier = 1 + (p->baseMultiplier - 1) * levelFunctionFactor;
else if (auto p = statModifier.ptr<StatValueModifier>())
p->value *= levelFunctionFactor;
else if (auto p = statModifier.ptr<StatEffectiveMultiplier>())
p->effectiveMultiplier = 1 + (p->effectiveMultiplier - 1) * levelFunctionFactor;
m_statusEffects.append(statModifier);
}
}
if (auto augmentConfig = instanceValue("currentAugment", Json()))
m_statusEffects.appendAll(augmentConfig.getArray("effects", JsonArray()).transformed(jsonToPersistentStatusEffect));
}
HeadArmor::HeadArmor(Json const& config, String const& directory, Json const& data)
: ArmorItem(config, directory, data) {
m_maleImage = AssetPath::relativeTo(directory, config.getString("maleFrames"));
m_femaleImage = AssetPath::relativeTo(directory, config.getString("femaleFrames"));
2023-06-24 12:49:47 +00:00
String maskDirectivesStr = instanceValue("mask").toString();
if (!maskDirectivesStr.empty() && !maskDirectivesStr.contains("?"))
m_maskDirectives = "?addmask=" + AssetPath::relativeTo(directory, maskDirectivesStr) + ";0;0";
else
m_maskDirectives = maskDirectivesStr;
2023-06-20 04:33:09 +00:00
}
ItemPtr HeadArmor::clone() const {
return make_shared<HeadArmor>(*this);
}
String const& HeadArmor::frameset(Gender gender) const {
if (gender == Gender::Male)
return m_maleImage;
else
return m_femaleImage;
}
2023-06-24 12:49:47 +00:00
Directives const& HeadArmor::maskDirectives() const {
2023-06-20 04:33:09 +00:00
return m_maskDirectives;
}
List<Drawable> HeadArmor::preview(PlayerPtr const& viewer) const {
Gender gender = viewer ? viewer->gender() : Gender::Male;
//Humanoid humanoid = Humanoid::makeDummy(gender);
Humanoid humanoid = viewer ? *viewer->humanoid() : Humanoid::makeDummy(gender);
return humanoid.renderDummy(gender, this, nullptr, nullptr, nullptr);
2023-06-20 04:33:09 +00:00
}
ChestArmor::ChestArmor(Json const& config, String const& directory, Json const& data)
: ArmorItem(config, directory, data) {
Json maleImages = config.get("maleFrames");
m_maleBodyImage = AssetPath::relativeTo(directory, maleImages.getString("body"));
m_maleFrontSleeveImage = AssetPath::relativeTo(directory, maleImages.getString("frontSleeve"));
m_maleBackSleeveImage = AssetPath::relativeTo(directory, maleImages.getString("backSleeve"));
Json femaleImages = config.get("femaleFrames");
m_femaleBodyImage = AssetPath::relativeTo(directory, femaleImages.getString("body"));
m_femaleFrontSleeveImage = AssetPath::relativeTo(directory, femaleImages.getString("frontSleeve"));
m_femaleBackSleeveImage = AssetPath::relativeTo(directory, femaleImages.getString("backSleeve"));
}
ItemPtr ChestArmor::clone() const {
return make_shared<ChestArmor>(*this);
}
String const& ChestArmor::bodyFrameset(Gender gender) const {
if (gender == Gender::Male)
return m_maleBodyImage;
else
return m_femaleBodyImage;
}
String const& ChestArmor::frontSleeveFrameset(Gender gender) const {
if (gender == Gender::Male)
return m_maleFrontSleeveImage;
else
return m_femaleFrontSleeveImage;
}
String const& ChestArmor::backSleeveFrameset(Gender gender) const {
if (gender == Gender::Male)
return m_maleBackSleeveImage;
else
return m_femaleBackSleeveImage;
}
List<Drawable> ChestArmor::preview(PlayerPtr const& viewer) const {
Gender gender = viewer ? viewer->gender() : Gender::Male;
//Humanoid humanoid = Humanoid::makeDummy(gender);
Humanoid humanoid = viewer ? *viewer->humanoid() : Humanoid::makeDummy(gender);
return humanoid.renderDummy(gender, nullptr, this, nullptr, nullptr);
2023-06-20 04:33:09 +00:00
}
LegsArmor::LegsArmor(Json const& config, String const& directory, Json const& data)
: ArmorItem(config, directory, data) {
m_maleImage = AssetPath::relativeTo(directory, config.getString("maleFrames"));
m_femaleImage = AssetPath::relativeTo(directory, config.getString("femaleFrames"));
}
ItemPtr LegsArmor::clone() const {
return make_shared<LegsArmor>(*this);
}
String const& LegsArmor::frameset(Gender gender) const {
if (gender == Gender::Male)
return m_maleImage;
else
return m_femaleImage;
}
List<Drawable> LegsArmor::preview(PlayerPtr const& viewer) const {
Gender gender = viewer ? viewer->gender() : Gender::Male;
//Humanoid humanoid = Humanoid::makeDummy(gender);
Humanoid humanoid = viewer ? *viewer->humanoid() : Humanoid::makeDummy(gender);
return humanoid.renderDummy(gender, nullptr, nullptr, this, nullptr);
2023-06-20 04:33:09 +00:00
}
BackArmor::BackArmor(Json const& config, String const& directory, Json const& data)
: ArmorItem(config, directory, data) {
m_maleImage = AssetPath::relativeTo(directory, config.getString("maleFrames"));
m_femaleImage = AssetPath::relativeTo(directory, config.getString("femaleFrames"));
}
ItemPtr BackArmor::clone() const {
return make_shared<BackArmor>(*this);
}
String const& BackArmor::frameset(Gender gender) const {
if (gender == Gender::Male)
return m_maleImage;
else
return m_femaleImage;
}
List<Drawable> BackArmor::preview(PlayerPtr const& viewer) const {
Gender gender = viewer ? viewer->gender() : Gender::Male;
//Humanoid humanoid = Humanoid::makeDummy(gender);
Humanoid humanoid = viewer ? *viewer->humanoid() : Humanoid::makeDummy(gender);
return humanoid.renderDummy(gender, nullptr, nullptr, nullptr, this);
2023-06-20 04:33:09 +00:00
}
}