Compare commits

...

11 Commits

37 changed files with 486 additions and 91 deletions

View File

@ -9,6 +9,7 @@ import sys
import time import time
import logging import logging
import certifi import certifi
import math
from PIL import Image from PIL import Image
from mutagen.oggvorbis import OggVorbis from mutagen.oggvorbis import OggVorbis
from distutils.dir_util import copy_tree from distutils.dir_util import copy_tree
@ -127,27 +128,40 @@ def fetch_and_cut_song(tape, ffmpeg_version):
"or download the latest release version manually.") "or download the latest release version manually.")
sys.exit() sys.exit()
walkman = ["./utils/ffmpeg-" + ffmpeg_version + "-full_build/bin/ffmpeg.exe",
"-i", f"./build/music/{tape['identifier']}.ogg",
"-af", f"highpass=f=300,lowpass=f=12000",
f"./build/music/{tape['identifier']}-walkman.ogg"]
try:
subprocess.call(walkman)
except FileNotFoundError:
print("ffmpeg not in utils directory. Run python install_dependencies.py "
"or download the latest release version manually.")
sys.exit()
def assemble_png_image(tapes, icons=False): def assemble_png_image(tapes, icons=False):
if icons: if icons:
img_names = [f"./source/images/{tape['identifier']}_icon.png" for tape in tapes] img_names = [f"./source/images/{tape['identifier']}_icon.png" for tape in tapes]
images = [Image.open("./source/images/boombox_icon.png")]
else: else:
img_names = [f"./source/images/{tape['identifier']}.png" for tape in tapes] img_names = [f"./source/images/{tape['identifier']}.png" for tape in tapes]
images = []
images += [Image.open(x) for x in img_names] images = [Image.open(x) for x in img_names]
widths, heights = zip(*(i.size for i in images)) widths, heights = zip(*(i.size for i in images))
total_width = max(widths) columns = int((len(images))**0.5)
max_height = sum(heights) rows = int(math.ceil(len(images) / columns))
total_width = max(widths) * columns
max_height = max(heights) * rows
new_im = Image.new('RGBA', (total_width, max_height)) new_im = Image.new('RGBA', (total_width, max_height))
y_offset = 0 for i, im in enumerate(images):
for im in images: x_offset = max(widths) * (i % columns)
new_im.paste(im, (0, y_offset)) y_offset = max(heights) * math.floor(i / columns)
y_offset += im.size[1] new_im.paste(im, (x_offset, y_offset))
if icons: if icons:
new_im.save("./build/icons.png") new_im.save("./build/icons.png")
@ -167,7 +181,7 @@ def prepare_music(data):
logging.info("downloading and cutting the songs") logging.info("downloading and cutting the songs")
for i, tape in enumerate(data): for i, tape in enumerate(data):
if not os.path.exists(f"./build/music/{tape['identifier']}.ogg"): if not (os.path.exists(f"./build/music/{tape['identifier']}.ogg") or os.path.exists(f"./build/music/{tape['identifier']}-walkman.ogg")):
logging.info(f"{i + 1}/{len(data)} Downloading: {tape['name']}") logging.info(f"{i + 1}/{len(data)} Downloading: {tape['name']}")
fetch_and_cut_song(tape, ffmpeg_version) fetch_and_cut_song(tape, ffmpeg_version)
else: else:
@ -187,6 +201,7 @@ def prepare_images(data, config):
logging.info(f"copying other images") logging.info(f"copying other images")
shutil.copy("./source/images/boombox.png", "./build/boombox.png") shutil.copy("./source/images/boombox.png", "./build/boombox.png")
shutil.copy("./source/images/boombox_icon.png", "./build/boombox_icon.png")
shutil.copy("./source/images/PreviewImage.png", "./build/PreviewImage.png") shutil.copy("./source/images/PreviewImage.png", "./build/PreviewImage.png")
@ -201,6 +216,9 @@ def build_xml_code(data, config):
condition_delta = [f"{1 / use_length:0.5f}" for use_length in use_lengths] condition_delta = [f"{1 / use_length:0.5f}" for use_length in use_lengths]
affliction_delta = [100 / song_length for song_length in song_lengths] affliction_delta = [100 / song_length for song_length in song_lengths]
columns = int((len(data))**0.5)
positions = [{"column": i % columns, "row": math.floor(i / columns)} for i in range(len(data))]
logging.info(f"creating jinja environment") logging.info(f"creating jinja environment")
# create jinja2 environment # create jinja2 environment
j2env = j2.Environment(loader=j2.FileSystemLoader(Path("."))) j2env = j2.Environment(loader=j2.FileSystemLoader(Path(".")))
@ -224,11 +242,13 @@ def build_xml_code(data, config):
# render the template # render the template
output_file.write(template1.render(tapes=data, config=config, output_file.write(template1.render(tapes=data, config=config,
condition_delta=condition_delta, condition_delta=condition_delta,
affliction_delta=affliction_delta)) affliction_delta=affliction_delta,
song_lengths=song_lengths,
positions=positions))
with open(f"./build/{config['slug']}_style.xml", "w+", encoding="utf8") as output_file: with open(f"./build/{config['slug']}_style.xml", "w+", encoding="utf8") as output_file:
# render the template # render the template
output_file.write(template2.render(tapes=data, config=config)) output_file.write(template2.render(tapes=data, config=config, positions=positions))
def deploy(config): def deploy(config):

View File

@ -5,8 +5,10 @@
<UIStyle file="Mods/{{ config['name'] }}/{{ config['slug'] }}_style.xml" /> <UIStyle file="Mods/{{ config['name'] }}/{{ config['slug'] }}_style.xml" />
<None file="Mods/{{ config['name'] }}/icons.png" /> <None file="Mods/{{ config['name'] }}/icons.png" />
<None file="Mods/{{ config['name'] }}/covers.png" /> <None file="Mods/{{ config['name'] }}/covers.png" />
<None file="Mods/{{ config['name'] }}/boombox.png" />{% for tape in tapes %} <None file="Mods/{{ config['name'] }}/boombox.png" />
<None file="Mods/{{ config['name'] }}/music/{{ tape["identifier"] }}.ogg" />{% endfor %} <None file="Mods/{{ config['name'] }}/boombox_icon.png" />{% for tape in tapes %}
<None file="Mods/{{ config['name'] }}/music/{{ tape["identifier"] }}.ogg" />
<None file="Mods/{{ config['name'] }}/music/{{ tape["identifier"] }}-walkman.ogg" />{% endfor %}
<None file="Mods/{{ config['name'] }}/sound_effects/boombox_insert_cassette.ogg" /> <None file="Mods/{{ config['name'] }}/sound_effects/boombox_insert_cassette.ogg" />
<None file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" /> <None file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" />
<None file="Mods/{{ config['name'] }}/sound_effects/cassette_drop.ogg" /> <None file="Mods/{{ config['name'] }}/sound_effects/cassette_drop.ogg" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

View File

@ -198,7 +198,7 @@
</TitleText> </TitleText>
{% for tape in tapes %} {% for tape in tapes %}
<{{ config['slug'] }}_cover_{{ tape.identifier }} color="255,255,255,255" textcolor="0,0,0,255"> <{{ config['slug'] }}_cover_{{ tape.identifier }} color="255,255,255,255" textcolor="0,0,0,255">
<Sprite name="{{ config['slug'] }}_cover_{{ tape.identifier }}" texture="Mods/{{ config['name'] }}/covers.png" size="0.0, 0.0" sourcerect="0,{{ loop.index0*328 }},512,328" origin="0.5,0.5" compress="false" tile="false"/> <Sprite name="{{ config['slug'] }}_cover_{{ tape.identifier }}" texture="Mods/{{ config['name'] }}/covers.png" size="0.0, 0.0" sourcerect="{{ 512 * positions[loop.index0]['column'] }},{{ 328 * positions[loop.index0]['row'] }},512,328" origin="0.5,0.5" compress="false" tile="false"/>
</{{ config['slug'] }}_cover_{{ tape.identifier }}>{% endfor %} </{{ config['slug'] }}_cover_{{ tape.identifier }}>{% endfor %}
<ita_document1 color="255,255,255,255" textcolor="0,0,0,255"> <ita_document1 color="255,255,255,255" textcolor="0,0,0,255">

View File

@ -200,7 +200,7 @@
</TitleText> </TitleText>
{% for tape in tapes %} {% for tape in tapes %}
<{{ config['slug'] }}_cover_{{ tape.identifier }} color="255,255,255,255" textcolor="0,0,0,255"> <{{ config['slug'] }}_cover_{{ tape.identifier }} color="255,255,255,255" textcolor="0,0,0,255">
<Sprite name="{{ config['slug'] }}_cover_{{ tape.identifier }}" texture="Mods/{{ config['name'] }}/covers.png" size="0.0, 0.0" sourcerect="0,{{ loop.index0*328 }},512,328" origin="0.5,0.5" compress="false" tile="false"/> <Sprite name="{{ config['slug'] }}_cover_{{ tape.identifier }}" texture="Mods/{{ config['name'] }}/covers.png" size="0.0, 0.0" sourcerect="{{ 512 * positions[loop.index0]['column'] }},{{ 328 * positions[loop.index0]['row'] }},512,328" origin="0.5,0.5" compress="false" tile="false"/>
</{{ config['slug'] }}_cover_{{ tape.identifier }}>{% endfor %} </{{ config['slug'] }}_cover_{{ tape.identifier }}>{% endfor %}
<InnerGlow color="255,255,255,204" hovercolor="255,255,255,204" selectedcolor="255,255,255,204"> <InnerGlow color="255,255,255,204" hovercolor="255,255,255,204" selectedcolor="255,255,255,204">
<Sprite texture="Content/UI/InnerGlow.png" sourcerect="0,0,512,384" slice="128,128,384,256" /> <Sprite texture="Content/UI/InnerGlow.png" sourcerect="0,0,512,384" slice="128,128,384,256" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
{% if config['slug'] != "sunken_tapes" %}<!--This mod is based on Sunken Tapes. See https://git.kompot.si/jaka/barotrauma-sunken-tapes and https://steamcommunity.com/sharedfiles/filedetails/?id=2616577901 for the source material and code generator.-->{% else %}<!--Code licensed under GPLv3 and generated with a script available at https://git.kompot.si/jaka/barotrauma-sunken-tapes-->{% endif %} {% if config['slug'] != "sunken_tapes" %}<!--This mod is based on Sunken Tapes. See https://git.kompot.si/jaka/barotrauma-sunken-tapes and https://steamcommunity.com/sharedfiles/filedetails/?id=2616577901 for the source material and code generator.-->{% else %}<!--Code licensed under GPLv3 and generated with a script available at https://git.kompot.si/jaka/barotrauma-sunken-tapes-->{% endif %}
<Items> <Items>
<Item name="Boombox" cargocontaineridentifier="metalcrate" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}boombox" category="Equipment" Tags="mediumitem,boombox" scale="0.5" description="" price="850" impactsoundtag="impact_metal_light" isshootable="true"> <Item name="Boombox" cargocontaineridentifier="metalcrate" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}boombox" category="Equipment" Tags="mediumitem,boombox,sunken-tapes-player" scale="0.5" description="" price="850" impactsoundtag="impact_metal_light" isshootable="true" HideConditionBar="true">
<PreferredContainer primary="abandonedcrewcab" spawnprobability="0.1"/> <PreferredContainer primary="abandonedcrewcab" spawnprobability="0.1"/>
<PreferredContainer primary="outpostcrewcabinet" spawnprobability="0.1"/> <PreferredContainer primary="outpostcrewcabinet" spawnprobability="0.1"/>
<Price baseprice="500" soldeverywhere="false"> <Price baseprice="500" soldeverywhere="false">
@ -11,52 +11,44 @@
<Price locationtype="military" multiplier="1.5" sold="false"/> <Price locationtype="military" multiplier="1.5" sold="false"/>
<Price locationtype="mine" multiplier="1.5" sold="false"/> <Price locationtype="mine" multiplier="1.5" sold="false"/>
</Price> </Price>
<Deconstruct time="20">
<Item identifier="aluminium" />
<Item identifier="copper" />
</Deconstruct>
<Fabricate suitablefabricators="fabricator" requiredtime="45">
<RequiredSkill identifier="mechanical" level="45" />
<RequiredSkill identifier="electrical" level="55" />
<RequiredItem identifier="aluminium" />
<RequiredItem identifier="copper" />
<RequiredItem identifier="plastic" />
<RequiredItem identifier="fpgacircuit" />
</Fabricate>
<Upgrade gameversion="0.9.2.0" scale="0.5" /> <Upgrade gameversion="0.9.2.0" scale="0.5" />
<InventoryIcon texture="Mods/{{ config['name'] }}/icons.png" sourcerect="0,0,64,64" origin="0.5,0.5" /> <InventoryIcon texture="Mods/{{ config['name'] }}/boombox_icon.png" sourcerect="0,0,64,64" origin="0.5,0.5" />
<Sprite texture="Mods/{{ config['name'] }}/boombox.png" sourcerect="0,0,100,60" depth="0.55" origin="0.5,0.5" /> <Sprite texture="Mods/{{ config['name'] }}/boombox.png" sourcerect="0,0,100,60" depth="0.55" origin="0.5,0.5" />
<Body width="100" height="60" /> <Body width="100" height="60" />
<LightComponent LightColor="0.78,0.04,0.235,0.59" range="10" powerconsumption="0" blinkfrequency="1" IsOn="false" canbeselected="false"> <LightComponent LightColor="0.0,0.85,0.0,0.7" range="4" powerconsumption="0" blinkfrequency="0" IsOn="false" canbeselected="false">
</LightComponent> </LightComponent>
<CustomInterface canbeselected="true" drawhudwhenequipped="true" allowuioverlap="true"> <CustomInterface canbeselected="true" drawhudwhenequipped="true" allowuioverlap="true">
<GuiFrame relativesize="0.10,0.07" anchor="CenterLeft" pivot="BottomLeft" relativeoffset="0.006,-0.05" style="ItemUI" /> <GuiFrame relativesize="0.10,0.07" anchor="CenterLeft" pivot="BottomLeft" relativeoffset="0.006,-0.05" style="ItemUI" />
<TickBox text="Play"> <TickBox text="Play">
<StatusEffect type="OnUse" targettype="This" IsOn="true"> <StatusEffect type="OnUse" targettype="This" IsOn="true">
<Conditional IsOn="false" /> <Conditional IsOn="false" />
<sound file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" type="OnUse" range="500" volume="1.0" /> <sound file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" type="OnUse" range="300" volume="1.0" />
</StatusEffect> </StatusEffect>
<!--StatusEffect type="OnUse" targettype="Contained" comparison="And">
<Conditional condition="lte 50.0" />
<Conditional condition="gt 25.0" />
<RequiredItem items="cassette" type="Contained" />
<sound file="Content/Sounds/FireSmall.ogg" type="OnUse" range="1000" loop="true" volume="1.0" />
</StatusEffect>
<StatusEffect type="OnUse" targettype="Contained" comparison="And">
<Conditional condition="lte 25.0" />
<Conditional condition="gt 10.0" />
<RequiredItem items="cassette" type="Contained" />
<sound file="Content/Sounds/FireSmall.ogg" type="OnUse" range="1000" loop="true" volume="1.0" />
</StatusEffect>
<StatusEffect type="OnUse" targettype="Contained">
<Conditional condition="lte 10.0" />
<RequiredItem items="cassette" type="Contained" />
<sound file="Content/Sounds/FireSmall.ogg" type="OnUse" range="1000" loop="true" volume="1.0" />
</StatusEffect-->
{% for tape in tapes %}
<StatusEffect type="OnUse" targettype="Contained" condition="-{{ condition_delta[loop.index0] }}">
<RequiredItem items="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-{{ tape.identifier }}" type="Contained" />
<SpawnItem identifiers="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}song-{{ tape.identifier }}" spawnposition="ContainedInventory" />
</StatusEffect>{% endfor %}
<StatusEffect type="OnSecondaryUse" targettype="This" IsOn="false" > <StatusEffect type="OnSecondaryUse" targettype="This" IsOn="false" >
<Conditional IsOn="true" /> <Conditional IsOn="true" />
<sound file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" type="OnUse" range="500" volume="1.0" /> <sound file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" type="OnUse" range="300" volume="1.0" />
<Use /> <Use />
</StatusEffect> </StatusEffect>
</TickBox> </TickBox>
</CustomInterface> </CustomInterface>
<Holdable slots="RightHand,LeftHand" selectkey="Use" pickkey="Select" attachable="false" aimable="false" holdpos="5,-65" holdangle="0" aimpos="5,30" handle1="0,30" handle2="0,30" swingamount="20,5" swingspeed="0.5" swingwhenusing="true" msg="ItemMsgPickUpUse"> <Holdable slots="RightHand,LeftHand" aimable="false" holdpos="5,-65" holdangle="0" aimpos="5,30" handle1="0,30" handle2="0,30" swingamount="25,7" swingspeed="0.5" swingwhenusing="true" msg="ItemMsgPickupSelect">
<StatusEffect type="OnBroken" target="This">
<Remove />
</StatusEffect>
</Holdable> </Holdable>
<ItemContainer hideitems="true" drawinventory="true" capacity="1" maxstacksize="1" slotsperrow="6" itempos="0,0" iteminterval="0,0" itemrotation="0" canbeselected="false" containedspritedepth="0.79"> <ItemContainer hideitems="true" drawinventory="true" capacity="1" maxstacksize="1" slotsperrow="6" itempos="0,0" iteminterval="0,0" itemrotation="0" canbeselected="false" containedspritedepth="0.79" >
<StatusEffect type="OnUse" targettype="Contained" > <StatusEffect type="OnUse" targettype="Contained" >
<Use /> <Use />
</StatusEffect> </StatusEffect>
@ -65,69 +57,107 @@
</ItemContainer> </ItemContainer>
</Item> </Item>
<!-- tape box --> <Item name="Walkman" cargocontaineridentifier="metalcrate" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}walkman" category="Equipment" Tags="smallitem,walkman,sunken-tapes-player" scale="0.5" description="" price="450" impactsoundtag="impact_metal_light" isshootable="true" HideConditionBar="true">
<PreferredContainer primary="abandonedcrewcab" spawnprobability="0.1"/>
<Item name="Cassette Tape Box" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-tape-box" category="Equipment" tags="smallitem,mobilecontainer,tool" cargocontaineridentifier="" showcontentsintooltip="true" Scale="0.5" fireproof="true" description="" impactsoundtag="impact_metal_heavy"> <PreferredContainer primary="outpostcrewcabinet" spawnprobability="0.1"/>
<PreferredContainer secondary="wreckstoragecab" spawnprobability="0.06"/> <Price baseprice="450" soldeverywhere="false">
<PreferredContainer primary="outpostcrewcabinet" minamount="0" maxamount="1" spawnprobability="0.2"/>
<Deconstruct time="10">
<Item identifier="steel" />
</Deconstruct>
<Fabricate suitablefabricators="fabricator" requiredtime="20">
<RequiredSkill identifier="mechanical" level="20" />
<Item identifier="steel" />
</Fabricate>
<Price baseprice="75" >
<Price locationtype="outpost" multiplier="1" minavailable="1" /> <Price locationtype="outpost" multiplier="1" minavailable="1" />
<Price locationtype="city" multiplier="0.9" minavailable="1" /> <Price locationtype="city" multiplier="0.7" minavailable="1"/>
<Price locationtype="research" multiplier="1.25" minavailable="1" /> <Price locationtype="research" multiplier="1.5" sold="false"/>
<Price locationtype="military" multiplier="1.25" minavailable="1" /> <Price locationtype="military" multiplier="1.5" sold="false"/>
<Price locationtype="mine" multiplier="1.25" minavailable="1" /> <Price locationtype="mine" multiplier="1.5" sold="false"/>
</Price> </Price>
<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="640,256,64,64" origin="0.5,0.6" /> <Deconstruct time="20">
<Sprite texture="Content/Items/Tools/tools.png" sourcerect="314,1,94,74" origin="0.5,0.5" /> </Deconstruct>
<Body width="90" height="60" density="20" /> <Fabricate suitablefabricators="fabricator" requiredtime="45">
<MeleeWeapon slots="RightHand,LeftHand,Any" controlpose="true" aimpos="45,10" handle1="0,10" handle2="0,10" holdangle="90" reload="1" range="50" combatpriority="6" msg="ItemMsgPickUpSelect"> <RequiredSkill identifier="mechanical" level="45" />
<Attack structuredamage="10" itemdamage="5" stun="0.6" targetimpulse="2"> <RequiredSkill identifier="electrical" level="55" />
<Affliction identifier="blunttrauma" strength="2" /> <RequiredItem identifier="aluminium" />
<Sound file="Content/Items/Weapons/Smack2.ogg" range="800" /> <RequiredItem identifier="copper" />
</Attack> <RequiredItem identifier="plastic" />
</MeleeWeapon> <RequiredItem identifier="fpgacircuit" />
<ItemContainer capacity="24" keepopenwhenequipped="true" movableframe="true"> </Fabricate>
<Containable items="cassette" /> <Upgrade gameversion="0.9.2.0" scale="0.5" />
<InventoryIcon texture="Mods/{{ config['name'] }}/boombox_icon.png" sourcerect="0,0,64,64" origin="0.5,0.5" />
<Sprite texture="Mods/{{ config['name'] }}/boombox.png" sourcerect="0,0,100,60" depth="0.55" origin="0.5,0.5" />
<Body width="100" height="60" />
<LightComponent LightColor="0.0,0.85,0.0,0.7" range="4" powerconsumption="0" blinkfrequency="0" IsOn="false" canbeselected="false">
</LightComponent>
<CustomInterface canbeselected="true" drawhudwhenequipped="true" allowuioverlap="true">
<GuiFrame relativesize="0.10,0.07" anchor="CenterLeft" pivot="BottomLeft" relativeoffset="0.006,-0.05" style="ItemUI" />
<TickBox text="Play">
<StatusEffect type="OnUse" targettype="This" IsOn="true">
<Conditional IsOn="false" />
<sound file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" type="OnUse" range="300" volume="1.0" />
</StatusEffect>
<StatusEffect type="OnSecondaryUse" targettype="This" IsOn="false" >
<Conditional IsOn="true" />
<sound file="Mods/{{ config['name'] }}/sound_effects/boombox_play_cassette.ogg" type="OnUse" range="300" volume="1.0" />
<Use />
</StatusEffect>
</TickBox>
</CustomInterface>
<Holdable slots="RightHand,LeftHand,Any" holdpos="5,-65" holdangle="0" aimpos="5,-65" handle1="0,30" handle2="0,30" swingamount="25,8" swingspeed="0.5" swingwhenusing="true" msg="ItemMsgPickupSelect">
<StatusEffect type="OnBroken" target="This">
<Remove />
</StatusEffect>
</Holdable>
<ItemContainer hideitems="true" drawinventory="true" capacity="1" maxstacksize="1" slotsperrow="6" itempos="0,0" iteminterval="0,0" itemrotation="0" canbeselected="false" containedspritedepth="0.79" >
<StatusEffect type="OnUse" targettype="Contained" >
<Use />
</StatusEffect>
<Containable items="cassette">
</Containable>
</ItemContainer> </ItemContainer>
<aitarget sightrange="1000" soundrange="1000" fadeouttime="2" />
<Upgrade gameversion="0.10.0.0" scale="0.5" />
</Item> </Item>
<!-- Cassette Tapes --> <!-- Cassette Tapes -->
{% for tape in tapes %} {% for tape in tapes %}
<Item name="Tape: {{ tape.name }}" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-{{ tape.identifier }}" category="Equipment" maxstacksize="8" Tags="smallitem,cassette" cargocontaineridentifier="metalcrate" scale="0.5" isshootable="true" impacttolerance="1.3"> <Item name="Tape: {{ tape.name }}" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-{{ tape.identifier }}" category="Equipment" maxstacksize="8" Tags="smallitem,cassette" cargocontaineridentifier="metalcrate" scale="0.5" isshootable="true" impacttolerance="1.3" >
<PreferredContainer primary="abandonedcrewcab" spawnprobability="0.05"/> <PreferredContainer primary="abandonedcrewcab" spawnprobability="0.05"/>
<PreferredContainer primary="outpostcrewcabinet" minamount="0" maxamount="1" spawnprobability="0.05"/> <PreferredContainer primary="outpostcrewcabinet" minamount="0" maxamount="1" spawnprobability="0.05"/>
<Price baseprice="{{ tape.price }}" soldeverywhere="false">{% for location in ["outpost", "city", "research", "military", "mine"] %} <Price baseprice="{{ tape.price }}" soldeverywhere="false">{% for location in ["outpost", "city", "research", "military", "mine"] %}
<Price locationtype="{{ location }}" multiplier="{{ tape.multipliers[loop.index0] }}" sold="{{ tape.sold[loop.index0] }}" minavailable="1" />{% endfor %} <Price locationtype="{{ location }}" multiplier="{{ tape.multipliers[loop.index0] }}" sold="{{ tape.sold[loop.index0] }}" minavailable="1" />{% endfor %}
</Price> </Price>
<InventoryIcon texture="Mods/{{ config['name'] }}/icons.png" sourcerect="0,{{ loop.index0*41 + 64 }},64,41" origin="0.5,0.5" /> <Deconstruct time="10">
<Sprite texture="Mods/{{ config['name'] }}/icons.png" sourcerect="0,{{ loop.index0*41 + 64 }},64,41" depth="0.6" origin="0.5,0.5" /> </Deconstruct>
<Fabricate suitablefabricators="fabricator" displayname="recycleitem" requiredtime="{{ song_lengths[loop.index0]*0.5 }}">
<RequiredSkill identifier="mechanical" level="25" />
<RequiredSkill identifier="electrical" level="45" />
<RequiredItem identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-{{ tape.identifier }}" mincondition="0.25" usecondition="true"/>
<RequiredItem identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-blank" />
<RequiredItem identifier="fpgacircuit" />
</Fabricate>
<InventoryIcon texture="Mods/{{ config['name'] }}/icons.png" sourcerect="{{ 64 * positions[loop.index0]['column'] }},{{ 41 * positions[loop.index0]['row'] }},64,41" origin="0.5,0.5" />
<Sprite texture="Mods/{{ config['name'] }}/icons.png" sourcerect="{{ 64 * positions[loop.index0]['column'] }},{{ 41 * positions[loop.index0]['row'] }},64,41" depth="0.6" origin="0.5,0.5" />
<Body width="48" height="48" /> <Body width="48" height="48" />
<Throwable slots="Any,RightHand,LeftHand" holdpos="0,0" handle1="0,0" throwforce="4.0" aimpos="35,-10" msg="ItemMsgPickUpSelect"> <Throwable slots="Any,RightHand,LeftHand" holdpos="5,-65" holdangle="0" handle1="0,1" throwforce="4.0" aimpos="35,-10" msg="Aim to throw">
<StatusEffect type="OnImpact" target="This" Condition="-5.0" disabledeltatime="true"> <StatusEffect type="OnImpact" target="This" Condition="-5.0" disabledeltatime="true">
<sound file="Mods/{{ config['name'] }}/sound_effects/cassette_drop.ogg" range="500" volume="1.0" /> <sound file="Mods/{{ config['name'] }}/sound_effects/cassette_drop.ogg" range="500" volume="1.0" />
</StatusEffect> </StatusEffect>
</Throwable> </Throwable>
<CustomInterface canbeselected="false" drawhudwhenequipped="true" allowuioverlap="true"> <CustomInterface canbeselected="true" drawhudwhenequipped="true" allowuioverlap="true" msg="Equip to inspect">
<GuiFrame relativesize="{{ 512.0 / config['resolution_x'] }},{{ 328.0 / config['resolution_y'] }}" anchor="CenterRight" pivot="CenterRight" style="{{ config['slug'] }}_cover_{{ tape.identifier }}" /> <GuiFrame relativesize="{{ 512.0 / config['resolution_x'] }},{{ 328.0 / config['resolution_y'] }}" anchor="CenterRight" pivot="CenterRight" style="{{ config['slug'] }}_cover_{{ tape.identifier }}" />
</CustomInterface> </CustomInterface>
<ItemContainer hideitems="true" capacity="1" drawinventory="false" canbeselected="false" canbecombined="true" removecontaineditemsondeconstruct="true"> <ItemContainer hideitems="true" capacity="1" drawinventory="false" canbeselected="false" canbecombined="true" removecontaineditemsondeconstruct="true" showcontainedstateindicator="false">
<StatusEffect type="OnNotContained" targettype="Contained"> <StatusEffect type="OnNotContained" targettype="Contained">
<Use /> <Use />
</StatusEffect> </StatusEffect>
<StatusEffect type="OnContained" targettype="This"> <StatusEffect type="OnContained" targettype="This">
<Conditional hastag="!eq boombox" targetcontainer="true" /> <Conditional hastag="!eq sunken-tapes-player" targetcontainer="true" />
<Use /> <Use />
</StatusEffect> </StatusEffect>
<StatusEffect type="OnContained" targettype="This" comparison="And">
<Conditional hastag="boombox" targetcontainer="true" />
<Conditional IsOn="true" targetcontainer="true" />
<SpawnItem identifiers="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}song-{{ tape.identifier }}" spawnposition="ThisInventory" />
</StatusEffect>
<StatusEffect type="OnContained" targettype="This" comparison="And">
<Conditional hastag="walkman" targetcontainer="true" />
<Conditional IsOn="true" targetcontainer="true" />
<SpawnItem identifiers="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}song-walkman-{{ tape.identifier }}" spawnposition="ThisInventory" />
</StatusEffect>
<StatusEffect type="OnUse" targettype="Contained"> <StatusEffect type="OnUse" targettype="Contained">
<Use /> <Use />
</StatusEffect> </StatusEffect>
@ -165,6 +195,62 @@
</ItemComponent> </ItemComponent>
</Item> </Item>
<Item name="Song (Walkman): {{ tape.name }}" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}song-walkman-{{ tape.identifier }}" Tags="song" category="Misc">
<Sprite texture="Content/Items/Electricity/signalcomp.png" depth="0.8" sourcerect="0,160,4,4" origin="0.5,0.5" />
<Body width="48" height="48" />
<InventoryIcon texture="Content/Items/Electricity/signalcomp.png" sourcerect="0,160,4,4" origin="0.5,0.5" />
<ItemComponent>
<StatusEffect type="Always" target="This">
<sound file="Mods/{{ config['name'] }}/music/{{ tape.identifier }}-walkman.ogg" type="OnUse" range="200" loop="true" volume="1.0" />
</StatusEffect>{% if tape.buffs %}
<StatusEffect type="Always" target="NearbyCharacters" range="200">{% for buff in tape.buffs %}
{% if buff == "psychosis" %}<Affliction identifier="{{ buff }}" strength= "{{ '%0.4f' % (tape.buff_multiplier*(delta + 0.1)*0.5) }}" />{% else %}<Affliction identifier="{{ buff }}" strength= "{{ '%0.4f' % (tape.buff_multiplier*(delta*4 + 1)*0.5) }}" />{% endif %}{% endfor %}
</StatusEffect>{% endif %}
<StatusEffect type="OnNotContained" targettype="This">
<Remove />
</StatusEffect>
<StatusEffect type="OnUse" targettype="This">
<Remove />
</StatusEffect>
</ItemComponent>
</Item>
{% endfor %} {% endfor %}
<!-- tape box -->
<Item name="Cassette Tape Box" identifier="{% if config['slug'] != "sunken_tapes" %}{{ config["slug"] }}-{% endif %}cassette-tape-box" category="Equipment" tags="smallitem,mobilecontainer,tool" cargocontaineridentifier="" showcontentsintooltip="true" Scale="0.5" fireproof="true" description="" impactsoundtag="impact_metal_heavy">
<PreferredContainer secondary="wreckstoragecab" spawnprobability="0.06"/>
<PreferredContainer primary="outpostcrewcabinet" minamount="0" maxamount="1" spawnprobability="0.2"/>
<Deconstruct time="10">
<Item identifier="steel" />
</Deconstruct>
<Fabricate suitablefabricators="fabricator" requiredtime="20">
<RequiredSkill identifier="mechanical" level="20" />
<Item identifier="steel" />
</Fabricate>
<Price baseprice="75" >
<Price locationtype="outpost" multiplier="1" minavailable="1" />
<Price locationtype="city" multiplier="0.9" minavailable="1" />
<Price locationtype="research" multiplier="1.25" minavailable="1" />
<Price locationtype="military" multiplier="1.25" minavailable="1" />
<Price locationtype="mine" multiplier="1.25" minavailable="1" />
</Price>
<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="640,256,64,64" origin="0.5,0.6" />
<Sprite texture="Content/Items/Tools/tools.png" sourcerect="314,1,94,74" origin="0.5,0.5" />
<Body width="90" height="60" density="20" />
<MeleeWeapon slots="RightHand,LeftHand,Any" controlpose="true" aimpos="45,10" handle1="0,10" handle2="0,10" holdangle="90" reload="1" range="50" combatpriority="6" msg="ItemMsgPickUpSelect">
<Attack structuredamage="10" itemdamage="5" stun="0.6" targetimpulse="2">
<Affliction identifier="blunttrauma" strength="2" />
<Sound file="Content/Items/Weapons/Smack2.ogg" range="800" />
</Attack>
</MeleeWeapon>
<ItemContainer capacity="24" keepopenwhenequipped="true" movableframe="true">
<Containable items="cassette" />
</ItemContainer>
<aitarget sightrange="1000" soundrange="1000" fadeouttime="2" />
<Upgrade gameversion="0.10.0.0" scale="0.5" />
</Item>
</Items> </Items>

View File

@ -1,3 +1,17 @@
- identifier: blank
name: Blank Tape
source: ./source/original_audio/blank.ogg
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
price: 100
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, false, false, false] # outpost, city, research, military, mine
no_of_uses: 12
buffs: False
buff_multiplier: 0.5
- identifier: dmx - identifier: dmx
name: DMX - X Gon Give It To Ya name: DMX - X Gon Give It To Ya
source: source:
@ -15,8 +29,7 @@
no_of_uses: 6 no_of_uses: 6
buffs: buffs:
- strengthen - strengthen
- haste buff_multiplier: 0.5
buff_multiplier: 0.75
- identifier: dmxcut - identifier: dmxcut
name: DMX Carnage Cut name: DMX Carnage Cut
@ -35,9 +48,46 @@
no_of_uses: 6 no_of_uses: 6
buffs: buffs:
- strengthen - strengthen
- haste
buff_multiplier: 1.0 buff_multiplier: 1.0
- identifier: blade
name: Vampire Dance Club
source:
url: https://www.youtube.com/watch?v=cNOP2t9FObw
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.04
price: 500
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, false, false, false, false] # outpost, city, research, military, mine
no_of_uses: 5
buffs:
- strengthen
buff_multiplier: 0.5
- identifier: atarispeed
name: Atari Teenage Riot - SPEED
source:
url: https://www.youtube.com/watch?v=plAr3adKbyc
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
price: 650
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, false, false, true, false] # outpost, city, research, military, mine
no_of_uses: 6
buffs:
- haste
buff_multiplier: 0.7
- identifier: ddt - identifier: ddt
name: Dragostea Din Tei name: Dragostea Din Tei
source: source:
@ -176,6 +226,46 @@
buffs: False buffs: False
buff_multiplier: 0.5 buff_multiplier: 0.5
- identifier: vjeranpas
name: Termiti - Vjeran pas
source:
url: https://www.youtube.com/watch?v=EOAiYRxLpq0
start: 00:00:00
end: -1
volume: 3
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
- location: outpostcrewcabinet
probability: 0.01
price: 450
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [true, true, false, false, false] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: put
name: Morbidi I Mnoći - Put
source:
url: https://www.youtube.com/watch?v=18Ku0EaiS88
start: 00:00:00
end: 00:04:18
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
- location: outpostcrewcabinet
probability: 0.01
price: 450
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, false, false, true] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: shanty1 - identifier: shanty1
name: Doodle Let Me Go name: Doodle Let Me Go
source: source:
@ -216,13 +306,73 @@
buffs: False buffs: False
buff_multiplier: 0.5 buff_multiplier: 0.5
- identifier: shanty3
name: Roll the Old Chariot
source:
url: https://www.youtube.com/watch?v=-CuyLbC2TZo
start: 00:00:00
end: 00:02:33
volume: 6
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
- location: outpostcrewcabinet
probability: 0.05
price: 500
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [true, false, false, false, true] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: shanty4
name: Weigh, Hey and up She Rises
source:
url: https://www.youtube.com/watch?v=1YSltK-10zk
start: 00:00:00
end: -1
volume: 6
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
- location: outpostcrewcabinet
probability: 0.05
price: 500
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, false, false, true, true] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: shanty5
name: Roll Northumbria
source:
url: https://www.youtube.com/watch?v=-d3XHQVMHDM
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
- location: outpostcrewcabinet
probability: 0.05
price: 500
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, false, true, false] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: rum - identifier: rum
name: 15 Men and a Bottle of Rum name: 15 Men and a Bottle of Rum
source: source:
url: https://www.youtube.com/watch?v=nzcv5TJkJBA url: https://www.youtube.com/watch?v=nzcv5TJkJBA
start: 00:00:00 start: 00:00:00
end: -1 end: -1
volume: 0 volume: 6
note: "" note: ""
spawn: spawn:
- location: abandonedcrewcab - location: abandonedcrewcab
@ -276,6 +426,26 @@
buffs: False buffs: False
buff_multiplier: 0.5 buff_multiplier: 0.5
- identifier: deadmeadow
name: Dead Meadow - Me and the Devil Blues
source:
url: https://www.youtube.com/watch?v=HejsUs-IND8
start: 00:00:00
end: -1
volume: 6
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.02
- location: outpostcrewcabinet
probability: 0.01
price: 550
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, false, false, false] # outpost, city, research, military, mine
no_of_uses: 4
buffs: False
buff_multiplier: 0.5
- identifier: hardbass - identifier: hardbass
name: Hardbass name: Hardbass
source: source:
@ -512,3 +682,120 @@
buffs: buffs:
- psychosis - psychosis
buff_multiplier: 0.25 buff_multiplier: 0.25
- identifier: devilinthedetails
name: Boards of Canada - The Devil Is in the Details
source:
url: https://www.youtube.com/watch?v=wxPLzms6Coc
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
price: 350
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, false, false, true, false] # outpost, city, research, military, mine
no_of_uses: 1
buffs:
- psychosis
buff_multiplier: 0.25
- identifier: alphabrain
name: L.O.T.I.O.N. Multinational Corporation - Alphabrain
source:
url: https://www.youtube.com/watch?v=P6js2T8EB0c
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.05
- location: outpostcrewcabinet
probability: 0.01
price: 300
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, false, true, false] # outpost, city, research, military, mine
no_of_uses: 4
buffs: False
buff_multiplier: 0.5
- identifier: underwaterlove
name: Smoke City - Underwater Love
source:
url: https://www.youtube.com/watch?v=HuLjsW8XhY4
start: 00:00:00
end: 00:06:46
volume: 0
note: ""
spawn:
- location: outpostcrewcabinet
probability: 0.02
price: 250
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, true, false, false] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: theroom
name: The Room
source:
url: https://www.youtube.com/watch?v=NZfox7y8VAg
start: 00:00:00
end: -1
volume: 12
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.03
- location: outpostcrewcabinet
probability: 0.01
price: 250
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, false, false, false] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: theshadowsareyou
name: Kiss The Anus Of A Black Cat - The Shadows Are You
source:
url: https://www.youtube.com/watch?v=Dn2hOxuLY8M
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.04
- location: outpostcrewcabinet
probability: 0.01
price: 500
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [true, false, true, false, true] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5
- identifier: balans
name: Balans - Sam Naprej
source:
url: https://www.youtube.com/watch?v=JqqXdF6DP6U
start: 00:00:00
end: -1
volume: 0
note: ""
spawn:
- location: abandonedcrewcab
probability: 0.04
- location: outpostcrewcabinet
probability: 0.01
price: 650
multipliers: [1, 1, 1, 1, 1] # outpost, city, research, military, mine
sold: [false, true, true, false, false] # outpost, city, research, military, mine
no_of_uses: 6
buffs: False
buff_multiplier: 0.5