Merge pull request #14 from ZioPao/modular_prosthetics
Modular prosthetics
@@ -53,6 +53,7 @@
|
||||
"FHSwapHandsAction",
|
||||
"getClassFieldVal",
|
||||
"SandboxVars",
|
||||
"getClassField"
|
||||
"getClassField",
|
||||
"ISWearClothing"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
0.9.15
|
||||
- Hotfix to sound not stopping when performing an amputation on another player
|
||||
|
||||
0.9.14
|
||||
- Optimizations
|
||||
- New icon for the mod
|
||||
|
||||
@@ -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>
|
||||
@@ -85,4 +85,15 @@
|
||||
<path>media/clothing/clothingItems/Surgery_Right_Tourniquet.xml</path>
|
||||
<guid>9a5fe063-63c7-4e6f-81ca-ee77c6678e0d</guid>
|
||||
</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>
|
||||
@@ -11,7 +11,7 @@ local function TocCheckIfStillInfected(limbs_data)
|
||||
local check = false
|
||||
|
||||
|
||||
for _, v in ipairs(GetBodyParts()) do
|
||||
for _, v in pairs(GetBodyParts()) do
|
||||
if limbs_data[v].is_infected then
|
||||
check = true
|
||||
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
|
||||
for i = body_part_types:size() - 1, 0, -1 do
|
||||
local bodyPart = body_part_types:get(i);
|
||||
bodyPart:SetInfected(false);
|
||||
local bodyPart = body_part_types:get(i)
|
||||
bodyPart:SetInfected(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
|
||||
local item = worn_items:get(i):getItem()
|
||||
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
|
||||
end
|
||||
end
|
||||
@@ -151,7 +151,7 @@ function TocCutLimb(part_name, surgeon_factor, bandage_table, painkiller_table)
|
||||
local base_damage_value = 100
|
||||
|
||||
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
|
||||
player:removeWornItem(tourniquet_item)
|
||||
@@ -240,13 +240,20 @@ function TocCutLimb(part_name, surgeon_factor, bandage_table, painkiller_table)
|
||||
TocDeleteOtherAmputatedLimbs(side)
|
||||
|
||||
--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)
|
||||
player:setWornItem(amputation_clothing_item:getBodyLocation(), amputation_clothing_item)
|
||||
|
||||
|
||||
-- Set blood on the amputated limb
|
||||
TocSetBloodOnAmputation(getPlayer(), adiacent_body_part)
|
||||
|
||||
if part_name == "Left_Foot" or part_name == "Right_Foot" then
|
||||
SetMissingFootAnimation(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -20,13 +20,10 @@ local function FixSingleBodyPartType(body_part_type, use_oven)
|
||||
end
|
||||
|
||||
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))
|
||||
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))
|
||||
FixSingleBodyPartType(depended_body_part_type, use_oven)
|
||||
|
||||
|
||||
@@ -6,15 +6,47 @@
|
||||
|
||||
---Equip a prosthesis transforming a normal item into a clothing item
|
||||
---@param part_name string
|
||||
---@param prosthesis_item any the prosthesis item
|
||||
---@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 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 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 added_prosthesis ~= nil then
|
||||
@@ -40,6 +72,8 @@ end
|
||||
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
|
||||
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
|
||||
local prosthesis_name = string.match(equipped_prosthesis_full_type, prost_v)
|
||||
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:getInventory():Remove(equipped_prosthesis)
|
||||
toc_data.Limbs[part_name].equipped_prosthesis = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ TocContextMenus.CreateMenus = function(player, context, worldObjects, test)
|
||||
local local_player = getSpecificPlayer(player)
|
||||
--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
|
||||
for x = v:getSquare():getX() - 1, v:getSquare():getX() + 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
|
||||
if v_stove:getCurrentTemperature() > 250 then
|
||||
|
||||
-- ipairs here to keep the order
|
||||
for _, v_bodypart in ipairs(GetBodyParts()) do
|
||||
if part_data[v_bodypart].is_cut and part_data[v_bodypart].is_amputation_shown and
|
||||
not part_data[v_bodypart].is_operated then
|
||||
|
||||
@@ -154,6 +154,9 @@ local function SetupTocMainUI(surgeon, patient, limbs_data)
|
||||
main_ui["b31"]:setPath(GetImageName("Right_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
|
||||
|
||||
|
||||
@@ -435,6 +438,15 @@ local function CreateTocMainUI()
|
||||
main_ui:addImageButton("b32", "", OnClickTocMainUI)
|
||||
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()
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@ if TheOnlyCure == nil then
|
||||
TheOnlyCure = {}
|
||||
end
|
||||
|
||||
|
||||
local pairs = pairs
|
||||
|
||||
|
||||
-----------------------------------------
|
||||
-- MP HANDLING CHECKS
|
||||
function CheckIfCanBeCut(part_name, limbs_data)
|
||||
@@ -60,9 +64,8 @@ end
|
||||
|
||||
function CheckIfItemIsProsthesis(item)
|
||||
|
||||
-- TODO find a cleaner way
|
||||
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
|
||||
if v == item_full_type then
|
||||
@@ -88,7 +91,7 @@ end
|
||||
|
||||
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
|
||||
return (limbs_data[side .. "_Hand"].is_prosthesis_equipped or limbs_data[side .. "_LowerArm"].is_prosthesis_equipped)
|
||||
end
|
||||
|
||||
@@ -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")
|
||||
@@ -17,6 +20,162 @@ Commands["ResponseCanAct"] = function(arg)
|
||||
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)
|
||||
local arg = {}
|
||||
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
|
||||
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)
|
||||
end
|
||||
|
||||
function SendEquipProsthesis(player, part_name, prosthesis_base_name)
|
||||
function SendEquipProsthesis(player, part_name, item, prosthesis_base_name)
|
||||
local arg = {}
|
||||
arg["From"] = getPlayer():getOnlineID()
|
||||
arg["To"] = player:getOnlineID()
|
||||
arg["command"] = "EquipProsthesis"
|
||||
arg["toSend"] = { part_name, prosthesis_base_name}
|
||||
arg["toSend"] = { part_name, item, prosthesis_base_name}
|
||||
sendClientCommand("TOC", "SendServer", arg)
|
||||
end
|
||||
|
||||
@@ -90,7 +249,6 @@ function AskCanEquipProsthesis(player, part_name)
|
||||
sendClientCommand("TOC", "SendServer", arg)
|
||||
end
|
||||
|
||||
|
||||
function AskCanUnequipProsthesis(player, part_name)
|
||||
GetConfirmUIMP().responseReceive = false
|
||||
local arg = {}
|
||||
@@ -101,165 +259,3 @@ function AskCanUnequipProsthesis(player, part_name)
|
||||
|
||||
sendClientCommand("TOC", "SendServer", arg)
|
||||
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)
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@ function TocGetBodyPartFromPartName(part_name)
|
||||
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_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
|
||||
|
||||
-- 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_LowerArm" then return BodyPartType.UpperArm_L 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
|
||||
|
||||
function TocFindCorrectClothingProsthesis(item_name, part_name)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function TocReapplyAmputationClothingItem(mod_data)
|
||||
local player = getPlayer()
|
||||
local player_inv = player:getInventory()
|
||||
@@ -6,15 +11,21 @@ local function TocReapplyAmputationClothingItem(mod_data)
|
||||
for _, limb in ipairs(TOC_limbs) do
|
||||
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
|
||||
if player_inv:FindAndReturn(amputated_clothing_name) == nil then
|
||||
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)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
TocResetClothingItemBodyLocation(player, side, limb)
|
||||
end
|
||||
@@ -34,8 +45,9 @@ function TocCheckCompatibilityWithOlderVersions(mod_data)
|
||||
print("TOC: Something was wrongly initiliazed before. Resetting parameters")
|
||||
TocResetEverything()
|
||||
else
|
||||
print("TOC: Found compatible data, correcting models in case of errors")
|
||||
TocReapplyAmputationClothingItem(mod_data)
|
||||
print("TOC: Bypassing reapplying of amputations, assuming that everything is correct")
|
||||
--print("TOC: Found compatible data, correcting models in case of errors and adding limbs")
|
||||
--TocReapplyAmputationClothingItem(mod_data)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -45,11 +45,13 @@ function TocResetEverything()
|
||||
TheOnlyCure.InitTheOnlyCure(_, player)
|
||||
|
||||
-- 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
|
||||
local amputation_item = player_inventory:FindAndReturn(amputation_item_name)
|
||||
if amputation_item ~= nil then
|
||||
@@ -71,6 +73,12 @@ function TocResetEverything()
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Reset special flag for legs amputations
|
||||
SetMissingFootAnimation(false)
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -130,3 +138,15 @@ function TocTestBodyLocations()
|
||||
|
||||
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
|
||||
@@ -25,6 +25,9 @@ local function PartNameToBodyLocationAmputation(name)
|
||||
if name == "Left_Hand" 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_Foot" then return "TOC_LegLeft" end
|
||||
if name == "Right_Foot" then return "TOC_LegRight" end
|
||||
end
|
||||
|
||||
function TocFindItemInProstBodyLocation(part_name, patient)
|
||||
@@ -71,7 +74,7 @@ end
|
||||
-- Override and mod compat helper
|
||||
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
|
||||
|
||||
if limbs_data[side .. "_Hand"].is_cut then
|
||||
@@ -86,3 +89,17 @@ function TocPopulateCanBeHeldTable(can_be_held, limbs_data)
|
||||
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
|
||||
@@ -8,7 +8,7 @@ if not TheOnlyCure then
|
||||
end
|
||||
|
||||
TOC_sides = { "Left", "Right" }
|
||||
TOC_limbs = { "Hand", "LowerArm", "UpperArm" }
|
||||
TOC_limbs = { "Hand", "LowerArm", "UpperArm", "Foot"}
|
||||
|
||||
local function TocCutLimbForTrait(player, limbs_data, 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
|
||||
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)
|
||||
|
||||
-- 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_lowerarm = { "WoodenHook", "MetalHook", "MetalHand", "ProstheticKnife" }
|
||||
local accepted_prosthesis_upperarm = {} -- For future stuff
|
||||
local accepted_prosthesis_foot = {}
|
||||
|
||||
for _, side in ipairs(TOC_sides) do
|
||||
for _, limb in ipairs(TOC_limbs) do
|
||||
for _, side in pairs(TOC_sides) do
|
||||
for _, limb in pairs(TOC_limbs) do
|
||||
|
||||
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
|
||||
mod_data.TOC.Limbs[part_name].cicatrization_base_time = 1700
|
||||
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].depends_on = { side .. "_Hand", side .. "_LowerArm", }
|
||||
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
|
||||
@@ -102,6 +142,10 @@ local function TocSetInitData(mod_data, player)
|
||||
Left_Hand = {},
|
||||
Left_LowerArm = {},
|
||||
Left_UpperArm = {},
|
||||
|
||||
Left_Foot = {},
|
||||
Right_Foot = {},
|
||||
|
||||
is_other_bodypart_infected = false
|
||||
},
|
||||
Prosthesis = {
|
||||
@@ -161,8 +205,8 @@ local function TocSetInitData(mod_data, player)
|
||||
|
||||
|
||||
|
||||
for _, side in ipairs(TOC_sides) do
|
||||
for _, limb in ipairs(TOC_limbs) do
|
||||
for _, side in pairs(TOC_sides) do
|
||||
for _, limb in pairs(TOC_limbs) do
|
||||
|
||||
local part_name = side .. "_" .. limb
|
||||
|
||||
@@ -208,6 +252,7 @@ function TheOnlyCure.InitTheOnlyCure(_, player)
|
||||
else
|
||||
TocCheckCompatibilityWithOlderVersions(mod_data)
|
||||
TocUpdateBaseData(mod_data) -- Since it's gonna be common to update stuff
|
||||
TocCheckLegsAmputations(mod_data)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -216,14 +261,20 @@ local function TocDeclareTraits()
|
||||
local amp1 = TraitFactory.addTrait("Amputee_Hand", getText("UI_trait_Amputee_Hand"), -8,
|
||||
getText("UI_trait_Amputee_Hand_desc"), false, false)
|
||||
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,
|
||||
getText("UI_trait_Amputee_LowerArm_desc"), false, false)
|
||||
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,
|
||||
getText("UI_trait_Amputee_UpperArm_desc"), false, false)
|
||||
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,
|
||||
false)
|
||||
|
||||
@@ -3,9 +3,8 @@ require "TimedActions/ISEquipWeaponAction"
|
||||
require "TimedActions/ISUnequipAction"
|
||||
require "ISUI/ISInventoryPaneContextMenu"
|
||||
|
||||
|
||||
local og_ISBaseTimedActionAdjustMaxTime = ISBaseTimedAction.adjustMaxTime
|
||||
|
||||
|
||||
function ISBaseTimedAction:adjustMaxTime(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 player_inventory = getPlayerInventory(self.player).inventory
|
||||
|
||||
|
||||
if instanceof(item_to_check, "InventoryItem") then
|
||||
og_ISInventoryPaneOnMouseDoubleClick(self, x, y)
|
||||
elseif CheckIfItemIsAmputatedLimb(item_to_check.items[1]) or CheckIfItemIsInstalledProsthesis(item_to_check.items[1]) then
|
||||
--print("TOC: Can't double click this item")
|
||||
else
|
||||
og_ISInventoryPaneOnMouseDoubleClick(self, x, y)
|
||||
|
||||
end
|
||||
og_ISInventoryPaneOnMouseDoubleClick(self, x, y)
|
||||
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ function ISInventoryPane.getActualItems(items)
|
||||
local ret = og_ISInventoryPaneGetActualItems(items)
|
||||
|
||||
-- This is gonna be slower than just overriding the function but hey it's more compatible
|
||||
|
||||
for i = 1, #ret do
|
||||
local item_full_type = ret[i]:getFullType()
|
||||
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
|
||||
function ISEquipWeaponAction:perform()
|
||||
|
||||
-- TODO this is only for weapons, not items. Won't work for everything I think
|
||||
--TODO Block it before even performing
|
||||
-- TODO in the inventory menu there is something broken, even though this works
|
||||
@@ -153,7 +151,7 @@ function ISEquipWeaponAction:perform()
|
||||
if self.item then
|
||||
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)
|
||||
if prosthesis_name then
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ local function CheckIfPlayerIsInfected(player, toc_data)
|
||||
end
|
||||
|
||||
-- Check for everything else
|
||||
for _, v in ipairs(GetOtherBodyPartTypes()) do
|
||||
for _, v in pairs(GetOtherBodyPartTypes()) do
|
||||
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
|
||||
break
|
||||
@@ -171,12 +171,14 @@ end
|
||||
|
||||
-- MAIN UPDATE FUNCTIONS
|
||||
|
||||
|
||||
local function TocUpdateOnTick()
|
||||
|
||||
local player = getPlayer()
|
||||
if player == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local toc_data = player:getModData().TOC
|
||||
if toc_data ~= nil then
|
||||
CheckIfPlayerIsInfected(player, toc_data)
|
||||
@@ -196,7 +198,7 @@ local function TocUpdateEveryTenMinutes()
|
||||
local part_data = player:getModData().TOC.Limbs
|
||||
|
||||
--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
|
||||
player:getXp():AddXP(Perks[side .. "_Hand"], 4)
|
||||
end
|
||||
@@ -247,6 +249,7 @@ local function TocUpdateEveryOneMinute()
|
||||
-- Sends only Limbs since the other stuff is mostly static
|
||||
if toc_data ~= nil then
|
||||
-- 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 } )
|
||||
end
|
||||
|
||||
|
||||
@@ -23,7 +23,12 @@ end
|
||||
|
||||
function ISCutLimb:stop()
|
||||
|
||||
print("Stopping ISCutLimb")
|
||||
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
|
||||
@@ -115,6 +120,7 @@ function ISCutLimb:perform()
|
||||
|
||||
if self.patient ~= self.surgeon and isClient() then
|
||||
SendCutLimb(self.patient, self.part_name, surgeon_factor, bandage_table, painkiller_table)
|
||||
sendClientCommand(self.surgeon, "TOC", "AskStopAmputationSound", {surgeon_id = self.surgeon:getOnlineID()})
|
||||
else
|
||||
TocCutLimb(self.part_name, surgeon_factor, bandage_table, painkiller_table)
|
||||
end
|
||||
|
||||
@@ -3,6 +3,9 @@ require "TimedActions/ISBaseTimedAction"
|
||||
ISInstallProsthesis = ISBaseTimedAction:derive("ISInstallProsthesis");
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
@@ -49,17 +52,19 @@ function ISInstallProsthesis:perform()
|
||||
return
|
||||
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
|
||||
|
||||
SendEquipProsthesis(self.patient, self.part_name, prosthesis_base_name)
|
||||
SendEquipProsthesis(self.patient, self.part_name, self.item, prosthesis_base_name)
|
||||
else
|
||||
TocEquipProsthesis(self.part_name, prosthesis_base_name)
|
||||
TocEquipProsthesis(self.part_name, self.item, prosthesis_base_name)
|
||||
|
||||
end
|
||||
|
||||
|
||||
self.surgeon:getInventory():Remove(prosthesis_base_name) -- Removes the base item after we transferred everything
|
||||
|
||||
-- needed to remove from queue / start next.
|
||||
ISBaseTimedAction.perform(self)
|
||||
end
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
--- A rly big thx to Fenris_Wolf and Chuck to help me with that. Love you guy
|
||||
|
||||
|
||||
---Server side
|
||||
local TOC_Commands = {}
|
||||
local ClientCommands = {}
|
||||
|
||||
|
||||
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"])
|
||||
sendServerCommand(otherPlayer, "TOC", arg["command"], arg)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Cut Limb stuff
|
||||
TOC_Commands["AskDamageOtherPlayer"] = function(_, arg)
|
||||
-- Cutting Limbs
|
||||
ClientCommands.AskDamageOtherPlayer = function(_, arg)
|
||||
|
||||
local patient = getPlayerByOnlineID(arg[1])
|
||||
local patient_id = arg[1]
|
||||
@@ -23,24 +22,38 @@ TOC_Commands["AskDamageOtherPlayer"] = function(_, arg)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
-- 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 })
|
||||
sendServerCommand("TOC", "SetCrawlAnimation", {id = args.id, check = args.check})
|
||||
|
||||
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 -----------
|
||||
|
||||
function TOC_OnInitGlobalModData()
|
||||
@@ -49,18 +62,15 @@ end
|
||||
|
||||
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
|
||||
|
||||
|
||||
Events.OnClientCommand.Add(TOC_Commands.OnClientCommand)
|
||||
Events.OnClientCommand.Add(OnClientCommand)
|
||||
|
||||
|
||||
TOC_Commands.ChangePlayerState = function(playerObj, args)
|
||||
ModData.get("TOC_PLAYER_DATA")[playerObj:getUsername()] = args
|
||||
ModData.transmit("TOC_PLAYER_DATA")
|
||||
end
|
||||
@@ -1,20 +1,26 @@
|
||||
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 function AddBodyLocationBefore(new_location, move_to_location)
|
||||
local group = BodyLocations.getGroup("Human")
|
||||
local list = getClassFieldVal(group, getClassField(group, 1))
|
||||
group:getOrCreateLocation(new_location)
|
||||
local newItem = list:get(list:size()-1)
|
||||
print("TOC: Created new body location" .. newItem:getId())
|
||||
|
||||
list:remove(newItem) -- We can't use the Index, it works if we pass the item though!
|
||||
local new_item = list:get(list:size()-1)
|
||||
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!
|
||||
local i = group:indexOf(move_to_location)
|
||||
list:add(i, newItem)
|
||||
list:add(i, new_item)
|
||||
end
|
||||
|
||||
|
||||
AddBodyLocationBefore("TOC_ArmRight", "Shoes")
|
||||
AddBodyLocationBefore("TOC_ArmLeft", "Shoes")
|
||||
|
||||
addBodyLocationBefore("TOC_ArmRight", "Shoes")
|
||||
addBodyLocationBefore("TOC_ArmLeft", "Shoes")
|
||||
addBodyLocationBefore("TOC_ArmRightProsthesis", "Shoes")
|
||||
addBodyLocationBefore("TOC_ArmLeftProsthesis", "Shoes")
|
||||
|
||||
|
||||
AddBodyLocationBefore("TOC_ArmRightProsthesis", "Shoes")
|
||||
AddBodyLocationBefore("TOC_ArmLeftProsthesis", "Shoes")
|
||||
|
||||
AddBodyLocationBefore("TOC_LegRight", "FannyPackFront")
|
||||
AddBodyLocationBefore("TOC_LegLeft", "FannyPackFront")
|
||||
|
||||
|
||||
AddBodyLocationBefore("TOC_LegRightProsthesis", "FannyPackFront")
|
||||
AddBodyLocationBefore("TOC_LegLeftProsthesis", "FannyPackFront")
|
||||
|
||||
@@ -478,6 +478,45 @@ item Surgery_Right_Tourniquet
|
||||
Tooltip = Test,
|
||||
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,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ recipe Make wooden hook
|
||||
Category: Surgeon,
|
||||
Tooltip: Recipe_Tooltip_Wooden_hook,
|
||||
NeedToBeLearn: true,
|
||||
|
||||
}
|
||||
|
||||
recipe Make metal hook
|
||||
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 671 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 381 B |
|
After Width: | Height: | Size: 683 B |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 843 B |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 671 B |
|
After Width: | Height: | Size: 981 B |
|
After Width: | Height: | Size: 282 B |
|
After Width: | Height: | Size: 683 B |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 680 B |
@@ -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")
|
||||