diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2795927223/filelist.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2795927223/filelist.xml new file mode 100644 index 00000000..1d230f59 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2795927223/filelist.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/TalentTrees.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/TalentTrees.xml new file mode 100644 index 00000000..78be8fbd --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/TalentTrees.xml @@ -0,0 +1,8640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/endocrinebooster.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/endocrinebooster.xml new file mode 100644 index 00000000..d2545ee6 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/endocrinebooster.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/filelist.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/filelist.xml new file mode 100644 index 00000000..e526a206 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2913302583/filelist.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Client/ItemBox.cs b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Client/ItemBox.cs new file mode 100644 index 00000000..c07762f7 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Client/ItemBox.cs @@ -0,0 +1,323 @@ +using Barotrauma.Items.Components; +using Barotrauma; +using HarmonyLib; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System.Collections.Generic; +using System; +using System.ComponentModel; +using Barotrauma.Networking; +using System.Linq; + +namespace BaroMod_sjx +{ + partial class ItemBoxImpl + { + + [HarmonyPatch(typeof(Inventory), nameof(Inventory.DrawSlot))] + class Patch_DrawSlot + { + public class context + { + public SpriteBatch spriteBatch; + + public Inventory inventory; + public Sprite? indicatorSprite; + public Sprite? emptyIndicatorSprite; + public Sprite? itemSprite; + public Rectangle conditionIndicatorArea; + + public int max_value; + public int cur_value; + public Vector2 sprite_pos; + public float sprite_scale; + public float rotation; + public Color spriteColor; + public context(SpriteBatch sb, Inventory inv, Sprite? full, Sprite? empty, Sprite? item, Rectangle area, int max, int cur, Vector2 sp, float ss, float rot, Color sc) + { + spriteBatch = sb; + inventory = inv; + indicatorSprite = full; + emptyIndicatorSprite = empty; + itemSprite = item; + conditionIndicatorArea = area; + max_value = max; + cur_value = cur; + sprite_pos = sp; + sprite_scale = ss; + rotation = rot; + spriteColor = sc; + } + } + + static private void Invoke_DrawItemStateIndicator( + SpriteBatch spriteBatch, Inventory inventory, + Sprite indicatorSprite, Sprite emptyIndicatorSprite, Rectangle containedIndicatorArea, float containedState, + bool pulsate = false) + { + AccessTools.Method(typeof(Inventory), "DrawItemStateIndicator")! + .Invoke(null, new object[] { spriteBatch, inventory, indicatorSprite, emptyIndicatorSprite, containedIndicatorArea, containedState, pulsate }); + } + + private static Sprite? GetTargetSprite(ConditionStorage conditionStorage, Inventory iv) + { + Inventory.ItemSlot target_slot; + { + Inventory.ItemSlot[] slots = (AccessTools.Field(typeof(Inventory), "slots").GetValue(iv)! as Inventory.ItemSlot[])!; + if (conditionStorage.slotIndex >= slots.Length) + { + DebugConsole.LogError($"ConditionStorage of {(iv.Owner as Item)!.Prefab.Identifier} specified index {conditionStorage.slotIndex} out of {slots.Length}!"); + return null; + } + target_slot = slots[conditionStorage.slotIndex]; + } + if (target_slot.Any()) + { + Item i = target_slot.First(); + return i.Prefab.InventoryIcon ?? i.Sprite; + } + else + { + return null; + } + } + + public static bool Prefix(out context? __state, + SpriteBatch spriteBatch, Inventory inventory, VisualSlot slot, Item item, int slotIndex) + { + if (inventory != null && item != null && get_componentsByType(item).TryGetValue(typeof(ConditionStorage), out List? comps)) + { + ConditionStorage conditionStorage = (comps.First() as ConditionStorage)!; + if (!conditionStorage.showIcon && !conditionStorage.showCount) + { + __state = null; + return true; + } + + + Rectangle rect = slot.Rect; + rect.Location += slot.DrawOffset.ToPoint(); + + if (slot.HighlightColor.A > 0) + { + float inflateAmount = (slot.HighlightColor.A / 255.0f) * slot.HighlightScaleUpAmount * 0.5f; + rect.Inflate(rect.Width * inflateAmount, rect.Height * inflateAmount); + } + + var itemContainer = item.GetComponent(); + + Sprite? indicatorSprite; + Sprite? emptyIndicatorSprite; + Rectangle conditionIndicatorArea; + if (conditionStorage.showCount) + { + + + if (itemContainer is null) + { + DebugConsole.LogError($"Item {item.Prefab.Identifier} has ConditionStorage but no ItemContainer!"); + __state = null; + return true; + } + if (itemContainer.InventoryTopSprite != null || itemContainer.InventoryBottomSprite != null) + { + __state = null; + return true; + } + int dir = slot.SubInventoryDir; + + if (itemContainer.ShowContainedStateIndicator) + { + conditionIndicatorArea = new Rectangle(rect.X, rect.Bottom - (int)(10 * GUI.Scale), rect.Width, (int)(10 * GUI.Scale)); + } + else + { + conditionIndicatorArea = new Rectangle( + rect.X, dir < 0 ? rect.Bottom + HUDLayoutSettings.Padding / 2 : rect.Y - HUDLayoutSettings.Padding / 2 - Inventory.ContainedIndicatorHeight, + rect.Width, Inventory.ContainedIndicatorHeight); + conditionIndicatorArea.Inflate(-4, 0); + } + + + GUIComponentStyle indicatorStyle = GUIStyle.GetComponentStyle("ContainedStateIndicator.Default")!; + indicatorSprite = indicatorStyle.GetDefaultSprite(); + emptyIndicatorSprite = indicatorStyle.GetSprite(GUIComponent.ComponentState.Hover); + } + else + { + indicatorSprite = null; + emptyIndicatorSprite = null; + conditionIndicatorArea = new Rectangle(); + } + + Vector2 itemPos; + float scale; + float rotation; + Sprite? item_sprite; + Color spriteColor; + + if (conditionStorage.showIcon) + { + item_sprite = GetTargetSprite(conditionStorage, itemContainer.Inventory!); + if (item_sprite != null) + { + scale = Math.Min(Math.Min((rect.Width - 10) / item_sprite.size.X, (rect.Height - 10) / item_sprite.size.Y), 2.0f); + itemPos = rect.Center.ToVector2(); + if (itemPos.Y > GameMain.GraphicsHeight) + { + itemPos.Y -= Math.Min( + (itemPos.Y + item_sprite.size.Y / 2 * scale) - GameMain.GraphicsHeight, + (itemPos.Y - item_sprite.size.Y / 2 * scale) - rect.Y); + } + + rotation = 0.0f; + if (slot.HighlightColor.A > 0) + { + rotation = (float)Math.Sin(slot.HighlightTimer * MathHelper.TwoPi) * slot.HighlightTimer * 0.3f; + } + + spriteColor = item_sprite == item.Sprite ? item.GetSpriteColor() : item.GetInventoryIconColor(); + } + else + { + scale = 1.0f; + rotation = 0.0f; + spriteColor = Color.White; + } + } + else + { + item_sprite = null; + scale = 1.0f; + rotation = 0.0f; + spriteColor = Color.White; + } + Vector2 center = rect.Center.ToVector2() + (new Vector2(conditionStorage.iconShiftX, conditionStorage.iconShiftY)) * slot.Rect.Size.ToVector2() * 0.5f; + __state = new context(spriteBatch, inventory, indicatorSprite, emptyIndicatorSprite, item_sprite, + conditionIndicatorArea, conditionStorage.maxItemCount, conditionStorage.currentItemCount, center, + scale * conditionStorage.iconScale, rotation, spriteColor); + } + else + { + __state = null; + } + return true; + } + public static void Postfix(context? __state) + { + if (__state != null) + { + __state.itemSprite?.Draw(__state.spriteBatch, __state.sprite_pos, __state.spriteColor, __state.rotation, __state.sprite_scale); + if (__state.indicatorSprite != null && __state.emptyIndicatorSprite != null) + { + Invoke_DrawItemStateIndicator(__state.spriteBatch, __state.inventory, __state.indicatorSprite, __state.emptyIndicatorSprite, __state.conditionIndicatorArea, + __state.cur_value / (float)__state.max_value); + string info_text = $"{__state.cur_value}/{__state.max_value}"; + float text_scale = 0.75f; + Vector2 info_size = GUIStyle.SmallFont.MeasureString(info_text) * text_scale; + GUIStyle.SmallFont.DrawString(__state.spriteBatch, info_text, __state.conditionIndicatorArea.Center.ToVector2() - (info_size * 0.5f), Color.White, 0.0f, Vector2.Zero, text_scale, SpriteEffects.None, 0.0f); + } + } + } + } + } + + partial class ConditionStorage : ItemComponent, IServerSerializable + { + private CoroutineHandle? resetPredictionCoroutine = null; + private int? last_server_update_count = null; + private float resetPredictionTimer = 1.0f; + + float last_update_time = 0; + + const double remove_time = 1.0; + + class ItemStackedInfo + { + public Item target; + public Inventory removed_from; + public Character user; + public double timestamp; + public int slot; + public ItemStackedInfo(Item item, Character character, Inventory removedFrom, int from_slot) + { + target = item; + removed_from = removedFrom; + user = character; + slot = from_slot; + timestamp = Timing.TotalTime; + } + } + + // keep a list of items removed on client side so that they can be put back into container after timeour + private List removed = new List(); + + + void RemoveItem_track(Item item, Character user, Inventory removedFrom, int slot) + { + removed.Add(new ItemStackedInfo(item, user, removedFrom, slot)); + } + + void UpdateRemovedItems() + { + var copy = removed.CreateCopy(); + foreach (var item in copy) + { + // updated from server to be removed + if (item.target.Removed) + { + removed.Remove(item); + } + // timeout for removed item. put it back. + else if (Timing.TotalTime - item.timestamp > remove_time) + { + if (!item.removed_from.TryPutItem(item.target, item.slot, false, false, item.user, false, false)) + { + item.target.Drop(item.user, true, true); + } + removed.Remove(item); + } + } + if (removed.Any()) + { + IsActive = true; + } + } + + partial void OnCountPredictionChanged() + { + if (GameMain.Client == null || !last_server_update_count.HasValue) { return; } + if (resetPredictionCoroutine == null || !CoroutineManager.IsCoroutineRunning(resetPredictionCoroutine)) + { + resetPredictionCoroutine = CoroutineManager.StartCoroutine(ResetPredictionAfterDelay()); + } + } + + private IEnumerable ResetPredictionAfterDelay() + { + while (resetPredictionTimer > 0.0f) + { + resetPredictionTimer -= CoroutineManager.DeltaTime; + yield return CoroutineStatus.Running; + } + if (last_server_update_count.HasValue) { SetItemCount(last_server_update_count.Value, false); } + resetPredictionCoroutine = null; + yield return CoroutineStatus.Success; + } + + public void ClientEventRead(IReadMessage msg, float sendingTime) + { + if (last_update_time <= sendingTime) + { + last_update_time = sendingTime; + last_server_update_count = msg.ReadRangedInteger(0, maxItemCount); + SetItemCount(last_server_update_count.Value, true); + } + else + { + // discard the number, but still extract it from stream. + msg.ReadRangedInteger(0, maxItemCount); + } + } + } +} diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBox.sln b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBox.sln new file mode 100644 index 00000000..7dc8d315 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBox.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32825.248 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ItemBoxClient", "ItemBoxClient.csproj", "{D6EE7363-56EC-442E-8A50-C12111C41B59}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ItemBoxServer", "ItemBoxServer.csproj", "{35F1A00E-3387-47F2-BC89-6DB51BF829F4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Debug|x64.ActiveCfg = Debug|x64 + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Debug|x64.Build.0 = Debug|x64 + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Release|Any CPU.Build.0 = Release|Any CPU + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Release|x64.ActiveCfg = Release|x64 + {D6EE7363-56EC-442E-8A50-C12111C41B59}.Release|x64.Build.0 = Release|x64 + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Debug|x64.Build.0 = Debug|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Release|Any CPU.Build.0 = Release|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Release|x64.ActiveCfg = Release|Any CPU + {35F1A00E-3387-47F2-BC89-6DB51BF829F4}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BE43C433-493F-4E78-9590-A780226B0FB3} + EndGlobalSection +EndGlobal diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBoxClient.csproj b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBoxClient.csproj new file mode 100644 index 00000000..993d29d4 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBoxClient.csproj @@ -0,0 +1,46 @@ + + + + net6.0 + enable + enable + AnyCPU;x64 + + + + 1701;1702;CS0122 + $(DefineConstants)TRACE;CLIENT + + + + 1701;1702;CS0122 + $(DefineConstants)TRACE;CLIENT + + + + 1701;1702;CS0122 + $(DefineConstants)TRACE;CLIENT + + + + 1701;1702;CS0122 + $(DefineConstants)TRACE;CLIENT + + + + + ..\Refs\0Harmony.dll + + + ..\Refs\Client\Barotrauma.dll + + + ..\Refs\MonoGame.Framework.Windows.NetStandard.dll + + + ..\Refs\XNATypes.dll + + + + + diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBoxServer.csproj b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBoxServer.csproj new file mode 100644 index 00000000..f9a9b8e3 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/ItemBoxServer.csproj @@ -0,0 +1,34 @@ + + + + net6.0 + enable + enable + + + + $(DefineConstants)TRACE;SERVER + + + + $(DefineConstants)TRACE;SERVER + + + + ..\Refs\0Harmony.dll + + + ..\Refs\Server\DedicatedServer.dll + + + ..\Refs\MonoGame.Framework.Windows.NetStandard.dll + + + ..\Refs\Server\NetScriptAssembly.dll + + + ..\Refs\XNATypes.dll + + + + diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/RunConfig.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/RunConfig.xml new file mode 100644 index 00000000..5796b9a9 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/RunConfig.xml @@ -0,0 +1,5 @@ + + + Standard + Standard + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Server/ItemBox.cs b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Server/ItemBox.cs new file mode 100644 index 00000000..4a59392a --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Server/ItemBox.cs @@ -0,0 +1,57 @@ +using Barotrauma; +using HarmonyLib; +using System.Reflection; +using System.Linq; +using Barotrauma.Items.Components; +using System.Collections.Generic; +using System; +using Microsoft.Xna.Framework; +using System.ComponentModel; +using Barotrauma.Networking; + +namespace BaroMod_sjx +{ + + partial class ConditionStorage : ItemComponent, IServerSerializable + { + /* + private CoroutineHandle? sendStateCoroutine; + private int lastSentState; + private float sendStateTimer; + */ + partial void OnCountPredictionChanged() + { + /* + sendStateTimer = 0.5f; + if (sendStateCoroutine == null) + { + sendStateCoroutine = CoroutineManager.StartCoroutine(SendStateAfterDelay()); + }*/ + } + + /* + private IEnumerable SendStateAfterDelay() + { + while (sendStateTimer > 0.0f) + { + sendStateTimer -= CoroutineManager.DeltaTime; + yield return CoroutineStatus.Running; + } + + if (Item.Removed || GameMain.NetworkMember == null) + { + yield return CoroutineStatus.Success; + } + + sendStateCoroutine = null; + if (lastSentState != currentItemCount) { Item.CreateServerEvent(this); } + yield return CoroutineStatus.Success; + }*/ + + public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData? extraData = null) + { + EventData eventData = ExtractEventData(extraData); + msg.WriteRangedInteger(eventData.ItemCount, 0, maxItemCount); + } + } +} \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Shared/ItemBox.cs b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Shared/ItemBox.cs new file mode 100644 index 00000000..ec300418 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/CSharp/Shared/ItemBox.cs @@ -0,0 +1,408 @@ +using Barotrauma; +using HarmonyLib; +using System.Reflection; +using System.Linq; +using Barotrauma.Items.Components; +using System.Collections.Generic; +using System; +using Microsoft.Xna.Framework; +using System.ComponentModel; +using Barotrauma.Networking; + +namespace BaroMod_sjx +{ + partial class ItemBoxImpl : ACsMod + { + const string harmony_id = "com.sjx.ItemIOFramework"; + /* + const string box_identifier = "ItemBox"; + const float max_condition = 1.0f; + const int item_count = 1024; + const float increment = max_condition / item_count; + */ + private readonly Harmony harmony; + + public ItemBoxImpl() + { + harmony = new Harmony(harmony_id); + harmony.PatchAll(Assembly.GetExecutingAssembly()); + Barotrauma.DebugConsole.AddWarning("Loaded ItemBox Impl"); + } + + public override void Stop() + { + harmony.UnpatchAll(harmony_id); + } + + + + static Dictionary> get_componentsByType(Item item) + { + return (AccessTools.Field(typeof(Item), "componentsByType").GetValue(item)! as Dictionary>)!; + } + + [HarmonyPatch(typeof(Inventory))] + class Patch_PutItem + { + static MethodBase TargetMethod() + { + Barotrauma.DebugConsole.AddWarning("Patch_PutItem TargetMethod"); + return AccessTools.Method(typeof(Inventory), "PutItem"); + } + + public class context + { + public Character user; + public ConditionStorage target; + public context(Character user, ConditionStorage target) + { + this.user = user; + this.target = target; + } + } + + public static bool Prefix(Inventory __instance, Character user, int i, out context? __state) + { + __state = null; + ConditionStorage? target = ConditionStorage.GetFromInventory(__instance); + if (target != null && i == target.slotIndex) + { + __state = new context(user, target); + } + return true; + } + public static void Postfix(context? __state) + { + if (__state != null) + { + __state.target.OnPutItemDone(__state.user); + } + } + } + + [HarmonyPatch(typeof(Inventory), nameof(Inventory.RemoveItem))] + class Patch_RemoveItem + { + public static bool Prefix(Inventory __instance, out ConditionStorage? __state, Item item) + { + __state = null; + // do not add items if sub is unloading or if removed for overflow. + if (!Submarine.Unloading) + { + ConditionStorage? target = ConditionStorage.GetFromInventory(__instance); + if (target != null) + { + if (target.GetSlot()?.Contains(item) ?? false) + { + if (target.flag_remove_no_spawn) + { + target.flag_remove_no_spawn = false; + } + else + { + target.QualityStacked = item.Quality; + target.ConditionStacked = item.Condition; + target.item_type = item.Prefab; + __state = target; + } + } + } + } + return true; + } + public static void Postfix(ConditionStorage? __state) + { + if (__state != null) + { + __state.OnRemoveItemDone(); + } + } + } + + [HarmonyPatch(typeof(Inventory))] + class Patch_TrySwapping + { + static MethodBase TargetMethod() + { + return AccessTools.Method(typeof(Inventory), "TrySwapping"); + } + + public static bool Prefix(Inventory __instance, Item item, ref bool __result) + { + if (ConditionStorage.GetFromInventory(__instance) != null || + (item != null && item.ParentInventory != null && ConditionStorage.GetFromInventory(item.ParentInventory) != null)) + { + __result = false; + return false; + } + return true; + } + } + + [HarmonyPatch(typeof(Inventory))] + class Patch_CreateNetworkEvent + { + static MethodBase TargetMethod() + { + return AccessTools.Method(typeof(Inventory), "CreateNetworkEvent"); + } + + public static bool Prefix(Inventory __instance, out ConditionStorage? __state) + { + __state = null; + if (GameMain.NetworkMember != null) + { + __state = ConditionStorage.GetFromInventory(__instance); + } + return true; + } + + public static void Postfix(ConditionStorage? __state) + { + if (__state != null) + { + __state.SyncItemCount(); + } + } + } + } + + partial class ConditionStorage : ItemComponent + { + private readonly struct EventData : IEventData + { + public readonly int ItemCount; + + public EventData(int ItemCount) + { + this.ItemCount = ItemCount; + } + } + + [Serialize(0, IsPropertySaveable.No, description: "Index of the stacking slot in same item's ItemContainer component")] + public int slotIndex { get; private set; } + + [Serialize(true, IsPropertySaveable.No, description: "Shows count and percentage of stacking item")] + public bool showCount { get; private set; } + + [Serialize(1024, IsPropertySaveable.No, description: "Maximum number of items stacked within")] + public int maxItemCount { get; private set; } + + [Serialize(true, IsPropertySaveable.No, description: "Shows icon of stacking item")] + public bool showIcon { get; private set; } + + [Serialize(0.6f, IsPropertySaveable.No, description: "icon scale compared to full")] + public float iconScale { get; private set; } + + [Serialize(0.0f, IsPropertySaveable.No, description: "shift x of icon")] + public float iconShiftX { get; private set; } + + [Serialize(0.1f, IsPropertySaveable.No, description: "shift y of icon, down is positive")] + public float iconShiftY { get; private set; } + + [Editable(minValue: 0, maxValue: int.MaxValue), Serialize(0, IsPropertySaveable.Yes, description: "Current item count")] + // camel case needed for save compatibility + public int currentItemCount + { + get => _currentItemCount; + // assume set by + set + { + SetItemCount(value, false); + } + } + + void SetItemCount(int value, bool is_network_event = false) + { + if (is_network_event || GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) + // authoritative number. will need to send to client later if server. + { + if (value != _currentItemCount) + { + OnCountActualChanged(); + } + } + // predicted number. need to be reset later + else + { + if (value != _currentItemCount) + { + OnCountPredictionChanged(); + } + } + IsActive = true; + _currentItemCount = value; + } + + public ItemInventory itemInventory => Item.OwnInventory; + public ItemContainer itemContainer => Item.GetComponent(); + + public int _currentItemCount; + + // replace setting parent container hack, so that harpoon guns work correctly + public bool flag_remove_no_spawn; + + partial void OnCountActualChanged(); + partial void OnCountPredictionChanged(); + + + [Editable, Serialize("", IsPropertySaveable.Yes, description: "current stacked item")] + public Identifier ItemIdentifier + { + get + { + return item_type?.Identifier ?? ""; + } + set + { + if (value.IsEmpty) + { + item_type = null; + } + else + { + item_type = ItemPrefab.Find("", value.ToIdentifier()); + } + } + } + + public ItemPrefab? item_type; + + [Editable(MinValueInt = 0, MaxValueInt = Quality.MaxQuality), Serialize(0, IsPropertySaveable.Yes, description: "current stacked item quality")] + public int QualityStacked { get; set; } + + [Editable, Serialize(float.NaN, IsPropertySaveable.Yes, description: "current stacked item condition")] + public float ConditionStacked { get; set; } + + + + public ConditionStorage(Item item, ContentXElement element) : base(item, element) { } + + public bool IsFull => currentItemCount >= maxItemCount; + public bool IsEmpty() => currentItemCount <= 0; + + public void SyncItemCount() + { +#if SERVER + Item.CreateServerEvent(this, new EventData(currentItemCount)); +#endif + } + + public override void Update(float deltaTime, Camera cam) + { + base.Update(deltaTime, cam); + SyncItemCount(); + IsActive = false; + } + + public static int SlotPreserveCount(ItemPrefab prefab, Inventory inventory, ItemContainer container, int slot_index) + { + int resolved_stack_size = Math.Min(Math.Min(prefab.GetMaxStackSize(inventory), container.GetMaxStackSize(slot_index)), Inventory.MaxPossibleStackSize); + if (resolved_stack_size <= 1) + { + return 1; + } + else + { + return resolved_stack_size - 1; + } + } + + public static ConditionStorage? GetFromInventory(Inventory inventory) + { + if (inventory.Owner is Item parentItem) + { + return parentItem.GetComponent(); + } + else + { + return null; + } + } + + public Inventory.ItemSlot? GetSlot() + { + Inventory.ItemSlot[] slots = (AccessTools.Field(typeof(Inventory), "slots").GetValue(itemInventory)! as Inventory.ItemSlot[])!; + if (slotIndex >= slots.Length) + { + DebugConsole.LogError($"ConditionStorage of {Item.Prefab.Identifier} specified index {slotIndex} out of {slots.Length}!"); + return null; + } + return slots[slotIndex]; + } + + public void OnPutItemDone(Character user) + { + ItemContainer container = itemContainer; + Inventory.ItemSlot target_slot; + { + Inventory.ItemSlot[] slots = (AccessTools.Field(typeof(Inventory), "slots").GetValue(itemInventory)! as Inventory.ItemSlot[])!; + if (slotIndex >= slots.Length) + { + DebugConsole.LogError($"ConditionStorage of {Item.Prefab.Identifier} specified index {slotIndex} out of {slots.Length}!"); + return; + } + target_slot = slots[slotIndex]; + } + + if (target_slot.Items.Any()) + { + QualityStacked = target_slot.Items.First().Quality; + ConditionStacked = target_slot.Items.First().Condition; + item_type = target_slot.Items.First().Prefab; + if (!IsFull) + { + //bool edited = false; + int preserve = SlotPreserveCount(target_slot.Items.First().Prefab, itemInventory, container, slotIndex); + var it = target_slot.Items.ToArray().AsEnumerable().GetEnumerator(); + while (it.MoveNext() && !IsFull) + { + if (preserve > 0) + { + preserve--; + } + else if (Entity.Spawner != null) + { + // client cannot despawn items, single player needs to despawn + Entity.Spawner.AddItemToRemoveQueue(it.Current); + SetItemCount(currentItemCount + 1); + flag_remove_no_spawn = true; + itemInventory.RemoveItem(it.Current); + break; + } + } + } + } + } + + public void OnRemoveItemDone() + { + Inventory.ItemSlot target_slot; + { + Inventory.ItemSlot[] slots = (AccessTools.Field(typeof(Inventory), "slots").GetValue(itemInventory)! as Inventory.ItemSlot[])!; + if (slotIndex >= slots.Length) + { + DebugConsole.LogError($"ConditionStorage of {(itemInventory.Owner as Item)!.Prefab.Identifier} specified index {slotIndex} out of {slots.Length}!"); + return; + } + target_slot = slots[slotIndex]; + } + + int preserve = SlotPreserveCount(item_type!, itemInventory, itemContainer, slotIndex); + int spawn_count = preserve - target_slot.Items.Count; + int can_spawn = Math.Min(spawn_count, currentItemCount); + + // other may be queued, so spawn only one + if (can_spawn > 0) + { + if (Entity.Spawner != null) + { + SetItemCount(currentItemCount - 1); + + Item.Spawner.AddItemToSpawnQueue(item_type, itemInventory, + ConditionStacked, QualityStacked, spawnIfInventoryFull: true); + } + } + } + } +} diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/ItemBox.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/ItemBox.xml new file mode 100644 index 00000000..9f4507b2 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/ItemBox.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/Text/English.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/Text/English.xml new file mode 100644 index 00000000..df924a03 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/Text/English.xml @@ -0,0 +1,5 @@ + + + Item Box + Stack your stackable items in one entity. + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/Text/SimplifiedChinese.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/Text/SimplifiedChinese.xml new file mode 100644 index 00000000..63173b51 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/XML/Text/SimplifiedChinese.xml @@ -0,0 +1,5 @@ + + + 物品箱 + 让你可叠加的物品叠加在一个实体上面 + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/filelist.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/filelist.xml new file mode 100644 index 00000000..b86aace9 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/2950383008/filelist.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.Png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.Png new file mode 100644 index 00000000..3ead257f --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.Png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbc84d7b4edd2365079225de33a0dd963d9fd9f1569288599a8c4aab0b2c77dd +size 6007 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.gif b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.gif new file mode 100644 index 00000000..097aa3ef Binary files /dev/null and b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.gif differ diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.pfi b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.pfi new file mode 100644 index 00000000..5c10c3e5 Binary files /dev/null and b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.pfi differ diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.xml new file mode 100644 index 00000000..3f952b44 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/ExtinguisherComponent.xml @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/FlamerComponent.Png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/FlamerComponent.Png new file mode 100644 index 00000000..01fa40cc --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/FlamerComponent.Png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10a130780cb051b867ed17a38eb201061fab2e84fd3bce9fb3cea46c0c12cde8 +size 6032 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/filelist.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/filelist.xml new file mode 100644 index 00000000..4cc73b63 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3389755246/filelist.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/Client/BmsUtil.cs b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/Client/BmsUtil.cs new file mode 100644 index 00000000..3991eb42 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/Client/BmsUtil.cs @@ -0,0 +1,78 @@ +using System.Linq; +using Barotrauma; +using Barotrauma.Items.Components; + +using Barotrauma.Extensions; +using System.Collections.Generic; + +namespace BmsUtils +{ + public static class Util + { + private static List GetStackBoxIndex(ItemInventory inv) + { + var stackBoxsIndex = new List(); + for (var i = 0; i < inv.Capacity; i++) + { + var items = inv.GetItemsAt(i).ToList(); + if (items.None()) { continue; } + if (items.First().Prefab.Identifier.ToString() == "StackBox" && items.First().OwnInventories.First().AllItemsMod.Any()) + { + stackBoxsIndex.Add(i); + } + } + return stackBoxsIndex; + } + public static void PushItems(bool toStackBox = false) + { + + var controlCharacter = Character.Controlled; + var selectedContainer = controlCharacter.SelectedItem?.GetComponent(); + var leftHandItems = controlCharacter.Inventory.GetItemsAt(5).FirstOrDefault()?.OwnInventory; + var rightHandItems = controlCharacter.Inventory.GetItemsAt(6).FirstOrDefault()?.OwnInventory; + + if (leftHandItems != null) + { + for (var i = 0; i < leftHandItems.Capacity; i++) + { + foreach (var item in leftHandItems.GetItemsAt(i).ToList()) + { + if (toStackBox) + { + foreach (var boxIndex in GetStackBoxIndex(selectedContainer.Inventory)) + { + selectedContainer.Inventory.TryPutItem(item, boxIndex, allowSwapping: false, allowCombine: true, user: null, createNetworkEvent: true); + } + + } + else + { + selectedContainer.Inventory.TryPutItem(item, controlCharacter, createNetworkEvent: true, ignoreCondition: true); + } + } + } + } + if (rightHandItems != null) + { + for (var i = 0; i < rightHandItems.Capacity; i++) + { + foreach (var item in rightHandItems.GetItemsAt(i).ToList()) + { + if (toStackBox) + { + foreach (var boxIndex in GetStackBoxIndex(selectedContainer.Inventory)) + { + selectedContainer.Inventory.TryPutItem(item, boxIndex, allowSwapping: false, allowCombine: true, user: null, createNetworkEvent: true); + } + + } + else + { + selectedContainer.Inventory.TryPutItem(item, controlCharacter, createNetworkEvent: true, ignoreCondition: true); + } + } + } + } + } + } +} diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/Client/Bmsmod.cs b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/Client/Bmsmod.cs new file mode 100644 index 00000000..41005052 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/Client/Bmsmod.cs @@ -0,0 +1,92 @@ +using System.Reflection; +using Barotrauma.Extensions; +using Microsoft.Xna.Framework; +using HarmonyLib; +using System.Linq; +using Barotrauma; +using BmsUtils; + +// debug +// using System.Diagnostics; + +namespace Bms_Harmony +{ + partial class BmsHarmony : ACsMod + { + const string harmony_id = "com.Bms.Harmony"; + private readonly Harmony harmony; + + public override void Stop() + { + harmony.UnpatchAll(harmony_id); + } + + public BmsHarmony() + { + harmony = new Harmony(harmony_id); + harmony.PatchAll(Assembly.GetExecutingAssembly()); + Barotrauma.DebugConsole.AddWarning("Loaded BmsHarmony"); + } + + [HarmonyPatch(typeof(Barotrauma.Items.Components.ItemContainer))] + class Patch_MergeStacks + { + static MethodBase TargetMethod() + { + Barotrauma.DebugConsole.AddWarning("Patch_MergeStacks TargetMethod"); + return AccessTools.Method(typeof(Barotrauma.Items.Components.ItemContainer), "MergeStacks"); + } + static bool Prefix(Barotrauma.Items.Components.ItemContainer __instance) + { + for (int i = 0; i < __instance.Inventory.Capacity - 1; i++) + { + var items = __instance.Inventory.GetItemsAt(i).ToList(); + if (items.None()) { continue; } + if (items.First().Prefab.Identifier.ToString() == "StackBox" && + items.First().OwnInventories.First().AllItemsMod.Any()) + { + for (int j = 0; j < __instance.Inventory.Capacity - 1; j++) + { + var items2 = __instance.Inventory.GetItemsAt(j).ToList(); + if (items2.None()) { continue; } + if (items2.First().Prefab.Identifier.ToString() != "StackBox") + { + items2.ForEach(it => __instance.Inventory.TryPutItem(it, i, allowSwapping: false, allowCombine: true, user: null, createNetworkEvent: false)); + continue; + } + + } + } + } + return true; + } + } + + [HarmonyPatch(typeof(Barotrauma.Items.Components.ItemContainer))] + class Patch_CreateGUI + { + static MethodBase TargetMethod() + { + Barotrauma.DebugConsole.AddWarning("Patch_CreateGUI TargetMethod"); + return AccessTools.Method(typeof(Barotrauma.Items.Components.ItemContainer), "CreateGUI"); + } + + static void Postfix(Barotrauma.Items.Components.ItemContainer __instance) + { + if (__instance.Inventory.Capacity > 1) + { + var layoutGroup = __instance.GuiFrame.FindChild(c => c is Barotrauma.GUILayoutGroup, recursive: true); + new GUIButton(new RectTransform(Vector2.One, layoutGroup.RectTransform, scaleBasis: ScaleBasis.Smallest), style: "PushButton") + { + ToolTip = TextManager.Get("bms.pushicon"), + OnClicked = (btn, userdata) => + { + Util.PushItems(true); + return true; + } + }; + } + } + } + } +} diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/RunConfig.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/RunConfig.xml new file mode 100644 index 00000000..5796b9a9 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/CSharp/RunConfig.xml @@ -0,0 +1,5 @@ + + + Standard + Standard + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/LICENSE b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/LICENSE new file mode 100644 index 00000000..50bc8779 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Diemoe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/English.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/English.xml new file mode 100644 index 00000000..2770bfba --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/English.xml @@ -0,0 +1,6 @@ + + + + All transferred to item box + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/Push.png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/Push.png new file mode 100644 index 00000000..5d074843 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/Push.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13e2b051bb4cca27befc98490a5a11745a83726c1a24686f2b842b5efd50427c +size 653 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/SimplifiedChinese.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/SimplifiedChinese.xml new file mode 100644 index 00000000..17be29c6 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/SimplifiedChinese.xml @@ -0,0 +1,6 @@ + + + + 全部转移至物品箱 + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/style.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/style.xml new file mode 100644 index 00000000..03dceedd --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/Text/style.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/filelist.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/filelist.xml new file mode 100644 index 00000000..0e8fce35 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3406279065/filelist.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/Lua/Autorun/ReloadLua.lua b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/Lua/Autorun/ReloadLua.lua new file mode 100644 index 00000000..1ce9dc0b --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/Lua/Autorun/ReloadLua.lua @@ -0,0 +1,466 @@ +if SERVER then return end + +LuaUserData.RegisterType("Barotrauma.Items.Components.ItemContainer+SlotRestrictions") +LuaUserData.RegisterType('System.Collections.Immutable.ImmutableArray`1[[Barotrauma.Items.Components.ItemContainer+SlotRestrictions, Barotrauma]]') +LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.Items.Components.ItemContainer'], 'slotRestrictions') +LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.ItemInventory'], 'slots') +LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.CharacterInventory"], "slots") + + -- 配置重试参数 + local RETRY_CONFIG = { + INTERVAL = 0.3, -- 重试间隔(秒) + MAX_ATTEMPTS = 3, -- 最大尝试次数 + VALIDITY_DURATION = 5,-- 记录有效期(秒) + GENERATION_INTERVAL = 0.5 -- 分代时间间隔 + } + + -- 状态存储表 + local retryQueue = {} -- 结构: + -- { + -- [magID] = + -- { + -- generations = + -- { + -- [generationID] = { attempts, nextAttempt, expiry }, + -- ... + -- }, + -- mag = entityRef + -- }, + -- ... + -- } + +local function isSlotFull(slotRestriction, slot) + return slotRestriction.MaxStackSize - #slot.items +end + +local function tryPutItemsInInventory(character, hand, anotherhand, handInv, handIEnumerable, anotherhandIEnumerable) + + -- 重试队列管理 + local function addToRetryQueue(mag) + if not mag then return end + + local currentTime = Timer.GetTime() + local magID = mag.ID + + -- 生成分代ID(每0.5秒为一个分代) + local generationID = math.floor(currentTime / RETRY_CONFIG.GENERATION_INTERVAL) + + -- 初始化队列条目 + if not retryQueue[magID] then + retryQueue[magID] = { + mag = mag, + generations = {} + } + end + + -- 更新分代记录 + local entry = retryQueue[magID] + if not entry.generations[generationID] then + entry.generations[generationID] = { + attempts = 0, + nextAttempt = currentTime + RETRY_CONFIG.INTERVAL, + expiry = currentTime + RETRY_CONFIG.VALIDITY_DURATION + } + else + -- 延长该分代的过期时间 + entry.generations[generationID].expiry = currentTime + RETRY_CONFIG.VALIDITY_DURATION + end + + -- print(string.format("Added generation %d for %s", generationID, mag.Name)) + end + + if not handInv then return end + + local handInvSlots = handInv.slots + + local function getPlayerInvItemsWithoutHand() + local playerInvItems = character.Inventory.AllItemsMod + -- 去除双手持有的物品,避免在双持情况下互相抢弹药 + for i = #playerInvItems, 1, -1 do + local item = playerInvItems[i] + if (hand and item.ID == hand.ID) or (anotherhand and item.ID == anotherhand.ID) then + table.remove(playerInvItems, i) + end + end + return playerInvItems + end + + -- 内部堆叠实现(原tryStackMagzine拆分) + local function tryStackMagazineInternal(mag) + if not mag or mag.ConditionPercentage > 0 then + return false + end + + -- 原有堆叠逻辑 + local function tryStackInInventory(inventory, Mag) + local identifier = Mag.Prefab.Identifier + for i, slot in ipairs(inventory.slots) do + for _, item in ipairs(slot.items) do + if item.HasTag("weapon") then goto continue end + if item.Prefab.Identifier.Equals(identifier) and item.ConditionPercentage == 0 and item.ID ~= Mag.ID then -- 只有空弹匣可堆叠 + if inventory.CanBePutInSlot(Mag, i-1) then + inventory.TryPutItem(Mag, i-1, false, true, nil) + return true + end + end + ::continue:: + end + end + return false + end + + -- 尝试玩家库存 + if tryStackInInventory(character.Inventory, mag) then + return true + end + + -- 尝试子容器 + for item in getPlayerInvItemsWithoutHand() do + if item.OwnInventory and tryStackInInventory(item.OwnInventory, mag) then + return true + end + end + + return false + end + + -- 外部入口函数(替换原tryStackMagzine) + local function tryStackMagzine(mag) + if not mag then return false end + + -- 立即尝试 + local success = tryStackMagazineInternal(mag) + + -- 失败时加入队列 + if not success then + -- 防止重复添加 + addToRetryQueue(mag) + end + + return success + end + + -- -- 堆叠弹匣 + -- local function tryStackMagzine(Mag) + -- if Mag == nil or Mag.ConditionPercentage ~= 0 then return false end + -- local function tryStackInInventory(inventory, Mag) + -- local identifier = Mag.Prefab.Identifier + -- for i, slot in ipairs(inventory.slots) do + -- for _, item in ipairs(slot.items) do + -- if item.HasTag("weapon") then goto continue end + -- if item.Prefab.Identifier.Equals(identifier) and item.ConditionPercentage == 0 and item.ID ~= Mag.ID then -- 只有空弹匣可堆叠 + -- if inventory.TryPutItem(Mag, i-1, false, true, nil) then + -- return true + -- end + -- end + -- ::continue:: + -- end + -- end + -- return false + -- end + + -- -- 尝试将弹匣堆叠到玩家物品栏1-10 + -- if tryStackInInventory(character.Inventory, Mag) then + -- return true + -- end + + -- -- 尝试将弹匣堆叠到玩家背包、衣服等子物品栏 + -- for item in getPlayerInvItemsWithoutHand() do + -- if item.OwnInventory then + -- if tryStackInInventory(item.OwnInventory, Mag) then + -- return true + -- end + -- end + -- end + -- return false + -- end + + -- 卸载弹匣 + local function unloadMag(index) + local unloadedMag = handInvSlots[index].items[1] + + -- 尝试堆叠弹匣 + if tryStackMagzine(unloadedMag) then return true end + + local slots = character.Inventory.slots + -- 如果都失败了,优先尝试将弹匣放入玩家背包、衣服子物品栏 + for i = #slots, 1, -1 do + if i == 4 or i == 5 or i == 8 then + if character.Inventory.TryPutItem(unloadedMag, i-1, false, true, nil) then + return true + end + end + end + + -- 然后尝试将弹匣放入玩家物品栏1-10 + for i = #slots, 1, -1 do + if i <= 8 or i == 19 then goto continue end + if character.Inventory.CanBePutInSlot(unloadedMag, i-1) then + character.Inventory.TryPutItem(unloadedMag, i-1, false, false, nil) + return true + end + ::continue:: + end + + -- 保底情况,将弹匣丢到地面,暂时视为false,目前bool未使用 + unloadedMag.Drop(character, true, true) + return false + end + + -- 根据 index 构建一个含有所有可用的弹药/弹匣的 table,参数 num 是要寻找的数量 + local function findAvailableItemInPlayerInv(index, num) + local itemTable = {} + + for item in getPlayerInvItemsWithoutHand() do + local count = 0 + + -- 忽略掉所有带武器标签的物品,避免从其他武器中抢弹药 + if item.HasTag("weapon") then goto continue end + if handInv.CanBePutInSlot(item, index) and item.ConditionPercentage > 0 then + if itemTable[item.Prefab.Identifier.value] == nil then itemTable[item.Prefab.Identifier.value] = {} end + + table.insert(itemTable[item.Prefab.Identifier.value], item) + count = count + 1 + if count >= num then break end + end + if item.OwnInventory then + for item2 in item.OwnInventory.AllItemsMod do + if handInv.CanBePutInSlot(item2, index) and item2.ConditionPercentage > 0 then + if itemTable[item2.Prefab.Identifier.value] == nil then itemTable[item2.Prefab.Identifier.value] = {} end + + table.insert(itemTable[item2.Prefab.Identifier.value], item2) + count = count + 1 + if count >= num then break end + end + end + end + ::continue:: + end + + local maxLength = 0 + local maxElement = {} + for identifier, items in pairs(itemTable) do + if #items > maxLength then + maxLength = #items + maxElement = itemTable[identifier] + end + end + + return maxElement + end + + -- 根据 index 寻找可用的弹匣,但不要装入unloadedMag + local function findAvailableMagInPlayerInv(index, unloadedMag) + for item in getPlayerInvItemsWithoutHand() do + -- 忽略掉所有带武器标签的物品,避免从其他武器中抢弹药 + if item.HasTag("weapon") then goto continue end + if item and item.ID ~= unloadedMag.ID and handInv.CanBePutInSlot(item, index) and item.ConditionPercentage > 0 then + return item + end + if item.OwnInventory then + for item2 in item.OwnInventory.AllItemsMod do + if item2 and item2.ID ~= unloadedMag.ID and handInv.CanBePutInSlot(item2, index) and item2.ConditionPercentage > 0 then + return item2 + end + end + end + ::continue:: + end + return nil + end + + -- 根据 identifier 构建一个含有所有可用的弹药/弹匣的 table,参数 num 是要寻找的数量 + local function findAvailableItemWithIdentifier(identifier, num) + local findTable = {} + local count = 0 + for item in getPlayerInvItemsWithoutHand() do + -- 忽略掉所有带武器标签的物品,避免从其他武器中抢弹药 + if item.HasTag("weapon") then goto continue end + + if item.Prefab.Identifier.Equals(identifier) then + table.insert(findTable, item) + count = count + 1 + if count >= num then + return findTable + end + end + if item.OwnInventory then + for item2 in item.OwnInventory.AllItemsMod do + if item2.Prefab.Identifier.Equals(identifier) then + table.insert(findTable, item2) + count = count + 1 + if count >= num then + return findTable + end + end + end + end + ::continue:: + end + return findTable + end + + -- 根据 identifier 返回一个可用于堆叠已有弹匣的物品 + local function findAvailableForStackingInPlayerInv(identifier) + local itemList = {} + for item in getPlayerInvItemsWithoutHand() do + if item.HasTag("weapon") then goto continue end + if item.Prefab.Identifier.Equals(identifier) and item.ConditionPercentage > 0 then + table.insert(itemList, item) + end + if item.OwnInventory then + for item2 in item.OwnInventory.AllItemsMod do + if item2.Prefab.Identifier.Equals(identifier) and item2.ConditionPercentage > 0 then + table.insert(itemList, item2) + end + end + end + ::continue:: + end + -- 对 itemList 依照 ConditionPercentage 进行升序排序 + table.sort(itemList, function(a, b) return a.ConditionPercentage < b.ConditionPercentage end) + + return itemList + end + + local function putItem(item, index, isForStacking, isForSplitting) + if item == nil or item.ConditionPercentage == 0 or item == hand or item == anotherhand then return end + if not handInv.TryPutItem(item, index, isForStacking, isForSplitting, character, true, true) + then return false end -- 如果上弹失败,则返回false + return true + end + + -- 对枪械中每个 SlotRestriction 进行处理 + local itemContainer = handInv.Container + local i = math.max(itemContainer.ContainedStateIndicatorSlot + 1, 1) -- 准确定位弹匣的slot + local handInvSlotRestriction = itemContainer.slotRestrictions[i-1] + -- 空物品情况 + if #handInvSlots[i].items == 0 then + for _, item in ipairs(findAvailableItemInPlayerInv(i - 1, isSlotFull(handInvSlotRestriction, handInvSlots[i]))) do + putItem(item, i - 1, false, false) + end + -- 已有可堆叠弹药的情况 + elseif #handInvSlots[i].items > 0 and isSlotFull(handInvSlotRestriction, handInvSlots[i]) > 0 then + for _, item in ipairs(findAvailableItemWithIdentifier(handInvSlots[i].items[1].Prefab.Identifier, isSlotFull(handInvSlotRestriction, handInvSlots[i]))) do + putItem(item, i - 1, false, false) + end + end + -- 已有弹匣的情况 + if isSlotFull(handInvSlotRestriction, handInvSlots[i]) == 0 and #handInvSlots[i].items == 1 and handInvSlots[i].items[1].ConditionPercentage ~= 100 then + local itemlist = findAvailableForStackingInPlayerInv(handInvSlots[i].items[1].Prefab.Identifier) + local item = itemlist[1] + if (#itemlist == 1 and handInvSlots[i].items[1].ConditionPercentage == 0) or (item and item.ConditionPercentage ~=100 and handInvSlots[i].items[1].ConditionPercentage == 0) then --特殊情况,只剩一个弹匣下处理堆叠问题 + unloadMag(i) + putItem(item, i - 1, true, true) + end + if not putItem(item, i - 1, true, true) then -- 如果上弹失败,卸载弹匣 + local unloadedMag = handInvSlots[i].items[1] + unloadMag(i) + -- 如果此时双手武器未装备,重新装备武器 + local currentHand = character.Inventory.GetItemInLimbSlot(handIEnumerable[1]) + local currentAnotherHand = character.Inventory.GetItemInLimbSlot(anotherhandIEnumerable[1]) + if (currentHand == hand and currentAnotherHand == anotherhand) ~= true then + if hand and anotherhand and hand.ID == anotherhand.ID then -- 如果为双手武器 + for _, handSlotType in ipairs { InvSlotType.LeftHand, InvSlotType.RightHand } do + local handSlotIndex = character.Inventory.FindLimbSlot(handSlotType) + if handSlotIndex >= 0 then + character.Inventory.TryPutItem(hand, handSlotIndex, true, false, character, true, true) + end + end + else -- 如果为单手武器或者双持武器 + character.Inventory.TryPutItem(hand, character, handIEnumerable, true, true) + character.Inventory.TryPutItem(anotherhand, character, anotherhandIEnumerable, true, true) + end + end + local findMag = findAvailableMagInPlayerInv(i - 1, unloadedMag) + if #itemlist == 0 and unloadedMag.ConditionPercentage > 0 and findMag == nil then + putItem(unloadedMag, i - 1, false, false) + else + putItem(findMag, i - 1, false, false) + end + end + tryStackMagzine(item) -- 尝试堆叠空弹匣 + end + + -- 注册每帧检查,在多人游戏对tryStackMagazine进行重试 + Hook.Add("think", "magazineRetrySystem", function() + if not retryQueue then return end + local currentTime = Timer.GetTime() + + -- 遍历所有条目 + for magID, entry in pairs(retryQueue) do + local mag = entry.mag + local hasValidGenerations = false + + -- 实体有效性检查 + if not mag or mag.ID ~= magID then + retryQueue[magID] = nil + goto continue + end + + for genID, genRecord in pairs(entry.generations) do + -- 清理过期分代 + if currentTime > genRecord.expiry then + entry.generations[genID] = nil + -- print("Generation expired:", genID) + goto next_generation + end + + -- 执行重试条件检查 + if currentTime >= genRecord.nextAttempt then + -- 执行重试 + local success = tryStackMagazineInternal(mag) + + if success then + -- 成功时清除全部分代 + retryQueue[magID] = nil + -- print("Success via generation:", genID) + goto continue + else + -- 更新重试状态 + genRecord.attempts = genRecord.attempts + 1 + genRecord.nextAttempt = currentTime + RETRY_CONFIG.INTERVAL + + -- 超过最大尝试次数 + if genRecord.attempts >= RETRY_CONFIG.MAX_ATTEMPTS then + entry.generations[genID] = nil + -- print("Max attempts for generation:", genID) + end + end + end + + hasValidGenerations = true + ::next_generation:: + end + + -- 清理空条目 + if not hasValidGenerations then + retryQueue[magID] = nil + end + + ::continue:: + end + end) +end + +Hook.Patch("Barotrauma.Character", "ControlLocalPlayer", function(instance, ptable) + if retryQueue == nil then Hook.Remove("think", "magazineRetrySystem") end + if not PlayerInput.KeyHit(Keys.R) then return end + local Character = instance + if not Character then return end + + local rightHand = Character.Inventory.GetItemInLimbSlot(InvSlotType.RightHand) + local leftHand = Character.Inventory.GetItemInLimbSlot(InvSlotType.LeftHand) + local rightHandIEnumerable = {InvSlotType.RightHand} + local leftHandIEnumerable = {InvSlotType.LeftHand} + + if not rightHand and not leftHand then return end + + if rightHand and rightHand.HasTag("weapon") then + tryPutItemsInInventory(Character, rightHand, leftHand, rightHand.OwnInventory, rightHandIEnumerable, leftHandIEnumerable) + end + + if leftHand and not leftHand.Equals(rightHand) and leftHand.HasTag("weapon") then + tryPutItemsInInventory(Character, leftHand, rightHand, leftHand.OwnInventory, leftHandIEnumerable, rightHandIEnumerable) + end +end, Hook.HookMethodType.After) diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/PressRtoReload.png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/PressRtoReload.png new file mode 100644 index 00000000..40a17f2e --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/PressRtoReload.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7cbe3c1f9d524fad4ae2f22246159e984ee832371f9016cc95375ddf86c4448 +size 26231 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/Reload.code-workspace b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/Reload.code-workspace new file mode 100644 index 00000000..eece1027 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/Reload.code-workspace @@ -0,0 +1,41 @@ +{ + "folders": [ + { + "path": "." + }, + ], + "settings": { + "Lua.diagnostics.libraryFiles": "Enable", + "Lua.workspace.library": [ + "D:/Projects/Barotrauma/types/client", + "D:/Projects/Barotrauma/types/shared", + ], + + "Lua.diagnostics.disable": [ + "param-type-mismatch", + "return-type-mismatch", + "undefined-field", + "need-check-nil", + "assign-type-mismatch", + "redundant-return-value", + "missing-parameter", + "undefined-global", + "missing-return-value", + "undefined-doc-name", + "missing-return", + "cast-local-type", + "deprecated", + ], + }, + "launch": { + "version": "0.2.0", + "configurations": [ + { + "name": "MoonSharp Attach", + "type": "moonsharp-debug", + "request": "attach", + "debugServer" : 41912 + } + ] + } +} \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/filelist.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/filelist.xml new file mode 100644 index 00000000..1788f076 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3413495302/filelist.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/CUI.png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/CUI.png new file mode 100644 index 00000000..e9f759f0 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/CUI.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79204bd67761e8abf0b8ddb0d4f313ae829f963feee896242e3fa465cbcba3e0 +size 5884 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Default Styles.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Default Styles.xml new file mode 100644 index 00000000..521dd166 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Default Styles.xml @@ -0,0 +1,73 @@ + + + + CUIPalette.Component.Background + CUIPalette.Component.Border + CUIPalette.Handle.Background + CUIPalette.Handle.Grabbed + + + CUIPalette.Frame.Background + CUIPalette.Frame.Border + + + CUIPalette.Component.Text + Transparent + Transparent + [4,0] + + + CUIPalette.Input.Text + CUIPalette.Input.Border + CUIPalette.Input.Background + + + CUIPalette.Button.Background + CUIPalette.Button.Border + CUIPalette.Button.Disabled + [4,2] + [0.5,0.5] + + + CUIPalette.Button.Background + CUIPalette.Button.Disabled + + + CUIPalette.Button.Background + CUIPalette.Button.Border + CUIPalette.Button.Background + + + CUIPalette.CloseButton.Background + Transparent + + + Transparent + Transparent + CUIPalette.DDOption.Hover + CUIPalette.DDOption.Text + [0,0] + [4,0] + + + Transparent + Transparent + + + CUIPalette.Main.Text + + + White + Black + + + Transparent + + + Transparent + + + Transparent + Transparent + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Interaction icons sharp.png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Interaction icons sharp.png new file mode 100644 index 00000000..29e70290 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Interaction icons sharp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6e6e1f37f5c6d11e034983fd62001a0e7a86ed6200d0031dab8235e5a27e3ef +size 14791 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Interaction icons.png b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Interaction icons.png new file mode 100644 index 00000000..6730aae6 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Interaction icons.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48e73051969cb0b2b3f534b24dd655d5dad73345931ea5d1f4b3ceb9d4b6bb18 +size 20615 diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/PaletteDemo.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/PaletteDemo.xml new file mode 100644 index 00000000..6ae13d75 --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/PaletteDemo.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Palettes/Sets/Blue.xml b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Palettes/Sets/Blue.xml new file mode 100644 index 00000000..331fdedf --- /dev/null +++ b/Daedalic Entertainment GmbH/Barotrauma/WorkshopMods/Installed/3438745304/Assets/Palettes/Sets/Blue.xml @@ -0,0 +1,55 @@ + + + + +
+