diff --git a/assets_src/m02_outpost.png b/assets_src/m02_outpost.png new file mode 100644 index 0000000..09a22cd Binary files /dev/null and b/assets_src/m02_outpost.png differ diff --git a/assets_src/map_m02.png b/assets_src/map_m02.png new file mode 100644 index 0000000..6387901 Binary files /dev/null and b/assets_src/map_m02.png differ diff --git a/assets_src/renders/lacquer.png b/assets_src/renders/lacquer.png new file mode 100644 index 0000000..a97627e Binary files /dev/null and b/assets_src/renders/lacquer.png differ diff --git a/assets_src/renders/lacquer_raw.png b/assets_src/renders/lacquer_raw.png new file mode 100644 index 0000000..e3cbc6d Binary files /dev/null and b/assets_src/renders/lacquer_raw.png differ diff --git a/mods/vinylgod/fluent/lua.ftl b/mods/vinylgod/fluent/lua.ftl index 55344e7..60a79d1 100644 --- a/mods/vinylgod/fluent/lua.ftl +++ b/mods/vinylgod/fluent/lua.ftl @@ -5,3 +5,7 @@ objective-failed = Objective failed press-first-records = Build a Pressing Plant and bank 2000 records survive-the-probe = Survive the Stream's survey probe keep-the-van-alive = Do not lose the Pop-Up Shop + +destroy-the-transcoder = Destroy the Transcoder before the master is cut +keep-the-selector-alive = The Selector must survive +wipe-the-outpost = Level the whole outpost diff --git a/mods/vinylgod/fluent/rules.ftl b/mods/vinylgod/fluent/rules.ftl index 11ba81a..0c61a6f 100644 --- a/mods/vinylgod/fluent/rules.ftl +++ b/mods/vinylgod/fluent/rules.ftl @@ -107,3 +107,5 @@ actor-droneport = .name = Drone Port actor-waxseed = .name = Wax Seep +actor-lacquer = + .name = Master Lacquer diff --git a/mods/vinylgod/maps/arena/map.bin b/mods/vinylgod/maps/arena/map.bin index 0632ba7..1c997a0 100644 Binary files a/mods/vinylgod/maps/arena/map.bin and b/mods/vinylgod/maps/arena/map.bin differ diff --git a/mods/vinylgod/maps/compression/map.bin b/mods/vinylgod/maps/compression/map.bin index 203e898..b84601b 100644 Binary files a/mods/vinylgod/maps/compression/map.bin and b/mods/vinylgod/maps/compression/map.bin differ diff --git a/mods/vinylgod/maps/district/map.bin b/mods/vinylgod/maps/district/map.bin index cff1a24..466d053 100644 Binary files a/mods/vinylgod/maps/district/map.bin and b/mods/vinylgod/maps/district/map.bin differ diff --git a/mods/vinylgod/maps/m01/map.bin b/mods/vinylgod/maps/m01/map.bin index c75996c..53d1c78 100644 Binary files a/mods/vinylgod/maps/m01/map.bin and b/mods/vinylgod/maps/m01/map.bin differ diff --git a/mods/vinylgod/maps/m02/m02.lua b/mods/vinylgod/maps/m02/m02.lua new file mode 100644 index 0000000..d3eac99 --- /dev/null +++ b/mods/vinylgod/maps/m02/m02.lua @@ -0,0 +1,57 @@ +-- 02: CRATE DIGGERS — timed raid, no base building. + +TIME_LIMIT = DateTime.Minutes(6) +Deadline = nil + +WorldLoaded = function() + Mrp = Player.GetPlayer("Player") + Stream = Player.GetPlayer("Enemy") + InitObjectives(Mrp) + + KillTranscoder = Mrp.AddPrimaryObjective("destroy-the-transcoder") + KeepSelector = Mrp.AddPrimaryObjective("keep-the-selector-alive") + WipeOutpost = Mrp.AddSecondaryObjective("wipe-the-outpost") + + Deadline = DateTime.GameTime + TIME_LIMIT + + Trigger.OnKilled(Transcoder, function() + if not Mrp.IsObjectiveCompleted(KillTranscoder) then + Mrp.MarkCompletedObjective(KillTranscoder) + Mrp.MarkCompletedObjective(KeepSelector) + UserInterface.SetMissionText("") + end + end) + + Trigger.OnKilled(TheSelector, function() + Mrp.MarkFailedObjective(KeepSelector) + end) + + local outpost = { Transcoder, outpost1, outpost2, turret1, turret2 } + Trigger.OnAllKilled(outpost, function() + Mrp.MarkCompletedObjective(WipeOutpost) + end) + + -- the deadline: the master gets cut and the raid was for nothing + Trigger.AfterDelay(TIME_LIMIT, function() + if not Mrp.IsObjectiveCompleted(KillTranscoder) then + if not MasterLacquer.IsDead then + MasterLacquer.Kill() + end + Media.PlaySpeechNotification(Mrp, "Lose") + Mrp.MarkFailedObjective(KillTranscoder) + end + end) +end + +Tick = function() + if Deadline ~= nil and not Mrp.IsObjectiveCompleted(KillTranscoder) + and not Mrp.IsObjectiveFailed(KillTranscoder) then + local left = Deadline - DateTime.GameTime + if left < 0 then + left = 0 + end + if left % 25 == 0 then + UserInterface.SetMissionText("Master cut in " .. Utils.FormatTime(left)) + end + end +end diff --git a/mods/vinylgod/maps/m02/map.bin b/mods/vinylgod/maps/m02/map.bin new file mode 100644 index 0000000..2179b66 Binary files /dev/null and b/mods/vinylgod/maps/m02/map.bin differ diff --git a/mods/vinylgod/maps/m02/map.png b/mods/vinylgod/maps/m02/map.png new file mode 100644 index 0000000..c34c583 Binary files /dev/null and b/mods/vinylgod/maps/m02/map.png differ diff --git a/mods/vinylgod/maps/m02/map.yaml b/mods/vinylgod/maps/m02/map.yaml new file mode 100644 index 0000000..57336d0 --- /dev/null +++ b/mods/vinylgod/maps/m02/map.yaml @@ -0,0 +1,127 @@ +MapFormat: 12 + +RequiresMod: vinylgod + +Title: 02 - Crate Diggers + +Author: Monster Robot Party + +Tileset: VINYLGOD + +MapSize: 50,50 + +Bounds: 1,1,48,48 + +Visibility: MissionSelector + +Categories: Campaign + +LockPreview: True + +Players: + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + Faction: vinylgod + PlayerReference@Player: + Name: Player + Playable: True + Required: True + AllowBots: False + LockFaction: True + Faction: vinylgod + LockSpawn: True + LockTeam: True + Enemies: Enemy + PlayerReference@Enemy: + Name: Enemy + Faction: stream + Enemies: Player + +Actors: + spawn0: mpspawn + Owner: Neutral + Location: 8,40 + TheSelector: selector + Owner: Player + Location: 8,40 + strike1: stacktank + Owner: Player + Location: 10,41 + strike2: spinner + Owner: Player + Location: 7,42 + strike3: spinner + Owner: Player + Location: 11,39 + strike4: djgrunt + Owner: Player + Location: 9,43 + strike5: djgrunt + Owner: Player + Location: 10,43 + strike6: djgrunt + Owner: Player + Location: 8,44 + strike7: roadie + Owner: Player + Location: 6,41 + strike8: boombike + Owner: Player + Location: 12,42 + Transcoder: transcoder + Owner: Enemy + Location: 38,9 + MasterLacquer: lacquer + Owner: Neutral + Location: 41,10 + outpost1: datacentre + Owner: Enemy + Location: 35,12 + outpost2: podfarm + Owner: Enemy + Location: 41,13 + turret1: adblocker + Owner: Enemy + Location: 34,9 + turret2: adblocker + Owner: Enemy + Location: 38,14 + guard1: bufferbot + Owner: Enemy + Location: 36,15 + guard2: bufferbot + Owner: Enemy + Location: 37,15 + guard3: bufferbot + Owner: Enemy + Location: 39,16 + guard4: drmwalker + Owner: Enemy + Location: 34,16 + guard5: crawler + Owner: Enemy + Location: 30,20 + picket1: bufferbot + Owner: Enemy + Location: 24,28 + picket2: bufferbot + Owner: Enemy + Location: 25,29 + picket3: adblocker + Owner: Enemy + Location: 22,30 + waxseed0: waxseed + Owner: Neutral + Location: 12,40 + waxseed1: waxseed + Owner: Neutral + Location: 26,26 + waxseed2: waxseed + Owner: Neutral + Location: 40,20 + +Rules: vinylgod|rules/campaign.yaml, rules.yaml + +FluentMessages: vinylgod|fluent/lua.ftl diff --git a/mods/vinylgod/maps/m02/rules.yaml b/mods/vinylgod/maps/m02/rules.yaml new file mode 100644 index 0000000..fa69d25 --- /dev/null +++ b/mods/vinylgod/maps/m02/rules.yaml @@ -0,0 +1,5 @@ +world: + LuaScript: + Scripts: campaign.lua, m02.lua + MissionData: + Briefing: A Stream transcoder outpost has found something under the hill: a master lacquer. The original of an original. The only one.\n\nIn six minutes it will be a receipt.\n\nTake the outpost apart. No van, no plant, no reinforcements - what you brought is what you have.\n\nThe Selector does not get to die out here. diff --git a/mods/vinylgod/maps/needledrop/map.bin b/mods/vinylgod/maps/needledrop/map.bin index 1ca6a43..0e1d2ae 100644 Binary files a/mods/vinylgod/maps/needledrop/map.bin and b/mods/vinylgod/maps/needledrop/map.bin differ diff --git a/mods/vinylgod/maps/shellmap/map.bin b/mods/vinylgod/maps/shellmap/map.bin index 2b04a82..e2688cb 100644 Binary files a/mods/vinylgod/maps/shellmap/map.bin and b/mods/vinylgod/maps/shellmap/map.bin differ diff --git a/mods/vinylgod/maps/vinylgod/map.bin b/mods/vinylgod/maps/vinylgod/map.bin index be92501..d173fbc 100644 Binary files a/mods/vinylgod/maps/vinylgod/map.bin and b/mods/vinylgod/maps/vinylgod/map.bin differ diff --git a/mods/vinylgod/missions/vinylgod.yaml b/mods/vinylgod/missions/vinylgod.yaml index 0ad0cfb..272b3d0 100644 --- a/mods/vinylgod/missions/vinylgod.yaml +++ b/mods/vinylgod/missions/vinylgod.yaml @@ -1,2 +1,3 @@ SIDE A - Monster Robot Party: m01 + m02 diff --git a/mods/vinylgod/rules/combat.yaml b/mods/vinylgod/rules/combat.yaml index 392c581..e67df09 100644 --- a/mods/vinylgod/rules/combat.yaml +++ b/mods/vinylgod/rules/combat.yaml @@ -275,6 +275,7 @@ boombike: # hit them. Upgrade path: dedicated AA armaments + AirborneActor-only targeting. ^AirUnit: + ScriptTriggers: BodyOrientation: QuantizeFacingsFromSequence: RenderSprites: diff --git a/mods/vinylgod/rules/economy.yaml b/mods/vinylgod/rules/economy.yaml index 72458cf..f81e843 100644 --- a/mods/vinylgod/rules/economy.yaml +++ b/mods/vinylgod/rules/economy.yaml @@ -1,4 +1,5 @@ ^EconSprite: + ScriptTriggers: BodyOrientation: QuantizeFacingsFromSequence: RenderSprites: @@ -288,3 +289,26 @@ waxseed: MaxRange: 60 MapEditorData: Categories: Resource spawn + +# The master lacquer — mission prop. Deliberately not Targetable: the player +# must not be able to shoot the thing they came to rescue. +lacquer: + ScriptTriggers: + BodyOrientation: + QuantizeFacingsFromSequence: + RenderSprites: + WithSpriteBody: + Interactable: + HiddenUnderShroud: + Building: + Footprint: x + Dimensions: 1,1 + TerrainTypes: Clear, Wax + Tooltip: + Name: actor-lacquer.name + AppearsOnRadar: + HitShape: + Health: + HP: 1000 + MapEditorData: + Categories: Props diff --git a/mods/vinylgod/sequences/assets/lacquer.png b/mods/vinylgod/sequences/assets/lacquer.png new file mode 100644 index 0000000..7ec6f4e Binary files /dev/null and b/mods/vinylgod/sequences/assets/lacquer.png differ diff --git a/mods/vinylgod/sequences/economy.yaml b/mods/vinylgod/sequences/economy.yaml index 417b76e..5d221f5 100644 --- a/mods/vinylgod/sequences/economy.yaml +++ b/mods/vinylgod/sequences/economy.yaml @@ -269,3 +269,7 @@ compressor: waxseed: idle: Filename: sequences/assets/waxseed.png + +lacquer: + idle: + Filename: sequences/assets/lacquer.png diff --git a/tools/gen_mission2.py b/tools/gen_mission2.py new file mode 100644 index 0000000..6ae9abd --- /dev/null +++ b/tools/gen_mission2.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +"""Generate campaign mission 02 — CRATE DIGGERS (timed raid, no base building).""" +import os, struct +from PIL import Image + +SIZE = 48 +W = H = SIZE + 2 +MAP = os.path.join(os.path.dirname(__file__), '..', 'mods', 'vinylgod', 'maps', 'm02') +os.makedirs(MAP, exist_ok=True) + +WAX = [(12, 40, 4), (26, 26, 5), (40, 20, 3)] + +data = bytearray() +data += struct.pack('