diff --git a/CataclysmWin.cbp b/CataclysmWin.cbp
index aaa51ad828957..23492058a7da2 100644
--- a/CataclysmWin.cbp
+++ b/CataclysmWin.cbp
@@ -556,6 +556,8 @@
+
+
diff --git a/data/json/mutation_ordering.json b/data/json/mutation_ordering.json
new file mode 100644
index 0000000000000..a01be8719a8ec
--- /dev/null
+++ b/data/json/mutation_ordering.json
@@ -0,0 +1,60 @@
+[
+ {
+ "type" : "overlay_order",
+ "ordering" :
+ [
+ {
+ "id" : [ "THRESH_CATTLE", "THRESH_CEPHALOPOD", "THRESH_SLIME", "WEB_RAPPEL", "WEB_ROPE", "WEB_SPINNER", "WEB_WALKER", "WEB_WEAVER", "WINGS_BAT", "WINGS_BIRD", "WINGS_BUTTERFLY", "WINGS_INSECT" ],
+ "order" : 500
+ },{
+ "id" : [ "BEAUTIFUL", "BEAUTIFUL2", "BEAUTIFUL3", "LARGE", "PRETTY", "RADIOACTIVE1", "RADIOACTIVE2", "RADIOACTIVE3", "REGEN" ],
+ "order" : 1000
+ },{
+ "id" : [ "ALBINO", "BARK", "CHITIN", "CHITIN2", "CHITIN3", "CHITIN_FUR", "CHITIN_FUR2", "CHITIN_FUR3", "FEATHERS", "FELINE_FUR", "FUR", "LEAVES", "LIGHT_FUR", "LUPINE_FUR", "LYNX_FUR", "PLANTSKIN", "SCALES", "SKIN_ROUGH", "SLEEK_SCALES", "SORES", "THORNS", "TROGLO2", "TROGLO3", "URSINE_FUR", "VISCOUS" ],
+ "order" : 1500
+ },{
+ "id" : [ "ARACHNID_ARMS", "ARACHNID_ARMS_OK", "ARM_FEATHERS", "ARM_TENTACLES", "ARM_TENTACLES_4", "ARM_TENTACLES_8" ],
+ "order" : 2000
+ },{
+ "id" : [ "PAWS", "PAWS_LARGE", "SLIME_HANDS" ],
+ "order" : 2500
+ },{
+ "id" : [ "CLAWS", "CLAWS_RAT", "CLAWS_RETRACT", "LONG_FINGERNAILS", "VINES1", "VINES2", "VINES3" ],
+ "order" : 3000
+ },{
+ "id" : [ "TAIL_CATTLE", "TAIL_CLUB", "TAIL_FIN", "TAIL_LONG", "TAIL_RAPTOR", "TAIL_RAT", "TAIL_STING", "TAIL_STUB", "TAIL_THICK" ],
+ "order" : 3500
+ },{
+ "id" : [ "LEG_TENTACLES" ],
+ "order" : 4000
+ },{
+ "id" : [ "HOOVES", "ROOTS1", "ROOTS2", "ROOTS3", "TALONS" ],
+ "order" : 4500
+ },{
+ "id" : [ "FLOWERS" ],
+ "order" : 5000
+ },{
+ "id" : [ "ELFA_EARS", "FELINE_EARS", "LUPINE_EARS", "URSINE_EARS" ],
+ "order" : 5500
+ },{
+ "id" : [ "ANTENNAE", "ANTLERS", "CURVED_HORNS", "HORNS", "POINTED_HORNS" ],
+ "order" : 6000
+ },{
+ "id" : [ "COMPOUND_EYES", "ELFAEYES", "FEL_EYE", "LIZ_EYE" ],
+ "order" : 6500
+ },{
+ "id" : [ "BEAK", "BEAK_HUM", "BEAK_PECK", "MUZZLE", "MUZZLE_BEAR", "MUZZLE_LONG", "MUZZLE_RAT", "MINOTAUR", "SLIT_NOSTRILS", "SNOUT", "WHISKERS", "WHISKERS_RAT" ],
+ "order" : 7000
+ },{
+ "id" : [ "FANGS", "MANDIBLES", "SABER_TEETH" ],
+ "order" : 7500
+ },{
+ "id" : [ "FORKED_TONGUE" ],
+ "order" : 8000
+ },{
+ "id" : [ "PROF_CYBERCOP", "PROF_FED", "PROF_PD_DET", "PROF_POLICE", "PROF_SWAT", "PHEROMONE_INSECT" ],
+ "order" : 8500
+ }
+ ]
+ }
+]
diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md
index eb2f4c50c347e..ca514f08f0d88 100644
--- a/doc/JSON_INFO.md
+++ b/doc/JSON_INFO.md
@@ -14,6 +14,7 @@
* skills.json - skill descriptions and ID's
* snippets.json - flier/poster descriptions
* mutations.json - traits/mutations
+* mutation_ordering.json - draw order for mutation overlays in tiles mode
* vehicle_groups.json - vehicle spawn groups
* vehicle_parts.json - vehicle parts, does NOT affect flag effects
@@ -1414,7 +1415,7 @@ The id of an overmap terrain type (see overmap_terrain.json) of the starting loc
Arbitrary flags. Mods can modify this via "add:flags" / "remove:flags". TODO: document them.
###TILE_CONFIG
-Each tileset has a tile_config.json describing how to map the contents of a sprite sheet to various tile identifiers, different orientations, etc. Example:
+Each tileset has a tile_config.json describing how to map the contents of a sprite sheet to various tile identifiers, different orientations, etc. The ordering of the overlays used for displaying mutations can be controlled as well. The ordering can be used to override the default ordering provided in `mutation_ordering.json`. Example:
```JSON
{ // whole file is a single object
"tile_info": [ // tile_info is mandatory
@@ -1500,5 +1501,54 @@ Each tileset has a tile_config.json describing how to map the contents of a spri
]
}
]
+ "overlay_ordering": [
+ {
+ "id" : "WINGS_BAT", // mutation name, in a string or array of strings
+ "order" : 1000 // range from 0 - 9999, 9999 being the topmost layer
+ },
+ {
+ "id" : [ "PLANTSKIN", "BARK" ], // mutation name, in a string or array of strings
+ "order" : 3500 // order is applied to all items in the array
+ }
+ ]
}
```
+
+# Mutation overlay ordering
+
+The file `mutation_ordering.json` defines the order that visual mutation overlays are rendered on a character ingame. The layering value from 0 (bottom) - 9999 (top) sets the order.
+
+Example:
+```JSON
+[
+ {
+ "type" : "overlay_order",
+ "ordering" :
+ [
+ {
+ "id" : [ "BEAUTIFUL", "BEAUTIFUL2", "BEAUTIFUL3", "LARGE", "PRETTY", "RADIOACTIVE1", "RADIOACTIVE2", "RADIOACTIVE3", "REGEN" ],
+ "order" : 1000
+ },{
+ "id" : [ "HOOVES", "ROOTS1", "ROOTS2", "ROOTS3", "TALONS" ],
+ "order" : 4500
+ },{
+ "id" : "FLOWERS",
+ "order" : 5000
+ },{
+ "id" : [ "PROF_CYBERCOP", "PROF_FED", "PROF_PD_DET", "PROF_POLICE", "PROF_SWAT", "PHEROMONE_INSECT" ],
+ "order" : 8500
+ }
+ ]
+ }
+]
+```
+
+## "id"
+(string)
+
+The internal ID of the mutation. Can be provided as a single string, or an array of strings. The order value provided will be applied to all items in the array.
+
+## "order"
+(integer)
+
+The ordering value of the mutation overlay. Values range from 0 - 9999, 9999 being the topmost drawn layer. Mutations that are not in any list will default to 9999.
diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp
index 57cf48358a93a..103eab0cd2888 100644
--- a/src/cata_tiles.cpp
+++ b/src/cata_tiles.cpp
@@ -27,6 +27,7 @@
#include "weather.h"
#include "weighted_list.h"
#include "submap.h"
+#include "overlay_ordering.h"
#include
#include
@@ -518,6 +519,28 @@ void cata_tiles::load_tilejson_from_file(const std::string &tileset_dir, std::if
load_tilejson_from_file(config, 0, newsize);
offset = newsize;
}
+
+ // allows a tileset to override the order of mutation images being applied to a character
+ if( config.has_array( "overlay_ordering" ) ) {
+ tileset_mutation_overlay_ordering.clear();
+ JsonArray orderarray = config.get_array( "overlay_ordering" );
+ while( orderarray.has_more() ) {
+ JsonObject ordering = orderarray.next_object();
+
+ int order = ordering.get_int( "order" );
+ if( ordering.has_array( "id" ) ) {
+ JsonArray jsarr = ordering.get_array( "id" );
+ while( jsarr.has_more() ) {
+ std::string mut_id = jsarr.next_string();
+ tileset_mutation_overlay_ordering[mut_id] = order;
+ }
+ } else {
+ std::string mut_id = ordering.get_string( "id" );
+ tileset_mutation_overlay_ordering[mut_id] = order;
+ }
+ }
+ }
+
// offset should be the total number of sprites loaded from every tileset image
// eliminate any sprite references that are too high to exist
// also eliminate negative sprite references
diff --git a/src/init.cpp b/src/init.cpp
index 9db0185f1dd9e..d00fee4a84210 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -49,6 +49,7 @@
#include "clzones.h"
#include "sounds.h"
#include "gates.h"
+#include "overlay_ordering.h"
#include
#include
@@ -220,6 +221,7 @@ void DynamicDataLoader::initialize()
type_function_map["playlist"] = new StaticFunctionAccessor(&sfx::load_playlist);
type_function_map["gate"] = new StaticFunctionAccessor(&gates::load_gates);
+ type_function_map["overlay_order"] = new StaticFunctionAccessor( &load_overlay_ordering );
}
void DynamicDataLoader::reset()
diff --git a/src/overlay_ordering.cpp b/src/overlay_ordering.cpp
new file mode 100644
index 0000000000000..c3efdbf94754c
--- /dev/null
+++ b/src/overlay_ordering.cpp
@@ -0,0 +1,25 @@
+#include "overlay_ordering.h"
+
+std::unordered_map base_mutation_overlay_ordering;
+std::unordered_map tileset_mutation_overlay_ordering;
+
+void load_overlay_ordering( JsonObject &jsobj )
+{
+ JsonArray jarr = jsobj.get_array( "ordering" );
+ while( jarr.has_more() ) {
+ JsonObject ordering = jarr.next_object();
+
+ JsonArray jsarr;
+ int order = ordering.get_int( "order" );
+ if( ordering.has_array( "id" ) ) {
+ jsarr = ordering.get_array( "id" );
+ while( jsarr.has_more() ) {
+ std::string mut_id = jsarr.next_string();
+ base_mutation_overlay_ordering[mut_id] = order;
+ }
+ } else {
+ std::string mut_id = ordering.get_string( "id" );
+ base_mutation_overlay_ordering[mut_id] = order;
+ }
+ }
+}
diff --git a/src/overlay_ordering.h b/src/overlay_ordering.h
new file mode 100644
index 0000000000000..0b24437f8a230
--- /dev/null
+++ b/src/overlay_ordering.h
@@ -0,0 +1,14 @@
+#ifndef OVERLAY_ORDERING_H
+#define OVERLAY_ORDERING_H
+
+#include "json.h"
+
+#include
+#include
+
+extern std::unordered_map base_mutation_overlay_ordering;
+extern std::unordered_map tileset_mutation_overlay_ordering;
+
+void load_overlay_ordering( JsonObject &jsobj );
+
+#endif
diff --git a/src/player.cpp b/src/player.cpp
index 2bddd40bd5941..28bb877d9fc02 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -47,6 +47,7 @@
#include "catalua.h"
#include "npc.h"
#include "cata_utility.h"
+#include "overlay_ordering.h"
#include