Merge pull request #14 from ZioPao/modular_prosthetics

Modular prosthetics
This commit is contained in:
Alessandro
2023-02-11 22:01:42 +01:00
committed by GitHub
55 changed files with 1208 additions and 276 deletions
+2 -1
View File
@@ -53,6 +53,7 @@
"FHSwapHandsAction", "FHSwapHandsAction",
"getClassFieldVal", "getClassFieldVal",
"SandboxVars", "SandboxVars",
"getClassField" "getClassField",
"ISWearClothing"
] ]
} }
+3
View File
@@ -1,3 +1,6 @@
0.9.15
- Hotfix to sound not stopping when performing an amputation on another player
0.9.14 0.9.14
- Optimizations - Optimizations
- New icon for the mod - New icon for the mod
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode>
<m_Name>aim_default</m_Name>
<m_AnimName>Bob_Sit_FishingIdle</m_AnimName>
<m_Priority>4</m_Priority>
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
<m_SyncTrackingEnabled>false</m_SyncTrackingEnabled>
<m_SpeedScale>IdleSpeed</m_SpeedScale>
<m_BlendTime>0.30</m_BlendTime>
<m_maxTorsoTwist>70.0</m_maxTorsoTwist>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Transitions>
<m_Target>Idle</m_Target>
<m_AnimName>Bob_Sit_FishingIdle</m_AnimName>
<m_blendInTime>0.3</m_blendInTime>
<m_blendOutTime>0.3</m_blendOutTime>
<m_speedScale>1.2</m_speedScale>
</m_Transitions>
<m_Transitions>
<m_Target>sneakIdle</m_Target>
<m_AnimName>Bob_Sit_FishingIdle</m_AnimName>
<m_blendInTime>0.3</m_blendInTime>
<m_blendOutTime>0.3</m_blendOutTime>
<m_speedScale>1.2</m_speedScale>
</m_Transitions>
<m_Transitions>
<m_Target>sneakIdleLow</m_Target>
<m_AnimName>Bob_Sit_FishingIdle</m_AnimName>
<m_blendInTime>0.3</m_blendInTime>
<m_blendOutTime>0.3</m_blendOutTime>
<m_speedScale>1.2</m_speedScale>
</m_Transitions>
</animNode>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode>
<m_Name>NoLegs_Idle</m_Name>
<m_AnimName>Bob_Sit_FishingIdle</m_AnimName>
<m_DeferredBoneName>Translation_Data</m_DeferredBoneName>
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
<m_Looped>true</m_Looped>
<m_SpeedScale>0.8</m_SpeedScale>
<m_BlendTime>0.20</m_BlendTime>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Transitions>
<m_Target>NoLegs_IdleSneak</m_Target>
<m_blendInTime>0.1</m_blendInTime>
</m_Transitions>
<m_Transitions>
<m_Target>NoLegs_Idle</m_Target>
<m_blendInTime>0.35</m_blendInTime>
<m_blendOutTime>0.35</m_blendOutTime>
</m_Transitions>
</animNode>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode>
<m_Name>NoLegs_IdleSneak</m_Name>
<m_AnimName>Bob_ScrambleFloorIdle</m_AnimName>
<m_Looped>true</m_Looped>
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
<m_SyncTrackingEnabled>false</m_SyncTrackingEnabled>
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
<m_SpeedScale>0.8</m_SpeedScale>
<m_BlendTime>0.20</m_BlendTime>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>sneaking</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
</animNode>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode>
<m_Name>NoLegs_Walk</m_Name>
<m_AnimName>Bob_Crawl</m_AnimName>
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
<m_Looped>true</m_Looped>
<m_SpeedScale>1.5</m_SpeedScale>
<m_BlendTime>0.20</m_BlendTime>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Events>
<m_EventName>Footstep</m_EventName>
<m_TimePc>0.15</m_TimePc>
<m_ParameterValue>walk</m_ParameterValue>
</m_Events>
<m_Events>
<m_EventName>Footstep</m_EventName>
<m_TimePc>0.6</m_TimePc>
<m_ParameterValue>walk</m_ParameterValue>
</m_Events>
</animNode>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode>
<m_Name>NoLegs_WalkSneak</m_Name>
<m_AnimName>Zombie_CrawlUnder</m_AnimName>
<m_DeferredBoneName>Translation_Data</m_DeferredBoneName>
<m_Looped>true</m_Looped>
<m_SpeedScale>1.5</m_SpeedScale>
<m_BlendTime>0.20</m_BlendTime>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>sneaking</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>inTrees</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>false</m_BoolValue>
</m_Conditions>
<m_Events>
<m_EventName>Footstep</m_EventName>
<m_TimePc>0.15</m_TimePc>
<m_ParameterValue>sneak_walk</m_ParameterValue>
</m_Events>
<m_Events>
<m_EventName>Footstep</m_EventName>
<m_TimePc>0.6</m_TimePc>
<m_ParameterValue>sneak_walk</m_ParameterValue>
</m_Events>
</animNode>
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode>
<m_Name>NoLegs_Turn</m_Name>
<m_DeferredBoneName>Bip01</m_DeferredBoneName>
<m_deferredBoneAxis>Y</m_deferredBoneAxis>
<m_useDeferedRotation>true</m_useDeferedRotation>
<m_SpeedScale>0.80</m_SpeedScale>
<m_BlendTime>0.10</m_BlendTime>
<m_BlendOutTime>0.20</m_BlendOutTime>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>isTurning</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_SubStateBoneWeights>
<boneName>Bip01_Pelvis</boneName>
<includeDescendants>false</includeDescendants>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_Spine</boneName>
<includeDescendants>false</includeDescendants>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_BackPack</boneName>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_DressFront</boneName>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_DressBack</boneName>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_L_Thigh</boneName>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_R_Thigh</boneName>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01</boneName>
<includeDescendants>false</includeDescendants>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Translation_Data</boneName>
<includeDescendants>false</includeDescendants>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_Prop1</boneName>
<weight>0.00</weight>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<boneName>Bip01_Prop2</boneName>
<weight>0.00</weight>
</m_SubStateBoneWeights>
</animNode>
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode x_extends="NoLegs_Turn.xml">
<m_Name>NoLegs_TurnIdle</m_Name>
<m_Looped>false</m_Looped>
<m_EarlyTransitionOut>true</m_EarlyTransitionOut>
<m_BlendOutTime>0.10</m_BlendOutTime>
<m_Conditions />
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>isMoving</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>false</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>Aim</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>false</m_BoolValue>
</m_Conditions>
<m_Transitions>
<m_Target>Idle</m_Target>
<m_blendInTime>0.1</m_blendInTime>
</m_Transitions>
<m_SubStateBoneWeights />
<m_SubStateBoneWeights>
<weight>0.25</weight>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights>
<weight>0.20</weight>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
</animNode>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode x_extends="NoLegs_TurnIdle.xml">
<m_Name>NoLegs_TurnIdle180</m_Name>
<m_Conditions />
<m_Conditions />
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>isTurningAround</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_SubStateBoneWeights />
<m_SubStateBoneWeights>
<weight>0.00</weight>
</m_SubStateBoneWeights>
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
<m_SubStateBoneWeights />
</animNode>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode x_extends="NoLegs_TurnIdle180.xml">
<m_Name>NoLegs_turnIdle180L</m_Name>
<m_AnimName>Bob_Crawl</m_AnimName>
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>twist</m_Name>
<m_Type>LESS</m_Type>
<m_FloatValue>0</m_FloatValue>
</m_Conditions>
</animNode>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<animNode x_extends="NoLegs_TurnIdle180.xml">
<m_Name>NoLegs_TurnIdle180R</m_Name>
<m_AnimName>Bob_EmoteWaveBye</m_AnimName>
<m_Conditions />
<m_Conditions />
<m_Conditions />
<m_Conditions>
<m_Name>IsCrawling</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
<m_Conditions>
<m_Name>twist</m_Name>
<m_Type>GTR</m_Type>
<m_FloatValue>0</m_FloatValue>
</m_Conditions>
</animNode>
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<clothingItem>
<m_MaleModel>Amputation\Amputation_GenericModel</m_MaleModel>
<m_FemaleModel>Amputation\Amputation_GenericModel</m_FemaleModel>
<m_GUID>506c0fc0-b50c-4667-bafa-ae22e3c2c0dc</m_GUID>
<m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint>
<m_Masks>8</m_Masks>
<m_MasksFolder>none</m_MasksFolder>
<textureChoices>Amputations\Forearm\skin01_b</textureChoices>
<textureChoices>Amputations\Forearm\skin02_b</textureChoices>
<textureChoices>Amputations\Forearm\skin03_b</textureChoices>
<textureChoices>Amputations\Forearm\skin04_b</textureChoices>
<textureChoices>Amputations\Forearm\skin05_b</textureChoices>
<textureChoices>Amputations\Forearm\skin01_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin02_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin03_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin04_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin05_hairy_b</textureChoices>
<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>
</clothingItem>
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<clothingItem>
<m_MaleModel>Amputation\Amputation_GenericModel</m_MaleModel>
<m_FemaleModel>Amputation\Amputation_GenericModel</m_FemaleModel>
<m_GUID>2600c2ab-bfeb-49c3-b0b5-e21c6d83d5c2</m_GUID>
<m_Static>false</m_Static>
<m_AllowRandomHue>false</m_AllowRandomHue>
<m_AllowRandomTint>false</m_AllowRandomTint>
<m_Masks>10</m_Masks>
<m_MasksFolder>none</m_MasksFolder>
<textureChoices>Amputations\Forearm\skin01_b</textureChoices>
<textureChoices>Amputations\Forearm\skin02_b</textureChoices>
<textureChoices>Amputations\Forearm\skin03_b</textureChoices>
<textureChoices>Amputations\Forearm\skin04_b</textureChoices>
<textureChoices>Amputations\Forearm\skin05_b</textureChoices>
<textureChoices>Amputations\Forearm\skin01_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin02_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin03_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin04_hairy_b</textureChoices>
<textureChoices>Amputations\Forearm\skin05_hairy_b</textureChoices>
<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>
</clothingItem>
+11
View File
@@ -85,4 +85,15 @@
<path>media/clothing/clothingItems/Surgery_Right_Tourniquet.xml</path> <path>media/clothing/clothingItems/Surgery_Right_Tourniquet.xml</path>
<guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid> <guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid>
</files> </files>
<files>
<path>media/clothing/clothingItems/Amputation_Left_Foot.xml</path>
<guid>506c0fc0-b50c-4667-bafa-ae22e3c2c0dc</guid>
</files>
<files>
<path>media/clothing/clothingItems/Amputation_Right_Foot.xml</path>
<guid>2600c2ab-bfeb-49c3-b0b5-e21c6d83d5c2</guid>
</files>
</fileGuidTable> </fileGuidTable>
@@ -11,7 +11,7 @@ local function TocCheckIfStillInfected(limbs_data)
local check = false local check = false
for _, v in ipairs(GetBodyParts()) do for _, v in pairs(GetBodyParts()) do
if limbs_data[v].is_infected then if limbs_data[v].is_infected then
check = true check = true
end end
@@ -37,8 +37,8 @@ local function TocCureInfection(body_damage, part_name)
-- TODO I think this is enough... we should just cycle if with everything instead of that crap up there -- TODO I think this is enough... we should just cycle if with everything instead of that crap up there
for i = body_part_types:size() - 1, 0, -1 do for i = body_part_types:size() - 1, 0, -1 do
local bodyPart = body_part_types:get(i); local bodyPart = body_part_types:get(i)
bodyPart:SetInfected(false); bodyPart:SetInfected(false)
end end
if body_part_type:scratched() then body_part_type:setScratched(false, false) end if body_part_type:scratched() then body_part_type:setScratched(false, false) end
@@ -104,7 +104,7 @@ local function FindTourniquetInWornItems(patient, side)
for i = 1, worn_items:size() - 1 do -- Maybe wornItems:size()-1 for i = 1, worn_items:size() - 1 do -- Maybe wornItems:size()-1
local item = worn_items:get(i):getItem() local item = worn_items:get(i):getItem()
local item_full_type = item:getFullType() local item_full_type = item:getFullType()
if string.find(item_full_type, "Test_Tourniquet_" .. side) then if string.find(item_full_type, "Surgery_" .. side .. "_Tourniquet") then
return item return item
end end
end end
@@ -151,7 +151,7 @@ function TocCutLimb(part_name, surgeon_factor, bandage_table, painkiller_table)
local base_damage_value = 100 local base_damage_value = 100
if tourniquet_item ~= nil then if tourniquet_item ~= nil then
base_damage_value = 50 base_damage_value = 50 -- TODO Decrease mostly blood and damage, add pain, not everything else
if part_name == "Left_UpperArm" or part_name == "Right_UpperArm" then if part_name == "Left_UpperArm" or part_name == "Right_UpperArm" then
player:removeWornItem(tourniquet_item) player:removeWornItem(tourniquet_item)
@@ -240,13 +240,20 @@ function TocCutLimb(part_name, surgeon_factor, bandage_table, painkiller_table)
TocDeleteOtherAmputatedLimbs(side) TocDeleteOtherAmputatedLimbs(side)
--Equip new model for amputation --Equip new model for amputation
local amputation_clothing_item = player:getInventory():AddItem(TocFindAmputatedClothingFromPartName(part_name)) local amputation_clothing_item_name = TocFindAmputatedClothingFromPartName(part_name)
print(amputation_clothing_item_name)
local amputation_clothing_item = player:getInventory():AddItem(amputation_clothing_item_name)
TocSetCorrectTextureForAmputation(amputation_clothing_item, player, false) TocSetCorrectTextureForAmputation(amputation_clothing_item, player, false)
player:setWornItem(amputation_clothing_item:getBodyLocation(), amputation_clothing_item) player:setWornItem(amputation_clothing_item:getBodyLocation(), amputation_clothing_item)
-- Set blood on the amputated limb -- Set blood on the amputated limb
TocSetBloodOnAmputation(getPlayer(), adiacent_body_part) TocSetBloodOnAmputation(getPlayer(), adiacent_body_part)
if part_name == "Left_Foot" or part_name == "Right_Foot" then
SetMissingFootAnimation(true)
end
end end
end end
@@ -20,13 +20,10 @@ local function FixSingleBodyPartType(body_part_type, use_oven)
end end
local function SetBodyPartsStatusAfterOperation(player, limbs_data, part_name, use_oven) local function SetBodyPartsStatusAfterOperation(player, limbs_data, part_name, use_oven)
--for _, v in ipairs(GetBodyParts()) do
local body_part_type = player:getBodyDamage():getBodyPart(TocGetAdiacentBodyPartFromPartName(part_name)) local body_part_type = player:getBodyDamage():getBodyPart(TocGetAdiacentBodyPartFromPartName(part_name))
FixSingleBodyPartType(body_part_type, use_oven) FixSingleBodyPartType(body_part_type, use_oven)
for _, v in ipairs(limbs_data[part_name].depends_on) do for _, v in pairs(limbs_data[part_name].depends_on) do
local depended_body_part_type = player:getBodyDamage():getBodyPart(TocGetAdiacentBodyPartFromPartName(v)) local depended_body_part_type = player:getBodyDamage():getBodyPart(TocGetAdiacentBodyPartFromPartName(v))
FixSingleBodyPartType(depended_body_part_type, use_oven) FixSingleBodyPartType(depended_body_part_type, use_oven)
@@ -6,15 +6,47 @@
---Equip a prosthesis transforming a normal item into a clothing item ---Equip a prosthesis transforming a normal item into a clothing item
---@param part_name string ---@param part_name string
---@param prosthesis_item any the prosthesis item
---@param prosthesis_base_name string ---@param prosthesis_base_name string
function TocEquipProsthesis(part_name, prosthesis_base_name) function TocEquipProsthesis(part_name, prosthesis_item, prosthesis_base_name)
-- TODO probably will have to move this from the TOC menu to classic equip to have dynamic durability
-- TODO We need to pass the original item so we can get its data!
local player = getPlayer() local player = getPlayer()
local toc_data = player:getModData().TOC local toc_data = player:getModData().TOC
local item_mod_data = prosthesis_item:getModData()
if item_mod_data.TOC == nil then
GenerateEquippedProsthesis(prosthesis_item, "Test") -- TODO Change it with the limb
item_mod_data = prosthesis_item:getModData() -- Updates it
end
--print("TOC: Test durability normal item " .. item_mod_data.TOC.durability)
local prosthesis_name = TocFindCorrectClothingProsthesis(prosthesis_base_name, part_name) local prosthesis_name = TocFindCorrectClothingProsthesis(prosthesis_base_name, part_name)
local added_prosthesis = player:getInventory():AddItem(prosthesis_name) local added_prosthesis = player:getInventory():AddItem(prosthesis_name)
-- Add parameters to added_prosthesis
local added_prosthesis_mod_data = added_prosthesis:getModData()
added_prosthesis_mod_data.TOC = {
durability = item_mod_data.TOC.durability,
speed = item_mod_data.TOC.speed,
}
--print("TOC: Test durability new item " .. added_prosthesis_mod_data.TOC.durability)
if part_name ~= nil then if part_name ~= nil then
if added_prosthesis ~= nil then if added_prosthesis ~= nil then
@@ -40,6 +72,8 @@ end
function TocUnequipProsthesis(patient, part_name, equipped_prosthesis) function TocUnequipProsthesis(patient, part_name, equipped_prosthesis)
-- TODO Pass the parameters generated from EquipProsthesis to the re-generated normal item
local toc_data = patient:getModData().TOC local toc_data = patient:getModData().TOC
toc_data.Limbs[part_name].is_prosthesis_equipped = false toc_data.Limbs[part_name].is_prosthesis_equipped = false
@@ -50,14 +84,21 @@ function TocUnequipProsthesis(patient, part_name, equipped_prosthesis)
for _, prost_v in ipairs(GetProsthesisList()) do for _, prost_v in ipairs(GetProsthesisList()) do
local prosthesis_name = string.match(equipped_prosthesis_full_type, prost_v) local prosthesis_name = string.match(equipped_prosthesis_full_type, prost_v)
if prosthesis_name then if prosthesis_name then
patient:getInventory():AddItem("TOC." .. prosthesis_name)
-- Get mod data from equipped prosthesis so we can get its parameters
local equipped_prosthesis_mod_data = equipped_prosthesis:getModData()
local base_prosthesis_item = patient:getInventory():AddItem("TOC." .. prosthesis_name)
local base_prosthesis_item_mod_data = base_prosthesis_item.getModData()
base_prosthesis_item_mod_data.TOC = {
durability = equipped_prosthesis_mod_data.TOC.durability,
speed = equipped_prosthesis_mod_data.TOC.speed
}
patient:setWornItem(equipped_prosthesis:getBodyLocation(), nil) patient:setWornItem(equipped_prosthesis:getBodyLocation(), nil)
patient:getInventory():Remove(equipped_prosthesis) patient:getInventory():Remove(equipped_prosthesis)
toc_data.Limbs[part_name].equipped_prosthesis = nil toc_data.Limbs[part_name].equipped_prosthesis = nil
end end
end end
end end
@@ -16,7 +16,7 @@ TocContextMenus.CreateMenus = function(player, context, worldObjects, test)
local local_player = getSpecificPlayer(player) local local_player = getSpecificPlayer(player)
--local players = getOnlinePlayers() --local players = getOnlinePlayers()
for k, v in ipairs(worldObjects) do for k, v in pairs(worldObjects) do
-- help detecting a player by checking nearby squares -- help detecting a player by checking nearby squares
for x = v:getSquare():getX() - 1, v:getSquare():getX() + 1 do for x = v:getSquare():getX() - 1, v:getSquare():getX() + 1 do
for y = v:getSquare():getY() - 1, v:getSquare():getY() + 1 do for y = v:getSquare():getY() - 1, v:getSquare():getY() + 1 do
@@ -79,6 +79,7 @@ TocContextMenus.CreateOperateWithOvenMenu = function(player, context, worldObjec
-- Check temperature -- Check temperature
if v_stove:getCurrentTemperature() > 250 then if v_stove:getCurrentTemperature() > 250 then
-- ipairs here to keep the order
for _, v_bodypart in ipairs(GetBodyParts()) do for _, v_bodypart in ipairs(GetBodyParts()) do
if part_data[v_bodypart].is_cut and part_data[v_bodypart].is_amputation_shown and if part_data[v_bodypart].is_cut and part_data[v_bodypart].is_amputation_shown and
not part_data[v_bodypart].is_operated then not part_data[v_bodypart].is_operated then
+12
View File
@@ -154,6 +154,9 @@ local function SetupTocMainUI(surgeon, patient, limbs_data)
main_ui["b31"]:setPath(GetImageName("Right_Hand", limbs_data)) main_ui["b31"]:setPath(GetImageName("Right_Hand", limbs_data))
main_ui["b32"]:setPath(GetImageName("Left_Hand", limbs_data)) main_ui["b32"]:setPath(GetImageName("Left_Hand", limbs_data))
main_ui["b41"]:setPath(GetImageName("Right_Foot", limbs_data))
main_ui["b42"]:setPath(GetImageName("Left_Foot", limbs_data))
end end
@@ -435,6 +438,15 @@ local function CreateTocMainUI()
main_ui:addImageButton("b32", "", OnClickTocMainUI) main_ui:addImageButton("b32", "", OnClickTocMainUI)
main_ui["b32"]:addArg("part_name", "Left_Hand") main_ui["b32"]:addArg("part_name", "Left_Hand")
main_ui:nextLine()
main_ui:addImageButton("b41", "", OnClickTocMainUI)
main_ui["b41"]:addArg("part_name", "Right_Foot")
main_ui:addImageButton("b42", "", OnClickTocMainUI)
main_ui["b42"]:addArg("part_name", "Left_Foot")
main_ui:saveLayout() main_ui:saveLayout()
+18
View File
@@ -0,0 +1,18 @@
-- Thanks to Glytcher and Matías N. Salas for helping out with this
function SetMissingFootAnimation(check)
local player = getPlayer()
player:setVariable("IsCrawling", tostring(check))
if not isServer() and not isClient() then
print("SP, so it's fine")
else
sendClientCommand(player, "TOC", "NotifyNewCrawlAnimation", {id = player:getOnlineID(), check = check})
end
end
+6 -3
View File
@@ -4,6 +4,10 @@ if TheOnlyCure == nil then
TheOnlyCure = {} TheOnlyCure = {}
end end
local pairs = pairs
----------------------------------------- -----------------------------------------
-- MP HANDLING CHECKS -- MP HANDLING CHECKS
function CheckIfCanBeCut(part_name, limbs_data) function CheckIfCanBeCut(part_name, limbs_data)
@@ -60,9 +64,8 @@ end
function CheckIfItemIsProsthesis(item) function CheckIfItemIsProsthesis(item)
-- TODO find a cleaner way
local item_full_type = item:getFullType() local item_full_type = item:getFullType()
local prosthesis_list = GetProsthesisList() local prosthesis_list = GetProsthesisList() -- TODO this isn't gonna work after the modular prost rewrite
for _, v in pairs(prosthesis_list) do for _, v in pairs(prosthesis_list) do
if v == item_full_type then if v == item_full_type then
@@ -88,7 +91,7 @@ end
function CheckIfProsthesisAlreadyInstalled(limbs_data, part_name) function CheckIfProsthesisAlreadyInstalled(limbs_data, part_name)
for _, side in ipairs(TOC_sides) do for _, side in pairs(TOC_sides) do
if string.find(part_name, side) then if string.find(part_name, side) then
return (limbs_data[side .. "_Hand"].is_prosthesis_equipped or limbs_data[side .. "_LowerArm"].is_prosthesis_equipped) return (limbs_data[side .. "_Hand"].is_prosthesis_equipped or limbs_data[side .. "_LowerArm"].is_prosthesis_equipped)
end end
+165 -169
View File
@@ -1,8 +1,11 @@
-- Synchronization and MP related stuff ------------------------------------------
-------- THE ONLY CURE BUT BETTER --------
------------------------------------------
------------ CLIENT COMMANDS -------------
local Commands = {} local ServerCommands = {}
Commands["ResponseCanAct"] = function(arg) ServerCommands.ResponseCanAct = function(arg)
print("TOC: ResponseCanAct") print("TOC: ResponseCanAct")
@@ -17,6 +20,162 @@ Commands["ResponseCanAct"] = function(arg)
end end
ServerCommands.CanCutLimb = function(arg)
local part_name = arg["toSend"]
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Cut", CheckIfCanBeCut(part_name) }
sendClientCommand("TOC", "SendServer", arg)
end
ServerCommands.CutLimb = function(arg)
local data = arg["toSend"]
TocCutLimb(data[1], data[2], data[3], data[4])
end
ServerCommands.CanOperateLimb = function(arg)
local part_name = arg["toSend"]
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Operate", CheckIfCanBeOperated(part_name) }
sendClientCommand("TOC", "SendServer", arg)
end
ServerCommands.OperateLimb = function(arg)
local data = arg["toSend"]
TocOperateLimb(data[1], data[2], data[3])
end
ServerCommands.CanEquipProsthesis = function(arg)
local part_name = arg["toSend"]
--local item = arg["toSend"][2] -- TODO Add item prosth here
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = {part_name, "Equip", CheckIfProsthesisCanBeEquipped(part_name) }
sendClientCommand("TOC", "SendServer", arg)
end
ServerCommands.EquipProsthesis = function(arg)
-- part_name = arg[1]
-- prosthesis_item = arg[2]
-- prosthesis_name = arg[3]
local data = arg["toSend"]
TocEquipProsthesis(data[1], data[2], data[3])
end
ServerCommands.CanUnequipProsthesis = function(arg)
local part_name = arg["toSend"]
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Unequip", CheckIfProsthesisCanBeUnequipped(part_name)}
sendClientCommand("TOC", "SendServer", arg)
end
ServerCommands.UnequipProsthesis = function(arg)
-- part_name = arg[1]
local data = arg["toSend"]
TheOnlyCure.TocUnequipProsthesis(data[1], data[2])
end
ServerCommands.CanResetEverything = function(arg)
local part_name = "RightHand" --useless
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Cut", true }
sendClientCommand("TOC", "SendServer", arg)
end
ServerCommands.ResetEverything = function(_)
TocResetEverything()
end
-- Used when amputating the limb of another player
ServerCommands.AcceptDamageOtherPlayer = function(arg)
local patient = getPlayerByOnlineID(arg[1])
local part_name = arg[2]
TocDamagePlayerDuringAmputation(patient, part_name)
end
-- Used to propagate animation changes after amputating a foot
ServerCommands.SetCrawlAnimation = function(args)
local player = getPlayerByOnlineID(args.id)
local check = args.check
player:setVariable('IsCrawling', tostring(check))
end
-- Used to propagate the stop of the sound of amputation
ServerCommands.StopAmputationSound = function(args)
local player = getPlayerByOnlineID(args.surgeon_id)
player:getEmitter():stopSoundByName("Amputation_Sound")
end
local function OnTocServerCommand(module, command, args)
if module == 'TOC' then
print("TOC: On Toc Server Command " .. command)
if ServerCommands[command] then
print("Found command, executing it now")
args = args or {}
ServerCommands[command](args)
end
end
end
Events.OnServerCommand.Add(OnTocServerCommand)
---------------------------------- Global Mod Data -----------------------------
function TOC_OnReceiveGlobalModData(key, modData)
if modData then
ModData.remove(key)
ModData.add(key, modData)
end
end
Events.OnReceiveGlobalModData.Add(TOC_OnReceiveGlobalModData)
function TOC_OnConnected()
ModData.request("TOC_PLAYER_DATA")
end
Events.OnConnected.Add(TOC_OnConnected)
--------------------------------------------------------
function SendCutLimb(player, part_name, surgeon_factor, bandage_table, painkiller_table) function SendCutLimb(player, part_name, surgeon_factor, bandage_table, painkiller_table)
local arg = {} local arg = {}
arg["From"] = getPlayer():getOnlineID() arg["From"] = getPlayer():getOnlineID()
@@ -25,7 +184,7 @@ function SendCutLimb(player, part_name, surgeon_factor, bandage_table, painkille
-- TODO Hotfix for sound, fix this later -- TODO Hotfix for sound, fix this later
arg["toSend"] = {part_name, surgeon_factor, bandage_table, painkiller_table, getPlayer():getOnlineID()} arg["toSend"] = {part_name, surgeon_factor, bandage_table, painkiller_table}
@@ -41,12 +200,12 @@ function SendOperateLimb(player, part_name, surgeon_factor, use_oven)
sendClientCommand("TOC", "SendServer", arg) sendClientCommand("TOC", "SendServer", arg)
end end
function SendEquipProsthesis(player, part_name, prosthesis_base_name) function SendEquipProsthesis(player, part_name, item, prosthesis_base_name)
local arg = {} local arg = {}
arg["From"] = getPlayer():getOnlineID() arg["From"] = getPlayer():getOnlineID()
arg["To"] = player:getOnlineID() arg["To"] = player:getOnlineID()
arg["command"] = "EquipProsthesis" arg["command"] = "EquipProsthesis"
arg["toSend"] = { part_name, prosthesis_base_name} arg["toSend"] = { part_name, item, prosthesis_base_name}
sendClientCommand("TOC", "SendServer", arg) sendClientCommand("TOC", "SendServer", arg)
end end
@@ -90,7 +249,6 @@ function AskCanEquipProsthesis(player, part_name)
sendClientCommand("TOC", "SendServer", arg) sendClientCommand("TOC", "SendServer", arg)
end end
function AskCanUnequipProsthesis(player, part_name) function AskCanUnequipProsthesis(player, part_name)
GetConfirmUIMP().responseReceive = false GetConfirmUIMP().responseReceive = false
local arg = {} local arg = {}
@@ -101,165 +259,3 @@ function AskCanUnequipProsthesis(player, part_name)
sendClientCommand("TOC", "SendServer", arg) sendClientCommand("TOC", "SendServer", arg)
end end
-- Patient (receive)
Commands["CutLimb"] = function(arg)
local arg = arg["toSend"]
local surgeon_id = arg[5]
-- Disable the sound coming from the surgeon
getPlayerByOnlineID(surgeon_id):getEmitter():stopSoundByName("Amputation_Sound")
TocCutLimb(arg[1], arg[2], arg[3], arg[4])
end
Commands["OperateLimb"] = function(arg)
local arg = arg["toSend"]
TocOperateLimb(arg[1], arg[2], arg[3])
end
Commands["EquipProsthesis"] = function(arg)
-- part_name = arg[1]
-- prosthesis = arg[2]
local arg = arg["toSend"]
TocEquipProsthesis(arg[1], arg[2])
end
Commands["UnequipProsthesis"] = function(arg)
-- part_name = arg[1]
local arg = arg["toSend"]
TheOnlyCure.TocUnequipProsthesis(arg[1], arg[2])
end
Commands["CanCutLimb"] = function(arg)
local part_name = arg["toSend"]
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Cut", CheckIfCanBeCut(part_name) }
sendClientCommand("TOC", "SendServer", arg)
end
Commands["CanOperateLimb"] = function(arg)
local part_name = arg["toSend"]
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Operate", CheckIfCanBeOperated(part_name) }
sendClientCommand("TOC", "SendServer", arg)
end
Commands["CanEquipProsthesis"] = function(arg)
local part_name = arg["toSend"]
--local item = arg["toSend"][2] -- TODO Add item prosth here
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = {part_name, "Equip", CheckIfProsthesisCanBeEquipped(part_name) }
sendClientCommand("TOC", "SendServer", arg)
end
Commands["CanUnequipProsthesis"] = function(arg)
local part_name = arg["toSend"]
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Unequip", CheckIfProsthesisCanBeUnequipped(part_name)}
sendClientCommand("TOC", "SendServer", arg)
end
Commands["CanResetEverything"] = function(arg)
local part_name = "RightHand" --useless
arg["To"] = arg["From"]
arg["From"] = getPlayer():getOnlineID()
arg["command"] = "ResponseCanAct"
arg["toSend"] = { part_name, "Cut", true }
sendClientCommand("TOC", "SendServer", arg)
end
Commands["ResetEverything"] = function(arg)
local arg = arg["toSend"]
TocResetEverything()
end
-- Cheating stuff
Commands["AcceptResetEverything"] = function(arg)
local clicked_player = getPlayerByOnlineID(arg[1]) -- TODO delete this
TocResetEverything()
end
-- Cut Limb stuff
Commands["AcceptDamageOtherPlayer"] = function(arg)
local patient_id = arg[1]
local patient = getPlayerByOnlineID(arg[1])
local part_name = arg[2]
TocDamagePlayerDuringAmputation(patient, part_name)
end
-- Base stuff
local function OnTocServerCommand(module, command, args)
if module == 'TOC' then
print("TOC: On Toc Server Command " .. command)
if Commands[command] then
print("Found command, executing it now")
args = args or {}
Commands[command](args)
end
end
end
Events.OnServerCommand.Add(OnTocServerCommand)
---------------------------------- TEST -----------------------------
function TOC_OnReceiveGlobalModData(key, modData)
if modData then
ModData.remove(key)
ModData.add(key, modData)
end
end
Events.OnReceiveGlobalModData.Add(TOC_OnReceiveGlobalModData)
function TOC_OnConnected()
ModData.request("TOC_PLAYER_DATA")
end
Events.OnConnected.Add(TOC_OnConnected)
+10
View File
@@ -74,6 +74,11 @@ function TocGetBodyPartFromPartName(part_name)
if part_name == "Left_Hand" then return BodyPartType.Hand_L end if part_name == "Left_Hand" then return BodyPartType.Hand_L end
if part_name == "Left_LowerArm" then return BodyPartType.ForeArm_L end if part_name == "Left_LowerArm" then return BodyPartType.ForeArm_L end
if part_name == "Left_UpperArm" then return BodyPartType.UpperArm_L end if part_name == "Left_UpperArm" then return BodyPartType.UpperArm_L end
-- New Legs stuff
if part_name == "Right_Foot" then return BodyPartType.Foot_R end
if part_name == "Left_Foot" then return BodyPartType.Foot_L end
end end
-- Custom mapping to make more sense when cutting a limb -- Custom mapping to make more sense when cutting a limb
@@ -85,6 +90,11 @@ function TocGetAdiacentBodyPartFromPartName(part_name)
if part_name == "Left_Hand" then return BodyPartType.ForeArm_L end if part_name == "Left_Hand" then return BodyPartType.ForeArm_L end
if part_name == "Left_LowerArm" then return BodyPartType.UpperArm_L end if part_name == "Left_LowerArm" then return BodyPartType.UpperArm_L end
if part_name == "Left_UpperArm" then return BodyPartType.Torso_Upper end if part_name == "Left_UpperArm" then return BodyPartType.Torso_Upper end
if part_name == "Right_Foot" then return BodyPartType.LowerLeg_R end
if part_name == "Left_Foot" then return BodyPartType.LowerLeg_L end
end end
function TocFindCorrectClothingProsthesis(item_name, part_name) function TocFindCorrectClothingProsthesis(item_name, part_name)
+16 -4
View File
@@ -1,3 +1,8 @@
local function TocReapplyAmputationClothingItem(mod_data) local function TocReapplyAmputationClothingItem(mod_data)
local player = getPlayer() local player = getPlayer()
local player_inv = player:getInventory() local player_inv = player:getInventory()
@@ -6,15 +11,21 @@ local function TocReapplyAmputationClothingItem(mod_data)
for _, limb in ipairs(TOC_limbs) do for _, limb in ipairs(TOC_limbs) do
local part_name = side .. "_" .. limb local part_name = side .. "_" .. limb
if mod_data.TOC.Limbs[part_name].is_cut and mod_data.TOC.Limbs[part_name].is_amputation_shown then -- Check this before since we could have changed some stuff about part names before fixing them. Could break things
local part_data = mod_data.TOC.Limbs[part_name]
if part_data then
if part_data.is_cut and part_data.is_amputation_shown then
local amputated_clothing_name = "TOC.Amputation_" .. part_name local amputated_clothing_name = "TOC.Amputation_" .. part_name
if player_inv:FindAndReturn(amputated_clothing_name) == nil then if player_inv:FindAndReturn(amputated_clothing_name) == nil then
local amputation_clothing_item = player:getInventory():AddItem(TocFindAmputatedClothingFromPartName(part_name)) local amputation_clothing_item = player:getInventory():AddItem(TocFindAmputatedClothingFromPartName(part_name))
TocSetCorrectTextureForAmputation(amputation_clothing_item, player, mod_data.TOC.Limbs[part_name].is_cicatrized) TocSetCorrectTextureForAmputation(amputation_clothing_item, player, part_data.is_cicatrized)
player:setWornItem(amputation_clothing_item:getBodyLocation(), amputation_clothing_item) player:setWornItem(amputation_clothing_item:getBodyLocation(), amputation_clothing_item)
end end
end end
end
TocResetClothingItemBodyLocation(player, side, limb) TocResetClothingItemBodyLocation(player, side, limb)
end end
@@ -34,8 +45,9 @@ function TocCheckCompatibilityWithOlderVersions(mod_data)
print("TOC: Something was wrongly initiliazed before. Resetting parameters") print("TOC: Something was wrongly initiliazed before. Resetting parameters")
TocResetEverything() TocResetEverything()
else else
print("TOC: Found compatible data, correcting models in case of errors") print("TOC: Bypassing reapplying of amputations, assuming that everything is correct")
TocReapplyAmputationClothingItem(mod_data) --print("TOC: Found compatible data, correcting models in case of errors and adding limbs")
--TocReapplyAmputationClothingItem(mod_data)
end end
end end
+24 -4
View File
@@ -45,11 +45,13 @@ function TocResetEverything()
TheOnlyCure.InitTheOnlyCure(_, player) TheOnlyCure.InitTheOnlyCure(_, player)
-- Destroy the amputation or prosthesis item -- Destroy the amputation or prosthesis item
for _, v in ipairs(GetBodyParts()) do
-- TODO This is incredibly shitty, but we can't use worn items since we need to consider the case that the item wasn't applied
local amputation_item_name = TocFindAmputationOrProsthesisName(v, player, "Amputation")
local prosthesis_item_name = TocFindAmputationOrProsthesisName(v, player, "Prosthesis")
for _, side in pairs(TOC_sides) do
for _, limb in pairs(TOC_limbs) do
local part_name = side .. "_" .. limb
local amputation_item_name = TocFindAmputationOrProsthesisName(part_name, player, "Amputation")
local prosthesis_item_name = TocFindAmputationOrProsthesisName(part_name, player, "Prosthesis")
if amputation_item_name ~= nil then if amputation_item_name ~= nil then
local amputation_item = player_inventory:FindAndReturn(amputation_item_name) local amputation_item = player_inventory:FindAndReturn(amputation_item_name)
if amputation_item ~= nil then if amputation_item ~= nil then
@@ -74,6 +76,12 @@ function TocResetEverything()
end end
-- Reset special flag for legs amputations
SetMissingFootAnimation(false)
end
-- Set correct body locations for items in inventory -- Set correct body locations for items in inventory
function TocResetClothingItemBodyLocation(player, side, limb) function TocResetClothingItemBodyLocation(player, side, limb)
local player_inventory = player:getInventory() local player_inventory = player:getInventory()
@@ -130,3 +138,15 @@ function TocTestBodyLocations()
end end
end end
function TocTestItem()
local player = getPlayer()
local player_inventory = player:getInventory()
local item_name = "TOC.Amputation_" .. "Right" .. "_" .. "Hand"
local found_item = player_inventory:FindAndReturn(item_name)
print(found_item:getID())
print("_______________")
found_item:setID(12334)
print(found_item:getID())
end
+18 -1
View File
@@ -25,6 +25,9 @@ local function PartNameToBodyLocationAmputation(name)
if name == "Left_Hand" then return "TOC_ArmLeft" end if name == "Left_Hand" then return "TOC_ArmLeft" end
if name == "Left_LowerArm" then return "TOC_ArmLeft" end if name == "Left_LowerArm" then return "TOC_ArmLeft" end
if name == "Left_UpperArm" then return "TOC_ArmLeft" end if name == "Left_UpperArm" then return "TOC_ArmLeft" end
if name == "Left_Foot" then return "TOC_LegLeft" end
if name == "Right_Foot" then return "TOC_LegRight" end
end end
function TocFindItemInProstBodyLocation(part_name, patient) function TocFindItemInProstBodyLocation(part_name, patient)
@@ -71,7 +74,7 @@ end
-- Override and mod compat helper -- Override and mod compat helper
function TocPopulateCanBeHeldTable(can_be_held, limbs_data) function TocPopulateCanBeHeldTable(can_be_held, limbs_data)
for _, side in ipairs(TOC_sides) do for _, side in pairs(TOC_sides) do
can_be_held[side] = true can_be_held[side] = true
if limbs_data[side .. "_Hand"].is_cut then if limbs_data[side .. "_Hand"].is_cut then
@@ -86,3 +89,17 @@ function TocPopulateCanBeHeldTable(can_be_held, limbs_data)
end end
end end
-----------------------------------------
function TocCheckLegsAmputations(mod_data)
if mod_data.TOC.Limbs["Left_Foot"].is_cut or mod_data.TOC.Limbs["Right_Foot"].is_cut then
SetMissingFootAnimation(true)
end
end
+56 -5
View File
@@ -8,7 +8,7 @@ if not TheOnlyCure then
end end
TOC_sides = { "Left", "Right" } TOC_sides = { "Left", "Right" }
TOC_limbs = { "Hand", "LowerArm", "UpperArm" } TOC_limbs = { "Hand", "LowerArm", "UpperArm", "Foot"}
local function TocCutLimbForTrait(player, limbs_data, part_name) local function TocCutLimbForTrait(player, limbs_data, part_name)
local amputation_clothing_item = player:getInventory():AddItem("TOC.Amputation_" .. part_name) local amputation_clothing_item = player:getInventory():AddItem("TOC.Amputation_" .. part_name)
@@ -27,6 +27,33 @@ local function TocCutLimbForTrait(player, limbs_data, part_name)
limbs_data[v].is_cicatrized = true limbs_data[v].is_cicatrized = true
end end
end end
local function InitSpecificPart(mod_data, part_name)
if mod_data.TOC.Limbs[part_name] == nil then
mod_data.TOC.Limbs[part_name] = {}
end
mod_data.TOC.Limbs[part_name].is_cut = false
mod_data.TOC.Limbs[part_name].is_infected = false
mod_data.TOC.Limbs[part_name].is_operated = false
mod_data.TOC.Limbs[part_name].is_cicatrized = false
mod_data.TOC.Limbs[part_name].is_cauterized = false
mod_data.TOC.Limbs[part_name].is_amputation_shown = false
mod_data.TOC.Limbs[part_name].cicatrization_time = 0
mod_data.TOC.Limbs[part_name].is_prosthesis_equipped = false
mod_data.TOC.Limbs[part_name].equipped_prosthesis = {}
end
local function TocUpdateBaseData(mod_data) local function TocUpdateBaseData(mod_data)
-- TODO The prosthetic knife needs to be a weapon first and foremost, so other than a -- TODO The prosthetic knife needs to be a weapon first and foremost, so other than a
@@ -37,12 +64,20 @@ local function TocUpdateBaseData(mod_data)
local accepted_prosthesis_hand = { "WoodenHook", "MetalHook", "MetalHand", "ProstheticKnife" } local accepted_prosthesis_hand = { "WoodenHook", "MetalHook", "MetalHand", "ProstheticKnife" }
local accepted_prosthesis_lowerarm = { "WoodenHook", "MetalHook", "MetalHand", "ProstheticKnife" } local accepted_prosthesis_lowerarm = { "WoodenHook", "MetalHook", "MetalHand", "ProstheticKnife" }
local accepted_prosthesis_upperarm = {} -- For future stuff local accepted_prosthesis_upperarm = {} -- For future stuff
local accepted_prosthesis_foot = {}
for _, side in ipairs(TOC_sides) do for _, side in pairs(TOC_sides) do
for _, limb in ipairs(TOC_limbs) do for _, limb in pairs(TOC_limbs) do
local part_name = side .. "_" .. limb local part_name = side .. "_" .. limb
-- Check if part was initialized
if mod_data.TOC.Limbs[part_name] == nil then
InitSpecificPart(mod_data, part_name)
end
if limb == "Hand" then if limb == "Hand" then
mod_data.TOC.Limbs[part_name].cicatrization_base_time = 1700 mod_data.TOC.Limbs[part_name].cicatrization_base_time = 1700
mod_data.TOC.Limbs[part_name].depends_on = {} mod_data.TOC.Limbs[part_name].depends_on = {}
@@ -69,6 +104,11 @@ local function TocUpdateBaseData(mod_data)
mod_data.TOC.Limbs[part_name].cicatrization_base_time = 2000 mod_data.TOC.Limbs[part_name].cicatrization_base_time = 2000
mod_data.TOC.Limbs[part_name].depends_on = { side .. "_Hand", side .. "_LowerArm", } mod_data.TOC.Limbs[part_name].depends_on = { side .. "_Hand", side .. "_LowerArm", }
mod_data.TOC.Prosthesis.Accepted_Prosthesis[part_name] = accepted_prosthesis_upperarm mod_data.TOC.Prosthesis.Accepted_Prosthesis[part_name] = accepted_prosthesis_upperarm
elseif limb == "Foot" then
mod_data.TOC.Limbs[part_name].cicatrization_base_time = 1700
mod_data.TOC.Limbs[part_name].depends_on = {}
mod_data.TOC.Prosthesis.Accepted_Prosthesis[part_name] = accepted_prosthesis_foot
end end
end end
@@ -102,6 +142,10 @@ local function TocSetInitData(mod_data, player)
Left_Hand = {}, Left_Hand = {},
Left_LowerArm = {}, Left_LowerArm = {},
Left_UpperArm = {}, Left_UpperArm = {},
Left_Foot = {},
Right_Foot = {},
is_other_bodypart_infected = false is_other_bodypart_infected = false
}, },
Prosthesis = { Prosthesis = {
@@ -161,8 +205,8 @@ local function TocSetInitData(mod_data, player)
for _, side in ipairs(TOC_sides) do for _, side in pairs(TOC_sides) do
for _, limb in ipairs(TOC_limbs) do for _, limb in pairs(TOC_limbs) do
local part_name = side .. "_" .. limb local part_name = side .. "_" .. limb
@@ -208,6 +252,7 @@ function TheOnlyCure.InitTheOnlyCure(_, player)
else else
TocCheckCompatibilityWithOlderVersions(mod_data) TocCheckCompatibilityWithOlderVersions(mod_data)
TocUpdateBaseData(mod_data) -- Since it's gonna be common to update stuff TocUpdateBaseData(mod_data) -- Since it's gonna be common to update stuff
TocCheckLegsAmputations(mod_data)
end end
end end
@@ -216,14 +261,20 @@ local function TocDeclareTraits()
local amp1 = TraitFactory.addTrait("Amputee_Hand", getText("UI_trait_Amputee_Hand"), -8, local amp1 = TraitFactory.addTrait("Amputee_Hand", getText("UI_trait_Amputee_Hand"), -8,
getText("UI_trait_Amputee_Hand_desc"), false, false) getText("UI_trait_Amputee_Hand_desc"), false, false)
amp1:addXPBoost(Perks.Left_Hand, 4) amp1:addXPBoost(Perks.Left_Hand, 4)
amp1:addXPBoost(Perks.Fitness, -1)
amp1:addXPBoost(Perks.Strength, -1)
local amp2 = TraitFactory.addTrait("Amputee_LowerArm", getText("UI_trait_Amputee_LowerArm"), -10, local amp2 = TraitFactory.addTrait("Amputee_LowerArm", getText("UI_trait_Amputee_LowerArm"), -10,
getText("UI_trait_Amputee_LowerArm_desc"), false, false) getText("UI_trait_Amputee_LowerArm_desc"), false, false)
amp2:addXPBoost(Perks.Left_Hand, 4) amp2:addXPBoost(Perks.Left_Hand, 4)
amp2:addXPBoost(Perks.Fitness, -1)
amp2:addXPBoost(Perks.Strength, -1)
local amp3 = TraitFactory.addTrait("Amputee_UpperArm", getText("UI_trait_Amputee_UpperArm"), -20, local amp3 = TraitFactory.addTrait("Amputee_UpperArm", getText("UI_trait_Amputee_UpperArm"), -20,
getText("UI_trait_Amputee_UpperArm_desc"), false, false) getText("UI_trait_Amputee_UpperArm_desc"), false, false)
amp3:addXPBoost(Perks.Left_Hand, 4) amp3:addXPBoost(Perks.Left_Hand, 4)
amp3:addXPBoost(Perks.Fitness, -1)
amp3:addXPBoost(Perks.Strength, -1)
TraitFactory.addTrait("Insensitive", getText("UI_trait_Insensitive"), 6, getText("UI_trait_Insensitivedesc"), false, TraitFactory.addTrait("Insensitive", getText("UI_trait_Insensitive"), 6, getText("UI_trait_Insensitivedesc"), false,
false) false)
+5 -7
View File
@@ -3,9 +3,8 @@ require "TimedActions/ISEquipWeaponAction"
require "TimedActions/ISUnequipAction" require "TimedActions/ISUnequipAction"
require "ISUI/ISInventoryPaneContextMenu" require "ISUI/ISInventoryPaneContextMenu"
local og_ISBaseTimedActionAdjustMaxTime = ISBaseTimedAction.adjustMaxTime local og_ISBaseTimedActionAdjustMaxTime = ISBaseTimedAction.adjustMaxTime
function ISBaseTimedAction:adjustMaxTime(maxTime) function ISBaseTimedAction:adjustMaxTime(maxTime)
local original_max_time = og_ISBaseTimedActionAdjustMaxTime(self, maxTime) local original_max_time = og_ISBaseTimedActionAdjustMaxTime(self, maxTime)
@@ -73,14 +72,15 @@ function ISInventoryPane:onMouseDoubleClick(x, y)
local item_to_check = self.items[self.mouseOverOption] local item_to_check = self.items[self.mouseOverOption]
local player_inventory = getPlayerInventory(self.player).inventory local player_inventory = getPlayerInventory(self.player).inventory
if instanceof(item_to_check, "InventoryItem") then if instanceof(item_to_check, "InventoryItem") then
og_ISInventoryPaneOnMouseDoubleClick(self, x, y) og_ISInventoryPaneOnMouseDoubleClick(self, x, y)
elseif CheckIfItemIsAmputatedLimb(item_to_check.items[1]) or CheckIfItemIsInstalledProsthesis(item_to_check.items[1]) then elseif CheckIfItemIsAmputatedLimb(item_to_check.items[1]) or CheckIfItemIsInstalledProsthesis(item_to_check.items[1]) then
--print("TOC: Can't double click this item") --print("TOC: Can't double click this item")
else
og_ISInventoryPaneOnMouseDoubleClick(self, x, y)
end end
og_ISInventoryPaneOnMouseDoubleClick(self, x, y)
@@ -93,7 +93,6 @@ function ISInventoryPane.getActualItems(items)
local ret = og_ISInventoryPaneGetActualItems(items) local ret = og_ISInventoryPaneGetActualItems(items)
-- This is gonna be slower than just overriding the function but hey it's more compatible -- This is gonna be slower than just overriding the function but hey it's more compatible
for i = 1, #ret do for i = 1, #ret do
local item_full_type = ret[i]:getFullType() local item_full_type = ret[i]:getFullType()
if string.find(item_full_type, "Amputation_") or string.find(item_full_type, "Prost_") then if string.find(item_full_type, "Amputation_") or string.find(item_full_type, "Prost_") then
@@ -120,7 +119,6 @@ end
local og_ISEquipWeaponActionPerform = ISEquipWeaponAction.perform local og_ISEquipWeaponActionPerform = ISEquipWeaponAction.perform
function ISEquipWeaponAction:perform() function ISEquipWeaponAction:perform()
-- TODO this is only for weapons, not items. Won't work for everything I think -- TODO this is only for weapons, not items. Won't work for everything I think
--TODO Block it before even performing --TODO Block it before even performing
-- TODO in the inventory menu there is something broken, even though this works -- TODO in the inventory menu there is something broken, even though this works
@@ -153,7 +151,7 @@ function ISEquipWeaponAction:perform()
if self.item then if self.item then
local item_name = self.item:getFullType() local item_name = self.item:getFullType()
for _, prost_v in ipairs(GetProsthesisList()) do for _, prost_v in pairs(GetProsthesisList()) do
local prosthesis_name = string.match(item_name, prost_v) local prosthesis_name = string.match(item_name, prost_v)
if prosthesis_name then if prosthesis_name then
self.character:Say("This isn't the right way to equip this...") self.character:Say("This isn't the right way to equip this...")
@@ -0,0 +1,89 @@
local BaseStats = {
LeatherBase = {
durability = 25,
speed = 15
},
WoodenBase = {
durability = 10,
speed = 5,
},
MetalBase = {
durability = 75,
speed = 7,
}
}
local TopStats = {
}
function GenerateEquippedProsthesis(prosthesis_item, limb)
-- TODO Durability should be decided from the clothing item xml. Same thing for disassembling stuff
-- TODO some stuff should be defined by the limb, like -10 if forearm in speed
-- -- when we equip a prosthesis, we're gonna pass these parameters to the newly generated clothing item
-- -- when we unequip it, we regen the normal item with the parameters from the clothing item
local durability = 0
local speed = 0
local prosthesis_name = prosthesis_item:getFullType()
for base_name, base_values in pairs(BaseStats) do
-- Check the name of the prosthesis item, set the correct values
if string.find(prosthesis_name, base_name) then
durability = base_values.durability
speed = base_values.speed
end
end
for top_name, top_values in pairs(TopStats) do
-- Check the name of the prosthesis item, set the correct values
if string.find(prosthesis_name, top_name) then
durability = durability + top_values.durability
speed = speed + top_values.speed
end
end
local item_mod_data = prosthesis_item:getModData()
--------------------
-- TEST STUFF
durability = 12
speed = 51
-------------------
item_mod_data.TOC = {
durability = durability,
speed = speed,
}
end
--local ProsthesisRecipe = {}
-- function ProsthesisRecipe.OnCreate.Hook(items, result, player, selectedItem)
-- -- Set mod data for item with durability and all that crap
-- end
+5 -2
View File
@@ -19,7 +19,7 @@ local function CheckIfPlayerIsInfected(player, toc_data)
end end
-- Check for everything else -- Check for everything else
for _, v in ipairs(GetOtherBodyPartTypes()) do for _, v in pairs(GetOtherBodyPartTypes()) do
if body_damage:getBodyPart(v):bitten() then if body_damage:getBodyPart(v):bitten() then
toc_data.Limbs.is_other_bodypart_infected = true -- Even one is enough, stop cycling if we find it toc_data.Limbs.is_other_bodypart_infected = true -- Even one is enough, stop cycling if we find it
break break
@@ -171,12 +171,14 @@ end
-- MAIN UPDATE FUNCTIONS -- MAIN UPDATE FUNCTIONS
local function TocUpdateOnTick() local function TocUpdateOnTick()
local player = getPlayer() local player = getPlayer()
if player == nil then if player == nil then
return return
end end
local toc_data = player:getModData().TOC local toc_data = player:getModData().TOC
if toc_data ~= nil then if toc_data ~= nil then
CheckIfPlayerIsInfected(player, toc_data) CheckIfPlayerIsInfected(player, toc_data)
@@ -196,7 +198,7 @@ local function TocUpdateEveryTenMinutes()
local part_data = player:getModData().TOC.Limbs local part_data = player:getModData().TOC.Limbs
--Experience for prosthesis user --Experience for prosthesis user
for _, side in ipairs(TOC_sides) do for _, side in pairs(TOC_sides) do
if part_data[side .. "_Hand"].is_prosthesis_equipped or part_data[side .. "_LowerArm"].is_prosthesis_equipped then if part_data[side .. "_Hand"].is_prosthesis_equipped or part_data[side .. "_LowerArm"].is_prosthesis_equipped then
player:getXp():AddXP(Perks[side .. "_Hand"], 4) player:getXp():AddXP(Perks[side .. "_Hand"], 4)
end end
@@ -247,6 +249,7 @@ local function TocUpdateEveryOneMinute()
-- Sends only Limbs since the other stuff is mostly static -- Sends only Limbs since the other stuff is mostly static
if toc_data ~= nil then if toc_data ~= nil then
-- FIXME Send little packets instead of the whole thing? -- FIXME Send little packets instead of the whole thing?
-- TODO we shouldn't run this if we're in SP I guess?
sendClientCommand(player, 'TOC', 'ChangePlayerState', { toc_data.Limbs } ) sendClientCommand(player, 'TOC', 'ChangePlayerState', { toc_data.Limbs } )
end end
@@ -23,7 +23,12 @@ end
function ISCutLimb:stop() function ISCutLimb:stop()
print("Stopping ISCutLimb")
self.surgeon:getEmitter():stopSoundByName("Amputation_Sound") self.surgeon:getEmitter():stopSoundByName("Amputation_Sound")
sendClientCommand(self.surgeon, "TOC", "AskStopAmputationSound", {surgeon_id = self.surgeon:getOnlineID()})
-- TODO test this with more than 2 players
-- TODO this gets bugged when player dies while amputating
end end
@@ -115,6 +120,7 @@ function ISCutLimb:perform()
if self.patient ~= self.surgeon and isClient() then if self.patient ~= self.surgeon and isClient() then
SendCutLimb(self.patient, self.part_name, surgeon_factor, bandage_table, painkiller_table) SendCutLimb(self.patient, self.part_name, surgeon_factor, bandage_table, painkiller_table)
sendClientCommand(self.surgeon, "TOC", "AskStopAmputationSound", {surgeon_id = self.surgeon:getOnlineID()})
else else
TocCutLimb(self.part_name, surgeon_factor, bandage_table, painkiller_table) TocCutLimb(self.part_name, surgeon_factor, bandage_table, painkiller_table)
end end
@@ -3,6 +3,9 @@ require "TimedActions/ISBaseTimedAction"
ISInstallProsthesis = ISBaseTimedAction:derive("ISInstallProsthesis"); ISInstallProsthesis = ISBaseTimedAction:derive("ISInstallProsthesis");
function ISInstallProsthesis:isValid() function ISInstallProsthesis:isValid()
-- TODO add here conditions if the action can be performed or not, so if thing is in inventory
-- TODO 'not sure about multiplayer, maybe an overriding check?
return true return true
end end
@@ -49,17 +52,19 @@ function ISInstallProsthesis:perform()
return return
end end
self.surgeon:getInventory():Remove(prosthesis_base_name) -- Removes the base item and substitute it with the part one
if self.patient ~= self.surgeon and isClient() then if self.patient ~= self.surgeon and isClient() then
SendEquipProsthesis(self.patient, self.part_name, prosthesis_base_name) SendEquipProsthesis(self.patient, self.part_name, self.item, prosthesis_base_name)
else else
TocEquipProsthesis(self.part_name, prosthesis_base_name) TocEquipProsthesis(self.part_name, self.item, prosthesis_base_name)
end end
self.surgeon:getInventory():Remove(prosthesis_base_name) -- Removes the base item after we transferred everything
-- needed to remove from queue / start next. -- needed to remove from queue / start next.
ISBaseTimedAction.perform(self) ISBaseTimedAction.perform(self)
end end
+34 -24
View File
@@ -1,19 +1,18 @@
--- A rly big thx to Fenris_Wolf and Chuck to help me with that. Love you guy
---Server side local ClientCommands = {}
local TOC_Commands = {}
TOC_Commands["SendServer"] = function(player, arg) -- Main handler of base functions for TOC, not changed till now 'cause it works
ClientCommands.SendServer = function(player, arg)
local otherPlayer = getPlayerByOnlineID(arg["To"]) local otherPlayer = getPlayerByOnlineID(arg["To"])
sendServerCommand(otherPlayer, "TOC", arg["command"], arg) sendServerCommand(otherPlayer, "TOC", arg["command"], arg)
end end
-- Cutting Limbs
-- Cut Limb stuff ClientCommands.AskDamageOtherPlayer = function(_, arg)
TOC_Commands["AskDamageOtherPlayer"] = function(_, arg)
local patient = getPlayerByOnlineID(arg[1]) local patient = getPlayerByOnlineID(arg[1])
local patient_id = arg[1] local patient_id = arg[1]
@@ -23,24 +22,38 @@ TOC_Commands["AskDamageOtherPlayer"] = function(_, arg)
end end
ClientCommands.AskStopAmputationSound = function(_, args)
print("TOC: We're in AskStopAmputationSound")
sendServerCommand("TOC", "StopAmputationSound", {surgeon_id = args.surgeon_id})
end
-- Animations
ClientCommands.NotifyNewCrawlAnimation = function(player, args)
sendServerCommand("TOC", "SetCrawlAnimation", {id = args.id, check = args.check})
-- CHEATING STUFF
TOC_Commands["AskToResetEverything"] = function(_, arg)
local clicked_player = getPlayerByOnlineID(arg[1])
local clicked_player_id = arg[1]
sendServerCommand(clicked_player, "TOC", "AcceptResetEverything", { clicked_player_id })
end end
-- Cheats
ClientCommands.AskToResetEverything = function(_, arg)
local clicked_player = getPlayerByOnlineID(arg[1])
sendServerCommand(clicked_player, "TOC", "ResetEverything", {})
end
-- Global Mod Data data handler
ClientCommands.ChangePlayerState = function(playerObj, args)
ModData.get("TOC_PLAYER_DATA")[playerObj:getUsername()] = args
ModData.transmit("TOC_PLAYER_DATA")
end
------ Global Mod Data ----------- ------ Global Mod Data -----------
function TOC_OnInitGlobalModData() function TOC_OnInitGlobalModData()
@@ -49,18 +62,15 @@ end
Events.OnInitGlobalModData.Add(TOC_OnInitGlobalModData) Events.OnInitGlobalModData.Add(TOC_OnInitGlobalModData)
TOC_Commands.OnClientCommand = function(module, command, playerObj, args)
if module == 'TOC' and TOC_Commands[command] then ------------------------------------------------------
TOC_Commands[command](playerObj, args)
local function OnClientCommand(module, command, playerObj, args)
if module == 'TOC' and ClientCommands[command] then
ClientCommands[command](playerObj, args)
end end
end end
Events.OnClientCommand.Add(OnClientCommand)
Events.OnClientCommand.Add(TOC_Commands.OnClientCommand)
TOC_Commands.ChangePlayerState = function(playerObj, args)
ModData.get("TOC_PLAYER_DATA")[playerObj:getUsername()] = args
ModData.transmit("TOC_PLAYER_DATA")
end
+18 -12
View File
@@ -1,20 +1,26 @@
local function addBodyLocationBefore(new_location, move_to_location) local function AddBodyLocationBefore(new_location, move_to_location)
-- FIXME This doesn't really move a body location, it just re-adds it to another index. Find a way to remove it entirely (maybe setExclusive?)
local group = BodyLocations.getGroup("Human") local group = BodyLocations.getGroup("Human")
local list = getClassFieldVal(group, getClassField(group, 1)) local list = getClassFieldVal(group, getClassField(group, 1))
group:getOrCreateLocation(new_location) group:getOrCreateLocation(new_location)
local newItem = list:get(list:size()-1) local new_item = list:get(list:size()-1)
print("TOC: Created new body location" .. newItem:getId()) print("TOC: Created new body location" .. new_item:getId())
list:remove(new_item) -- We can't use the Index, it works if we pass the item though!
list:remove(newItem) -- We can't use the Index, it works if we pass the item though!
local i = group:indexOf(move_to_location) local i = group:indexOf(move_to_location)
list:add(i, newItem) list:add(i, new_item)
end end
AddBodyLocationBefore("TOC_ArmRight", "Shoes")
AddBodyLocationBefore("TOC_ArmLeft", "Shoes")
addBodyLocationBefore("TOC_ArmRight", "Shoes")
addBodyLocationBefore("TOC_ArmLeft", "Shoes")
addBodyLocationBefore("TOC_ArmRightProsthesis", "Shoes") AddBodyLocationBefore("TOC_ArmRightProsthesis", "Shoes")
addBodyLocationBefore("TOC_ArmLeftProsthesis", "Shoes") AddBodyLocationBefore("TOC_ArmLeftProsthesis", "Shoes")
AddBodyLocationBefore("TOC_LegRight", "FannyPackFront")
AddBodyLocationBefore("TOC_LegLeft", "FannyPackFront")
AddBodyLocationBefore("TOC_LegRightProsthesis", "FannyPackFront")
AddBodyLocationBefore("TOC_LegLeftProsthesis", "FannyPackFront")
+39
View File
@@ -478,6 +478,45 @@ item Surgery_Right_Tourniquet
Tooltip = Test, Tooltip = Test,
CanHaveHoles = false, CanHaveHoles = false,
} }
item Amputation_Left_Foot
{
Type = Clothing,
DisplayName = Amputated Left Foot,
ClothingItem = Amputation_Left_Foot,
BodyLocation = TOC_LegLeft,
Weight = 0,
CombatSpeedModifier = 0.9,
BloodLocation = Hands;LowerArms,
Insulation = 1.0,
WindResistance = 1.0,
WaterResistance = 1.0,
Icon = genericAmputation,
CanHaveHoles = false,
}
item Amputation_Right_Foot
{
Type = Clothing,
DisplayName = Amputated Right Foot,
ClothingItem = Amputation_Right_Foot,
BodyLocation = TOC_LegRight,
Weight = 0,
CombatSpeedModifier = 0.9,
BloodLocation = Hands;LowerArms,
Insulation = 1.0,
WindResistance = 1.0,
WaterResistance = 1.0,
Icon = genericAmputation,
CanHaveHoles = false,
}
} }
+1
View File
@@ -82,6 +82,7 @@ recipe Make wooden hook
Category: Surgeon, Category: Surgeon,
Tooltip: Recipe_Tooltip_Wooden_hook, Tooltip: Recipe_Tooltip_Wooden_hook,
NeedToBeLearn: true, NeedToBeLearn: true,
} }
recipe Make metal hook recipe Make metal hook
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

+198
View File
@@ -0,0 +1,198 @@
import lxml.etree as gfg
import pandas as pd
import numpy as np
import openpyxl
def generate_clothing_item(name, model, texture_choices, guid = None):
root = gfg.Element("clothingItem")
m_MaleModel = gfg.Element("m_MaleModel")
m_MaleModel.text = f"{model}_Male"
root.append(m_MaleModel)
m_FemaleModel = gfg.Element("m_FemaleModel")
m_FemaleModel.text = f"{model}_Female"
root.append(m_FemaleModel)
m_GUID = gfg.Element("m_GUID")
if guid:
m_GUID.text = guid
else:
m_GUID.text = "get guid from func"
root.append(m_GUID)
m_Static = gfg.Element("m_Static")
m_Static.text = "false"
root.append(m_Static)
m_AllowRandomTint = gfg.Element("m_AllowRandomTint")
m_AllowRandomTint.text = "false"
root.append(m_AllowRandomTint)
# Defined by the amount of textures that we're gonna pass
for tex in texture_choices:
textureChoices = gfg.Element("textureChoices")
textureChoices.text = tex
root.append(textureChoices)
tree = gfg.ElementTree(root)
path = r'python_helpers/outputs/output_clothing/' + name + ".xml"
with open(path, "wb") as file:
tree.write(file, encoding='utf-8', xml_declaration=True, pretty_print=True )
def generate_recipe(recipe_name, recipe_items, result_name, time, skill_required, tooltip):
root_element = f"recipe {recipe_name}\n"
root_element += "\t{\n"
for item in recipe_items:
root_element += f"\t\t{item},\n"
root_element += f"\n\n\t\tResult: {result_name},\n"
root_element += f"\t\tTime: {time:.2f},\n"
root_element += "\t\tNeedToBeLearn: true,\n"
root_element += "\t\tCanBeDoneFromFloor: false,\n"
root_element += "\t\tOnGiveXP: NoXP_OnGiveXP,\n"
root_element += f"\t\tSkillRequired: {skill_required[0]}={skill_required[1]},\n"
root_element += "\t\tCategory: Surgeon,\n"
root_element += f"\t\tTooltip: {tooltip},\n"
root_element += "\t}"
with open("Test_recipe.txt", "wt") as file:
file.write(root_element)
file.close()
def generate_item(item_name, weight, item_type, display_category, display_name, icon, tooltip, can_have_holes, clothing_item=None, body_location = None, blood_location = None):
root_element = f"item {item_name}\n"
root_element += "\t{\n"
root_element += f"\t\tWeight = {weight},\n"
root_element += f"\t\tType = {item_type},\n"
root_element += f"\t\tDisplayCategory = {display_category},\n"
root_element += f"\t\tDisplayName = {display_name},\n"
if item_type == "Clothing":
root_element += f"\t\tClothingItem = {clothing_item},\n"
root_element += f"\t\tBodyLocation = {body_location},\n"
root_element += f"\t\tBloodLocation = {blood_location},\n"
root_element += f"\t\tIcon = {icon},\n"
root_element += f"\t\tTooltip = {tooltip},\n"
root_element += f"\t\tCanHaveHoles = {can_have_holes.lower()},\n"
root_element += "\t}\n"
path = r'python_helpers/outputs/output_item/script.txt'
with open(path, "at") as file:
file.write(root_element)
file.close()
###########################################################################################
def read_table(file_name: str, table_name: str) -> pd.DataFrame:
wb = openpyxl.load_workbook(file_name, read_only= False, data_only = True) # openpyxl does not have table info if read_only is True; data_only means any functions will pull the last saved value instead of the formula
for sheetname in wb.sheetnames: # pulls as strings
sheet = wb[sheetname] # get the sheet object instead of string
if table_name in sheet.tables: # tables are stored within sheets, not within the workbook, although table names are unique in a workbook
tbl = sheet.tables[table_name] # get table object instead of string
tbl_range = tbl.ref #something like 'C4:F9'
break # we've got our table, bail from for-loop
data = sheet[tbl_range] # returns a tuple that contains rows, where each row is a tuple containing cells
content = [[cell.value for cell in row] for row in data] # loop through those row/cell tuples
header = content[0] # first row is column headers
rest = content[1:] # every row that isn't the first is data
df = pd.DataFrame(rest, columns = header)
wb.close()
return df
###########################################################################################
excel_path = r'python_helpers/modules_prost.xlsx'
df_base = read_table(excel_path, "BaseTable")
df_top = read_table(excel_path, "TopTable")
# CLOTHING GENERATION PASS
limbs = ["Hand", "LowerArm"]
sides = ["Left", "Right"]
prost_bodylocations = ["TOC_ArmRightProsthesis", "TOC_ArmLeftProsthesis"]
for base_row in df_base.iterrows():
for top_row in df_top.iterrows():
base_name = base_row[1][0]
top_name = top_row[1][0]
for limb in limbs:
for side in sides:
current_name = "Prost_" + side + "_" + limb + "_" + base_name + "_" + top_name
generate_clothing_item(current_name, "test", {"test1", "test2"}, "123")
# ITEM GENERATION PASS - ASSEMBLED
for base_row in df_base.iterrows():
for top_row in df_top.iterrows():
base_id = base_row[1]["Base"]
top_id = top_row[1]["Top"]
item_id = base_id + "_" + top_id
item_type = "Clothing"
weight = "{0:.2f}".format(float(base_row[1]["Weight"]) + float(top_row[1]["Weight"]))
display_category = "Prosthesis"
display_name = "Prosthesis - " + base_row[1]["Display Name"] + " and " + top_row[1]["Display Name"]
for limb in limbs:
for side in sides:
clothing_item_name = "Prost_" + side + "_" + limb + "_" + base_id + "_" + top_id
bl = prost_bodylocations[0] if side == "Right" else prost_bodylocations[1]
generate_item(item_id, weight, item_type, display_category, display_name, "TempIcon", "TempTooltip", "false", clothing_item_name, bl, "TestBloodLocation")
# ITEM GENERATION PASS - Single item to assemble stuff
def generate_normal_items(df, type):
for row in df.iterrows():
item_id = "ProsthPart_" + row[1][type]
item_type = "Normal"
weight = "{0:.2f}".format(float(row[1]["Weight"]))
display_category = "Prosthesis"
display_name = row[1]["Display Name"]
generate_item(item_id, weight, item_type, display_category, display_name, "TempIcon", "TempTooltip", "false")
generate_normal_items(df_base, "Base")
generate_normal_items(df_top, "Top")
#########################################################################################
recipe_name = "Test Recipe"
recipe_items = ["Ass", "Penis", "Shit=3"]
result_name = "Cum sock"
time = 10
skill_required = ["Carpentry", "4"]
tooltip = "tooltip_test"
#generate_recipe(recipe_name, recipe_items, result_name, time, skill_required, tooltip)
item_name = "Ass Ass Ass"
weight = 100
item_type = "Clothing"
display_category = "Prosthesis"
display_name = "Ass cock"
clothing_item = "ClothingItemSomethingProst"
body_location = "TOC_ArmRightProsthesis"
#generate_item(item_name, weight, item_type, display_category, display_name, "test_icon", "test_tooltip", "false", clothing_item, body_location, "Hands")
Binary file not shown.