Skip to content

Commit b8296d6

Browse files
committed
Adds to #26 - The Hunger Baubles Collect & Eject Commands for Bauble Management
Adds ability to Limit Weapon Fire per Ship. The Hunger Baubles Game Info has booleans to tell you if you fired weapons. Add zoom when clicking tracked ship in GUI.
1 parent 96b77ae commit b8296d6

File tree

11 files changed

+245
-28
lines changed

11 files changed

+245
-28
lines changed

SBA_Serv/GUI/Sounds/EJECT.WAV

50.4 KB
Binary file not shown.

SBA_Serv/GUI/Sounds/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ Played when depositing Baubles in an Outpost for Bauble Hunt.
103103

104104
*3 down 1* by **fins**
105105

106+
[EJECT](https://www.freesound.org/people/BinaryMonkFlint/sounds/333295/)
107+
-------
108+
Played when ejecting a Bauble in The Hunger Baubles.
109+
110+
*Remove from socket* by **BinaryMonkFlint**
111+
106112
[MISSION](https://www.freesound.org/people/VASOTELVI/sounds/187917/)
107113
-------
108114
Played when a Ship completes a mission successfully in Discovery Quest.

SBA_Serv/GUI/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ def centerViewOnWorld(pos):
421421
if isinstance(obj, ShipGUI) and math.sqrt(obj._worldobj.body.position.get_dist_sqrd(v)) <= 32:
422422
logging.info("[GUI] Click Tracking Object #%d", obj._worldobj.id)
423423
trackplayer = obj._worldobj.player
424+
zoomout = False
424425
dynamiccamera = False
425426
break
426427
elif zoomout and event.button == 1:

SBA_Serv/Game/TheHungerBaubles.py

Lines changed: 109 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,24 @@
1515
from BaubleGame import *
1616
from Utils import CallbackTimer
1717
from World.Entities import Entity, PhysicalRound
18-
from World.WorldEntities import Ship
18+
from World.WorldEntities import Ship, Weapon, Torpedo, SpaceMine, Dragon, Asteroid
1919
from GUI.ObjWrappers.GUIEntity import GUIEntity, wrapcircle
2020
from World.WorldMath import intpos, friendly_type, PlayerStat, aligninstances, getPositionAwayFromOtherObjects
2121
from GUI.GraphicsCache import Cache
2222
from GUI.Helpers import debugfont
2323
from ThreadStuff.ThreadSafe import ThreadSafeDict
24+
from World.WorldCommands import FireTorpedoCommand, DeploySpaceMineCommand
25+
from World.Messaging import OneTimeCommand
2426
import logging
2527
import pygame
2628
import random
2729
import thread
2830
import math
2931
from operator import attrgetter
3032

33+
GAME_CMD_COLLECT = "COLCT"
34+
GAME_CMD_EJECT = "EJECT"
35+
3136
class TheHungerBaublesGame(BaseBaubleGame):
3237
def __init__(self, cfgobj):
3338

@@ -37,6 +42,9 @@ def __init__(self, cfgobj):
3742
self.__cornucopia_radius = cfgobj.getint("TheHungerBaubles", "cornucopia_radius")
3843
self.__spawned_num = 0
3944

45+
self.collect_radius = cfgobj.getint("TheHungerBaubles", "collect_radius")
46+
self.__limit_weapons = cfgobj.getboolean("TheHungerBaubles", "limit_weapons")
47+
4048
super(TheHungerBaublesGame, self).__init__(cfgobj)
4149

4250
def game_get_info(self):
@@ -46,6 +54,8 @@ def player_added(self, player, reason):
4654
super(TheHungerBaublesGame, self).player_added(player, reason)
4755
player.carrying = []
4856
player.collected = 0
57+
player.torpedo = False
58+
player.mine = False
4959

5060
def player_get_start_position(self):
5161
if self.cfg.getboolean("Tournament", "tournament"):
@@ -64,19 +74,13 @@ def world_add_remove_object(self, wobj, added):
6474

6575
# TODO: If an Asteroid or Dragon is destroyed, deposit bauble
6676

67-
return super(TheHungerBaublesGame, self).world_add_remove_object(wobj, added)
68-
69-
def world_physics_pre_collision(self, obj1, obj2):
70-
ship, other = aligninstances(obj1, obj2, Ship, Entity)
77+
if isinstance(wobj, Weapon) and wobj.owner != None and wobj.owner.player != None:
78+
if isinstance(wobj, Torpedo):
79+
wobj.owner.player.torpedo = added
80+
elif isinstance(wobj, SpaceMine):
81+
wobj.owner.player.mine = added
7182

72-
if ship != None:
73-
#if isinstance(other, Outpost):
74-
# logging.info("Ship #%d hit their base", ship.id)
75-
# return [ False, [self.depositBaubles, ship, other] ]
76-
if isinstance(other, Bauble):
77-
return [ False, [self.collectBaubles, ship, other] ]
78-
79-
return super(TheHungerBaublesGame, self).world_physics_pre_collision(obj1, obj2)
83+
return super(TheHungerBaublesGame, self).world_add_remove_object(wobj, added)
8084

8185
def get_player_cargo_value(self, player):
8286
return sum(b.value for b in player.carrying)
@@ -85,7 +89,7 @@ def get_player_cargo_weight(self, player):
8589
return sum(b.weight for b in player.carrying)
8690

8791
def collectBaubles(self, ship, bauble):
88-
logging.info("Collected Baubles Ship #%d", ship.id)
92+
logging.info("Collected Baubles Ship #%d bauble #%d", ship.id, bauble.id)
8993
if self.get_player_cargo_weight(ship.player) + bauble.weight <= self.__maxcarry:
9094
ship.player.carrying.append(bauble)
9195
ship.player.collected += 1
@@ -101,16 +105,50 @@ def collectBaubles(self, ship, bauble):
101105
#eif
102106
logging.info("Done Collecting Baubles #%d", ship.id)
103107

108+
def ejectBauble(self, player, bauble, died=False):
109+
logging.info("Ejecting Bauble Player %d Bauble #%d", player.netid, bauble.id)
110+
bauble.body.position = (player.object.body.position[0] + random.randint(-36, 36), player.object.body.position[1] + random.randint(-36, 36))
111+
bauble.destroyed = False # reset so that it won't get cleaned up
112+
player.carrying.remove(bauble)
113+
if not died:
114+
player.collected -= 1
115+
player.update_score(-bauble.value)
116+
117+
self.world.append(bauble)
118+
logging.info("Done Ejecting Baubles Player %d", player.netid)
119+
104120
def player_died(self, player, gone):
105121
# if ship destroyed, put baubles stored back
106-
for b in player.carrying:
107-
b.body.position = (player.object.body.position[0] + random.randint(-36, 36), player.object.body.position[1] + random.randint(-36, 36))
108-
b.destroyed = False # reset so that it won't get cleaned up
109-
110-
self.world.append(b)
122+
for b in player.carrying[:]:
123+
self.ejectBauble(player, b, True)
111124

112125
return super(TheHungerBaublesGame, self).player_died(player, gone)
113126

127+
def server_process_network_message(self, ship, cmdname, cmddict={}):
128+
if cmdname == GAME_CMD_COLLECT:
129+
if cmddict.has_key("ID") and isinstance(cmddict["ID"], int) and cmddict["ID"] > 0:
130+
return CollectCommand(ship, self, cmddict["ID"])
131+
else:
132+
return "The Hunger Baubles Collect Command requires an id."
133+
elif cmdname == GAME_CMD_EJECT:
134+
if cmddict.has_key("ID") and isinstance(cmddict["ID"], int) and cmddict["ID"] > 0:
135+
return EjectCommand(ship, self, cmddict["ID"])
136+
else:
137+
return "The Hunger Baubles Eject Command requires an id."
138+
139+
def server_process_command(self, ship, command):
140+
# The Hunger Baubles prevents firing while another torpedo of your exists
141+
#logging.info("Checking Command %s %s", repr(command), repr(ship.in_celestialbody))
142+
if self.__limit_weapons and hasattr(ship, "player"):
143+
if isinstance(command, FireTorpedoCommand) and ship.player.torpedo:
144+
logging.info("Preventing Ship #%d From Firing Torpedo", ship.id)
145+
return "The Hunger Baubles Rule - Can only fire one torpedo at a time"
146+
elif isinstance(command, DeploySpaceMineCommand) and ship.player.mine:
147+
logging.info("Preventing Ship #%d From Deploying Space Mine", ship.id)
148+
return "The Hunger Baubles Rule - Can only fire one space mine at a time"
149+
150+
return command
151+
114152
def game_get_extra_environment(self, player):
115153
v = 0
116154
w = 0
@@ -122,7 +160,8 @@ def game_get_extra_environment(self, player):
122160
baubles.append({ "MASS": b.weight, "VALUE": b.value, "ID": b.id})
123161

124162
env = super(TheHungerBaublesGame, self).game_get_extra_environment(player)
125-
env.update({"POSITION": self.__cornucopia_position, "BAUBLES": baubles})
163+
env.update({"POSITION": self.__cornucopia_position, "BAUBLES": baubles,
164+
"TORPEDO": player.torpedo, "MINE": player.mine })
126165

127166
return env
128167

@@ -143,16 +182,15 @@ def gui_draw_game_world_info(self, surface, flags, trackplayer):
143182
obj = player.object
144183
if obj != None:
145184
# draw number of objects carried
185+
bp = intpos(obj.body.position)
146186
text = debugfont().render(repr(len(player.carrying)), False, player.color)
147-
surface.blit(text, (obj.body.position[0]-30, obj.body.position[1]-4))
187+
surface.blit(text, (bp[0]-36, bp[1]-4))
148188
text = debugfont().render(repr(self.get_player_cargo_weight(player)), False, player.color)
149-
surface.blit(text, (obj.body.position[0]+30, obj.body.position[1]-4))
150-
# draw line between player and HomeBase
151-
#if flags["DEBUG"] and self.__bases.has_key(player.netid):
152-
#pygame.draw.line(surface, player.color, intpos(obj.body.position), intpos(self.__bases[player.netid].body.position))
153-
wrapcircle(surface, (255, 255, 0), self.__cornucopia_position, self.__cornucopia_radius, self.world.size, 3)
189+
surface.blit(text, (bp[0]+32, bp[1]-4))
190+
wrapcircle(surface, (0, 255, 255), bp, self.collect_radius, self.world.size, 1) # Pick up Range
154191

155-
# draw number of baubles carried by player
192+
# Cornucopia
193+
wrapcircle(surface, (255, 255, 0), self.__cornucopia_position, self.__cornucopia_radius, self.world.size, 3)
156194

157195
def round_start(self):
158196
logging.info("Game Start")
@@ -167,3 +205,47 @@ def world_create(self):
167205
self.__cornucopia_position = getPositionAwayFromOtherObjects(self.world, self.cfg.getint("TheHungerBaubles", "cornucopia_buffer_object"), self.cfg.getint("TheHungerBaubles", "cornucopia_buffer_edge"))
168206

169207
#TODO: Remove anything left inside cornucopia?
208+
209+
class CollectCommand(OneTimeCommand):
210+
"""
211+
The CollectCommand lets you pick up baubles in The Hunger Baubles Game.
212+
213+
The ID of the object to pick up is required and must be within a specific distance from your ship.
214+
"""
215+
NAME = GAME_CMD_COLLECT
216+
217+
def __init__(self, obj, game, id):
218+
super(CollectCommand, self).__init__(obj, CollectCommand.NAME, required=8)
219+
self.target = id
220+
self.game = game
221+
222+
def onetime(self):
223+
for wobj in self.game.world.getObjectsInArea(self._obj.body.position, self.game.collect_radius):
224+
if wobj.id == self.target and isinstance(wobj, Bauble):
225+
self.game.collectBaubles(self._obj, wobj)
226+
227+
def __repr__(self):
228+
return super(CollectCommand, self).__repr__() + " ID: #%d" % (self.target)
229+
230+
class EjectCommand(OneTimeCommand):
231+
"""
232+
The EjectCommand lets you eject baubles in The Hunger Baubles Game.
233+
234+
The ID of the object to pick up is required and must be within a specific distance from your ship.
235+
"""
236+
NAME = GAME_CMD_EJECT
237+
238+
def __init__(self, obj, game, id):
239+
super(EjectCommand, self).__init__(obj, EjectCommand.NAME, required=24)
240+
self.target = id
241+
self.game = game
242+
243+
def onetime(self):
244+
for wobj in self._obj.player.carrying:
245+
if wobj.id == self.target:
246+
self._obj.player.sound = "EJECT"
247+
self.game.ejectBauble(self._obj.player, wobj)
248+
return
249+
250+
def __repr__(self):
251+
return super(EjectCommand, self).__repr__() + " ID: #%d" % (self.target)

SBA_Serv/buildnum

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1120
1+
1121

SBA_Serv/game_thehungerbaubles.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,5 @@ respawn_bauble_on_collect = true
4343
cornucopia_radius = 200
4444
cornucopia_buffer_edge = 300
4545
cornucopia_buffer_object = 250
46+
collect_radius = 48
47+
limit_weapons = true

doc/games/thehungerbaubles.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@ How far should the cornucopia be from the edge of the world.
7272

7373
###cornucopia_buffer_object = int
7474
How far should the cornucopia be from the edge of other objects.
75+
76+
###collect_radius = int
77+
How far can a bauble be away from the ship for the Collect Command to pick it up.
78+
79+
###limit_weapons = boolean
80+
Should each player be limited to having one torpedo and one space mine in the world at a time?
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ihs.apcs.spacebattle.commands;
2+
3+
/**
4+
* "The Hunger Baubles" specific command to pick up the specified Bauble.
5+
* <p>
6+
* An id of the nearby bauble is required and must be within range to be picked up.
7+
*
8+
* @author Michael A. Hawker
9+
*
10+
* @since 1.2
11+
* @version 1.2
12+
*/
13+
public class CollectCommand extends ShipCommand {
14+
@SuppressWarnings("unused")
15+
private int ID;
16+
17+
/**
18+
* Creates a command to pick up the specified Bauble in range.
19+
* @param target id number of the bauble.
20+
*/
21+
public CollectCommand(int target) {
22+
this.ID = target;
23+
}
24+
25+
/* (non-Javadoc)
26+
* @see ihs.apcs.spacebattle.commands.ShipCommand#getName()
27+
*/
28+
@Override
29+
public String getName() {
30+
return CommandNames.Collect.toString();
31+
}
32+
33+
/**
34+
* Gets the one-time energy cost to initiate this command.
35+
* @return the amount of energy consumed by initiating this command (8)
36+
*/
37+
public static int getInitialEnergyCost() { return 8; }
38+
39+
/**
40+
* Collecting Baubles executes immediately.
41+
*
42+
* @return true
43+
*/
44+
public static boolean executesImmediately() { return true; }
45+
}

java_client_src/src/ihs/apcs/spacebattle/commands/CommandNames.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ public String toString() {
2525
return "CLOAK";
2626
}
2727
},
28+
Collect {
29+
public String toString() {
30+
return "COLCT";
31+
}
32+
},
2833
DeployLaserBeacon {
2934
public String toString() {
3035
return "DLBN";
@@ -40,6 +45,11 @@ public String toString() {
4045
return "DAYLB";
4146
}
4247
},
48+
Eject {
49+
public String toString() {
50+
return "EJECT";
51+
}
52+
},
4353
FireTorpedo {
4454
public String toString() {
4555
return "FIRE";
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ihs.apcs.spacebattle.commands;
2+
3+
/**
4+
* "The Hunger Baubles" specific command to eject the specified Bauble from your ship's cargo hold.
5+
* <p>
6+
* An id of a bauble is required and must be contained within your ship. See {@link ihs.apcs.spacebattle.games.TheHungerBaublesGameInfo#getBaublesInCargo()}.
7+
*
8+
* @author Michael A. Hawker
9+
*
10+
* @since 1.2
11+
* @version 1.2
12+
*/
13+
public class EjectCommand extends ShipCommand {
14+
@SuppressWarnings("unused")
15+
private int ID;
16+
17+
/**
18+
* Creates a command to drop the specified Bauble.
19+
* @param target id number of the bauble.
20+
*/
21+
public EjectCommand(int target) {
22+
this.ID = target;
23+
}
24+
25+
/* (non-Javadoc)
26+
* @see ihs.apcs.spacebattle.commands.ShipCommand#getName()
27+
*/
28+
@Override
29+
public String getName() {
30+
return CommandNames.Eject.toString();
31+
}
32+
33+
/**
34+
* Gets the one-time energy cost to initiate this command.
35+
* @return the amount of energy consumed by initiating this command (24)
36+
*/
37+
public static int getInitialEnergyCost() { return 24; }
38+
39+
/**
40+
* Ejecting Baubles executes immediately.
41+
*
42+
* @return true
43+
*/
44+
public static boolean executesImmediately() { return true; }
45+
}

0 commit comments

Comments
 (0)