mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-27 23:07:08 +01:00
reskate.outfit.worn() is meant to list full-body costumes: it has a "Costume" slot for them, between
the head and the feet. But no costume ever reached it. With a costume on, the list came back without
it, so a plugin that goes with a costume mod could not tell whether its costume was worn. Now it is
listed like any other item: {slot = "Costume", item = "Own_Hobkin", title = "Hobkin"}.
Why: the list leaves out the body's own parts (head shape, nose, skin...) by their catalog categories,
which start with "cust" (custhead, custnoses, custbodies...) or name the body. A full-body costume's
category is "cust_fullBodyCostume", so it matched both and was dropped before its slot was looked up.
A category that names a costume is now kept; everything else is decided as before.
The rule (category to slot) moves out of worn_items.cpp into outfit_kind.h as it was, so it can be
tested without the game: outfit_kind_tests (with the plugin tests) checks clothes by their slots, the
costume, the body's own parts, and an unknown category.
Checked in the game: with a costume mod's costume on, outfit.worn() returns
Costume | Own_Hobkin | Hobkin, where it returned nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.0 KiB
C++
50 lines
2.0 KiB
C++
// What a catalog category is worn as (Extension/Customization/outfit_kind.h): clothes by their slot,
|
|
// full-body costumes too, and the body's own parts left out.
|
|
#include "Extension/Customization/outfit_kind.h"
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
namespace {
|
|
using namespace dingosdk;
|
|
|
|
void check(bool ok, const std::string& message) {
|
|
if (ok) return;
|
|
std::cerr << "FAILED: " << message << '\n';
|
|
std::exit(1);
|
|
}
|
|
void worn_as(const char* category, const char* label) {
|
|
const auto kind = outfit_kind::of(category);
|
|
check(kind && kind->label == label, std::string(category) + " is worn as " + label);
|
|
}
|
|
void not_worn(const char* category) { check(!outfit_kind::of(category), std::string(category) + " is not worn"); }
|
|
} // namespace
|
|
|
|
int main() {
|
|
// Clothes and accessories, by the slot they are worn in.
|
|
worn_as("tops", "Top");
|
|
worn_as("headgear", "Headwear");
|
|
worn_as("eyewear", "Eyewear");
|
|
worn_as("bottoms", "Bottoms");
|
|
worn_as("shoes", "Shoes");
|
|
// A full-body costume (a mod's costume is one, Own_... in cust_fullBodyCostume): worn, though its
|
|
// category starts like the body's own parts and names the body.
|
|
worn_as("cust_fullBodyCostume", "Costume");
|
|
// The body's own parts, and what is not clothing.
|
|
not_worn("custhead");
|
|
not_worn("custbodies");
|
|
not_worn("custnoses");
|
|
not_worn("hair");
|
|
not_worn("tattoos");
|
|
not_worn("gestures");
|
|
not_worn("");
|
|
// A category this does not know: worn, its name made readable, after what it knows.
|
|
const auto unknown = outfit_kind::of("patches_x");
|
|
check(unknown && unknown->label == "Patches x" && unknown->order == 20, "an unknown category is its name made readable");
|
|
// From head to foot.
|
|
check(outfit_kind::of("headgear")->order < outfit_kind::of("cust_fullBodyCostume")->order &&
|
|
outfit_kind::of("cust_fullBodyCostume")->order < outfit_kind::of("shoes")->order,
|
|
"a costume sits between the head and the feet");
|
|
std::cout << "outfit_kind tests passed\n";
|
|
}
|