FILES ----- debug.macros dungeons\space\bountyspacesafehouse\end_1.json dungeons\space\bountyspacesafehouse\end_2.json dungeons\space\bountyspacesafehouse\end_3.json dungeons\space\bountyspacesafehouse\end_4.json dungeons\space\bountyspacesafehouse\end_5.json dungeons\space\bountyspacesafehouse\end_6.json dungeons\space\bountyspacesafehouse\room_10.json dungeons\space\bountyspacesafehouse\room_2.json dungeons\space\bountyspacesafehouse\room_3.json dungeons\space\bountyspacesafehouse\room_4.json dungeons\space\bountyspacesafehouse\room_5.json dungeons\space\bountyspacesafehouse\room_6.json dungeons\space\bountyspacesafehouse\room_7.json dungeons\space\bountyspacesafehouse\room_8.json dungeons\space\bountyspacesafehouse\room_9.json interface\scripted\bountyboard\bountyboardgui.lua monsters\boss\swansong\swansong.animation monsters\boss\swansong\swansong.lua quests\bounty\bounty.lua quests\bounty\bounty_gen.lua quests\bounty\clue_objects.config quests\bounty\find_space_clue_item.questtemplate quests\bounty\find_space_clue_npc.questtemplate quests\bounty\find_space_clue_object.questtemplate quests\bounty\find_space_clue_scan.questtemplate quests\bounty\generator.config quests\bounty\stages.lua scripts\bountygeneration.lua [NEW] sfx\npc\boss\swansong_beamstart.ogg [NEW] sfx\npc\boss\swansong_charge.ogg [NEW] sfx\npc\boss\swansong_rocket.ogg [NEW] sfx\npc\boss\swansong_rocket_target.ogg stagehands\bountymanager.lua DIFFS ----- debug.macros 30c30,67 < "/spawnitem heatprotectionback" --- > "/spawnitem heatprotectionback", > "/spawnitem mechbodyprotector", > "/spawnitem mechbodycultist2", > "/spawnitem mechbodyiris", > "/spawnitem mechboostergallant", > "/spawnitem mechboosterzero", > "/spawnitem mechboosterhammer", > "/spawnitem mechlegsintrepid", > "/spawnitem mecharmteslastream", > "/spawnitem mecharmmultidrone", > "/spawnitem mecharmspikefist", > "/spawnitem mecharmshielddrone", > "/spawnitem mecharmguidedmissiles", > "/spawnitem mecharmgravitymine", > "/spawnitem mecharmenergyblade", > "/spawnitem mecharmdualrifle", > "/spawnitem mecharmbeamsniper", > "/spawnitem techconsole", > "/spawnitem mechassemblystation", > "/giveessentialitem beamaxe beamaxe", > "/giveessentialitem wiretool wiretool", > "/giveessentialitem painttool painttool", > "/enabletech sprint", > "/enabletech doublejump", > "/enabletech multijump", > "/enabletech rocketjump", > "/enabletech walljump", > "/enabletech distortionsphere", > "/enabletech spikesphere", > "/enabletech aquasphere", > "/enabletech sonicsphere", > "/enabletech dash", > "/enabletech airdash", > "/enabletech blinkdash" > ], > > "fuel" : [ > "/spawnitem solidfuel 1000" dungeons\space\bountyspacesafehouse\end_1.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\end_2.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\end_3.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\end_4.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\end_5.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\end_6.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_10.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_2.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_3.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_4.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_5.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_6.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_7.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_8.json [TMX file differences are left out for huge size.] dungeons\space\bountyspacesafehouse\room_9.json [TMX file differences are left out for huge size.] interface\scripted\bountyboard\bountyboardgui.lua 685a686,699 > if #minorWorldPool == 0 then > -- put the bounties in the same systems as the major bounty visits, one in each system > local usedSystems = {} > local majorSystems = util.map(majorWorlds, coordinateSystem) > minorWorldPool = util.filter(worlds, function(w) > local system = coordinateSystem(w) > if contains(majorSystems, system) and not contains(usedSystems, system) and not contains(majorWorlds, w) then > table.insert(usedSystems, system) > return true > end > return false > end) > end > 689,694d702 < else < -- put the rest in the same systems as the major bounty visits < local majorSystems = util.filter(majorWorlds, function(w) return w.system end) < local worlds = util.filter(worlds, function(w) < return contains(majorSystems, w.system) < end) 701c709 < minorWorldPool = shallowCopy(majorWorlds) --- > minorWorldPool = util.filter(majorWorlds, function(c) return c.planet ~= 0 or c.satellite ~= 0 end) monsters\boss\swansong\swansong.animation 18c18,21 < "transition" : "idle" --- > "transition" : "idle", > "properties" : { > "immediateSound" : "/sfx/tech/mech_activate3.ogg" > } 34c37,40 < "transition" : "rocketloop" --- > "transition" : "rocketloop", > "properties" : { > "immediateSound" : "/sfx/tech/mech_activate1.ogg" > } 45c51,54 < "transition" : "idle" --- > "transition" : "idle", > "properties" : { > "immediateSound" : "/sfx/tech/mech_deactivate.ogg" > } 63c72,75 < "transition" : "idle" --- > "transition" : "idle", > "properties" : { > "immediateSound" : "/sfx/tech/mech_activate2.ogg" > } 79c91,94 < "transition" : "swordloop" --- > "transition" : "swordloop", > "properties" : { > "immediateSound" : "/sfx/melee/mech_energysword_windup2.ogg" > } 90c105,108 < "transition" : "idle" --- > "transition" : "idle", > "properties" : { > "immediateSound" : "/sfx/melee/mech_energysword_winddown1.ogg" > } 103c121,124 < "transition" : "idle" --- > "transition" : "idle", > "properties" : { > "immediateSound" : "/sfx/tech/mech_activate1.ogg" > } 119c140,143 < "transition" : "fireidle" --- > "transition" : "fireidle", > "properties" : { > "immediateSound" : "/sfx/gun/mech_gatling_windup.ogg" > } 126c150,153 < "transition" : "fireidle" --- > "transition" : "fireidle", > "properties" : { > "immediateSound" : "/sfx/gun/plasma_sniper1.ogg" > } 145c172,175 < "transition" : "idle" --- > "transition" : "idle", > "properties" : { > "immediateSound" : "/sfx/tech/mech_activate4.ogg" > } 792c822,884 < "deathPuff" : [ "/sfx/npc/enemydeathpuff.ogg" ] --- > "deathPuff" : [ "/sfx/npc/enemydeathpuff.ogg" ], > "spawnClank" : [ > "/sfx/melee/blunt_hit_metal1.ogg", > "/sfx/melee/blunt_hit_metal2.ogg", > "/sfx/melee/blunt_hit_metal3.ogg", > "/sfx/melee/blunt_hit_metal4.ogg", > "/sfx/melee/blunt_hit_metal5.ogg", > "/sfx/melee/blunt_hit_metal6.ogg" > ], > "thrustLoop" : [ > "/sfx/tech/mech_jetpack_loop1.ogg" > ], > "thrustBurst" : [ > "/sfx/tech/mech_jetpack_thrust1.ogg" > ], > "toggleGravityWarning" : [ > "/sfx/objects/camera_alert_on.ogg" > ], > "enableGravity" : [ > "/sfx/tech/mech_powerdown.ogg" > ], > "disableGravity" : [ > "/sfx/interface/ship_powerup.ogg" > ], > "fireRockets" : [ > "/sfx/npc/boss/swansong_rocket.ogg" > ], > "targetRockets" : [ > "/sfx/npc/boss/swansong_rocket_target.ogg" > ], > "blinkDash" : [ > "/sfx/npc/boss/cultistboss_blink.ogg" > ], > "charge" : [ > "/sfx/npc/boss/swansong_charge.ogg" > ], > "chargeBrake" : [ > "/sfx/gun/fireblast.ogg" > ], > "slash" : [ > "/sfx/melee/mech_energysword_swing1.ogg", > "/sfx/melee/mech_energysword_swing2.ogg", > "/sfx/melee/mech_energysword_swing3.ogg", > "/sfx/melee/mech_energysword_swing4.ogg" > ], > "beamStart" : [ > "/sfx/npc/boss/swansong_beamstart.ogg" > ], > "beamLoop" : [ > "/sfx/npc/boss/crystalboss_beam.ogg" > ], > "shockLoop" : [ > "/sfx/objects/plasmadisc.ogg" > ], > "transitionBurst" : [ > "/sfx/melee/hammer_smash2.ogg" > ], > "deathLoop" : [ > "/sfx/npc/boss/boss_dying.ogg" > ], > "deathBurst" : [ > "/sfx/tech/mech_explosion.ogg" > ] monsters\boss\swansong\swansong.lua 98d97 < world.debugText("%s", self.wings.angle, mcontroller.position(), "yellow") 143a143,152 > function setBoostSoundActive(active) > if active and self.boostSoundActive ~= true then > animator.playSound("thrustLoop", -1) > self.boostSoundActive = true > elseif not active then > animator.stopAllSounds("thrustLoop") > self.boostSoundActive = false > end > end > 201a211 > local boosting = false 212a223,225 > if animator.animationState(hand.part) == "idle" and state == "boost" then > boosting = true > end 216a230,233 > if boosting then > animator.playSound("thrustBurst") > end > setBoostSoundActive(boosting or animator.animationState("body") == "idlegrav") 310a328 > world.setDungeonGravity(0, 0) 322a341 > world.setDungeonGravity(0, 0) 350d368 < await(deactivateGravity()) 367a386,387 > > await(deactivateGravity()) 397a418 > 401a423 > animator.playSound("shockLoop", -1) 408c430,431 < --- > > animator.playSound("deathLoop", -1) 444a468,470 > animator.stopAllSounds("shockLoop") > animator.stopAllSounds("deathLoop") > animator.playSound("deathBurst") 527a554 > animator.playSound("blinkDash") 583c610,614 < await(delay(0.5)) --- > animator.playSound("beamStart") > await(delay(0.5)) -- windup > > animator.playSound("beamLoop", -1) > await(delay(0.2)) -- start firing 587c618 < await(delay(0.5)) --- > await(delay(0.3)) 591a623 > animator.stopAllSounds("beamLoop", 0.5) 681,682c713,716 < animator.setAnimationState("body", "spawn") < await(delay(1.0)) --- > await(join( > function() > animator.setAnimationState("body", "spawn") > await(delay(1.0)) 684,685c718,719 < animator.setAnimationState("lefthand", "spawn") < await(delay(0.5)) --- > animator.setAnimationState("lefthand", "spawn") > await(delay(0.5)) 687,688c721,722 < animator.setAnimationState("righthand", "spawn") < await(delay(0.5)) --- > animator.setAnimationState("righthand", "spawn") > await(delay(0.5)) 690,691c724,733 < animator.setAnimationState("wings", "spawn") < await(delay(0.75)) --- > animator.setAnimationState("wings", "spawn") > await(delay(0.75)) > end, > function() > for i = 1, 5 do > --animator.playSound("spawnClank") > await(delay(0.5)) > end > end > )) 694a737,742 > for i = 1, 2 do > animator.playSound("toggleGravityWarning") > await(delay(1.0)) > end > > animator.playSound("enableGravity") 713a762,767 > for i = 1, 2 do > animator.playSound("toggleGravityWarning") > await(delay(1.0)) > end > > animator.playSound("disableGravity") 788a843 > animator.playSound("targetRockets") 793c848 < animator.setAnimationState("righthand", "fire") --- > animator.setAnimationState("righthand", "fire", true) 800c855 < await(delay(0.2)) --- > await(delay(0.25)) 850a906,907 > > animator.playSound("fireRockets") 874a932,934 > > animator.playSound("targetRockets") > 943,944c1003,1006 < await(moveLeftHand({0.0, -1.0}, targetAngle + facing * util.toRadians(70), 2.0, 0.01)) < await(moveLeftHand({0.0, -1.0}, targetAngle + facing * util.toRadians(-70), 4.0, 0.01)) --- > animator.playSound("slash") > await(moveLeftHand({0.0, -1.0}, targetAngle + facing * util.toRadians(70), 2.0, 0.00)) > coroutine.yield() > await(moveLeftHand({0.0, -1.0}, targetAngle + facing * util.toRadians(-70), 4.0, 0.00)) 965a1028 > animator.playSound("charge") 1010a1074,1075 > animator.playSound("thrustBurst") > animator.playSound("thrustLoop", -1) 1047a1113 > animator.playSound("chargeBrake") 1066a1133 > animator.stopAllSounds("thrustLoop") 1079a1147 > animator.playSound("charge") 1111a1180 > animator.playSound("slash") 1205c1274,1278 < await(delay(0.7)) -- windup --- > animator.playSound("beamStart") > await(delay(0.5)) -- windup > > animator.playSound("beamLoop", -1) > await(delay(0.2)) -- start firing 1213a1287 > animator.stopAllSounds("beamLoop", 0.5) 1229a1304 > animator.playSound("shockLoop", -1) 1274a1350 > animator.stopAllSounds("shockLoop") 1277a1354 > animator.playSound("transitionBurst") quests\bounty\bounty.lua 145a146 > sb.logInfo("Find bounty manager") 148a150 > sb.logInfo("Maybe find bounty manager") 178c180,182 < return contains(locationWorlds, player.worldId()) --- > if contains(locationWorlds, player.worldId()) then > return true > end 204,206d207 < < quest.setWorldId(nil) < quest.setLocation(nil) 228c229,230 < world.sendEntityMessage(quest.questArcDescriptor().stagehandUniqueId, "playerComplete", player.uniqueId(), quest.questId()) --- > sb.logInfo("Send playerCompleted message") > world.sendEntityMessage(quest.questArcDescriptor().stagehandUniqueId, "playerCompleted", player.uniqueId(), quest.questId()) 238a241,243 > > quest.setWorldId(nil) > quest.setLocation(nil) 314a320 > sb.logInfo("Involves this world: %s", util.await(world.sendEntityMessage(stagehandId, "involvesQuest", quest.questId())):result()) quests\bounty\bounty_gen.lua 17c17 < local generator, target = questGenerator(behaviorName, "tutorial_bounty", 2) --- > local generator, target = questGenerator(behaviorName, "capture_bounty", 2) 47c47 < local categories = {"planet"} --- > local categories = {"planet", "anomaly"} quests\bounty\clue_objects.config 311a312,336 > }, > "astroconsole" : { > "tutorial" : { > "dialog" : " is [LOCATED] on [PLANET] ^green;^reset;" > }, > "planetClue" : { > "dialog" : "[QUERY_LOCATION] COMPLETE: ^green;^reset;", > "message" : "^green;^reset;? That sounds like a mighty fine tip-off if I ever heard one!" > }, > "planetBounty" : { > "dialog" : ">USER: ^green;^reset; >LOCATION: ^green;^reset;", > "message" : "You found the target's location? You better trek on over to ^green;^reset;!" > }, > "spaceClue" : { > "dialog" : ">HIDEOUT_SYSTEM LOCATION: ^green;^reset;", > "message" : "The target must have intel hidin' in the ^green;^reset; system... The trail is still hot!" > }, > "spaceBounty" : { > "dialog" : " is [LOCATED] in [SYSTEM] ^green;^reset;", > "message" : "The target is hidin' out somewhere in space over in ^green;^reset;. You know what to do, partner!" > }, > "vaultClue" : { > "dialog" : "[WELCOME_NEW_USER] The ^green;^reset; Vault Code = ^green;^reset; [BEEP BOOP]", > "message" : "The code is ! You better go back to that vault, partner!" > } quests\bounty\find_space_clue_item.questtemplate 41c41 < "^orange;Investigate containers^reset; for clues" --- > "^orange;Search^reset; for clues" quests\bounty\find_space_clue_npc.questtemplate 41c41 < "^orange;\"Interrogate\" criminals^reset; for clues" --- > "^orange;Search^reset; for clues" quests\bounty\find_space_clue_object.questtemplate 41c41 < "^orange;Investigate computers^reset; for clues" --- > "^orange;Search^reset; for clues" quests\bounty\find_space_clue_scan.questtemplate 41c41 < "^orange;Scan^reset; for clues" --- > "^orange;Search^reset; for clues" quests\bounty\generator.config 405a406 > "weight" : 500.0, 485,519c486,519 < // "find_space_clue_scan" : { < // "category" : "anomaly", < // "quest" : "find_space_clue_scan", < // "questParameters" : { < // "systemSpawns" : { < // "type" : "json", < // "spaceObject" : "bountyanomaly" < // } < // }, < // "clueTypes" : [ < // "planetClue", < // "planetBounty", < // "spaceClue", < // "spaceBounty" < // ], < < // "coordinate" : { < // "type" : "system", < // "questParameter" : "system" < // }, < < // "locations" : { < // "clue" : { < // "type" : "stagehand", < // "stagehand" : "clueroom" < // } < // }, < < // "spawns" : { < // "clue" : { < // "location" : "clue", < // "type" : "clueScan" < // } < // } < // }, --- > "find_space_clue_scan" : { > "category" : "anomaly", > "quest" : "find_space_clue_scan", > "questParameters" : {}, > "clueTypes" : [ > "planetClue", > "planetBounty", > "spaceClue", > "spaceBounty" > ], > > "systemSpawn" : { > "objectType" : "bountyanomaly" > }, > > "coordinate" : { > "type" : "system", > "questParameter" : "system" > }, > > "locations" : { > "clue" : { > "type" : "stagehand", > "stagehand" : "clueroom" > } > }, > > "spawns" : { > "clue" : { > "location" : "clue", > "type" : "clueScan" > } > } > }, 940c940,950 < "step" : "find_space_clue_item" --- > "step" : "find_clue_scan" > } > }, > > { > "prev" : { > "clueType" : "spaceClue" > }, > > "next" : { > "step" : "find_space_clue_scan" 1114a1125,1129 > "coordinate" : { > "type" : "previous", > "questParameter" : "world" > }, > 1178a1194,1198 > "coordinate" : { > "type" : "previous", > "questParameter" : "world" > }, > 1243a1264,1268 > "coordinate" : { > "type" : "previous", > "questParameter" : "world" > }, > quests\bounty\stages.lua 42d41 < 97c96,100 < while not storage.spawned["bounty"] and onQuestWorld() do --- > while not storage.spawned["bounty"] do > if not onQuestWorld() then > return previousStage() > end > 334c337 < while not storage.scannedClue do --- > while not storage.event["scannedClue"] do 347a351,352 > > return nextStage() scripts\bountygeneration.lua 150c150,154 < local species = util.randomFromList(gang.species or npcConfig.species, self.rand) --- > local speciesPool = npcConfig.species > if gang and gang.species then > speciesPool = gang.species > end > local species = util.randomFromList(speciesPool, self.rand) 489c493 < local usedPlanets = {} -- keep track of used planets to return with steps --- > local usedCoordinates = {} -- keep track of used coordinates to return with steps 583c587 < if lastQuestId and coordinateConfigs[lastQuestId].type == "world" then --- > if lastQuestId and coordinateConfigs[lastQuestId].type == "system" then 590c594 < table.insert(usedPlanets, world) --- > table.insert(usedCoordinates, world) 597c601,606 < local world = table.remove(planetPool, 1) --- > -- pick a system from the pool that's not previously visited > local world > local excludeSystems = util.map(usedCoordinates, coordinateSystem) > repeat > world = table.remove(planetPool, 1) > until world == nil or not contains(excludeSystems, coordinateSystem(world)) 601,603c610,611 < local system = copy(world) < system.planet = 0 < system.satellite = 0 --- > local system = coordinateSystem(world) > table.insert(usedCoordinates, system) 788,793d795 < sb.logInfo("SPawnconfig: %s\n%s", spawnConfig.npc, sb.jsonMerge({ < species = generated.species, < typeName = generated.typeName, < parameters = generated.parameters, < level = self.level < }, spawnConfig.npc)) 878d879 < sb.logInfo("Quest text: %s", sb.printJson(step.text)) 973c974 < return quests, usedPlanets --- > return quests, usedCoordinates 997,998c998,999 < local usedPlanets < arc.quests, usedPlanets = self:processSteps(steps, bountyTarget, planetPool) --- > local usedCoordinates > arc.quests, usedCoordinates = self:processSteps(steps, bountyTarget, planetPool) 1025c1026 < return arc, usedPlanets --- > return arc, usedCoordinates stagehands\bountymanager.lua 184c184 < function clearUnusedQuestSpawns() --- > function completeQuestParticipants(questId, playerId) 186,192c186,191 < for questId, questStore in pairs(storage.questStorage) do < if #questStore.players == 0 then < for _, spawnResult in pairs(questStore.spawned) do < if type(spawnResult) == "string" then < self.outbox:sendMessage(spawnResult, "playerCompleted", entity.uniqueId(), playerId, questId) < self.outbox:sendMessage(spawnResult, "unreserve", entity.uniqueId(), self.questArc) < end --- > local questStore = storage.questStorage[questId] > for _, spawnResult in pairs(questStore.spawned) do > if type(spawnResult) == "string" then > self.outbox:sendMessage(spawnResult, "playerCompleted", entity.uniqueId(), playerId, questId) > if #questStore.players == 0 then > self.outbox:sendMessage(spawnResult, "unreserve", entity.uniqueId(), self.questArc) 194d192 < questStore.spawned = {} 196a195 > questStore.spawned = {} 204d202 < clearUnusedQuestSpawns() 304c302,303 < sb.logInfo("Player %s completed %s", playerId, questId) --- > sb.logInfo("Player %s completed %s") > completeQuestParticipants(questId, playerId) 308d306 < clearUnusedQuestSpawns() 310d307 < sb.logInfo("Last quest on world? %s", lastQuestOnWorld(questId)) 317c314 < sb.logInfo("Player %s failed %s", playerId, questId) --- > sb.logInfo("Player %s failed %s") 335a333 > sb.logInfo("%s %s", questId, self.questId) 341a340 > sb.logInfo("%s %s", self.worldId, coordinateWorldId(world.coordinate)) 778,779c777,783 < for _, dungeonId in ipairs(storage.tileProtection) do < world.setTileProtection(dungeonId, false) --- > local celestialWorld = worldIdCoordinate(self.worldId) ~= nil > if celestialWorld then > for _, dungeonId in ipairs(storage.tileProtection) do > world.setTileProtection(dungeonId, false) > end > else > world.setTileProtection(0, false) 811,812c815,820 < for _, dungeonId in ipairs(storage.tileProtection) do < world.setTileProtection(dungeonId, true) --- > if celestialWorld then > for _, dungeonId in ipairs(storage.tileProtection) do > world.setTileProtection(dungeonId, true) > end > else > world.setTileProtection(0, true)