More directives optimization
This commit is contained in:
parent
e2424b7dcf
commit
7d205330db
@ -221,7 +221,7 @@ Color::Color(const String& name) {
|
||||
if (i != NamedColors.end())
|
||||
*this = i->second;
|
||||
else
|
||||
throw ColorException(strf("Named color %s not found", name));
|
||||
throw ColorException(strf("Named color %s not found", name), false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,30 +303,7 @@ uint32_t Color::toUint32() const {
|
||||
}
|
||||
|
||||
Color Color::fromHex(String const& s) {
|
||||
uint8_t cbytes[4];
|
||||
|
||||
if (s.utf8Size() == 3) {
|
||||
nibbleDecode(s.utf8Ptr(), 3, (char*)cbytes, 4);
|
||||
cbytes[0] = (cbytes[0] << 4) | cbytes[0];
|
||||
cbytes[1] = (cbytes[1] << 4) | cbytes[1];
|
||||
cbytes[2] = (cbytes[2] << 4) | cbytes[2];
|
||||
cbytes[3] = 255;
|
||||
} else if (s.utf8Size() == 4) {
|
||||
nibbleDecode(s.utf8Ptr(), 4, (char*)cbytes, 4);
|
||||
cbytes[0] = (cbytes[0] << 4) | cbytes[0];
|
||||
cbytes[1] = (cbytes[1] << 4) | cbytes[1];
|
||||
cbytes[2] = (cbytes[2] << 4) | cbytes[2];
|
||||
cbytes[3] = (cbytes[3] << 4) | cbytes[3];
|
||||
} else if (s.utf8Size() == 6) {
|
||||
hexDecode(s.utf8Ptr(), 6, (char*)cbytes, 4);
|
||||
cbytes[3] = 255;
|
||||
} else if (s.utf8Size() == 8) {
|
||||
hexDecode(s.utf8Ptr(), 8, (char*)cbytes, 4);
|
||||
} else {
|
||||
throw ColorException(strf("Improper size for hex string '%s' in Color::fromHex", s));
|
||||
}
|
||||
|
||||
return Color::rgba(cbytes[0], cbytes[1], cbytes[2], cbytes[3]);
|
||||
return Color::rgba(hexToVec4B(s));
|
||||
}
|
||||
|
||||
Vec4B Color::toRgba() const {
|
||||
@ -624,4 +601,31 @@ Vec4B Color::hueShiftVec4B(Vec4B color, float hue) {
|
||||
}
|
||||
}
|
||||
|
||||
Vec4B Color::hexToVec4B(String const& s) {
|
||||
Array<uint8_t, 4> cbytes;
|
||||
|
||||
if (s.utf8Size() == 3) {
|
||||
nibbleDecode(s.utf8Ptr(), 3, (char*)cbytes.data(), 4);
|
||||
cbytes[0] = (cbytes[0] << 4) | cbytes[0];
|
||||
cbytes[1] = (cbytes[1] << 4) | cbytes[1];
|
||||
cbytes[2] = (cbytes[2] << 4) | cbytes[2];
|
||||
cbytes[3] = 255;
|
||||
} else if (s.utf8Size() == 4) {
|
||||
nibbleDecode(s.utf8Ptr(), 4, (char*)cbytes.data(), 4);
|
||||
cbytes[0] = (cbytes[0] << 4) | cbytes[0];
|
||||
cbytes[1] = (cbytes[1] << 4) | cbytes[1];
|
||||
cbytes[2] = (cbytes[2] << 4) | cbytes[2];
|
||||
cbytes[3] = (cbytes[3] << 4) | cbytes[3];
|
||||
} else if (s.utf8Size() == 6) {
|
||||
hexDecode(s.utf8Ptr(), 6, (char*)cbytes.data(), 4);
|
||||
cbytes[3] = 255;
|
||||
} else if (s.utf8Size() == 8) {
|
||||
hexDecode(s.utf8Ptr(), 8, (char*)cbytes.data(), 4);
|
||||
} else {
|
||||
throw ColorException(strf("Improper size for hex string '%s' in Color::hexToVec4B", s), false);
|
||||
}
|
||||
|
||||
return Vec4B(move(cbytes));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
static Color temperature(float temp);
|
||||
|
||||
static Vec4B hueShiftVec4B(Vec4B color, float hue);
|
||||
|
||||
static Vec4B Color::hexToVec4B(String const& s);
|
||||
// Black
|
||||
Color();
|
||||
|
||||
|
@ -229,6 +229,10 @@ inline size_t DirectivesGroup::hash() const {
|
||||
return hasher.digest();
|
||||
}
|
||||
|
||||
const List<Directives>& DirectivesGroup::list() const {
|
||||
return m_directives;
|
||||
}
|
||||
|
||||
bool operator==(DirectivesGroup const& a, DirectivesGroup const& b) {
|
||||
return a.compare(b);
|
||||
}
|
||||
@ -237,6 +241,21 @@ bool operator!=(DirectivesGroup const& a, DirectivesGroup const& b) {
|
||||
return !a.compare(b);
|
||||
}
|
||||
|
||||
DataStream& operator>>(DataStream& ds, DirectivesGroup& directivesGroup) {
|
||||
String string;
|
||||
ds.read(string);
|
||||
|
||||
directivesGroup = move(DirectivesGroup(move(string)));
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator<<(DataStream& ds, DirectivesGroup const& directivesGroup) {
|
||||
ds.write(directivesGroup.toString());
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
size_t hash<DirectivesGroup>::operator()(DirectivesGroup const& s) const {
|
||||
return s.hash();
|
||||
}
|
||||
|
@ -73,9 +73,13 @@ public:
|
||||
void applyExistingImage(Image& image) const;
|
||||
|
||||
inline size_t hash() const;
|
||||
const List<Directives>& list() const;
|
||||
|
||||
friend bool operator==(DirectivesGroup const& a, DirectivesGroup const& b);
|
||||
friend bool operator!=(DirectivesGroup const& a, DirectivesGroup const& b);
|
||||
|
||||
friend DataStream& operator>>(DataStream& ds, DirectivesGroup& directives);
|
||||
friend DataStream& operator<<(DataStream& ds, DirectivesGroup const& directives);
|
||||
private:
|
||||
void buildString(String& string, const DirectivesGroup& directives) const;
|
||||
|
||||
|
@ -13,7 +13,7 @@ public:
|
||||
StarException() noexcept;
|
||||
virtual ~StarException() noexcept;
|
||||
|
||||
explicit StarException(std::string message) noexcept;
|
||||
explicit StarException(std::string message, bool genStackTrace = true) noexcept;
|
||||
explicit StarException(std::exception const& cause) noexcept;
|
||||
StarException(std::string message, std::exception const& cause) noexcept;
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
friend OutputProxy outputException(std::exception const& e, bool fullStacktrace);
|
||||
|
||||
protected:
|
||||
StarException(char const* type, std::string message) noexcept;
|
||||
StarException(char const* type, std::string message, bool genStackTrace = true) noexcept;
|
||||
StarException(char const* type, std::string message, std::exception const& cause) noexcept;
|
||||
|
||||
private:
|
||||
@ -68,22 +68,22 @@ void fatalException(std::exception const& e, bool showStackTrace);
|
||||
{}
|
||||
#endif
|
||||
|
||||
#define STAR_EXCEPTION(ClassName, BaseName) \
|
||||
class ClassName : public BaseName { \
|
||||
public: \
|
||||
template <typename... Args> \
|
||||
static ClassName format(char const* fmt, Args const&... args) { \
|
||||
return ClassName(strf(fmt, args...)); \
|
||||
} \
|
||||
ClassName() : BaseName(#ClassName, std::string()) {} \
|
||||
explicit ClassName(std::string message) : BaseName(#ClassName, move(message)) {} \
|
||||
explicit ClassName(std::exception const& cause) : BaseName(#ClassName, std::string(), cause) {} \
|
||||
ClassName(std::string message, std::exception const& cause) : BaseName(#ClassName, move(message), cause) {} \
|
||||
\
|
||||
protected: \
|
||||
ClassName(char const* type, std::string message) : BaseName(type, move(message)) {} \
|
||||
ClassName(char const* type, std::string message, std::exception const& cause) \
|
||||
: BaseName(type, move(message), cause) {} \
|
||||
#define STAR_EXCEPTION(ClassName, BaseName) \
|
||||
class ClassName : public BaseName { \
|
||||
public: \
|
||||
template <typename... Args> \
|
||||
static ClassName format(char const* fmt, Args const&... args) { \
|
||||
return ClassName(strf(fmt, args...)); \
|
||||
} \
|
||||
ClassName() : BaseName(#ClassName, std::string()) {} \
|
||||
explicit ClassName(std::string message, bool genStackTrace = true) : BaseName(#ClassName, move(message), genStackTrace) {} \
|
||||
explicit ClassName(std::exception const& cause) : BaseName(#ClassName, std::string(), cause) {} \
|
||||
ClassName(std::string message, std::exception const& cause) : BaseName(#ClassName, move(message), cause) {} \
|
||||
\
|
||||
protected: \
|
||||
ClassName(char const* type, std::string message, bool genStackTrace = true) : BaseName(type, move(message), genStackTrace) {} \
|
||||
ClassName(char const* type, std::string message, std::exception const& cause) \
|
||||
: BaseName(type, move(message), cause) {} \
|
||||
}
|
||||
|
||||
STAR_EXCEPTION(OutOfRangeException, StarException);
|
||||
|
@ -38,8 +38,8 @@ StarException::StarException() noexcept
|
||||
|
||||
StarException::~StarException() noexcept {}
|
||||
|
||||
StarException::StarException(std::string message) noexcept
|
||||
: StarException("StarException", move(message)) {}
|
||||
StarException::StarException(std::string message, bool genStackTrace) noexcept
|
||||
: StarException("StarException", move(message), genStackTrace) {}
|
||||
|
||||
StarException::StarException(std::exception const& cause) noexcept
|
||||
: StarException("StarException", std::string(), cause) {}
|
||||
@ -56,19 +56,19 @@ const char* StarException::what() const throw() {
|
||||
return m_whatBuffer.c_str();
|
||||
}
|
||||
|
||||
StarException::StarException(char const* type, std::string message) noexcept {
|
||||
auto printException = [](std::ostream& os, bool fullStacktrace, char const* type, std::string message, StackCapture stack) {
|
||||
StarException::StarException(char const* type, std::string message, bool genStackTrace) noexcept {
|
||||
auto printException = [](std::ostream& os, bool fullStacktrace, char const* type, std::string message, Maybe<StackCapture> stack) {
|
||||
os << "(" << type << ")";
|
||||
if (!message.empty())
|
||||
os << " " << message;
|
||||
|
||||
if (fullStacktrace) {
|
||||
if (fullStacktrace && stack) {
|
||||
os << std::endl;
|
||||
os << outputStack(stack);
|
||||
os << outputStack(*stack);
|
||||
}
|
||||
};
|
||||
|
||||
m_printException = bind(printException, _1, _2, type, move(message), captureStack());
|
||||
m_printException = bind(printException, _1, _2, type, move(message), genStackTrace ? captureStack() : Maybe<StackCapture>());
|
||||
}
|
||||
|
||||
StarException::StarException(char const* type, std::string message, std::exception const& cause) noexcept
|
||||
|
@ -145,7 +145,7 @@ StarException::StarException() noexcept : StarException(std::string("StarExcepti
|
||||
|
||||
StarException::~StarException() noexcept {}
|
||||
|
||||
StarException::StarException(std::string message) noexcept : StarException("StarException", move(message)) {}
|
||||
StarException::StarException(std::string message, bool genStackTrace) noexcept : StarException("StarException", move(message), genStackTrace) {}
|
||||
|
||||
StarException::StarException(std::exception const& cause) noexcept
|
||||
: StarException("StarException", std::string(), cause) {}
|
||||
@ -162,20 +162,20 @@ const char* StarException::what() const throw() {
|
||||
return m_whatBuffer.c_str();
|
||||
}
|
||||
|
||||
StarException::StarException(char const* type, std::string message) noexcept {
|
||||
StarException::StarException(char const* type, std::string message, bool genStackTrace) noexcept {
|
||||
auto printException = [](
|
||||
std::ostream& os, bool fullStacktrace, char const* type, std::string message, StackCapture stack) {
|
||||
std::ostream& os, bool fullStacktrace, char const* type, std::string message, Maybe<StackCapture> stack) {
|
||||
os << "(" << type << ")";
|
||||
if (!message.empty())
|
||||
os << " " << message;
|
||||
|
||||
if (fullStacktrace) {
|
||||
if (fullStacktrace && stack) {
|
||||
os << std::endl;
|
||||
os << outputStack(stack);
|
||||
os << outputStack(*stack);
|
||||
}
|
||||
};
|
||||
|
||||
m_printException = bind(printException, _1, _2, type, move(message), captureStack());
|
||||
m_printException = bind(printException, _1, _2, type, move(message), genStackTrace ? captureStack() : Maybe<StackCapture>());
|
||||
}
|
||||
|
||||
StarException::StarException(char const* type, std::string message, std::exception const& cause) noexcept
|
||||
|
@ -173,7 +173,7 @@ ImageOperation imageOperationFromString(String const& string) {
|
||||
} else if (type == "replace") {
|
||||
ColorReplaceImageOperation operation;
|
||||
for (size_t i = 0; i < (bits.size() - 1) / 2; ++i)
|
||||
operation.colorReplaceMap[Color::fromHex(bits[i * 2 + 1]).toRgba()] = Color::fromHex(bits[i * 2 + 2]).toRgba();
|
||||
operation.colorReplaceMap[Color::hexToVec4B(bits[i * 2 + 1])] = Color::hexToVec4B(bits[i * 2 + 2]);
|
||||
|
||||
return operation;
|
||||
|
||||
@ -259,7 +259,7 @@ ImageOperation imageOperationFromString(String const& string) {
|
||||
return FlipImageOperation{FlipImageOperation::FlipXY};
|
||||
|
||||
} else {
|
||||
throw ImageOperationException(strf("Could not recognize ImageOperation type %s", type));
|
||||
throw ImageOperationException(strf("Could not recognize ImageOperation type %s", type), false);
|
||||
}
|
||||
} catch (OutOfRangeException const& e) {
|
||||
throw ImageOperationException("Error reading ImageOperation", e);
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
namespace Star {
|
||||
|
||||
ArmorWearer::ArmorWearer() : m_lastNude(true), m_needsHumanoidSync(true) {
|
||||
ArmorWearer::ArmorWearer() : m_lastNude(true) {
|
||||
addNetElement(&m_headItemDataNetState);
|
||||
addNetElement(&m_chestItemDataNetState);
|
||||
addNetElement(&m_legsItemDataNetState);
|
||||
@ -25,26 +25,34 @@ ArmorWearer::ArmorWearer() : m_lastNude(true), m_needsHumanoidSync(true) {
|
||||
addNetElement(&m_chestCosmeticItemDataNetState);
|
||||
addNetElement(&m_legsCosmeticItemDataNetState);
|
||||
addNetElement(&m_backCosmeticItemDataNetState);
|
||||
|
||||
m_headNeedsSync = m_chestNeedsSync = m_legsNeedsSync = m_backNeedsSync = true;
|
||||
}
|
||||
|
||||
void ArmorWearer::setupHumanoidClothingDrawables(Humanoid& humanoid, bool forceNude) {
|
||||
if (m_lastNude != forceNude)
|
||||
bool nudeChanged = m_lastNude != forceNude;
|
||||
if (nudeChanged)
|
||||
m_lastNude = forceNude;
|
||||
else if (!m_needsHumanoidSync)
|
||||
return;
|
||||
|
||||
m_needsHumanoidSync = false;
|
||||
bool headNeedsSync = nudeChanged || m_headNeedsSync;
|
||||
bool chestNeedsSync = nudeChanged || m_chestNeedsSync;
|
||||
bool legsNeedsSync = nudeChanged || m_legsNeedsSync;
|
||||
bool backNeedsSync = nudeChanged || m_backNeedsSync;
|
||||
|
||||
bool bodyHidden = false;
|
||||
if (m_headCosmeticItem && !forceNude) {
|
||||
humanoid.setHeadArmorFrameset(m_headCosmeticItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setHeadArmorDirectives(m_headCosmeticItem->directives());
|
||||
humanoid.setHelmetMaskDirectives(m_headCosmeticItem->maskDirectives());
|
||||
if (headNeedsSync) {
|
||||
humanoid.setHeadArmorFrameset(m_headCosmeticItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setHeadArmorDirectives(m_headCosmeticItem->directives());
|
||||
humanoid.setHelmetMaskDirectives(m_headCosmeticItem->maskDirectives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_headCosmeticItem->hideBody();
|
||||
} else if (m_headItem && !forceNude) {
|
||||
humanoid.setHeadArmorFrameset(m_headItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setHeadArmorDirectives(m_headItem->directives());
|
||||
humanoid.setHelmetMaskDirectives(m_headItem->maskDirectives());
|
||||
if (headNeedsSync) {
|
||||
humanoid.setHeadArmorFrameset(m_headItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setHeadArmorDirectives(m_headItem->directives());
|
||||
humanoid.setHelmetMaskDirectives(m_headItem->maskDirectives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_headItem->hideBody();
|
||||
} else {
|
||||
humanoid.setHeadArmorFrameset("");
|
||||
@ -52,16 +60,20 @@ void ArmorWearer::setupHumanoidClothingDrawables(Humanoid& humanoid, bool forceN
|
||||
}
|
||||
|
||||
if (m_chestCosmeticItem && !forceNude) {
|
||||
humanoid.setBackSleeveFrameset(m_chestCosmeticItem->backSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setFrontSleeveFrameset(m_chestCosmeticItem->frontSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorFrameset(m_chestCosmeticItem->bodyFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorDirectives(m_chestCosmeticItem->directives());
|
||||
if (chestNeedsSync) {
|
||||
humanoid.setBackSleeveFrameset(m_chestCosmeticItem->backSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setFrontSleeveFrameset(m_chestCosmeticItem->frontSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorFrameset(m_chestCosmeticItem->bodyFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorDirectives(m_chestCosmeticItem->directives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_chestCosmeticItem->hideBody();
|
||||
} else if (m_chestItem && !forceNude) {
|
||||
humanoid.setBackSleeveFrameset(m_chestItem->backSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setFrontSleeveFrameset(m_chestItem->frontSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorFrameset(m_chestItem->bodyFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorDirectives(m_chestItem->directives());
|
||||
if (chestNeedsSync) {
|
||||
humanoid.setBackSleeveFrameset(m_chestItem->backSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setFrontSleeveFrameset(m_chestItem->frontSleeveFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorFrameset(m_chestItem->bodyFrameset(humanoid.identity().gender));
|
||||
humanoid.setChestArmorDirectives(m_chestItem->directives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_chestItem->hideBody();
|
||||
} else {
|
||||
humanoid.setBackSleeveFrameset("");
|
||||
@ -70,29 +82,39 @@ void ArmorWearer::setupHumanoidClothingDrawables(Humanoid& humanoid, bool forceN
|
||||
}
|
||||
|
||||
if (m_legsCosmeticItem && !forceNude) {
|
||||
humanoid.setLegsArmorFrameset(m_legsCosmeticItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setLegsArmorDirectives(m_legsCosmeticItem->directives());
|
||||
if (legsNeedsSync) {
|
||||
humanoid.setLegsArmorFrameset(m_legsCosmeticItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setLegsArmorDirectives(m_legsCosmeticItem->directives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_legsCosmeticItem->hideBody();
|
||||
} else if (m_legsItem && !forceNude) {
|
||||
humanoid.setLegsArmorFrameset(m_legsItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setLegsArmorDirectives(m_legsItem->directives());
|
||||
if (legsNeedsSync) {
|
||||
humanoid.setLegsArmorFrameset(m_legsItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setLegsArmorDirectives(m_legsItem->directives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_legsItem->hideBody();
|
||||
} else {
|
||||
humanoid.setLegsArmorFrameset("");
|
||||
}
|
||||
|
||||
if (m_backCosmeticItem && !forceNude) {
|
||||
humanoid.setBackArmorFrameset(m_backCosmeticItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setBackArmorDirectives(m_backCosmeticItem->directives());
|
||||
if (backNeedsSync) {
|
||||
humanoid.setBackArmorFrameset(m_backCosmeticItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setBackArmorDirectives(m_backCosmeticItem->directives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_backCosmeticItem->hideBody();
|
||||
} else if (m_backItem && !forceNude) {
|
||||
humanoid.setBackArmorFrameset(m_backItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setBackArmorDirectives(m_backItem->directives());
|
||||
if (backNeedsSync) {
|
||||
humanoid.setBackArmorFrameset(m_backItem->frameset(humanoid.identity().gender));
|
||||
humanoid.setBackArmorDirectives(m_backItem->directives());
|
||||
}
|
||||
bodyHidden = bodyHidden || m_backItem->hideBody();
|
||||
} else {
|
||||
humanoid.setBackArmorFrameset("");
|
||||
}
|
||||
|
||||
m_headNeedsSync = m_chestNeedsSync = m_legsNeedsSync = m_backNeedsSync = false;
|
||||
|
||||
humanoid.setBodyHidden(bodyHidden);
|
||||
}
|
||||
|
||||
@ -171,56 +193,56 @@ void ArmorWearer::setHeadItem(HeadArmorPtr headItem) {
|
||||
if (Item::itemsEqual(m_headItem, headItem))
|
||||
return;
|
||||
m_headItem = headItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_headNeedsSync |= !m_headCosmeticItem;
|
||||
}
|
||||
|
||||
void ArmorWearer::setHeadCosmeticItem(HeadArmorPtr headCosmeticItem) {
|
||||
if (Item::itemsEqual(m_headCosmeticItem, headCosmeticItem))
|
||||
return;
|
||||
m_headCosmeticItem = headCosmeticItem;
|
||||
m_needsHumanoidSync = true;
|
||||
}
|
||||
|
||||
void ArmorWearer::setChestCosmeticItem(ChestArmorPtr chestCosmeticItem) {
|
||||
if (Item::itemsEqual(m_chestCosmeticItem, chestCosmeticItem))
|
||||
return;
|
||||
m_chestCosmeticItem = chestCosmeticItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_headNeedsSync = true;
|
||||
}
|
||||
|
||||
void ArmorWearer::setChestItem(ChestArmorPtr chestItem) {
|
||||
if (Item::itemsEqual(m_chestItem, chestItem))
|
||||
return;
|
||||
m_chestItem = chestItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_chestNeedsSync |= !m_chestCosmeticItem;
|
||||
}
|
||||
|
||||
void ArmorWearer::setChestCosmeticItem(ChestArmorPtr chestCosmeticItem) {
|
||||
if (Item::itemsEqual(m_chestCosmeticItem, chestCosmeticItem))
|
||||
return;
|
||||
m_chestCosmeticItem = chestCosmeticItem;
|
||||
m_chestNeedsSync = true;
|
||||
}
|
||||
|
||||
void ArmorWearer::setLegsItem(LegsArmorPtr legsItem) {
|
||||
if (Item::itemsEqual(m_legsItem, legsItem))
|
||||
return;
|
||||
m_legsItem = legsItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_legsNeedsSync |= !m_legsCosmeticItem;
|
||||
}
|
||||
|
||||
void ArmorWearer::setLegsCosmeticItem(LegsArmorPtr legsCosmeticItem) {
|
||||
if (Item::itemsEqual(m_legsCosmeticItem, legsCosmeticItem))
|
||||
return;
|
||||
m_legsCosmeticItem = legsCosmeticItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_legsNeedsSync = true;
|
||||
}
|
||||
|
||||
void ArmorWearer::setBackItem(BackArmorPtr backItem) {
|
||||
if (Item::itemsEqual(m_backItem, backItem))
|
||||
return;
|
||||
m_backItem = backItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_backNeedsSync |= !m_backCosmeticItem;
|
||||
}
|
||||
|
||||
void ArmorWearer::setBackCosmeticItem(BackArmorPtr backCosmeticItem) {
|
||||
if (Item::itemsEqual(m_backCosmeticItem, backCosmeticItem))
|
||||
return;
|
||||
m_backCosmeticItem = backCosmeticItem;
|
||||
m_needsHumanoidSync = true;
|
||||
m_backNeedsSync = true;
|
||||
}
|
||||
|
||||
HeadArmorPtr ArmorWearer::headItem() const {
|
||||
@ -306,26 +328,23 @@ ItemDescriptor ArmorWearer::backCosmeticItemDescriptor() const {
|
||||
void ArmorWearer::netElementsNeedLoad(bool) {
|
||||
auto itemDatabase = Root::singleton().itemDatabase();
|
||||
|
||||
bool changed = false;
|
||||
if (m_headItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_headItemDataNetState.get(), m_headItem);
|
||||
if (m_chestItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_chestItemDataNetState.get(), m_chestItem);
|
||||
if (m_legsItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_legsItemDataNetState.get(), m_legsItem);
|
||||
if (m_backItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_backItemDataNetState.get(), m_backItem);
|
||||
|
||||
if (m_headCosmeticItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_headCosmeticItemDataNetState.get(), m_headCosmeticItem);
|
||||
m_headNeedsSync |= itemDatabase->loadItem(m_headCosmeticItemDataNetState.get(), m_headCosmeticItem);
|
||||
if (m_chestCosmeticItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_chestCosmeticItemDataNetState.get(), m_chestCosmeticItem);
|
||||
m_chestNeedsSync |= itemDatabase->loadItem(m_chestCosmeticItemDataNetState.get(), m_chestCosmeticItem);
|
||||
if (m_legsCosmeticItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_legsCosmeticItemDataNetState.get(), m_legsCosmeticItem);
|
||||
m_legsNeedsSync |= itemDatabase->loadItem(m_legsCosmeticItemDataNetState.get(), m_legsCosmeticItem);
|
||||
if (m_backCosmeticItemDataNetState.pullUpdated())
|
||||
changed |= itemDatabase->loadItem(m_backCosmeticItemDataNetState.get(), m_backCosmeticItem);
|
||||
m_backNeedsSync |= itemDatabase->loadItem(m_backCosmeticItemDataNetState.get(), m_backCosmeticItem);
|
||||
|
||||
m_needsHumanoidSync = changed;
|
||||
if (m_headItemDataNetState.pullUpdated())
|
||||
m_headNeedsSync |= !m_headCosmeticItem && itemDatabase->loadItem(m_headItemDataNetState.get(), m_headItem);
|
||||
if (m_chestItemDataNetState.pullUpdated())
|
||||
m_chestNeedsSync |= !m_chestCosmeticItem && itemDatabase->loadItem(m_chestItemDataNetState.get(), m_chestItem);
|
||||
if (m_legsItemDataNetState.pullUpdated())
|
||||
m_legsNeedsSync |= !m_legsCosmeticItem && itemDatabase->loadItem(m_legsItemDataNetState.get(), m_legsItem);
|
||||
if (m_backItemDataNetState.pullUpdated())
|
||||
m_backNeedsSync |= !m_backCosmeticItem && itemDatabase->loadItem(m_backItemDataNetState.get(), m_backItem);
|
||||
}
|
||||
|
||||
void ArmorWearer::netElementsNeedStore() {
|
||||
|
@ -35,8 +35,8 @@ public:
|
||||
|
||||
void setHeadItem(HeadArmorPtr headItem);
|
||||
void setHeadCosmeticItem(HeadArmorPtr headCosmeticItem);
|
||||
void setChestCosmeticItem(ChestArmorPtr chestCosmeticItem);
|
||||
void setChestItem(ChestArmorPtr chestItem);
|
||||
void setChestCosmeticItem(ChestArmorPtr chestCosmeticItem);
|
||||
void setLegsItem(LegsArmorPtr legsItem);
|
||||
void setLegsCosmeticItem(LegsArmorPtr legsCosmeticItem);
|
||||
void setBackItem(BackArmorPtr backItem);
|
||||
@ -84,7 +84,10 @@ private:
|
||||
NetElementData<ItemDescriptor> m_backCosmeticItemDataNetState;
|
||||
|
||||
bool m_lastNude;
|
||||
bool m_needsHumanoidSync;
|
||||
bool m_headNeedsSync;
|
||||
bool m_chestNeedsSync;
|
||||
bool m_legsNeedsSync;
|
||||
bool m_backNeedsSync;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,28 @@ Drawable::ImagePart& Drawable::ImagePart::addDirectives(Directives const& direct
|
||||
return *this;
|
||||
}
|
||||
|
||||
Drawable::ImagePart& Drawable::ImagePart::addDirectivesGroup(DirectivesGroup const& directivesGroup, bool keepImageCenterPosition) {
|
||||
if (directivesGroup.empty())
|
||||
return *this;
|
||||
|
||||
if (keepImageCenterPosition) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
Vec2F imageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
for (Directives const& directives : directivesGroup.list())
|
||||
image.directives += directives;
|
||||
Vec2F newImageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
|
||||
// If we are trying to maintain the image center, PRE translate the image by
|
||||
// the change in size / 2
|
||||
transformation *= Mat3F::translation((imageSize - newImageSize) / 2);
|
||||
} else {
|
||||
for (Directives const& directives : directivesGroup.list())
|
||||
image.directives += directives;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Drawable::ImagePart& Drawable::ImagePart::removeDirectives(bool keepImageCenterPosition) {
|
||||
if (keepImageCenterPosition) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
|
@ -30,6 +30,7 @@ struct Drawable {
|
||||
// transformed center of the image the same if the directives change the
|
||||
// image size.
|
||||
ImagePart& addDirectives(Directives const& directives, bool keepImageCenterPosition = false);
|
||||
ImagePart& addDirectivesGroup(DirectivesGroup const& directivesGroup, bool keepImageCenterPosition = false);
|
||||
|
||||
// Remove directives from this ImagePart, while optionally keeping the
|
||||
// transformed center of the image the same if the directives change the
|
||||
|
@ -487,7 +487,7 @@ void Monster::update(uint64_t) {
|
||||
void Monster::render(RenderCallback* renderCallback) {
|
||||
for (auto& drawable : m_networkedAnimator.drawables(position())) {
|
||||
if (drawable.isImage())
|
||||
drawable.imagePart().addDirectives(m_statusController->parentDirectives(), true);
|
||||
drawable.imagePart().addDirectivesGroup(m_statusController->parentDirectives(), true);
|
||||
renderCallback->addDrawable(move(drawable), m_monsterVariant.renderLayer);
|
||||
}
|
||||
|
||||
|
@ -385,7 +385,7 @@ void NetworkedAnimator::setPartTag(String const& partType, String tagName, Strin
|
||||
m_partTags[partType].set(move(tagName), move(tagValue));
|
||||
}
|
||||
|
||||
void NetworkedAnimator::setProcessingDirectives(String const& directives) {
|
||||
void NetworkedAnimator::setProcessingDirectives(Directives const& directives) {
|
||||
m_processingDirectives.set(directives);
|
||||
}
|
||||
|
||||
@ -562,8 +562,7 @@ List<Drawable> NetworkedAnimator::drawables(Vec2F const& position) const {
|
||||
}
|
||||
|
||||
List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const& position) const {
|
||||
String baseProcessingDirectives = "?";
|
||||
baseProcessingDirectives.append(m_processingDirectives.get());
|
||||
List<Directives> baseProcessingDirectives = { m_processingDirectives.get() };
|
||||
for (auto& pair : m_effects) {
|
||||
auto const& effectState = pair.second;
|
||||
|
||||
@ -571,11 +570,9 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
|
||||
auto const& effect = m_effects.get(pair.first);
|
||||
if (effect.type == "flash") {
|
||||
if (effectState.timer > effect.time / 2) {
|
||||
baseProcessingDirectives.append("?");
|
||||
baseProcessingDirectives.append(effect.directives);
|
||||
}
|
||||
} else if (effect.type == "directive") {
|
||||
baseProcessingDirectives.append("?");
|
||||
baseProcessingDirectives.append(effect.directives);
|
||||
} else {
|
||||
throw NetworkedAnimatorException(strf("No such NetworkedAnimator effect type '%s'", effect.type));
|
||||
@ -595,10 +592,9 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
|
||||
maybeZLevel = activePart.properties.value("flippedZLevel").optFloat().orMaybe(maybeZLevel);
|
||||
float zLevel = maybeZLevel.value(0.0f);
|
||||
|
||||
String processingDirectives = baseProcessingDirectives;
|
||||
size_t originalDirectivesSize = baseProcessingDirectives.size();
|
||||
if (auto directives = activePart.properties.value("processingDirectives").optString()) {
|
||||
processingDirectives.append("?");
|
||||
processingDirectives.append(*directives);
|
||||
baseProcessingDirectives.append(*directives);
|
||||
}
|
||||
|
||||
Maybe<unsigned> frame;
|
||||
@ -606,8 +602,7 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
|
||||
frame = activePart.activeState->frame;
|
||||
|
||||
if (auto directives = activePart.activeState->properties.value("processingDirectives").optString()) {
|
||||
processingDirectives.append("?");
|
||||
processingDirectives.append(*directives);
|
||||
baseProcessingDirectives.append(*directives);
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,9 +624,12 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
|
||||
});
|
||||
|
||||
if (!image.empty() && image[0] != ':' && image[0] != '?') {
|
||||
image = AssetPath::relativeTo(m_relativePath, image) + processingDirectives;
|
||||
image = AssetPath::relativeTo(m_relativePath, image);
|
||||
|
||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, centered, Vec2F());
|
||||
auto& imagePart = drawable.imagePart();
|
||||
for (Directives const& directives : baseProcessingDirectives)
|
||||
imagePart.addDirectives(directives);
|
||||
drawable.transform(partTransformation(partName));
|
||||
drawable.transform(globalTransformation());
|
||||
drawable.fullbright = fullbright;
|
||||
@ -639,6 +637,8 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
|
||||
|
||||
drawables.append({move(drawable), zLevel});
|
||||
}
|
||||
|
||||
baseProcessingDirectives.resize(originalDirectivesSize);
|
||||
});
|
||||
|
||||
sort(drawables, [](auto const& a, auto const& b) { return a.second < b.second; });
|
||||
|
@ -117,7 +117,7 @@ public:
|
||||
void setGlobalTag(String tagName, String tagValue);
|
||||
void setPartTag(String const& partType, String tagName, String tagValue);
|
||||
|
||||
void setProcessingDirectives(String const& directives);
|
||||
void setProcessingDirectives(Directives const& directives);
|
||||
void setZoom(float zoom);
|
||||
bool flipped() const;
|
||||
float flippedRelativeCenterLine() const;
|
||||
@ -287,7 +287,7 @@ private:
|
||||
struct Effect {
|
||||
String type;
|
||||
float time;
|
||||
String directives;
|
||||
Directives directives;
|
||||
|
||||
NetElementBool enabled;
|
||||
float timer;
|
||||
@ -314,7 +314,7 @@ private:
|
||||
OrderedHashMap<String, Sound> m_sounds;
|
||||
OrderedHashMap<String, Effect> m_effects;
|
||||
|
||||
NetElementString m_processingDirectives;
|
||||
NetElementData<Directives> m_processingDirectives;
|
||||
NetElementFloat m_zoom;
|
||||
|
||||
NetElementBool m_flipped;
|
||||
|
@ -454,7 +454,7 @@ void Npc::render(RenderCallback* renderCallback) {
|
||||
for (auto& drawable : m_humanoid.render()) {
|
||||
drawable.translate(position());
|
||||
if (drawable.isImage())
|
||||
drawable.imagePart().addDirectives(m_statusController->parentDirectives(), true);
|
||||
drawable.imagePart().addDirectivesGroup(m_statusController->parentDirectives(), true);
|
||||
renderCallback->addDrawable(move(drawable), renderLayer);
|
||||
}
|
||||
|
||||
|
@ -353,11 +353,11 @@ List<Drawable> Player::drawables() const {
|
||||
for (auto& drawable : m_humanoid->render()) {
|
||||
drawable.translate(position() + m_techController->parentOffset());
|
||||
if (drawable.isImage()) {
|
||||
drawable.imagePart().addDirectives(m_techController->parentDirectives(), true);
|
||||
drawable.imagePart().addDirectives(m_statusController->parentDirectives(), true);
|
||||
drawable.imagePart().addDirectivesGroup(m_techController->parentDirectives(), true);
|
||||
drawable.imagePart().addDirectivesGroup(m_statusController->parentDirectives(), true);
|
||||
|
||||
if (auto anchor = as<LoungeAnchor>(m_movementController->entityAnchor())) {
|
||||
if (auto directives = anchor->directives)
|
||||
if (auto& directives = anchor->directives)
|
||||
drawable.imagePart().addDirectives(*directives, true);
|
||||
}
|
||||
}
|
||||
|
@ -337,11 +337,11 @@ bool StatusController::uniqueStatusEffectActive(String const& effectName) const
|
||||
return false;
|
||||
}
|
||||
|
||||
String StatusController::primaryDirectives() const {
|
||||
const Directives& StatusController::primaryDirectives() const {
|
||||
return m_primaryDirectives;
|
||||
}
|
||||
|
||||
void StatusController::setPrimaryDirectives(String const& directives) {
|
||||
void StatusController::setPrimaryDirectives(Directives const& directives) {
|
||||
m_primaryDirectives = directives;
|
||||
}
|
||||
|
||||
@ -509,11 +509,11 @@ void StatusController::tickMaster() {
|
||||
removeUniqueEffect(key);
|
||||
}
|
||||
|
||||
String parentDirectives = m_primaryDirectives;
|
||||
for (auto const& pair : m_uniqueEffects) {
|
||||
parentDirectives.append("?");
|
||||
DirectivesGroup parentDirectives;
|
||||
parentDirectives.append(m_primaryDirectives);
|
||||
for (auto const& pair : m_uniqueEffects)
|
||||
parentDirectives.append(pair.second.parentDirectives);
|
||||
}
|
||||
|
||||
m_parentDirectives.set(move(parentDirectives));
|
||||
|
||||
updateAnimators();
|
||||
@ -524,7 +524,7 @@ void StatusController::tickSlave() {
|
||||
updateAnimators();
|
||||
}
|
||||
|
||||
String StatusController::parentDirectives() const {
|
||||
const DirectivesGroup& StatusController::parentDirectives() const {
|
||||
return m_parentDirectives.get();
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,8 @@ public:
|
||||
|
||||
bool uniqueStatusEffectActive(String const& effectName) const;
|
||||
|
||||
String primaryDirectives() const;
|
||||
void setPrimaryDirectives(String const& directives);
|
||||
const Directives& primaryDirectives() const;
|
||||
void setPrimaryDirectives(Directives const& directives);
|
||||
|
||||
// damage request and notification methods should only be called on the master controller.
|
||||
List<DamageNotification> applyDamageRequest(DamageRequest const& damageRequest);
|
||||
@ -118,7 +118,7 @@ public:
|
||||
void tickMaster();
|
||||
void tickSlave();
|
||||
|
||||
String parentDirectives() const;
|
||||
const DirectivesGroup& parentDirectives() const;
|
||||
List<Drawable> drawables() const;
|
||||
List<LightSource> lightSources() const;
|
||||
List<OverheadBar> overheadBars();
|
||||
@ -180,7 +180,7 @@ private:
|
||||
|
||||
struct UniqueEffectInstance {
|
||||
UniqueStatusEffectConfig effectConfig;
|
||||
String parentDirectives;
|
||||
Directives parentDirectives;
|
||||
HashSet<StatModifierGroupId> modifierGroups;
|
||||
StatScript script;
|
||||
UniqueEffectMetadataGroup::ElementId metadataId;
|
||||
@ -205,7 +205,7 @@ private:
|
||||
NetElementGroup m_netGroup;
|
||||
StatCollection m_statCollection;
|
||||
NetElementData<JsonObject> m_statusProperties;
|
||||
NetElementString m_parentDirectives;
|
||||
NetElementData<DirectivesGroup> m_parentDirectives;
|
||||
|
||||
UniqueEffectMetadataGroup m_uniqueEffectMetadata;
|
||||
EffectAnimatorGroup m_effectAnimators;
|
||||
@ -226,7 +226,7 @@ private:
|
||||
|
||||
Maybe<String> m_primaryAnimationConfig;
|
||||
StatScript m_primaryScript;
|
||||
String m_primaryDirectives;
|
||||
Directives m_primaryDirectives;
|
||||
EffectAnimatorGroup::ElementId m_primaryAnimatorId;
|
||||
|
||||
List<DamageNotification> m_pendingSelfDamageNotifications;
|
||||
|
@ -251,7 +251,7 @@ Maybe<TechController::ParentState> TechController::parentState() const {
|
||||
return m_parentState.get();
|
||||
}
|
||||
|
||||
String TechController::parentDirectives() const {
|
||||
DirectivesGroup const& TechController::parentDirectives() const {
|
||||
return m_parentDirectives.get();
|
||||
}
|
||||
|
||||
@ -501,10 +501,11 @@ LuaCallbacks TechController::makeTechCallbacks(TechModule& techModule) {
|
||||
|
||||
callbacks.registerCallback("setParentDirectives", [this, &techModule](Maybe<String> const& directives) {
|
||||
techModule.parentDirectives = directives.value();
|
||||
String newParentDirectives;
|
||||
|
||||
DirectivesGroup newParentDirectives;
|
||||
for (auto& module : m_techModules)
|
||||
newParentDirectives += module.parentDirectives;
|
||||
m_parentDirectives.set(newParentDirectives);
|
||||
newParentDirectives.append(module.parentDirectives);
|
||||
m_parentDirectives.set(move(newParentDirectives));
|
||||
});
|
||||
|
||||
callbacks.registerCallback("setParentHidden", [this](bool hidden) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "StarLuaComponents.hpp"
|
||||
#include "StarLuaActorMovementComponent.hpp"
|
||||
#include "StarTechDatabase.hpp"
|
||||
#include "StarDirectives.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
@ -67,7 +68,7 @@ public:
|
||||
void tickSlave();
|
||||
|
||||
Maybe<ParentState> parentState() const;
|
||||
String parentDirectives() const;
|
||||
DirectivesGroup const& parentDirectives() const;
|
||||
Vec2F parentOffset() const;
|
||||
bool toolUsageSuppressed() const;
|
||||
|
||||
@ -120,7 +121,7 @@ private:
|
||||
scriptComponent;
|
||||
bool visible;
|
||||
bool toolUsageSuppressed;
|
||||
String parentDirectives;
|
||||
Directives parentDirectives;
|
||||
TechAnimatorGroup::ElementId animatorId;
|
||||
};
|
||||
|
||||
@ -159,7 +160,7 @@ private:
|
||||
Vec2F m_aimPosition;
|
||||
|
||||
NetElementData<Maybe<ParentState>> m_parentState;
|
||||
NetElementString m_parentDirectives;
|
||||
NetElementData<DirectivesGroup> m_parentDirectives;
|
||||
NetElementFloat m_xParentOffset;
|
||||
NetElementFloat m_yParentOffset;
|
||||
NetElementBool m_parentHidden;
|
||||
|
@ -28,7 +28,7 @@ struct LoungeAnchor : EntityAnchor {
|
||||
StringSet effectEmitters;
|
||||
Maybe<String> emote;
|
||||
Maybe<String> dance;
|
||||
Maybe<String> directives;
|
||||
Maybe<Directives> directives;
|
||||
JsonObject armorCosmeticOverrides;
|
||||
Maybe<String> cursorOverride;
|
||||
bool cameraFocus;
|
||||
|
Loading…
Reference in New Issue
Block a user