Skip to content

Commit

Permalink
Warehouse quest in Raid on Pirate's Point seems to
Browse files Browse the repository at this point in the history
be complete
  • Loading branch information
jwvhewitt committed Feb 18, 2025
1 parent 868a28c commit aa96454
Show file tree
Hide file tree
Showing 29 changed files with 856 additions and 88 deletions.
4 changes: 3 additions & 1 deletion credits.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Slightly Smiling Face, Beaming Face with Smiling Eyes by Emily Jäger
* computer bug by Laymik from Noun Project (CC BY 3.0)
* up by Rizalwale from Noun Project (CC BY 3.0)
* Backpack by M. Adebadal from Noun Project (CC BY 3.0)
* Horse by G-CAT from Noun Project (CC BY 3.0)

MUSIC
=====
Expand Down Expand Up @@ -122,6 +123,7 @@ MUSIC
* three stems remixt by Martin Cee (softmartin) (c) copyright 2020 Licensed under a Creative Commons Attribution (3.0) license. http://dig.ccmixter.org/files/softmartin/61013 Ft: canton
* This One is Tough by Komiku, Public Domain
* Way Of The Samurai by HoliznaCC0, Public Domain
* "Shiny Tech" Kevin MacLeod (incompetech.com) Licensed under Creative Commons: By Attribution 4.0 License http://creativecommons.org/licenses/by/4.0/

NON-CC MUSIC
============
Expand Down Expand Up @@ -168,4 +170,4 @@ pixabay.com and other CC0 sound effect collections.
* rock_breaking.ogg by Blender Foundation, CC-BY-3.0
* Spell1.ogg by artisticdude, CC-BY-3.0
* UI_Electric_00.ogg by Little Robot Sound Factory, CC-BY-3.0
* upgrade1.ogg by KenneyNL, CC0
* upgrade1.ogg by KenneyNL, CC0
41 changes: 31 additions & 10 deletions data/sed_scenefeatures.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@
"label": "SCENE_FEATURE",
"scripts": {
"plot_subplots": "+subplot DUNGEONLEVEL_{unique_id}_{_uid}\n\n",
"main": "class DungeonLevel_{unique_id}_{_uid}( Plot ):\n LABEL = \"DUNGEONLEVEL_{unique_id}_{_uid}\"\n active = True\n scope = \"LOCALE\"\n\n #: plot_properties\n\n def custom_init( self, nart ):\n +init_plot\n # Do the connection here.\n #scutils.SCSceneConnection(self.elements[\"PARENT_SCENE\"], self.elements[\"LOCALE\"], {scene_connection})\n #: plot_init\n #: plot_actions\n #: plot_subplots\n return True\n\n #: plot_methods\n\n",
"scenario_build": "splot = self.add_sub_plot(nart, \"DUNGEON_GENERIC\", elements=dict(METROSCENE=the_world[{METROSCENE_UID}], METRO=the_world[{METROSCENE_UID}].metrodat, MISSION_GATE=the_world[{MISSION_GATE_UID}], DG_NAME={dg_name}, DG_ARCHITECTURE={dg_architecture}(), DG_SCENE_TAGS={dg_scene_tags}, DG_MONSTER_TAGS={dg_monster_tags}, DG_PARENT_SCENE=the_world[{PARENT_SCENE_UID}], DG_EXPLO_MUSIC={dg_explo_music}, DG_COMBAT_MUSIC={dg_combat_music}, DG_DECOR={dg_decor}))\n+add_physical LOCALE splot.elements[\"LOCALE\"]\nscutils.SCSceneConnection(the_world[{PARENT_SCENE_UID}], splot.elements[\"LOCALE\"], {scene_connection})\n\n\n\n"
"main": "class DungeonLevel_{unique_id}_{_uid}( Plot ):\n LABEL = \"DUNGEONLEVEL_{unique_id}_{_uid}\"\n active = True\n scope = \"LOCALE\"\n\n #: plot_properties\n\n def custom_init( self, nart ):\n +init_plot\n self.elements[dungeonmaker.DG_ARCHITECTURE] = nart.get_map_generator(self.elements[\"LOCALE\"]).archi\n self.elements[dungeonmaker.DG_NAME] = {dg_name}\n self.elements[dungeonmaker.DG_SCENE_TAGS] = {dg_scene_tags}\n self.elements[dungeonmaker.DG_MONSTER_TAGS] = {dg_monster_tags}\n\n # Do the connection here.\n #scutils.SCSceneConnection(self.elements[\"PARENT_SCENE\"], self.elements[\"LOCALE\"], {scene_connection})\n #: plot_init\n #: plot_actions\n #: plot_subplots\n return True\n\n #: plot_methods\n\n",
"scenario_build": "splot = self.add_sub_plot(nart, \"DUNGEON_GENERIC\", elements=dict(METROSCENE=the_world[{METROSCENE_UID}], METRO=the_world[{METROSCENE_UID}].metrodat, MISSION_GATE=the_world[{MISSION_GATE_UID}], DG_NAME={dg_name}, DG_ARCHITECTURE={dg_architecture}(), DG_SCENE_TAGS={dg_scene_tags}, DG_MONSTER_TAGS={dg_monster_tags}, DG_PARENT_SCENE=the_world[{PARENT_SCENE_UID}], DG_EXPLO_MUSIC={dg_explo_music}, DG_COMBAT_MUSIC={dg_combat_music}, DG_DECOR={dg_decor}), rank=self.rank+{rank_modifier})\n+add_physical LOCALE splot.elements[\"LOCALE\"]\nscutils.SCSceneConnection(the_world[{PARENT_SCENE_UID}], splot.elements[\"LOCALE\"], {scene_connection})\n\n\n\n"
},
"name": "New Singular Dungeon Level",
"display_name": "Level: {dg_name}",
Expand Down Expand Up @@ -129,13 +129,18 @@
"default_val": "None",
"var_type": "interior_decor"
},
"rank_modifier": {
"default_val": 0,
"var_type": "integer"
},
"scene_connection": {
"default_val": null,
"var_type": "scene_connection"
}
},
"child_types": [
"SCENE_FEATURE"
"SCENE_FEATURE",
"DUNGEON_SCENE_FEATURE"
],
"elements": {
"LOCALE": {
Expand All @@ -151,7 +156,8 @@
"element_key": "LOCALE",
"parent": "PARENT_SCENE",
"child_types": [
"SCENE_FEATURE"
"SCENE_FEATURE",
"DUNGEON_SCENE_FEATURE"
]
}
]
Expand All @@ -160,7 +166,7 @@
"label": "SCENE_FEATURE",
"scripts": {
"plot_subplots": "+subplot DUNGEON_{unique_id}_{_uid}\n\n",
"main": "class Dungeon_{unique_id}_{_uid}( Plot ):\n LABEL = \"DUNGEON_{unique_id}_{_uid}\"\n active = True\n scope = \"METRO\"\n\n #: plot_properties\n\n def custom_init( self, nart ):\n +init_plot\n #: plot_init\n #: plot_actions\n #: plot_subplots\n return True\n\n #: plot_methods\n\n",
"main": "class Dungeon_{unique_id}_{_uid}( Plot ):\n LABEL = \"DUNGEON_{unique_id}_{_uid}\"\n active = True\n scope = \"METRO\"\n\n #: plot_properties\n\n def custom_init( self, nart ):\n +init_plot\n self.elements[dungeonmaker.DG_ARCHITECTURE] = nart.get_map_generator(self.elements[\"LOCALE\"]).archi\n self.elements[dungeonmaker.DG_NAME] = {dg_name}\n self.elements[dungeonmaker.DG_SCENE_TAGS] = {dg_scene_tags}\n self.elements[dungeonmaker.DG_MONSTER_TAGS] = {dg_monster_tags}\n #: plot_init\n #: plot_actions\n #: plot_subplots\n return True\n\n #: plot_methods\n\n",
"scenario_build": "mydungeon = dungeonmaker.DungeonMaker(nart, self, name={dg_name}, architecture={dg_architecture}(), rank=self.rank, scene_tags={dg_scene_tags}, monster_tags={dg_monster_tags}, parent_scene=the_world[{PARENT_SCENE_UID}], explo_music={dg_explo_music}, combat_music={dg_combat_music}, decor={dg_decor})\n+add_physical DUNGEON mydungeon\nscutils.SCSceneConnection(the_world[{PARENT_SCENE_UID}], mydungeon.entry_level, {scene_connection})\n\n\n\n"
},
"name": "New Dungeon",
Expand Down Expand Up @@ -264,7 +270,8 @@
"desc": "Allows you to add features to the entry level.",
"is_new_branch": true,
"child_types": [
"SCENE_FEATURE"
"SCENE_FEATURE",
"DUNGEON_SCENE_FEATURE"
],
"elements": {
"LOCALE": {
Expand All @@ -281,7 +288,8 @@
"element_key": "LOCALE",
"parent": "DUNGEON",
"child_types": [
"SCENE_FEATURE"
"SCENE_FEATURE",
"DUNGEON_SCENE_FEATURE"
]
}
]
Expand All @@ -291,14 +299,15 @@
"scripts": {
"plot_subplots": "+subplot DUNGEON_GOAL_{unique_id}_{_uid}\n\n",
"main": "class DungeonGoal_{unique_id}_{_uid}( Plot ):\n LABEL = \"DUNGEON_GOAL_{unique_id}_{_uid}\"\n active = True\n scope = \"LOCALE\"\n\n #: plot_properties\n\n def custom_init( self, nart ):\n +init_plot\n #: plot_init\n #: plot_actions\n #: plot_subplots\n return True\n\n #: plot_methods\n\n",
"scenario_build": "+add_physical LOCALE the_world[{DUNGEON_UID}].goal_level\n"
"scenario_build": "+add_physical LOCALE the_world[{DUNGEON_UID}].goal_level\n\n\n"
},
"name": "Add Goal Level Features",
"display_name": "Goal: {dg_name}",
"desc": "Allows you to add features to the goal level.",
"is_new_branch": true,
"child_types": [
"SCENE_FEATURE"
"SCENE_FEATURE",
"DUNGEON_SCENE_FEATURE"
],
"elements": {
"LOCALE": {
Expand All @@ -315,9 +324,21 @@
"element_key": "LOCALE",
"parent": "DUNGEON",
"child_types": [
"SCENE_FEATURE"
"SCENE_FEATURE",
"DUNGEON_SCENE_FEATURE"
]
}
]
},
{
"label": "DUNGEON_SCENE_FEATURE",
"scripts": {
"plot_subplots": "+subplot DUNGEON_TREASURE\n\n\n\n"
},
"name": "Add Dungeon Treasure",
"display_name": "Dungeon Treasure",
"desc": "Add treasure to this dungeon level.",
"sorting_rank": 2000,
"category": "SUBPLOTS"
}
]
8 changes: 8 additions & 0 deletions game/chargen/lifepath.py
Original file line number Diff line number Diff line change
Expand Up @@ -1087,3 +1087,11 @@ def generate_random_lifepath(cgen):
current = random.choice(current.next)
else:
break



class LifePathEvent:
def __init__(self, name, stage):
self.name = name
self.stage = stage

2 changes: 1 addition & 1 deletion game/content/dungeonmaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def __init__(self, nart: GHNarrativeRequest, parent_plot: Plot, parent_scene, na
proto.level_plot = sp
self.levels.append(proto.real_scene)
if proto.terminal:
sp.add_sub_plot(nart, "DUNGEON_GOAL")
sp.add_sub_plot(nart, "DUNGEON_GOAL", elements={DG_MONSTER_TAGS: monster_tags}, rank=proto.level_plot.rank)
if parent and parent is not parent_scene:
connector(nart, parent_plot, parent, proto.real_scene, )
else:
Expand Down
5 changes: 5 additions & 0 deletions game/content/gharchitecture.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ class MilitaryOfficeDecor(OfficeDecor):
ghterrain.MapTerrain, ghterrain.EarthMapTerrain
)

class WarehouseDecor(OmniDec):
WALL_DECOR = (ghterrain.ShippingShelvesTerrain, ghterrain.ShippingShelvesTerrain, ghterrain.ShippingShelvesTerrain,
ghterrain.VentFanTerrain)
FLOOR_DECOR = (ghterrain.KenneyCrates, ghterrain.KenneyCrates)


class WorldScaleDeadzone(GearHeadArchitecture):
ENV = gears.tags.GroundEnv
Expand Down
6 changes: 4 additions & 2 deletions game/content/ghplots/dd_homebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,9 @@ def custom_init(self, nart):
# Create a building within the town.
building = self.register_element("_EXTERIOR", game.content.ghterrain.ResidentialBuilding(
waypoints={"DOOR": ghwaypoints.ScreenDoor(name="Bronze Horse Inn")},
tags=[pbge.randmaps.CITY_GRID_ROAD_OVERLAP]), dident="LOCALE")
tags=[pbge.randmaps.CITY_GRID_ROAD_OVERLAP],
door_sign=(game.content.ghterrain.BronzeHorseTerrainEast, game.content.ghterrain.BronzeHorseTerrainSouth)
), dident="LOCALE")

# Add the interior scene.
team1 = teams.Team(name="Player Team")
Expand All @@ -637,7 +639,7 @@ def custom_init(self, nart):
self.register_scene(nart, intscene, intscenegen, ident="INTERIOR", dident="LOCALE")
foyer = self.register_element('_introom', pbge.randmaps.rooms.ClosedRoom(width=10, height=10,
anchor=pbge.randmaps.anchors.south,
decorate=game.content.gharchitecture.ResidentialDecor()),
decorate=game.content.gharchitecture.BreakRoomDecor()),
dident="INTERIOR")
foyer.contents.append(team2)

Expand Down
2 changes: 2 additions & 0 deletions game/content/ghplots/dd_intro.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def custom_init( self, nart ):
myroom.contents.append(ghwaypoints.ClosedBoardingChute())
myroom.contents.append(ghwaypoints.VentFan())

#myroom.contents.append(game.content.ghterrain.PersonalCargoContainerTerrset())

npc = self.register_element("SHERIFF",
gears.selector.random_character(45, local_tags=self.elements["LOCALE"].attributes,
job=gears.jobs.ALL_JOBS["Sheriff"]))
Expand Down
2 changes: 1 addition & 1 deletion game/content/ghplots/dd_roadedge_unique.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class KerberosEncounterPlot(DZDREBasicPlotWithEncounterStuff):
active = True
scope = True
UNIQUE = True
BASE_RANK = 50
BASE_RANK = 40
ENCOUNTER_CHANCE = BASE_RANK
ENCOUNTER_ARCHITECTURE = gharchitecture.MechaScaleDeadzone

Expand Down
130 changes: 126 additions & 4 deletions game/content/ghplots/dungeon_extras.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import trace
from pbge.plots import Plot
import gears
import pbge
Expand All @@ -10,6 +11,18 @@
from game.ghdialogue import context


# **********************
# *** DUNGEON_GOAL ***
# **********************

class TreasureGoal(Plot):
LABEL = "DUNGEON_GOAL"

def custom_init(self, nart):
self.add_sub_plot(nart, "DUNGEON_TREASURE", rank=self.rank + 5)
return True


# ***********************
# *** DUNGEON_EXTRA ***
# ***********************
Expand Down Expand Up @@ -75,8 +88,8 @@ def custom_init(self, nart):
("ROBOT", "GUARD"), myscene.scale).contents
self.last_update = 0

mychest = self.register_element("GOAL", ghwaypoints.SteelBox(name="Crate", anchor=pbge.randmaps.anchors.middle,
treasure_rank=self.rank),
mychest = self.register_element("GOAL", ghwaypoints.StorageBox(name="Box", anchor=pbge.randmaps.anchors.middle,
treasure_rank=self.rank, treasure_type=(gears.tags.ST_ESSENTIAL, gears.tags.ST_MINERAL)),
dident="ROOM")

return True
Expand Down Expand Up @@ -428,9 +441,27 @@ def LOCALE_ENTER(self, camp: gears.GearHeadCampaign):
self.last_update = camp.time


class SpecialDungeonTreasure(Plot):
# Just call a DUNGEON_TREASURE plot.
LABEL = "DUNGEON_EXTRA"
active = True
scope = "LOCALE"

def custom_init(self, nart):
self.add_sub_plot(nart, "DUNGEON_TREASURE")
return True


# ***************************
# *** DUNGEON_TREASURE ***
# ***************************
#
# Add a treasure, or at least some kind of cash bonus for the PCs.
#

class GuardedTreasure(Plot):
# Fight some random monsters. They have stuff.
LABEL = "DUNGEON_EXTRA"
LABEL = "DUNGEON_TREASURE"
active = True
scope = "LOCALE"

Expand All @@ -442,7 +473,7 @@ def custom_init(self, nart):
self.elements[DG_MONSTER_TAGS], myscene.scale).contents
self.last_update = 0

mychest = self.register_element("GOAL", ghwaypoints.Crate(name="Crate", anchor=pbge.randmaps.anchors.middle),
mychest = self.register_element("GOAL", ghwaypoints.SteelBox(name="Box", anchor=pbge.randmaps.anchors.middle),
dident="ROOM")
mychest.contents += gears.selector.get_random_loot(self.rank, 50, (gears.tags.ST_TREASURE,))

Expand All @@ -459,3 +490,94 @@ def LOCALE_ENTER(self, camp: gears.GearHeadCampaign):
self.elements[DG_MONSTER_TAGS], camp.scene.scale).contents, myteam
)
self.last_update = camp.time


class AmmoTreasureChest(Plot):
LABEL = "DUNGEON_TREASURE"

DUNGEON_TYPES = {gears.tags.SCENE_BASE, gears.tags.SCENE_WAREHOUSE, gears.tags.SCENE_FACTORY, gears.tags.SCENE_GARAGE, gears.tags.SCENE_SHOP}

@classmethod
def matches(cls, pstate):
return (
cls.DUNGEON_TYPES.intersection(pstate.elements["LOCALE"].attributes) or
cls.LABEL == "TEST_DUNGEON_EXTRA"
)

def custom_init(self, nart):
myscene = self.elements["LOCALE"]
self.register_element("ROOM", self.elements[DG_ARCHITECTURE].get_a_room()(random.randint(5,10), random.randint(5,10)), dident="LOCALE")
mychest = self.register_element("GOAL", ghwaypoints.AmmoBox(treasure_rank=self.rank, anchor=pbge.randmaps.anchors.middle), dident="ROOM")
if random.randint(1,3) != 2:
self.add_sub_plot(nart, "MONSTER_ENCOUNTER", elements={"TYPE_TAGS": self.elements[DG_MONSTER_TAGS]})
return True


class LockedTreasureChest(Plot):
LABEL = "DUNGEON_TREASURE"

DUNGEON_TYPES = {gears.tags.SCENE_RUINS, gears.tags.SCENE_WAREHOUSE, gears.tags.SCENE_BUILDING}

@classmethod
def matches(cls, pstate):
return (
cls.DUNGEON_TYPES.intersection(pstate.elements["LOCALE"].attributes) or
cls.LABEL == "TEST_DUNGEON_EXTRA"
)

def custom_init(self, nart):
myscene = self.elements["LOCALE"]
self.register_element("ROOM", self.elements[DG_ARCHITECTURE].get_a_room()(random.randint(5,10), random.randint(5,10)), dident="LOCALE")
mychest = self.register_element("GOAL", ghwaypoints.LockedSteelBox(treasure_rank=self.rank, anchor=pbge.randmaps.anchors.middle,), dident="ROOM")
if random.randint(1,3) == 2:
self.add_sub_plot(nart, "MONSTER_ENCOUNTER", elements={"TYPE_TAGS": self.elements[DG_MONSTER_TAGS]})
return True


class StorageRoomRansack(Plot):
LABEL = "DUNGEON_TREASURE"

DUNGEON_TYPES = {gears.tags.SCENE_BASE, gears.tags.SCENE_WAREHOUSE}

@classmethod
def matches(cls, pstate):
return (
cls.DUNGEON_TYPES.intersection(pstate.elements["LOCALE"].attributes) or
cls.LABEL == "TEST_DUNGEON_EXTRA"
)

def custom_init(self, nart):
myscene = self.elements["LOCALE"]
myroom = self.register_element("ROOM", self.elements[DG_ARCHITECTURE].get_a_room()(random.randint(8,15), random.randint(8,15)), dident="LOCALE")
for t in range(random.randint(3,6)):
mychest = ghwaypoints.StorageBox(treasure_rank=self.rank, treasure_amount=50, treasure_type=(
gears.tags.ST_CONTRABAND, gears.tags.ST_ANTIQUE, gears.tags.ST_LOSTECH, gears.tags.ST_ESSENTIAL,
gears.tags.ST_TREASURE, gears.tags.ST_SURVIVAL, gears.tags.ST_TOOL, gears.tags.ST_MEDICINE, gears.tags.ST_MINERAL
))
if random.randint(1,5) != 1:
self.add_sub_plot(nart, "MONSTER_ENCOUNTER", elements={"TYPE_TAGS": self.elements[DG_MONSTER_TAGS]}, rank=self.rank+5)
return True


class PreZeroChest(Plot):
LABEL = "DUNGEON_TREASURE"

DUNGEON_TYPES = {gears.tags.SCENE_RUINS, gears.tags.SCENE_TEMPLE}

@classmethod
def matches(cls, pstate):
return (
cls.DUNGEON_TYPES.intersection(pstate.elements["LOCALE"].attributes) or
cls.LABEL == "TEST_DUNGEON_EXTRA"
)

def custom_init(self, nart):
myscene = self.elements["LOCALE"]
self.register_element("ROOM", self.elements[DG_ARCHITECTURE].get_a_room()(random.randint(5,10), random.randint(5,10)), dident="LOCALE")
mychest = self.register_element("GOAL", ghwaypoints.OldCrate(
treasure_rank=self.rank, anchor=pbge.randmaps.anchors.middle, treasure_amount=125,
treasure_type=(gears.tags.ST_ANTIQUE, gears.tags.ST_JEWELRY, gears.tags.ST_LOSTECH)
), dident="ROOM")
if random.randint(1,5) != 2:
self.add_sub_plot(nart, "MONSTER_ENCOUNTER", elements={"TYPE_TAGS": self.elements[DG_MONSTER_TAGS]})
return True
Loading

0 comments on commit aa96454

Please sign in to comment.