Skip to content

Commit

Permalink
MegaProps can move; progress made on the EscortShip objective
Browse files Browse the repository at this point in the history
  • Loading branch information
jwvhewitt committed Jul 15, 2024
1 parent b6f52cb commit a70158c
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 4 deletions.
79 changes: 76 additions & 3 deletions game/content/ghplots/mission_bigobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,14 @@ class BAM_EscortShip(Plot):
active = True
scope = "LOCALE"

DIRECTION_BY_ANCHOR = {
pbge.randmaps.anchors.north: megaprops.SOUTHWARD, pbge.randmaps.anchors.northeast: megaprops.SOUTHWARD,
pbge.randmaps.anchors.east: megaprops.WESTWARD, pbge.randmaps.anchors.southeast: megaprops.WESTWARD,
pbge.randmaps.anchors.south: megaprops.NORTHWARD, pbge.randmaps.anchors.southwest: megaprops.NORTHWARD,
pbge.randmaps.anchors.west: megaprops.EASTWARD, pbge.randmaps.anchors.northwest: megaprops.EASTWARD,
pbge.randmaps.anchors.middle: megaprops.NORTHWARD, None: megaprops.SOUTHWARD
}

def custom_init(self, nart):
myscene = self.elements["LOCALE"]
allyfac = self.elements.get("ALLIED_FACTION")
Expand All @@ -338,10 +346,12 @@ def custom_init(self, nart):
self.register_element(
"ESCORT_ROOM", ghrooms.OpenRoom(12, 12), dident=std_dident
)
entry_anchor = self.elements["ENTRANCE_ANCHOR"]

my_facing = self.register_element("_facing", self.DIRECTION_BY_ANCHOR.get(entry_anchor, megaprops.EASTWARD))

myship = self.register_element("SHIP", megaprops.CivilianWaterShip(rank=self.rank), dident="ESCORT_ROOM")

entry_anchor = self.elements["ENTRANCE_ANCHOR"]
troom = self.register_element(
"TARGET_ROOM", ghrooms.IndicatedRoom(
12, 12, anchor=pbge.randmaps.anchors.OPPOSITE_EDGE[entry_anchor]
Expand All @@ -357,17 +367,68 @@ def custom_init(self, nart):
self.elements[CTE_REINFORCEMENT_ROOMS] = reinforcement_rooms

team2: teams.Team = self.register_element(
CTE_ENEMY_TEAM, teams.Team(faction=myfac, enemies=(myscene.player_team,))
CTE_ENEMY_TEAM, teams.Team(faction=myfac, enemies=(myscene.player_team, myship))
)
self.register_element(CTE_INITIAL_ROOM, ghrooms.OpenRoom(10,10, anchor=pbge.randmaps.anchors.middle),
dident=std_dident)
self.add_sub_plot(nart, CTHREAT_MECHA, ident="THREAT")
self.did_init = False

self.obj = adventureseed.MissionObjective("Escort ship to safe zone", MAIN_OBJECTIVE_VALUE * 3)
self.adv.objectives.append(self.obj)
self.obj2 = adventureseed.MissionObjective("Protect ship from enemies", MAIN_OBJECTIVE_VALUE * 2)
self.adv.objectives.append(self.obj2)

self.initial_health = 0

return True

def t_START(self, camp: gears.GearHeadCampaign):
if not self.did_init:
self.subplots["THREAT"].activate(camp)
self.did_init = True
myprop = self.elements["SHIP"]
for p in myprop.get_members_in_play(camp):
self.initial_health += p.current_health

def t_COMBATROUND(self, camp: gears.GearHeadCampaign):
myprop = self.elements["SHIP"]
if not myprop.get_members_in_play(camp):
pbge.alert("Ship Destroyed", font=pbge.HUGEFONT, justify=0)
self.obj.failed = True
camp.check_trigger("FORCE_EXIT")
else:
facing = self.elements["_facing"]
for t in range(5):
myprop.move(camp, *facing)
if self._ship_has_escaped(camp, myprop, facing):
pbge.alert("Ship has escaped!")
self.obj.win(camp)
self.obj2.win(camp, sum([p.current_health for p in myprop.get_members_in_play(camp)]) * 100 // self.initial_health)
camp.check_trigger("FORCE_EXIT")
break

def _ship_has_escaped(self, camp: gears.GearHeadCampaign, ship: megaprops.MegaProp, facing):
troom = self.elements["TARGET_ROOM"]
all_out = True
for ship_part in ship.get_members_including_destroyed(camp):
if facing == megaprops.NORTHWARD:
if ship_part.pos[1] >= troom.area.bottom:
all_out = False
break
elif facing == megaprops.SOUTHWARD:
if ship_part.pos[1] < troom.area.top:
all_out = False
break
elif facing == megaprops.WESTWARD:
if ship_part.pos[0] >= troom.area.right:
all_out = False
break
else:
if ship_part.pos[0] < troom.area.left:
all_out = False
break
return all_out


# *******************************
Expand All @@ -385,7 +446,9 @@ def t_START(self, camp: gears.GearHeadCampaign):
CTE_MONSTER_TAGS = "CTE_MONSTER_TAGS"

CTE_ENEMY_TEAM = "ENEMY_TEAM"
CTE_INITIAL_ROOM = "INITIAL_ENEMY_ROOM" # May be None, in which case starts without enemies.
CTE_REINFORCEMENT_ROOMS = "REINFORCEMENT_ROOMS"
CTE_REINFOCEMENT_DELAY = "REINFORCEMENT_DELAY" # Defaults to a 1 round delay between reinforcements

class CTMecha(Plot):
LABEL = CTHREAT_MECHA
Expand All @@ -398,6 +461,15 @@ def custom_init(self, nart):
myroom = self.register_element("ROOM", roomtype(10, 10), dident="LOCALE")
self.elements[CTE_REINFORCEMENT_ROOMS] = [myroom,]

if CTE_INITIAL_ROOM in self.elements and self.elements[CTE_INITIAL_ROOM]:
myteam = self.elements.get(CTE_ENEMY_TEAM, teams.Team(enemies=(self.elements["LOCALE"].player_team,),
faction=self.elements.get("ENEMY_FACTION")))
myunit = gears.selector.RandomMechaUnit(
self.rank, 100, self.elements.get("ENEMY_FACTION"), self.elements["LOCALE"].environment,
add_commander=True
)
myteam.deploy_in_room(self.elements["LOCALE"], self.elements[CTE_INITIAL_ROOM], myunit.mecha_list)

self.reinforcements_counter = 1

return True
Expand All @@ -417,7 +489,7 @@ def deactivate(self, camp):
def add_reinforcements(self, camp):
myscene = self.elements["LOCALE"]
myrooms = self.elements[CTE_REINFORCEMENT_ROOMS]
myunit = gears.selector.RandomMechaUnit(self.rank, 100, self.elements.get("ENEMY_FACTION"),
myunit = gears.selector.RandomMechaUnit(self.rank, 70, self.elements.get("ENEMY_FACTION"),
camp.scene.environment, add_commander=False)
mek1 = myunit.mecha_list[0]
team2 = self.elements.get("ENEMY_TEAM", teams.Team(enemies=(myscene.player_team,)))
Expand All @@ -429,3 +501,4 @@ def t_COMBATROUND(self, camp):
self.reinforcements_counter -= 1
else:
self.add_reinforcements(camp)
self.reinforcements_counter = self.elements.get(CTE_REINFOCEMENT_DELAY, 1)
50 changes: 50 additions & 0 deletions game/content/megaprops.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from game import teams
import gears
import pbge
import random

class MegaProp(teams.Team):
POSITIONS = ((0,0), (1,0), (0,1), (-1,0), (0,-1))
Expand Down Expand Up @@ -29,6 +31,54 @@ def predeploy(self, gb, room):

super().predeploy(gb, room)

def move(self, camp: gears.GearHeadCampaign, dx=0, dy=0):
# Locate all the parts of this prop.
prop_parts = [p for p in camp.scene.contents if camp.scene.local_teams.get(p) is self]

# Locate all the positions where this prop is gonna be after the move.
destination_positions = {(p.pos[0] + dx, p.pos[1] + dy) for p in prop_parts}
blocked_tiles = camp.scene.get_blocked_tiles()
move_ok = True
collisions = list()
for actr in camp.scene.get_operational_actors():
if hasattr(actr, "pos") and actr not in prop_parts and actr.pos in destination_positions:
candidates = [vec for vec in camp.scene.ANGDIR if (actr.pos[0] + vec[0], actr.pos[1] + vec[1]) not in blocked_tiles]
if candidates:
push_vec = random.choice(candidates)
pbge.my_state.view.anim_list.append(
pbge.scenes.animobs.MoveModel(actr, dest=(actr.pos[0] + push_vec[0], actr.pos[1] + push_vec[1]))
)
blocked_tiles.add((actr.pos[0] + push_vec[0], actr.pos[1] + push_vec[1]))
collisions.append(actr)
else:
move_ok = False
collisions.append(actr)

if move_ok:
for p in prop_parts:
pbge.my_state.view.anim_list.append(pbge.scenes.animobs.MoveModel(p, dest=(p.pos[0] + dx, p.pos[1] + dy)))
pbge.my_state.view.handle_anim_sequence()
#self.deal_with_collisions(camp, collisions)
else:
pbge.my_state.view.anim_list.clear()
self.deal_with_collisions(camp, collisions)

def deal_with_collisions(self, camp, collisions):
invo = pbge.effects.Invocation(
name="Crash!!!",
fx=gears.geffects.DoDamage(
len(self.get_members_in_play(camp)), 10,
scatter=True, is_brutal=True, anim=gears.geffects.BigBoom
), area=pbge.scenes.targetarea.SingleTarget(),
)
invo.invoke(camp, None, [c.pos for c in collisions], pbge.my_state.view.anim_list)


NORTHWARD = (0,-1)
SOUTHWARD = (0,1)
EASTWARD = (1,0)
WESTWARD = (-1,0)


class CivilianWaterShip(MegaProp):
POSITIONS = ((0,0), (0,1), (0,-1), (0,2), (0,-2))
Expand Down
3 changes: 3 additions & 0 deletions game/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@ def retreat(self, camp):
def get_members_in_play(self, camp):
return [npc for npc in camp.scene.contents if
camp.scene.local_teams.get(npc, None) == self and npc.is_operational()]

def get_members_including_destroyed(self, camp):
return [npc for npc in camp.scene.contents if camp.scene.local_teams.get(npc, None) == self]
2 changes: 1 addition & 1 deletion history.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Room contents with fixed positions will now be placed on map
* Props are immovable even after they are destroyed
* Props will not be placed somewhere they can block movement
* calc_mission_reward can automatically round the reward to an round number
* calc_mission_reward can automatically round the reward to a round number
* Former lancemates who show up in buildings where they've been before will not be indicated as current members of the lance.
* A captured territory must be consolidated before another territory can be invaded in WorldMapWar
* PCs dying in a city scene should now be handled properly
Expand Down

0 comments on commit a70158c

Please sign in to comment.