6 Commits

Author SHA1 Message Date
ZioPao
839ce002a3 More tests 2025-10-04 15:05:33 +02:00
ZioPao
49eee7ce84 fix: 42.12 new bodyloc 2025-10-04 04:23:12 +02:00
ZioPao
1c72647d40 fix: fix for cheat prevention with both hands feasibility to false 2025-10-04 04:22:26 +02:00
ZioPao
a9a7063287 fix: override for both hands interaction for b42 and cheat prevention 2025-10-04 04:22:04 +02:00
ZioPao
a511ac777a refactor: reorganized settings for cd 2025-07-14 02:46:43 +02:00
ZioPao
04c7172d82 refactor: removed old code 2025-07-14 01:15:39 +02:00
42 changed files with 205 additions and 50 deletions

3
.gitignore vendored
View File

@@ -1 +1,2 @@
/media dev_stuff/gen_amp_textures/.venv
dev_stuff/gen_amp_textures/output

8
.vscode/tasks.json vendored
View File

@@ -6,14 +6,14 @@
{ {
"label": "Create Workshop folder", "label": "Create Workshop folder",
"type": "shell", "type": "shell",
"options": {"statusbar": {"label": "$(combine) Assemble Mod"}}, "options": {"statusbar": {"label": "$(combine) Assemble Mod - B42"}},
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py \"picch\" \"${workspaceFolderBasename}\" \"\"", "command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py \"42\" \"picch\" \"${workspaceFolderBasename}\" \"\"",
}, },
{ {
"label": "Create Workshop folder", "label": "Create Workshop folder",
"type": "shell", "type": "shell",
"options": {"statusbar": {"label": "$(combine) Assemble Mod (B41 ONLY)"}}, "options": {"statusbar": {"label": "$(combine) Assemble Mod - B41"}},
"command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack_b41.py \"picch\" \"${workspaceFolderBasename}\"", "command": "python ${config:zomboid_user_folder}/PaosCrap/make_workshop_pack.py \"41\" \"picch\" \"${workspaceFolderBasename}\" \"\"",
}, },
{ {
"label": "Create Workshop folder", "label": "Create Workshop folder",

View File

@@ -4,7 +4,7 @@ local OverridenMethodsArchive = require("TOC/OverridenMethodsArchive")
local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Get("ISClothingExtraAction_isValid") local og_ISClothingExtraAction_isValid = OverridenMethodsArchive.Get("ISClothingExtraAction_isValid")
---@diagnostic disable-next-line: duplicate-set-field ---@diagnostic disable-next-line: duplicate-set-field
function ISClothingExtraAction:isValid() function ISClothingExtraAction:isValid()
TOC_DEBUG.print("Inside ISClothingExtraAction:isValid 42") -- TOC_DEBUG.print("Inside ISClothingExtraAction:isValid 42")
TOC_DEBUG.print(OverridenMethodsArchive.Get("ISClothingExtraAction_isValid")) -- TOC_DEBUG.print(OverridenMethodsArchive.Get("ISClothingExtraAction_isValid"))
return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, instanceItem(self.extra)) return LimitActionsController.WrapClothingAction(self, og_ISClothingExtraAction_isValid, instanceItem(self.extra))
end end

View File

@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<clothingItem> <clothingItem>
<m_MaleModel>Amputation\Amputation_Left_LowerArm_Male</m_MaleModel> <m_MaleModel>Amputation\Amputation_FA_LR</m_MaleModel>
<m_FemaleModel>Amputation\Amputation_Left_LowerArm_Female</m_FemaleModel> <m_FemaleModel>Amputation\Amputation_Left_LowerArm_Female</m_FemaleModel>
<m_GUID>d3816fe0-48e1-4cf5-a8e4-48c72595edb4</m_GUID> <m_GUID>d3816fe0-48e1-4cf5-a8e4-48c72595edb4</m_GUID>
<m_Static>false</m_Static> <m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue> <m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint> <m_AllowRandomTint>false</m_AllowRandomTint>
<m_Masks>3</m_Masks> <m_UnderlayMasksFolder>media/textures/Amputations/Masks/TestDouble</m_UnderlayMasksFolder>
<m_Masks>4</m_Masks> <m_Masks>4</m_Masks>
<m_Masks>6</m_Masks>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<clothingItem>
<m_MaleModel>Amputation\Amputation_FA_LR</m_MaleModel>
<m_FemaleModel>Amputation\Amputation_FA_LR</m_FemaleModel>
<m_GUID>8e5bc1b4-d79b-4a17-b86b-71dab6ace816</m_GUID>
<m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint>
<m_Masks>4</m_Masks>
<m_Masks>6</m_Masks>
<!-- HUMAN -->
<textureChoices>Amputations\Human\Forearm\skin01_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin02_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin03_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin04_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin05_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin01_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin02_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin03_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin04_hairy_b</textureChoices>
<textureChoices>Amputations\Human\Forearm\skin05_hairy_b</textureChoices>
<!-- HUMAN AFTER CICATRIZATION -->
<textureChoices>Body\MaleBody01</textureChoices>
<textureChoices>Body\MaleBody02</textureChoices>
<textureChoices>Body\MaleBody03</textureChoices>
<textureChoices>Body\MaleBody04</textureChoices>
<textureChoices>Body\MaleBody05</textureChoices>
<textureChoices>Body\MaleBody01a</textureChoices>
<textureChoices>Body\MaleBody02a</textureChoices>
<textureChoices>Body\MaleBody03a</textureChoices>
<textureChoices>Body\MaleBody04</textureChoices>
<textureChoices>Body\MaleBody05a</textureChoices>
<!-- ZOMBIE -->
<textureChoices>Amputations\Zombie\Forearm\z_skin01_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin01_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin01_l3</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin02_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin02_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin02_l3</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin03_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin03_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin03_l3</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin04_l1</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin04_l2</textureChoices>
<textureChoices>Amputations\Zombie\Forearm\z_skin04_l3</textureChoices>
</clothingItem>

View File

@@ -57,5 +57,11 @@
<guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid> <guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid>
</files> </files>
<!-- TEST -->
<files>
<path>media/clothing/clothingItems/Amputation_ForeArm_LR.xml</path>
<guid>8e5bc1b4-d79b-4a17-b86b-71dab6ace816</guid>
</files>
</fileGuidTable> </fileGuidTable>

View File

@@ -57,7 +57,6 @@ function DataController:setup(key)
---@type tocModDataType ---@type tocModDataType
self.tocData = { self.tocData = {
-- Generic stuff that does not belong anywhere else -- Generic stuff that does not belong anywhere else
isInitializing = true,
isIgnoredPartInfected = false, isIgnoredPartInfected = false,
isAnyLimbCut = false, isAnyLimbCut = false,
limbs = {}, limbs = {},
@@ -93,10 +92,6 @@ function DataController:setup(key)
-- Sync with the server -- Sync with the server
self:apply() self:apply()
-- -- Disable lock
-- self.tocData.isInitializing = false
-- ModData.add(key, self.tocData)
triggerEvent("OnSetupTocData") triggerEvent("OnSetupTocData")
end end
@@ -339,14 +334,11 @@ end
---@param cicatrizationTime integer? ---@param cicatrizationTime integer?
function DataController:setLimbParams(limbName, ampStatus, cicatrizationTime) function DataController:setLimbParams(limbName, ampStatus, cicatrizationTime)
local limbData = self.tocData.limbs[limbName] local limbData = self.tocData.limbs[limbName]
if ampStatus.isCut ~= nil then limbData.isCut = ampStatus.isCut end for k, v in pairs(ampStatus) do
if ampStatus.isInfected ~= nil then limbData.isInfected = ampStatus.isInfected end if v ~= nil then
if ampStatus.isOperated ~= nil then limbData.isOperated = ampStatus.isOperated end limbData[k] = v
if ampStatus.isCicatrized ~= nil then limbData.isCicatrized = ampStatus.isCicatrized end end
if ampStatus.isCauterized ~= nil then limbData.isCauterized = ampStatus.isCauterized end end
if ampStatus.woundDirtyness ~= nil then limbData.woundDirtyness = ampStatus.woundDirtyness end
if ampStatus.isVisible ~= nil then limbData.isVisible = ampStatus.isVisible end
if cicatrizationTime ~= nil then limbData.cicatrizationTime = cicatrizationTime end if cicatrizationTime ~= nil then limbData.cicatrizationTime = cicatrizationTime end
end end

View File

@@ -17,7 +17,7 @@ ItemsController.Player = {}
---@return number ---@return number
---@private ---@private
function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatrized) function ItemsController.Player.GetAmputationTexturesIndex(playerObj, isCicatrized)
-- FIX Broken -- todo
local textureString = playerObj:getHumanVisual():getSkinTexture() local textureString = playerObj:getHumanVisual():getSkinTexture()
local isHairy = textureString:sub(-1) == "a" local isHairy = textureString:sub(-1) == "a"
@@ -79,13 +79,16 @@ end
---Deletes all the old amputation items, used for resets ---Deletes all the old amputation items, used for resets
---@param playerObj IsoPlayer ---@param playerObj IsoPlayer
function ItemsController.Player.DeleteAllOldAmputationItems(playerObj) function ItemsController.Player.DeleteAllOldAmputationItems(playerObj)
-- TODO Fix visual bug
-- This part is a workaround for a pretty shitty implementation on the java side. Check ProsthesisHandler for more infos -- This part is a workaround for a pretty shitty implementation on the java side. Check ProsthesisHandler for more infos
local group = BodyLocations.getGroup("Human") -- local group = BodyLocations.getGroup("Human")
group:setMultiItem("TOC_Arm", false) -- group:setMultiItem("TOC_Arm", false)
group:setMultiItem("TOC_ArmProst", false) -- group:setMultiItem("TOC_ArmProst", false)
for i = 1, #StaticData.LIMBS_STR do for i = 1, #StaticData.LIMBS_STR do
local limbName = StaticData.LIMBS_STR[i] local limbName = StaticData.LIMBS_STR[i]
-- TODO Won't work with dedicated clothingItems for multi amps
local clothItemName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName local clothItemName = StaticData.AMPUTATION_CLOTHING_ITEM_BASE .. limbName
local clothItem = playerObj:getInventory():FindAndReturn(clothItemName) local clothItem = playerObj:getInventory():FindAndReturn(clothItemName)
---@cast clothItem InventoryItem ---@cast clothItem InventoryItem
@@ -94,8 +97,8 @@ function ItemsController.Player.DeleteAllOldAmputationItems(playerObj)
-- Reset model just in case -- Reset model just in case
playerObj:resetModel() playerObj:resetModel()
group:setMultiItem("TOC_Arm", true) -- group:setMultiItem("TOC_Arm", true)
group:setMultiItem("TOC_ArmProst", true) -- group:setMultiItem("TOC_ArmProst", true)
end end
---Spawns and equips the correct amputation item to the player. ---Spawns and equips the correct amputation item to the player.

View File

@@ -36,11 +36,12 @@ end
-- We need to override when the player changes key binds manually to be sure that TOC changes are re-applied
local og_MainOptions_apply = MainOptions.apply
function MainOptions:apply(closeAfter)
og_MainOptions_apply(self, closeAfter)
CachedDataHandler.OverrideBothHandsFeasibility()
end
-------------------------------------------- --------------------------------------------

View File

@@ -23,7 +23,7 @@ end
function CachedDataHandler.CalculateCacheableValues(username) function CachedDataHandler.CalculateCacheableValues(username)
CachedDataHandler.CalculateHighestAmputatedLimbs(username) CachedDataHandler.CalculateHighestAmputatedLimbs(username)
if getPlayer():getUsername() == username then if getPlayer():getUsername() == username then
CachedDataHandler.CalculateBothHandsFeasibility() CachedDataHandler.OverrideBothHandsFeasibility()
end end
end end
@@ -130,14 +130,13 @@ function CachedDataHandler.GetHandFeasibility(side)
-- FIX horrendous workaround, but with a forced init we run the caching too early and it breaks this, setting it to nil. -- FIX horrendous workaround, but with a forced init we run the caching too early and it breaks this, setting it to nil.
if CachedDataHandler.handFeasibility[side] == nil then if CachedDataHandler.handFeasibility[side] == nil then
CachedDataHandler.CalculateBothHandsFeasibility() CachedDataHandler.OverrideBothHandsFeasibility()
end end
return CachedDataHandler.handFeasibility[side] return CachedDataHandler.handFeasibility[side]
end end
function CachedDataHandler.OverrideBothHandsFeasibility()
function CachedDataHandler.CalculateBothHandsFeasibility()
CachedDataHandler.CalculateHandFeasibility("Hand_L") CachedDataHandler.CalculateHandFeasibility("Hand_L")
CachedDataHandler.CalculateHandFeasibility("Hand_R") CachedDataHandler.CalculateHandFeasibility("Hand_R")
local interactStr = "Interact" local interactStr = "Interact"
@@ -151,13 +150,23 @@ function CachedDataHandler.CalculateBothHandsFeasibility()
if not CachedDataHandler.GetBothHandsFeasibility() then if not CachedDataHandler.GetBothHandsFeasibility() then
TOC_DEBUG.print("Disabling interact key") TOC_DEBUG.print("Disabling interact key")
TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey)) TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE)
else
TOC_DEBUG.print("Re-enabling interact key")
TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
if StaticData.COMPAT_42 then
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE, 0, false, false, false)
else
getCore():addKeyBinding(interactStr, Keyboard.KEY_NONE)
end
else
--TOC_DEBUG.print("Re-enabling interact key")
--TOC_DEBUG.print("Cached current key for interact: " .. tostring(CachedDataHandler.interactKey))
if StaticData.COMPAT_42 then
getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey, 0, false, false, false)
else
getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey) getCore():addKeyBinding(interactStr, CachedDataHandler.interactKey)
end end
end
end end
function CachedDataHandler.GetBothHandsFeasibility() function CachedDataHandler.GetBothHandsFeasibility()
@@ -165,3 +174,4 @@ function CachedDataHandler.GetBothHandsFeasibility()
end end
return CachedDataHandler return CachedDataHandler

View File

@@ -86,7 +86,7 @@ function ProsthesisHandler.SearchAndSetupProsthesis(item, isEquipping)
dcInst:apply() dcInst:apply()
-- Calculates hands feasibility once again -- Calculates hands feasibility once again
CachedDataHandler.CalculateBothHandsFeasibility() CachedDataHandler.OverrideBothHandsFeasibility()
return true return true
end end

View File

@@ -1,5 +1,6 @@
require("TOC/Debug") require("TOC/Debug")
require("NPCs/BodyLocations") require("NPCs/BodyLocations")
local StaticData = require("TOC/StaticData")
local BodyLocationsAPI = {} local BodyLocationsAPI = {}
local function customGetVal(obj, int) return getClassFieldVal(obj, getClassField(obj, int)) end local function customGetVal(obj, int) return getClassFieldVal(obj, getClassField(obj, int)) end
@@ -8,6 +9,8 @@ local group = BodyLocations.getGroup("Human")
---@type ArrayList ---@type ArrayList
local list = customGetVal(group, 1) local list = customGetVal(group, 1)
-- TODO Not sure if this method actually works as intende with b42, but for our use case it's fine...
---@param toRelocateOrCreate string ---@param toRelocateOrCreate string
---@param locationElement string ---@param locationElement string
---@param afterBoolean boolean ---@param afterBoolean boolean
@@ -19,7 +22,15 @@ function BodyLocationsAPI.MoveOrCreateBeforeOrAfter(toRelocateOrCreate, location
if itemToMoveTo ~= nil then if itemToMoveTo ~= nil then
-- Check type of arg 1 == string - if not, error out. -- Check type of arg 1 == string - if not, error out.
if type(toRelocateOrCreate) ~= "string" then error("Argument 1 is not of type string. Please re-check!", 2) end if type(toRelocateOrCreate) ~= "string" then error("Argument 1 is not of type string. Please re-check!", 2) end
local curItem = group:getOrCreateLocation(toRelocateOrCreate) -- get current item - or create
local curItem
if StaticData.COMPAT_42 then
curItem = BodyLocation.new(group, toRelocateOrCreate) -- create new item
group:getAllLocations():add(curItem) -- add to the list
else
curItem = group:getOrCreateLocation(toRelocateOrCreate) -- get current item - or create
end
list:remove(curItem) -- remove from the list list:remove(curItem) -- remove from the list
local index = group:indexOf(locationElement) -- get current index after removal of the location to move to local index = group:indexOf(locationElement) -- get current index after removal of the location to move to
if afterBoolean then index = index + 1 end -- if we want it after it, we increase the index to move to by one if afterBoolean then index = index + 1 end -- if we want it after it, we increase the index to move to by one
@@ -43,13 +54,15 @@ function TestBodyLocations()
print(bl:getId()) print(bl:getId())
end end
end end
-- MultiItem causes a ton of issues... fucking hell -- MultiItem causes a ton of issues... fucking hell
BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_Arm", "FullTop", true) -- BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_Arm", "Shirt", true)
group:setMultiItem("TOC_Arm", true) -- group:setMultiItem("TOC_Arm", true)
local curItem = BodyLocation.new(group, "TOC_Arm") -- create new item
group:getAllLocations():add(curItem) -- add to the list
BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_ArmProst", "TOC_Arm", true) BodyLocationsAPI.MoveOrCreateBeforeOrAfter("TOC_ArmProst", "TOC_Arm", true)
group:setMultiItem("TOC_ArmProst", true) group:setMultiItem("TOC_ArmProst", true)

View File

@@ -2,7 +2,7 @@
---@alias limbsTable {Hand_L : partDataType, ForeArm_L : partDataType, UpperArm_L : partDataType, Hand_R : partDataType, ForeArm_R : partDataType, UpperArm_R : partDataType } ---@alias limbsTable {Hand_L : partDataType, ForeArm_L : partDataType, UpperArm_L : partDataType, Hand_R : partDataType, ForeArm_R : partDataType, UpperArm_R : partDataType }
---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number } ---@alias prosthesisData {isProstEquipped : boolean, prostFactor : number }
---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R ---@alias prosthesesTable {Top_L : prosthesisData, Top_R : prosthesisData } -- TODO add Bottom_L and Bottom_R
---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean, isInitializing : boolean} ---@alias tocModDataType { limbs : limbsTable, prostheses : prosthesesTable, isIgnoredPartInfected : boolean, isAnyLimbCut : boolean}
--------------------------- ---------------------------

Binary file not shown.

View File

@@ -109,4 +109,24 @@ module TOC
CanHaveHoles = false, CanHaveHoles = false,
} }
item Amputation_FA_LR
{
Type = Clothing,
DisplayCategory = Amputation,
ClothingItem = Amputation_ForeArm_LR,
BodyLocation = TOC_Arm,
Weight = 0,
CombatSpeedModifier = 0.7,
BloodLocation = UpperArms;UpperBody,
Insulation = 1.0,
WindResistance = 1.0,
WaterResistance = 1.0,
CanHaveHoles = false,
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,46 @@
from pathlib import Path
from PIL import Image
input_bodies_path = Path('input/body')
input_wound_texture = Path('input/wound.png')
# 48, 33 TEXTURE
# 256,256
IMG_WIDTH = 256
COORDS_L = {
#"H": (0, 115),
"F": (0, 59),
"U": (0,21),
}
COORDS_R = {
#"H": (IMG_WIDTH - 50- COORDS_L['H'][0], COORDS_L['H'][1]),
"F": (IMG_WIDTH - 48 - COORDS_L['F'][0], COORDS_L['F'][1]),
"U": (IMG_WIDTH - 48 - COORDS_L['U'][0], COORDS_L['U'][1]),
}
STATES = ["BOTH"]
overlay = Image.open(input_wound_texture)
for filepath in input_bodies_path.glob('*.png'): # Only PNG files
base = Image.open(filepath)
body_name = filepath.stem
for key_L, value_L in COORDS_L.items():
for key_R, value_R in COORDS_R.items():
for state in STATES:
result = base.copy()
if state == "BOTH" or state == "ONLY_LEFT":
result.paste(overlay, value_L, mask=overlay)
if state == "BOTH" or state == "ONLY_RIGHT":
result.paste(overlay, value_R, mask=overlay)
result.save(f'output/{body_name}_{key_L}_{key_R}_{state}.png')