Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - vettlingr

Pages: 1 [2] 3 4 ... 19
16
Hello.

I am a big fan of the combine-drinks and combine-plants scripts of dfhack but always found
it tedious how I needed to manually go over every stockpile to combine all drinks in my forts.
That the sqript requires you to select a stockpile or write a single stockpiles id in the editor
makes it so that the script was hard to automate.

This is why I have added an -food -all function to the combine scripts, as well as merging combine-drinks and combine-plants into a single script "combine"

Download:
https://dffd.bay12games.com/file.php?id=15735

Code: [Select]
-- Merge food stacks in the selected stockpile or every stockpile
--[====[

combine-food by Vettlingr
==============
Merge stacks of food in the selected stockpile or all stockpiles.

]====]
local utils = require 'utils'

local f = {
    validArgs = utils.invert({ 'help', 'drinks', 'plants', 'meat', 'fish', 'fat', 'food', 'roasts', 'max', 'all', 'stockpile' });
    args = utils.processArgs({...}, validArgs);
help = [====[
Combine
=============
Merge stacks of food in selected Stockpile or across all stockpiles on the map.
Valid commands:
:``-drinks``:
    Merges drinks
:``-plants``:
    Merges plants
:``-meat``:
    Merges meat and intestines
:``-fat``:
    Merges fat and tallow
:``-roasts``:
    Merges prepared food
:``-fish``:
    Merges fish
:``-food``:
    Merges all food categories
:``-all``:
    Selects all stockpiles
:``-max``:
    Selects a maximum stacksize, if unspecified it will be set to 500

Examples:
combine -drinks -fish -all
    Combines drinks and fish stacks in all stockpiles

combine -food -all
    Combines all food types across all stockpiles

combine -fat -roasts -max 50
    Combines fat and prepared food in the selected stockpile with a preferred stacksize of 50

]====]
}

local max = 30

local drinks={}
local plants={}
local meats={}
local fat={}
local roasts={}
local fish={}

--Stockpile Stack sizes:
drinks.max  =   30
plants.max  =   6
meats.max   =   20
fat.max     =   20
roasts.max  =   20
fish.max    =   10

--Not sure if these are needed.
drinks.Tot=0 drinks.xTot=0
plants.Tot=0 plants.xTot=0
meats.Tot=0 meats.xTot=0
fat.Tot=0 fat.xTot=0
roasts.Tot=0 roasts.xTot=0
fish.Tot=0 fish.xTot=0

if f.args.max then max = tonumber(f.args.max) end

local stockpile = nil
if f.args.stockpile then stockpile = df.building.find(tonumber(f.args.stockpile)) end

local function itemsCompatible(item0, item1)
    return item0:getType() == item1:getType()
        and item0.mat_type == item1.mat_type
        and item0.mat_index == item1.mat_index
end

local function FishitemsCompatible(item0, item1)
    return item0:getType() == item1:getType()
        and item0.race == item1.race
        and item0.caste == item1.caste
end

function getItems(items, item, index, bool)
    repeat
        local nextBatch = {}
        for _,v in pairs(items) do
            -- Skip items currently tasked
            if #v.specific_refs == 0 then
                    if bool==1 and ( v:getType() == df.item_type.DRINK )then
                        item[index] = v
                        index = index + 1
                    elseif bool==2 and ( v:getType() == df.item_type.PLANT or v:getType() == df.item_type.PLANT_GROWTH ) then
                            item[index] = v
                            index = index + 1
                    elseif bool==3 and (v:getType() == df.item_type.MEAT ) then
                            item[index] = v
                            index = index + 1
                    elseif bool==4 and (v:getType() == df.item_type.GLOB ) then
                            item[index] = v
                            index = index + 1
                    elseif bool==5 and (v:getType() == df.item_type.FOOD or v:getType() == df.item_type.CHEESE ) then
                            item[index] = v
                            index = index + 1
                    elseif bool==10 and (v:getType() == df.item_type.FISH or v:getType() == df.item_type.FISH_RAW or v:getType() == df.item_type.EGG ) then
                        item[index] = v
                        index = index + 1
                    else
                    local containedItems = dfhack.items.getContainedItems(v)
                        if (bool==1 and #containedItems == 1) or (bool>1 and #containedItems > 0) then
                            for _,w in pairs(containedItems) do
                                table.insert(nextBatch, w)
                            end
                        end
                    end
                end
            end
        items = nextBatch
    until #items == 0
    return index
end

function Combineitems(building, tabl, food, bool)
    local rootItems
    if building then
        rootItems = dfhack.buildings.getStockpileContents(building)
    else
        rootItems = dfhack.items.getContainedItems(item)
    end
    if #rootItems == 0 and not f.args.all then
        qerror("Select a non-empty container")
        return
    else
        local foodCount = getItems(rootItems, food, 0, bool)
        local removedFood = { } --as:bool[]
        food.max=max
        if f.args.max then max = tonumber(f.args.max)
            if tonumber(f.args.max)== 0 then max = 500
            end
        end
        for i=0,(foodCount-2) do
            local currentFood = food[i] --as:df.item_foodst
            local itemsNeeded = max - currentFood.stack_size

            if removedFood[currentFood.id] == nil and itemsNeeded > 0 then
                local j = i+1
                local last = foodCount
                repeat
                    local sourceFood = food[j]
                        if bool>=10 and removedFood[sourceFood.id] == nil and FishitemsCompatible(currentFood, sourceFood) then
                            local amountToMove = math.min(itemsNeeded, sourceFood.stack_size)
                            itemsNeeded = itemsNeeded - amountToMove
                            currentFood.stack_size = currentFood.stack_size + amountToMove

                            if sourceFood.stack_size == amountToMove then
                                removedFood[sourceFood.id] = true
                                sourceFood.stack_size = 1
                            else
                                sourceFood.stack_size = sourceFood.stack_size - amountToMove
                            end
                            --                    else print("failed")
                        elseif bool <10 and removedFood[sourceFood.id] == nil and itemsCompatible(currentFood, sourceFood) then
                            local amountToMove = math.min(itemsNeeded, sourceFood.stack_size)
                            itemsNeeded = itemsNeeded - amountToMove
                            currentFood.stack_size = currentFood.stack_size + amountToMove

                            if sourceFood.stack_size == amountToMove then
                                removedFood[sourceFood.id] = true
                                if bool>1 then sourceFood.stack_size = 1 end
                            else
                                sourceFood.stack_size = sourceFood.stack_size - amountToMove
                            end
                            --                    else print("failed")
                        end
                    j = j + 1
                until j == foodCount or itemsNeeded == 0
            end
        end
        local removedCount = 0
        for id,removed in pairs(removedFood) do
            if removed then
                removedCount = removedCount + 1
                local removedFood = df.item.find(id)
                dfhack.items.remove(removedFood)
            end
        end
        if food.Tot == nil then food.Tot = 0 end
        if food.xTot == nil then food.xTot = 0 end
        food.Tot = food.Tot + foodCount
        food.xTot = food.xTot + removedCount
    end
end

if f.args.help then
    print(f.help)
    return
end
if not f.args.all then
    local building = stockpile or dfhack.gui.getSelectedBuilding(true)
    if building ~= nil and building:getType() ~= 29 then building = nil
        end
    if building ~= nil then
        if f.args.drinks or f.args.food then
            Combineitems(building, f, drinks, 1)
            print("found " .. drinks.Tot .. " drinks")
            print("merged " .. drinks.xTot .. " drinks")
        end
        if f.args.plants or f.args.food then
            Combineitems(building, f, plants, 2)
            print("found " .. plants.Tot .. " plants")
            print("merged " .. plants.xTot .. " plants")
        end
        if f.args.meat or f.args.food then
            Combineitems(building, f, meats, 3)
            print("found " .. meats.Tot .. " meat")
            print("merged " .. meats.xTot .. " meat")
        end
        if f.args.fat or f.args.food then
            Combineitems(building, f, fat, 4)
            print("found " .. fat.Tot .. " fat")
            print("merged " .. fat.xTot .. " fat")
        end
        if f.args.roasts or f.args.food then
            Combineitems(building, f, roasts, 5)
            print("found " .. roasts.Tot .. " prepared food")
            print("merged " .. roasts.xTot .. " prepared food")
        end
        if f.args.fish or f.args.food then
            Combineitems(building, f, fish, 10)
            print("found " .. fish.Tot .. " fish")
            print("merged " .. fish.xTot .. " fish")
        end
    else
        print('select a stockpile')
    end
else
    if f.args.all then
        print('Combining all food...')
        for _, building in pairs(df.global.world.buildings.all) do
            if building:getType() == 29 and building ~= nil then
                if building ~= nil then
                    if f.args.drinks or f.args.food then
                        Combineitems(building, f, drinks, 1)
                    end
                    if f.args.plants or f.args.food then
                        Combineitems(building, f, plants, 2)
                    end
                    if f.args.meat or f.args.food then
                        Combineitems(building, f, meats, 3)
                    end
                    if f.args.fat or f.args.food then
                        Combineitems(building, f, fat, 4)
                    end
                    if f.args.roasts or f.args.food then
                        Combineitems(building, f, roasts, 5)
                    end
                    if f.args.fish or f.args.food then
                        Combineitems(building, f, fish, 10)
                    end
                else
                    print('invalid')
                end
            end
        end
        if f.args.drinks or f.args.food then
            print("found " .. drinks.Tot .. " drinks")
            print("merged " .. drinks.xTot .. " drinks")
        end
        if f.args.plants or f.args.food then
            print("found " .. plants.Tot .. " plants")
            print("merged " .. plants.xTot .. " plants")
        end
        if f.args.meat or f.args.food then
            print("found " .. meats.Tot .. " meat")
            print("merged " .. meats.xTot .. " meat")
        end
        if f.args.fat or f.args.food then
            print("found " .. fat.Tot .. " fat or tallow")
            print("merged " .. fat.xTot .. " fat or tallow")
        end
        if f.args.roasts or f.args.food then
            print("found " .. roasts.Tot .. " prepared food")
            print("merged " .. roasts.xTot .. " prepared food")
        end
        if f.args.fish or f.args.food then
            print("found " .. fish.Tot .. " fish")
            print("merged " .. fish.xTot .. " fish")
        end
    end
    return
end



17
Did a quick rewrite of the statues adding porcelain, glass, stone and metal

Also tried to implement a metal effect seen below (Statues).

18
>I don't think I like the detail on the soil. My first thing was to think something transparent is laying there. Not sure how to interpret it yet.
its spent ammo. I think it looks way better than before ;)

19
If you do I can compile a alternate version of the pack and add it to the download. I would love to see the new version you came up with
You may find it interesting to include something like this too.
http://www.bay12forums.com/smf/index.php?topic=179206.msg8326776#msg8326776
I'm going to run it once per save and it fixes a lot of the new graphic stuff in 47.xx

20


Some of you may not know that I can code; but I can - and this is my second contribution to the Df community and Dfhack altogether.

This script Searches your save and indexes all creature raws of Angels and Experiments and generates a graphics file for them, giving them unique graphics in game.
The graphics art .pngs are derived from Mephs procedual creatures ultimately from Denzis Random Monsters.

Put the script into hack/scripts,
 the graphics files into your saves graphics folder,
  then and run the script in the dfhack terminal.

Also...
Back your stuff up!

Download on DFFD

Code: [Select]
--
--[====[

generate procedual graphics
==============
Generates graphics for necromancer experiments and divine creatures and puts it into your current save folder

]====]
local utils = require 'utils'

math.randomseed(os.time()) -- random initialize
math.random(); math.random(); math.random() -- warming up

function randomnumber( oneortwo )
        -- random generating
        if oneortwo == 1 then
            value1 = math.random(0,31)
            return value1
        end
        if oneortwo == 2 then
            value2 = math.random(0,29)
            return value2
    end
end
    local selection
    local key = 1
    local hfexpId = {}

    for id, raw in pairs(df.global.world.raws.creatures.all) do
        if raw.creature_id:startswith('HFEXP') then
            hfexpId[key] = raw.creature_id
            key = key + 1
        end
    end

    local key2 = 1
    local hfId = {}

    for id, raw in pairs(df.global.world.raws.creatures.all) do
        if raw.creature_id:startswith('HF') and not raw.creature_id:startswith('HFEXP') then
            hfId[key2] = raw.creature_id
            key2 = key2 + 1
        end
    end

function dfhack.getSavePath()
    if dfhack.isWorldLoaded() then
        return dfhack.getDFPath() .. '/data/save/' .. df.global.world.cur_savegame.save_dir .. '/raw/graphics/'
    end
end

os.execute('mkdir' .. dfhack.getSavePath()..'graphics_procedual_hfexp.txt')
file = io.open(dfhack.getSavePath()..'graphics_procedual_hfexp.txt', 'w')
file:write('graphics_procedual_hfexp\n')
file:write('[OBJECT:GRAPHICS] \n')
file:write('[TILE_PAGE:NECRO] \n')
file:write('[FILE:procedual_hfexp.png] \n')
file:write('[TILE_DIM:32:32] \n')
file:write('[PAGE_DIM:26:30] \n \n')

for i in ipairs(hfexpId) do
    file:write('[CREATURE_GRAPHICS:', hfexpId[i], '] \n')
    file:write('[DEFAULT:NECRO'..':'..randomnumber(1)..':'..randomnumber(2)..':AS_IS:DEFAULT] \n')
end

file:close()

os.execute('mkdir' .. dfhack.getSavePath()..'graphics_procedual_divine.txt')
file = io.open(dfhack.getSavePath()..'graphics_procedual_divine.txt', 'w')
file:write('graphics_procedual_divine\n')
file:write('[OBJECT:GRAPHICS] \n')
file:write('[TILE_PAGE:DIVINE] \n')
file:write('[FILE:procedual_divine.png] \n')
file:write('[TILE_DIM:32:32] \n')
file:write('[PAGE_DIM:26:30] \n \n')

for i in ipairs(hfId) do
    file:write('[CREATURE_GRAPHICS:', hfId[i], '] \n')
    file:write('[DEFAULT:DIVINE'..':'..randomnumber(1)..':'..randomnumber(2)..':AS_IS:DEFAULT] \n')
end

file:close()

print('Generated graphics for Divine and Experiments')
print('Found '..(key - 1)..' Experiments')
print('Found '..(key2 - 1)..' Angels')

return




Shameless Patreon Plug:

21
Patreon Post link (public) for random screenshots:
https://www.patreon.com/posts/1-6-alpha-lots-58359563?utm_medium=clipboard_copy&utm_source=copy_to_clipboard&utm_campaign=postshare

Script for generating Necromancer experiment and angel graphics:
https://dffd.bay12games.com/file.php?id=15729

New Construction Designations
Notice the transparency

22
I've retouched a lot of the creature sprite sheets for this tileset and tried to retrace some missing credits. Like the bird_new and bird uses sprites from Neorice and Paul Robertson, yet I could not find their names in the credits.

Otherwise I've fixed a lot of issues with child and adult sprites being the same size, sprites for zombies etc. I could post a pack here when I get the time. I would need to remove my own outline that my tileset uses, but that is in a separate layer in gimp so easy enough.

also, hello meph, long time no see ;)

Cheers

23
Posted a shadow update. Will post screenshots and features later. Loads of stuff coming in this one. I haven't tested it fully yet, though I think that there are a few erraneous lines of overrides left from a mod and the corpses won't show up as they are supposed to until I edit all creature raws.


Full list of new stuff: 1.6 Changelog
New wooden furniture and floor
Metal furniture
Porcelain and earthenware Furniture
Revamped grass colours
Evil biomes look more evil
Blocks have updated graphics
Animation is back!
All furnaces have tweaked graphics, Magma Furnaces now look distinct.
Large Rock pots have gracphics based on stone.
Jugs and flasks.
Meat and bone have new graphical representation
Corpses look better now
Partially mined tiles look better
Construction icons look great now
Porcelain, glass and wood Minetracks
Paved roads.
Revamped procedually generated beasts
New bird sprites
Spongebob and Ninjaturtles are purged, exterminated and removed, will never be back.
All Creature graphics have gotten a facelift by standard filter and outline. Though much remains to be done.
Cave fungus wood furniture.

24
(...)
I love the rocks and stones in Vettlingr. They are amazing, and definitely one of the reasons it's at the top of my tileset rotation. (...)
Exactly my thought as well.

(...)
Butchery (Stone):

(...)
Normally I wouldn't ask for this but as you are doing the rework of workshops anyway. What would you think about changing butchery a bit? Currently it does look braided whilst that wouldn't be practical thus it is a little confusing. For me at least.
Would you mind changing the top to something more flat? Wooden or metallic?

I mean, its a product of consistency. All workshop "Block" tables have the same pattern. the color of the table top reflects the color of the labor used to preform them. Hence the brown color gives the impression of a wicker top, which is unintentional. The previous iteration used a brass color filter to make it look metallic. I am a bit unsure how to progress keeping consistency with implementing your request, but I'll figure something out.

25
I've been busy touching up a few old sprites that were mostly placeholders from the start.
Most of the workshops have gotten a facelift, and their graphics will now reflect what material was used to build them, materials being wood, stone, metal and glass.

Butchery (Stone):


Tannery (Metal):


Dyery (Metal):


Siege Workshop (wood):


26
I love the look of the wooden furniture. Too often wooden furniture just looks like brown stone furniture. So would love to see this. You are doing great work. As for the metal furniture, I would just make it look distinct to the wood and stone. All the different metal furniture types from Meph’s set can be too different from each other and not fit well together visually. Just my two cents on it anyways. Keep up the great work on your tileset!

I originally put off doing the wooden furniture since I thought most people stuck to stone, and had a ragtag band of barebones wood furniture sprites as placeholders. Then I see on youtube and twitch how people actually use a lot more wood furniture in their forts than I thought. As the tileset progressed the wood furniture started looking out of place and the floor tiles looked hideous. Couldn't really bear watching people playing with my tileset constructing wooden forts as a result.

This tileset was originally made to address a lot of the inconsistencies that occur in Mephs. I wanted all furniture and wall sprites to fit very well together and wood items and architecture shouldn't look out of place close to metal and stone. Meph sure is a pioneer in the making of TWBT tileset and I have learnt a great deal from him and studying his override solutions. It feels like Meph showed me the TWBT solution for me to master its implementation. I am very grateful for his help.

I would like to add more features similar to what Meph has, especially unique sprites for certain materials. THough with steam release on the horizon, that may mean a lot of work just to end up scrapping it in the end, and I've already scrapped a lot so far.

Thanks for your input, I don't necessarily think my tileset should be compared to Mephs as they are both standalone entities with different styles and solutions at this point. Though one did encourage the other.

27
DF Modding / Re: Vettlingr's Geology Overhaul Mod, WIP
« on: August 28, 2021, 10:01:17 am »
Screenshots of mineral biomes:

Ultramafic Igneous Intrusive is very green since they contain large quantities of Mg-Olivine
Here you can find Iron, Nickel, Platinum and Chromium
Spoiler (click to show/hide)

Next up is Felsic Igneous intrusive, mostly consisting of quartz rich rocks such as granite, syenite and pegmatite
Here you find your tin, tungsten and cobalt
Spoiler (click to show/hide)

Metamorphic Amphibolite is rich in garnet and certain minerals, shown below are Manganspar (Rhodochrosite) cutting through a low temperature hydrothermal Tetrahedrite deposit
Spoiler (click to show/hide)

The following two images show ultra high pressure eclogite facies
This is where you find Titanium and sometimes diamonds. Kimberlite xenolith veins cut through the second picture.
Spoiler (click to show/hide)
Spoiler (click to show/hide)

28
Does anyone still work on this??

I would like to request an idea I have.

It would be cool to be able to use custom material groupings as a material flag/token like so:

[MATERIALGROUP:IGNEOUS_GRANULATE]
[INORGANIC:GRANITE]
[INORGANIC:DIORITE]
[INORGANIC:GABBRO]
[END]

Then apply it like so:
[OVERRIDE:205:T:MineralWallSmoothLR:6:142:::IGNEOUS_GRANULATE:]
[OVERRIDE:186:T:MineralWallSmoothUD:6:159:::IGNEOUS_GRANULATE:]
[OVERRIDE:200:T:MineralWallSmoothRU:6:173:::IGNEOUS_GRANULATE:]
[OVERRIDE:211:T:MineralWallSmoothRU2:6:126:::IGNEOUS_GRANULATE:]
[OVERRIDE:212:T:MineralWallSmoothR2U:6:190:::IGNEOUS_GRANULATE:]

That way you could limit the amount of override lines needed for materials that share the same override.

29
Thank.

I have been updating the descriptions to be more readable.

Been throwing a few ideas around on how to add to this mod. So far I have moved a few creatures to Goblin and renamed a few, but I'm not content with all of it yet.

Moved to goblin:
Lockspider - No longer has [NOFEAR]
Bittern
Shrewdog

Going to be added in next update?
Silver Fox - Swift vermin hunter. Trainable for hunting.
Oilbird - Plump cliff cave bird, butchered for a lot of fat. Maybe extract oil from them?

Right now, oil isn't really used for much and overlaps with fat in most reactions. So giving the option to extract oil from a domestic animal is a little redundant.

Still not entirely content with the Shaggy Desman/Molebeast/Taupe Mole. I'm not sure if it should be removed or made into a Slow growing shareable source for more valuable fur cloth, taupe is after all a very prized commodity.

30
DF Modding / Re: Vettlingr's Geology Overhaul Mod, WIP
« on: August 23, 2021, 09:49:58 am »
Code: [Select]
Metals organized so far
They are grouped into tiers based on their main alloying element.

Tier - Chromium, Cobalt // Tungsten
Chromril - Weapons and Armour - 2 Cobalt + 1 Mirron + 1 Tungsten, 1 Flux, 1 Coal
Mirron - Weapons and Armour - 2 Nickel + 2 Chromium + 1 Flux + 1 Coal
Tungsten - Weapons - Wolframite, Scheelite
Cobalt - Weapons and Armour - Cobaltite, Spherocobaltite

Tier - Iron
Brynstahl - Weapons and Armour - 3 Steel + 1 Mirron + 1 Molybdenum + 1 Charcoal + 1 Flux + 1 Fuel
Steel - Weapons and Armour - 4 Iron + 1 Mangan + 1 Charcoal + 1 Flux + 1 Fuel
Iron - Weapons and Armour - 5 Rust + 1 Charcoal + 1 Flux + 1 Fuel
Rust - Weapons and Armour - Magnetite, Haematite, Limonite, Goethite, Siderite, Wustite

Tier - Copper // Nickel, Tin, Aluminium
Orichalcum - Weapons and Armour - 3 Copper + 1 Aluminum + 1 Nickel Silver + 1 Raw Green Glass
Bronze - Weapons and Armour - 4 Copper + 1 Tin
Cupronickel - Weapons and Armour - 3 Copper + 2 Nickel
Brass - Armour - 3 Copper + 2 Zinc
Copper - Weapons and Armour - Native Copper, Malachite, Azurite, Chalcocite, Chalcopyrite, Bornite

Tier - Titanium // Molybdenum, Aluminium, Niobium
Titansteel - Weapons and Armour - 1 Vanadium + 3 Titanium
Titanium - Armour - Rutile, Ilmenite

Tier - Gold // Silver, Platinum
Thorium - Thunraz - Thorite, Thorianite
Uranium - Glowing Glass - Pitchblende
Truesilver - Furniture - 2 Platinum + 2 Gold + 1 Silver + Cinnabar
Platinum - Furniture - Native Platinum
Gold - Furniture - Native Gold, Goldstone
Silver - Furniture - Native Silver, Horn Silver, Acanthite, Silverstone

Tier Alloy Elements // Manganese, Vanadium, Niobium, Nickel
Nickel - Furniture - Garnierite, Pentlandite, Nickeline
Chromium - Furniture, studs - Chromite, Crocoite
Manganese - Steel, purple glass - Manganite, Pyrolusite, Rhodocrosite
Vanadium - Titansteel - Vanadinite, Patronite

Tier Pewter // Tin, Bismuth, Antimony, Lead
Tin Pewter - Furniture - 3 Tin Bars + 1 Lead/Bismuth/Antimony Bar
Lead Pewter - Furniture - 3 Lead Bars + 1 Tin/Bismuth/Antimony Bar
Tin - Furniture - Cassiterite, Stannite
Lead - Furniture - Galena, Cerusite, Crocoite(25%)
Antimony - Pewter - Stibnite
Bismuth - Pewter - Bismuthinite


Pages: 1 [2] 3 4 ... 19