Jump to content

How to create Annotated Stash Maps (41.6+)


RingoD123

Recommended Posts

This guide will teach you how to create Stash Map mods. If you have not already then it is worth checking out this guide on how to add lootable maps to the game world using the new procedural distributions system:


Once your lootable map is in game (or if you are wanting to add more using the ones already in game) you can then go ahead with this tutorial for creating your Stash maps. The first thing that you need to do is create a new folder named "StashDescriptions" in your mods "media\lua\shared" folder, if none of these folders already exist then create them.


Then you will need to create a StashDesc.lua file in the StashDescriptions folder, name it something unique for your mod (e.g bedfordStashDesc.lua). Once you have created the new file, open it and paste the following line in as the first line:

 

Spoiler

require "StashDescriptions/StashUtil";

 

Now you can start adding your stash maps, just leave a blank line after the first line you added above. Below are 2 examples each of the different stash types that can be made:

 

Spoiler

-- guns
local stashMap1 = StashUtil.newStash("BedfordStashMap1", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.spawnOnlyOnZed = true;
stashMap1.daysToSpawn = "10";
stashMap1.zombies = 5
stashMap1.traps = "5";
stashMap1.barricades = 50;
stashMap1.buildingX = 13782;
stashMap1.buildingY = 10524;
stashMap1.spawnTable = "GunCache2";
stashMap1:addContainer("GunBox","floors_interior_tilesandwood_01_62",nil,"bedroom",nil,nil,nil);
stashMap1:addStamp("X",nil,343,281,0,0,0);
stashMap1:addStamp(nil,"Stash_WpMap1_Text1",13266,10178,0,0,0);
stashMap1:addStamp("Circle",nil,13605,10374,0,0,0);
stashMap1:addStamp(nil,"Stash_WpMap1_Text2",13550,10396,0,0,0);
stashMap1:addStamp("Exclamation",nil,13452,10182,1,0,0);
stashMap1:addStamp(nil,"Stash_WpMap1_Text3",13475,10179,1,0,0);

 

local stashMap1 = StashUtil.newStash("BedfordStashMap2", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13751;
stashMap1.buildingY = 10531;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "GunCache2";
stashMap1:addContainer("GunBox","floors_interior_tilesandwood_01_62",nil,"bedroom",nil,nil,nil);
stashMap1:addContainer("GunBox","carpentry_01_16",nil,nil,nil,nil,nil);
stashMap1:addStamp("Target",nil,13243,10181,0,0,0);
stashMap1:addStamp("House",nil,13605,10374,0,0,0);
stashMap1:addStamp("Lightning",nil,13452,10182,1,0,0);

 

-- shotgun
local stashMap1 = StashUtil.newStash("BedfordStashMap3", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13620;
stashMap1.buildingY = 10515;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "ShotgunCache2";
stashMap1:addStamp("Skull",nil,13380,10274,0,0,0);
stashMap1:addStamp("X",nil,13520,10407,0,0,0);
stashMap1:addStamp("Question",nil,13873,10235,1,0,0);

 

local stashMap1 = StashUtil.newStash("BedfordStashMap4", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13596;
stashMap1.buildingY = 10516;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "ShotgunCache2";
stashMap1:addContainer("ShotgunBox",nil,"Base.Bag_DuffelBag",nil,nil,nil,nil);
stashMap1:addContainer("ShotgunBox","carpentry_01_16",nil,nil,nil,nil,nil);
stashMap1:addStamp("X",nil,13380,10274,0,0,0);
stashMap1:addStamp("House",nil,13520,10407,0,0,0);
stashMap1:addStamp("Target",nil,13873,10235,1,0,0);

 

-- tools
local stashMap1 = StashUtil.newStash("BedfordStashMap5", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13090;
stashMap1.buildingY = 10897;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "ToolsCache1";
stashMap1:addStamp("Circle",nil,13372,10366,0,0,0);
stashMap1:addStamp("Exclamation",nil,13650,10325,0,0,0);

 

local stashMap1 = StashUtil.newStash("BedfordStashMap6", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13112;
stashMap1.buildingY = 10899;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "ToolsCache1";
stashMap1:addContainer("ToolsBox",nil,"Base.Bag_DuffelBagTINT",nil,nil,nil,nil);
stashMap1:addContainer("ToolsBox","carpentry_01_16",nil,nil,nil,nil,nil);
stashMap1:addStamp("Exclamation",nil,13372,10266,0,0,0);
stashMap1:addStamp("Exclamation",nil,13650,10325,0,0,0);

 

-- survivor houses
local stashMap1 = StashUtil.newStash("BedfordStashMap7", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13248;
stashMap1.buildingY = 11313;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "SurvivorCache1";
stashMap1:addContainer("GunBox","carpentry_01_16",nil,nil,nil,nil,nil);
stashMap1:addContainer("ShotgunBox",nil,"Base.Bag_DuffelBagTINT",nil,nil,nil,nil);
stashMap1:addStamp("House",nil,13248,10418,0,0,0);
stashMap1:addStamp("Target",nil,13218,10359,0,0,0);

 

local stashMap1 = StashUtil.newStash("BedfordStashMap8", "Map", "Base.BedfordMap", "Stash_AnnotedMap");
stashMap1.daysToSpawn = "0";
stashMap1.buildingX = 13242;
stashMap1.buildingY = 11288;
stashMap1.zombies = 2;
stashMap1.barricades = 50;
stashMap1.spawnTable = "SurvivorCache1";
stashMap1:addContainer("ToolsBox",nil,"Base.Bag_DuffelBagTINT",nil,nil,nil,nil);
stashMap1:addContainer("ToolsBox","carpentry_01_16",nil,nil,nil,nil,nil);
stashMap1:addContainer("GunBox","carpentry_01_16",nil,nil,nil,nil,nil);
stashMap1:addContainer("ShotgunBox",nil,"Base.Bag_DuffelBagTINT",nil,nil,nil,nil);
stashMap1:addStamp("House",nil,13248,10418,0,0,0);
stashMap1:addStamp("X",nil,13218,10359,0,0,0);

 

As you can see with the examples above each map has its own unique name given as the first parameter in the brackets. Next up is it's item type, which is obviously Map, then the in game item it actually uses, in this case the map we added to the base game from the lootable map tutorial listed above. The last parameter is the "Stash_AnnotedMap" custom name which is needed, and yes it is spelled incorrectly.


We can govern how many in game days it takes before the stash maps become findable, how many barricades are put up around the building, how many traps are inside and how many zombies should spawn inside, these are maximum values, not guaranteed values. We can also choose if the stash maps can only be found on zombies or not.


The buildingX and buildingY co-ordinates are the co-ordinates of the building you want the stash to appear in, in world co-ordinates, you can always use the https://map.projectzomboid.com/ website to help with your co-ordinates if need be.

 

Next we have to choose what loot table the stash will pull from, in the above examples we are using SurvivorCache1, ToolsCache1, ShotgunCache2 and Guncache2, these act like regular room definitions but for the whole building.

Don't forget you can always check the vanilla stash descriptions in the games "media\lua\shared\StashDescriptions" folder

 

In the above examples you can see the "addStamp" lines, these will add stamps to your base lootable maps such as arrows, exclamation marks etc, these icons can be found in your zomboid install folder in "media/ui/LootableMaps/". All of the text references ("Stash_WpMap4_Text1" etc) can be found in the games "media\lua\shared\translate\en\Stash_EN.txt" file.

 

The X and Y co-ordinates to place the stamps are in world co-ordinates in the same fashion as adding a banner or legend to a regular map. You can then also specify a custom colour for your stamp using the last 3 parameters for R,G and B.


As you can see in some of the example above we are also spawning in some new containers, some examples are spawning in duffel bags, some wooden crates (carpentry_01_16) and some even as "hidden" floor stashes. Lets take a quick look at each:

 

Spoiler

stashMap1:addContainer("ToolsBox",nil,"Base.Bag_DuffelBag",nil,nil,nil,nil); - Here we are adding a duffelbag and populating it from the "ToolsBox" definition. It will spawn in a random position in the building.

 

stashMap1:addContainer("GunBox","carpentry_01_16",nil,nil,nil,nil,nil); - Here we are adding a wooden crate and populating it from the "GunBox" definition. It will spawn in a random position in the building.

 

stashMap1:addContainer("GunBox","floors_interior_tilesandwood_01_62",nil,"bedroom",nil,nil,nil); - Here we are adding a floor stash to a bedroom and populating it using the "GunBox" definition.

 

Notice how if a container is using an item (duffelbag) it does not need a tile (carpentry_01_16 or floors_interior_tilesandwood_01_62) and vice-versa. Also notice how a room is specified with the floor stash. The last 3 parameters are for an X,Y and Z postion within the buildings lot, but are not used in the above examples.

 

These Stash definitions can be found in distributions.lua and as with other distributions can be modded or completely new ones added. As well as the lootable map guide posted earlier in this guide, there is also this guide on customizing loot that can be helpful:

 

 

And that's it, you now have custom Annotated Stash Maps!

Link to comment
Share on other sites

  • RingoD123 changed the title to How to create Annotated Stash Maps (41.6+)
  • RingoD123 pinned this topic
  • 1 year later...

Hello,

 

I'm planning to make a mod with JUST a pile of annotated maps to spawn in, to fill in the world a bit more. Just wondering a few things so I can make the best use of them.

 

1. Can we spawn one map that effects two different buildings? Say if I wanted to have a story about a barricaded house, then place extra tools in the detached garage?

 

2. Can I use it to spawn in a vehicle?

 

3. Why to the general stashes seem to only add extra loot to the kitchen and bathrooms of stash houses?

 

4. What's the syntax of the addcontainer? Just wondering what all the "nil"s are for?

 

5. Is is possible to add specific items to a stash?

 

Thanks so much!

Link to comment
Share on other sites

16 hours ago, The Backlog said:

...

 

1. Probably not by default.

2. Probably not by default.

3. Not sure, I added mine to crates. Check Distribution tables.

4. I think this was covered in the examples.

5. Yes.

6. Probably.

 

It seems you're quite new, I recommend checking the pzwiki for some general information and discord is quite active too.

Link to comment
Share on other sites

21 hours ago, Neznajka said:

 

1. Probably not by default.

2. Probably not by default.

3. Not sure, I added mine to crates. Check Distribution tables.

4. I think this was covered in the examples.

5. Yes.

6. Probably.

 

It seems you're quite new, I recommend checking the pzwiki for some general information and discord is quite active too.

No, not new, just have some questions that were not covered by the dev (Who I expect has answers, since... you know). I've looked through all the PZwiki and both discords and almost nobody is making stashes, so I guess the entire community is "New" to the idea of making stashes. I've downloaded over 300 mod maps to only find about 4 maps that include stashes, and none of their examples provided clarity to these questions, and many of those examples are broken so the stash doesn't actually do what the maker expects.

I've already made a bunch of stashes in my mod, but not knowing the specifics of WHAT the system CAN do leads me to these questions.

 

Question #1 and #2 you are probably right about, but it would be really handy to be able to do those, thus asking the dev JIC. And since the syntax of the definitions looks like it's following javaish rules there should be a way to define another active building in the same stash.

 

for question #3 I did check the distro tables and that is where I found the current stashes are mostly adding them to cupboards. But again, why? Why are the stashes set up to break if you set the active building to a building that does not have cupboards. (There are several examples of this in the vanilla stashes) It makes it a bit wierd when you visit a stash house and find the extra loot in only the bathrooms and kitchens.

 

For question #4 Yes and no. They gave examples but did not give the syntax. My guess is it is something like addContainer("Container_Type","Container_Tile",Item,room_Description,xCord,YCord,ZCord) but since we don't have a stated syntax this is only guesswork. And not knowing the syntax limits what we can do with them.

 

Follow-up to question #5 How? I can't find any examples of a stash that does that. Random items from a pool yes, but every attempt I've tried makes the entire stash not initialize.

 

Follow-up to question #6 How? Again every description I've tried that is not a GunCache1, SurvivorCache2, etc breaks the entire stash.

Link to comment
Share on other sites

Since you are not new, I will give you more sources to look through to discover information by yourself.

 

shared/Stash descriptions/StashUtil.lua

zombie/core/stash/StashSystem

zombie/core/stash/

 

There are guides how to make custom distribution tables that are pretty much guaranteed to give you specific items. Otherwise you will need to go into coding zone if you want to get more options.

 

Obviously input from a dev would be better, but you can't always expect them to answer.

 

PS: I've seen a couple mods that add more stash. I took an unconventional approach while testing this system.

github link

Edited by Neznajka
Link to comment
Share on other sites

  • 8 months later...

I can't quite figure this out with this basic tutorial.

I was able to make a custom item and map using the Rosewood Map. I can loot it and it pops up fine, but none of the annotations appear. The building is also not populated.

Any clues. Thanks.

 



require "StashDescriptions/StashUtil";

 

local stashMap1 = StashUtil.newStash("IScn_Stash_Rosewood", "Map", "Base.RosewoodMap", "Stash_AnnotedMap");

stashMap1.daysToSpawn = "0";
stashMap1.spawnOnlyOnZed = false;
stashMap1.zombies = 2;
stashMap1.buildingX = 8419
stashMap1.buildingY = 11581
stashMap1.spawnTable = "ToolsCache1";
stashMap1:addContainer("ToolsBox",nil,"Base.Bag_DuffelBagTINT",nil,nil,nil,nil);
stashMap1:addStamp("Circle", nil, 8419, 11581, 0, 0, 1)
stashMap1:addStamp(nil, "Stash_RosewoodStashMap3_Text1", 8233, 11551, 0, 0, 1)
stashMap1:addStamp(nil, "Stash_RosewoodStashMap3_Text11", 8394, 11589, 0, 0, 1)
stashMap1:addStamp("X", nil, 8135, 11740, 0, 0, 0)
stashMap1:addStamp(nil, "Stash_RosewoodStashMap3_Text2", 8145, 11732, 0, 0, 0)
stashMap1:addStamp("ArrowSouth", nil, 8105, 11608, 1, 0, 0)
stashMap1:addStamp(nil, "Stash_RosewoodStashMap3_Text3", 8073, 11575, 1, 0, 0)

 

Link to comment
Share on other sites

 



require "ISMapDefinitions"

local MINZ = 0
local MAXZ = 24

local WATER_TEXTURE = false

local function replaceWaterStyle(mapUI)
    if not WATER_TEXTURE then return end
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:getLayerByName("water")
    if not layer then return end
    layer:setMinZoom(MINZ)
    layer:setFilter("water", "river")
    layer:removeAllFill()
    layer:removeAllTexture()
    layer:addFill(MINZ, 59, 141, 149, 255)
    layer:addFill(MAXZ, 59, 141, 149, 255)
end

local function overlayPNG(mapUI, x, y, scale, layerName, tex, alpha)
    local texture = getTexture(tex)
    if not texture then return end
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:newTextureLayer(layerName)
    layer:setMinZoom(MINZ)
    layer:addFill(MINZ, 255, 255, 255, (alpha or 1.0) * 255)
    layer:addTexture(MINZ, tex)
    layer:setBoundsInSquares(x, y, x + texture:getWidth() * scale, y + texture:getHeight() * scale)
end

LootMaps.Init.IScn_Stash_Rosewood = function(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    MapUtils.initDirectoryMapData(mapUI, 'media/maps/Muldraugh, KY')
    MapUtils.initDefaultStyleV1(mapUI)
    replaceWaterStyle(mapUI)
    mapAPI:setBoundsInSquares(7900, 11140, 8604, 12139)
    overlayPNG(mapUI, 7958, 11962, 0.666, "badge", "media/textures/worldMap/RosewoodBadge.png")
    overlayPNG(mapUI, 8213, 11161, 0.666, "legend", "media/textures/worldMap/Legend.png")
    MapUtils.overlayPaper(mapUI)
--    overlayPNG(mapUI, 26*300+100, 37*300+30, 0.666, "lootMapPNG", "media/ui/LootableMaps/rosewoodmap.png", 0.5)
end

 



module Base {

    item IScn_RosewoodMap {
        DisplayCategory     = Cartography,
        Type                = Map,
        DisplayName            = Rosewood Map (Family Home),
        Icon                = Map,
        Weight                = 0.1,
        Map                 = IScn_Stash_Rosewood,
        SurvivalGear        = TRUE,
        WorldStaticModel    = Map,
    },

}

Link to comment
Share on other sites

1 hour ago, TheoryOfMadness said:

 

 

  Hide contents

 

 


require "ISMapDefinitions"

local MINZ = 0
local MAXZ = 24

local WATER_TEXTURE = false

local function replaceWaterStyle(mapUI)
    if not WATER_TEXTURE then return end
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:getLayerByName("water")
    if not layer then return end
    layer:setMinZoom(MINZ)
    layer:setFilter("water", "river")
    layer:removeAllFill()
    layer:removeAllTexture()
    layer:addFill(MINZ, 59, 141, 149, 255)
    layer:addFill(MAXZ, 59, 141, 149, 255)
end

local function overlayPNG(mapUI, x, y, scale, layerName, tex, alpha)
    local texture = getTexture(tex)
    if not texture then return end
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:newTextureLayer(layerName)
    layer:setMinZoom(MINZ)
    layer:addFill(MINZ, 255, 255, 255, (alpha or 1.0) * 255)
    layer:addTexture(MINZ, tex)
    layer:setBoundsInSquares(x, y, x + texture:getWidth() * scale, y + texture:getHeight() * scale)
end

LootMaps.Init.IScn_Stash_Rosewood = function(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    MapUtils.initDirectoryMapData(mapUI, 'media/maps/Muldraugh, KY')
    MapUtils.initDefaultStyleV1(mapUI)
    replaceWaterStyle(mapUI)
    mapAPI:setBoundsInSquares(7900, 11140, 8604, 12139)
    overlayPNG(mapUI, 7958, 11962, 0.666, "badge", "media/textures/worldMap/RosewoodBadge.png")
    overlayPNG(mapUI, 8213, 11161, 0.666, "legend", "media/textures/worldMap/Legend.png")
    MapUtils.overlayPaper(mapUI)
--    overlayPNG(mapUI, 26*300+100, 37*300+30, 0.666, "lootMapPNG", "media/ui/LootableMaps/rosewoodmap.png", 0.5)
end
 

 

 

The above file should look like this:

 

 

 

 


require "ISMapDefinitions"

 

MapUtils = {}

 

function MapUtils.initDirectoryMapData(mapUI, directory)
    local mapAPI = mapUI.javaObject:getAPIv1()
    local file = directory..'/worldmap-forest.xml'
    if fileExists(file) then
        mapAPI:addData(file)
    end
    file = directory..'/worldmap.xml'
    if fileExists(file) then
        mapAPI:addData(file)
    end

    -- This call indicates the end of XML data files for the directory.
    -- If map features exist for a particular cell in this directory,
    -- then no data added afterwards will be used for that same cell.
    mapAPI:endDirectoryData()

 

    mapAPI:addImages(directory)
end

 

function MapUtils.initDefaultMapData(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    mapAPI:clearData()
    -- Add data from highest priority (mods) to lowest priority (vanilla)
    local dirs = getLotDirectories()
    for i=1,dirs:size() do
        MapUtils.initDirectoryMapData(mapUI, 'media/maps/'..dirs:get(i-1))
    end
end

 

local MINZ = 0
local MAXZ = 24

 

local WATER_TEXTURE = false

 

function MapUtils.initDefaultStyleV1(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()

 

    local r,g,b = 219/255, 215/255, 192/255
    mapAPI:setBackgroundRGBA(r, g, b, 1.0)
    mapAPI:setUnvisitedRGBA(r * 0.915, g * 0.915, b * 0.915, 1.0)
    mapAPI:setUnvisitedGridRGBA(r * 0.777, g * 0.777, b * 0.777, 1.0)

 

    styleAPI:clear()

 

    local layer = styleAPI:newPolygonLayer("forest")
    layer:setMinZoom(13.5)
    layer:setFilter("natural", "forest")
    if true then
        layer:addFill(MINZ, 189, 197, 163, 0)
        layer:addFill(13.5, 189, 197, 163, 0)
        layer:addFill(14, 189, 197, 163, 255)
        layer:addFill(MAXZ, 189, 197, 163, 255)
    else
        layer:addFill(MINZ, 255, 255, 255, 255)
        layer:addFill(MAXZ, 255, 255, 255, 255)
        layer:addTexture(MINZ, "media/textures/worldMap/Grass.png")
        layer:addTexture(MAXZ, "media/textures/worldMap/Grass.png")
        layer:addScale(13.5, 4.0)
        layer:addScale(MAXZ, 4.0)
    end
    
    layer = styleAPI:newPolygonLayer("water")
    layer:setMinZoom(MINZ)
    layer:setFilter("water", "river")
    if not WATER_TEXTURE then
        layer:addFill(MINZ, 59, 141, 149, 255)
        layer:addFill(MAXZ, 59, 141, 149, 255)
    else
        layer:addFill(MINZ, 59, 141, 149, 255)
        layer:addFill(14.5, 59, 141, 149, 255)
        layer:addFill(14.5, 255, 255, 255, 255)
        layer:addTexture(MINZ, nil)
        layer:addTexture(14.5, nil)
        layer:addTexture(14.5, "media/textures/worldMap/Water.png")
        layer:addTexture(MAXZ, "media/textures/worldMap/Water.png")
--        layer:addScale(MINZ, 4.0)
--        layer:addScale(MAX, 4.0)
    end

 

    layer = styleAPI:newPolygonLayer("road-trail")
    layer:setMinZoom(12.0)
    layer:setFilter("highway", "trail")
    layer:addFill(12.25, 185, 122, 87, 0)
    layer:addFill(13, 185, 122, 87, 255)
    layer:addFill(MAXZ, 185, 122, 87, 255)

 

    layer = styleAPI:newPolygonLayer("road-tertiary")
    layer:setMinZoom(11.0)
    layer:setFilter("highway", "tertiary")
    layer:addFill(11.5, 171, 158, 143, 0)
    layer:addFill(13, 171, 158, 143, 255)
    layer:addFill(MAXZ, 171, 158, 143, 255)

 

    layer = styleAPI:newPolygonLayer("road-secondary")
    layer:setMinZoom(11.0)
    layer:setFilter("highway", "secondary")
    layer:addFill(MINZ, 134, 125, 113, 255)
    layer:addFill(MAXZ, 134, 125, 113, 255)

 

    layer = styleAPI:newPolygonLayer("road-primary")
    layer:setMinZoom(11.0)
    layer:setFilter("highway", "primary")
    layer:addFill(MINZ, 134, 125, 113, 255)
    layer:addFill(MAXZ, 134, 125, 113, 255)

 

    layer = styleAPI:newPolygonLayer("railway")
    layer:setMinZoom(14.0)
    layer:setFilter("railway", "*")
    layer:addFill(MINZ, 200, 191, 231, 255)
    layer:addFill(MAXZ, 200, 191, 231, 255)

 

    -- Default, same as building-Residential
    layer = styleAPI:newPolygonLayer("building")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "yes")
    layer:addFill(13.0f, 210, 158, 105, 0)
    layer:addFill(13.5f, 210, 158, 105, 255)
    layer:addFill(MAXZ, 210, 158, 105, 255)

 

    layer = styleAPI:newPolygonLayer("building-Residential")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "Residential")
    layer:addFill(13.0f, 210, 158, 105, 0)
    layer:addFill(13.5f, 210, 158, 105, 255)
    layer:addFill(MAXZ, 210, 158, 105, 255)

 

    layer = styleAPI:newPolygonLayer("building-CommunityServices")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "CommunityServices")
    layer:addFill(13.0f, 139, 117, 235, 0)
    layer:addFill(13.5f, 139, 117, 235, 255)
    layer:addFill(MAXZ, 139, 117, 235, 255)

 

    layer = styleAPI:newPolygonLayer("building-Hospitality")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "Hospitality")
    layer:addFill(13.0f, 127, 206, 225, 0)
    layer:addFill(13.5f, 127, 206, 225, 255)
    layer:addFill(MAXZ, 127, 206, 225, 255)

 

    layer = styleAPI:newPolygonLayer("building-Industrial")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "Industrial")
    layer:addFill(13.0f, 56, 54, 53, 0)
    layer:addFill(13.5f, 56, 54, 53, 255)
    layer:addFill(MAXZ, 56, 54, 53, 255)

 

    layer = styleAPI:newPolygonLayer("building-Medical")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "Medical")
    layer:addFill(13.0f, 229, 128, 151, 0)
    layer:addFill(13.5f, 229, 128, 151, 255)
    layer:addFill(MAXZ, 229, 128, 151, 255)

 

    layer = styleAPI:newPolygonLayer("building-RestaurantsAndEntertainment")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "RestaurantsAndEntertainment")
    layer:addFill(13.0f, 245, 225, 60, 0)
    layer:addFill(13.5f, 245, 225, 60, 255)
    layer:addFill(MAXZ, 245, 225, 60, 255)

 

    layer = styleAPI:newPolygonLayer("building-RetailAndCommercial")
    layer:setMinZoom(13.0)
    layer:setFilter("building", "RetailAndCommercial")
    layer:addFill(13.0f, 184, 205, 84, 0)
    layer:addFill(13.5f, 184, 205, 84, 255)
    layer:addFill(MAXZ, 184, 205, 84, 255)
end

 

function MapUtils.overlayPaper(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:newTextureLayer("paper")
    layer:setMinZoom(0.00)
    local x1 = mapAPI:getMinXInSquares()
    local y1 = mapAPI:getMinYInSquares()
    local x2 = mapAPI:getMaxXInSquares() + 1
    local y2 = mapAPI:getMaxYInSquares() + 1
    layer:setBoundsInSquares(x1, y1, x2, y2)
    layer:setTile(true)
    layer:setUseWorldBounds(true)
    layer:addFill(14.00, 128, 128, 128, 0)
    layer:addFill(15.00, 128, 128, 128, 32)
    layer:addFill(15.00, 255, 255, 255, 32)
    layer:addTexture(0.00, "media/white.png")
    layer:addTexture(15.00, "media/white.png")
    layer:addTexture(15.00, "media/textures/worldMap/Paper.png")
end

 

function MapUtils.revealKnownArea(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    local x1 = mapAPI:getMinXInSquares()
    local y1 = mapAPI:getMinYInSquares()
    local x2 = mapAPI:getMaxXInSquares()
    local y2 = mapAPI:getMaxYInSquares()
    WorldMapVisited.getInstance():setKnownInSquares(x1, y1, x2, y2)
end

-----

 

local function replaceWaterStyle(mapUI)
    if not WATER_TEXTURE then return end
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:getLayerByName("water")
    if not layer then return end
    layer:setMinZoom(MINZ)
    layer:setFilter("water", "river")
    layer:removeAllFill()
    layer:removeAllTexture()
    layer:addFill(MINZ, 59, 141, 149, 255)
    layer:addFill(MAXZ, 59, 141, 149, 255)
end

 

local function overlayPNG(mapUI, x, y, scale, layerName, tex, alpha)
    local texture = getTexture(tex)
    if not texture then return end
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:newTextureLayer(layerName)
    layer:setMinZoom(MINZ)
    layer:addFill(MINZ, 255, 255, 255, (alpha or 1.0) * 255)
    layer:addTexture(MINZ, tex)
    layer:setBoundsInSquares(x, y, x + texture:getWidth() * scale, y + texture:getHeight() * scale)
end

 

local function overlayPNG2(mapUI, x, y, scaleX, scaleY, tex)
    local mapAPI = mapUI.javaObject:getAPIv1()
    local styleAPI = mapAPI:getStyleAPI()
    local layer = styleAPI:newTextureLayer("lootMapPNG")
    layer:setMinZoom(MINZ)
    local texture = getTexture(tex)
    layer:addFill(MINZ, 255, 255, 255, 128)
    layer:addTexture(MINZ, tex)
    layer:setBoundsInSquares(x, y, x + texture:getWidth() * scaleX, y + texture:getHeight() * scaleY)
end

-- -- -- -- --

 

LootMaps.Init.IScn_Stash_Rosewood = function(mapUI)
    local mapAPI = mapUI.javaObject:getAPIv1()
    MapUtils.initDirectoryMapData(mapUI, 'media/maps/Muldraugh, KY')
    MapUtils.initDefaultStyleV1(mapUI)
    replaceWaterStyle(mapUI)
    mapAPI:setBoundsInSquares(7900, 11140, 8604, 12139)
    overlayPNG(mapUI, 7958, 11962, 0.666, "badge", "media/textures/worldMap/RosewoodBadge.png")
    overlayPNG(mapUI, 8213, 11161, 0.666, "legend", "media/textures/worldMap/Legend.png")
    MapUtils.overlayPaper(mapUI)
--    overlayPNG(mapUI, 26*300+100, 37*300+30, 0.666, "lootMapPNG", "media/ui/LootableMaps/rosewoodmap.png", 0.5)
end
 

 

 

as per the lootable map guide:

 

Link to comment
Share on other sites

Those other functions are inherited and therefore unnecessary to copy. The only ones that need duplications are marked local functions

 

I was able to get the annotations to show up using the following code. Stash seems to work too. Just can't immediately teleport to it with NecroForge.

 

 

 


            local mapItem = c:AddItem("IScn_RosewoodMap");  
            mapItem:setMapID("IScn_Stash_Rosewood")
            local stash = StashSystem.getStash("IScn_Stash_Rosewood")
            StashSystem.doStashItem(stash, mapItem)
            mapItem:setName(mapItem:getDisplayName() .. ": " .. "Family Home")
            mapItem:setCustomName(true)  
 

 

Edited by TheoryOfMadness
Link to comment
Share on other sites

If you want you can subscribe to and download Bedford Falls on steam workshop, if you then add this file:

bedfordstashdescriptions.lua

to its "media/lua/shared/StashDescriptions" folder it will enable the test stashes from the original post of this thread and using the methods in the guides. Might be helpful in checking folder/file structure etc.

You can then load the game in debug mode (-debug in the launch options on steam), when in game select the debug menu, then the "dev" box at the top and then stash debugger, you can then select any Bedford Falls (or vanilla) stash map and click spawn, you will be teleported to the building and the stash will be populated. Obviously will also come in handy for testing your own too.

You can also press F8 when in game in debug mode to bring up the map debugger, you can use this to load and see what each map/stash maps shows.

Link to comment
Share on other sites

I think the difference with your code and mine, is that I am spawning the map directly. If I don't link it as above, it won't trigger the Stash system.

 

Appreciate the tips!

 

A few other details I learned.

- You can write your own text without the translation system e.g.

stashMap:addStamp(nil, "Meet up with the family", 11050, 6865, 0, 0, 1)

 

- Container definitions such

stashMap1:addContainer("ToolsBox",nil,"Base.Bag_DuffelBagTINT",nil,nil,nil,nil);

are tied directly to the spawnTable

Bag_DuffelBagTINT will only work with spawnTables that include it in e.g. ShotgunCache1

See media\lua\server\Items\Distributions.lua

Edited by TheoryOfMadness
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...