Skip to content

Commit 96b77ae

Browse files
committed
Initial Commit of #26 - The Hunger Baubles
Adds Game to Server and Client Game Info Ships get info on cargo in Game Info Ships have maximum capacity and spawn near a 'Cornucopia'
1 parent 808571c commit 96b77ae

File tree

11 files changed

+381
-8
lines changed

11 files changed

+381
-8
lines changed
3.45 KB
Loading

SBA_Serv/Game/Game.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def player_added(self, player, reason):
198198
self.spawnmanager.player_added(reason)
199199

200200

201-
def player_get_start_position(self, force=False):
201+
def player_get_start_position(self):
202202
"""
203203
Should return a position for a player to start at in the world.
204204
"""
@@ -365,11 +365,11 @@ def _game_add_ship_for_player(self, netid, roundstart=False):
365365
self.__aiships[netid].timealive = 0
366366
self.__aiships[netid].body.velocity = Vec2d(0, 0)
367367
if not roundstart: # ai ship will be initialized with a starting position for round entry, but if killed, will randomize
368-
self.__aiships[netid].body.position = self.player_get_start_position(True)
368+
self.__aiships[netid].body.position = self.player_get_start_position()
369369

370370
self._players[netid].object.ship_added() # tell AI ship to start
371371
else:
372-
self._players[netid].object = Ship(self.player_get_start_position(True), self.world)
372+
self._players[netid].object = Ship(self.player_get_start_position(), self.world)
373373
logging.info("Adding Ship for Player %d id #%d with Name %s", netid, self._players[netid].object.id, self._players[netid].name)
374374
self._players[netid].object.player = self._players[netid]
375375
self._players[netid].object.owner = self._players[netid].object # Make ships owners of themselves for easier logic with ownership?

SBA_Serv/Game/TheHungerBaubles.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
"""
2+
Space Battle Arena is a Programming Game.
3+
4+
Copyright (C) 2012-2016 Michael A. Hawker and Brett Wortzman
5+
6+
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
7+
8+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9+
10+
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
11+
12+
The full text of the license is available online: http://opensource.org/licenses/GPL-2.0
13+
"""
14+
15+
from BaubleGame import *
16+
from Utils import CallbackTimer
17+
from World.Entities import Entity, PhysicalRound
18+
from World.WorldEntities import Ship
19+
from GUI.ObjWrappers.GUIEntity import GUIEntity, wrapcircle
20+
from World.WorldMath import intpos, friendly_type, PlayerStat, aligninstances, getPositionAwayFromOtherObjects
21+
from GUI.GraphicsCache import Cache
22+
from GUI.Helpers import debugfont
23+
from ThreadStuff.ThreadSafe import ThreadSafeDict
24+
import logging
25+
import pygame
26+
import random
27+
import thread
28+
import math
29+
from operator import attrgetter
30+
31+
class TheHungerBaublesGame(BaseBaubleGame):
32+
def __init__(self, cfgobj):
33+
34+
self._respawn = cfgobj.getboolean("TheHungerBaubles", "respawn_bauble_on_collect")
35+
self.__maxcarry = cfgobj.getint("TheHungerBaubles", "ship_cargo_size")
36+
self.__cornucopia_position = (0, 0)
37+
self.__cornucopia_radius = cfgobj.getint("TheHungerBaubles", "cornucopia_radius")
38+
self.__spawned_num = 0
39+
40+
super(TheHungerBaublesGame, self).__init__(cfgobj)
41+
42+
def game_get_info(self):
43+
return {"GAMENAME": "TheHungerBaubles"}
44+
45+
def player_added(self, player, reason):
46+
super(TheHungerBaublesGame, self).player_added(player, reason)
47+
player.carrying = []
48+
player.collected = 0
49+
50+
def player_get_start_position(self):
51+
if self.cfg.getboolean("Tournament", "tournament"):
52+
div = 360 / (len(self._players) / self.cfg.getint("Tournament", "groups"))
53+
else:
54+
div = 200
55+
56+
ang = div * self.__spawned_num
57+
self.__spawned_num += 1
58+
dist = self.__cornucopia_radius + 64
59+
return (min(max(32, self.__cornucopia_position[0] + math.cos(math.radians(ang)) * dist), self.world.width - 32),
60+
min(max(32, self.__cornucopia_position[1] + math.sin(math.radians(ang)) * dist), self.world.height - 32))
61+
62+
def world_add_remove_object(self, wobj, added):
63+
# Check if this is a high-value bauble to add to our list of ones to pass to the client
64+
65+
# TODO: If an Asteroid or Dragon is destroyed, deposit bauble
66+
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)
71+
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)
80+
81+
def get_player_cargo_value(self, player):
82+
return sum(b.value for b in player.carrying)
83+
84+
def get_player_cargo_weight(self, player):
85+
return sum(b.weight for b in player.carrying)
86+
87+
def collectBaubles(self, ship, bauble):
88+
logging.info("Collected Baubles Ship #%d", ship.id)
89+
if self.get_player_cargo_weight(ship.player) + bauble.weight <= self.__maxcarry:
90+
ship.player.carrying.append(bauble)
91+
ship.player.collected += 1
92+
ship.player.update_score(bauble.value)
93+
ship.player.sound = "BAUBLE"
94+
95+
bauble.destroyed = True
96+
97+
if self._respawn:
98+
Bauble.spawn(self.world, self.cfg)
99+
else:
100+
logging.info("Player #%d Cargo Full", ship.id)
101+
#eif
102+
logging.info("Done Collecting Baubles #%d", ship.id)
103+
104+
def player_died(self, player, gone):
105+
# 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)
111+
112+
return super(TheHungerBaublesGame, self).player_died(player, gone)
113+
114+
def game_get_extra_environment(self, player):
115+
v = 0
116+
w = 0
117+
for b in player.carrying:
118+
v += b.value
119+
w += b.weight
120+
baubles = []
121+
for b in player.carrying:
122+
baubles.append({ "MASS": b.weight, "VALUE": b.value, "ID": b.id})
123+
124+
env = super(TheHungerBaublesGame, self).game_get_extra_environment(player)
125+
env.update({"POSITION": self.__cornucopia_position, "BAUBLES": baubles})
126+
127+
return env
128+
129+
def game_get_extra_radar_info(self, obj, objdata, player):
130+
"""
131+
Called by the World when the obj is being radared
132+
"""
133+
super(TheHungerBaublesGame, self).game_get_extra_radar_info(obj, objdata, player)
134+
if hasattr(obj, "player"):
135+
objdata["NUMSTORED"] = len(obj.player.carrying)
136+
objdata["VALUE"] = self.get_player_cargo_value(obj.player)
137+
138+
def player_get_stat_string(self, player):
139+
return str(int(player.bestscore)) + " - " + str(int(player.score)) + " in " + str(player.collected) + " : " + player.name + " w. " + str(self.get_player_cargo_weight(player))
140+
141+
def gui_draw_game_world_info(self, surface, flags, trackplayer):
142+
for player in self.game_get_current_player_list():
143+
obj = player.object
144+
if obj != None:
145+
# draw number of objects carried
146+
text = debugfont().render(repr(len(player.carrying)), False, player.color)
147+
surface.blit(text, (obj.body.position[0]-30, obj.body.position[1]-4))
148+
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)
154+
155+
# draw number of baubles carried by player
156+
157+
def round_start(self):
158+
logging.info("Game Start")
159+
160+
self.__spawned_num = 0
161+
162+
super(TheHungerBaublesGame, self).round_start()
163+
164+
def world_create(self):
165+
super(TheHungerBaublesGame, self).world_create()
166+
167+
self.__cornucopia_position = getPositionAwayFromOtherObjects(self.world, self.cfg.getint("TheHungerBaubles", "cornucopia_buffer_object"), self.cfg.getint("TheHungerBaubles", "cornucopia_buffer_edge"))
168+
169+
#TODO: Remove anything left inside cornucopia?

SBA_Serv/SBA_Serv.pyproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<Compile Include="Game\BaubleGame.py">
3737
<SubType>Code</SubType>
3838
</Compile>
39+
<Compile Include="Game\TheHungerBaubles.py" />
3940
<Compile Include="Game\BaubleHunt.py" />
4041
<Compile Include="Game\DiscoveryQuest.py">
4142
<SubType>Code</SubType>
@@ -143,6 +144,7 @@
143144
<Content Include="basicgame_survivor.cfg" />
144145
<Content Include="empty.cfg" />
145146
<Content Include="basicgame_hungryhungrybaubles_original.cfg" />
147+
<Content Include="game_thehungerbaubles.cfg" />
146148
<Content Include="game_kingofspace.cfg" />
147149
<Content Include="game_discoveryquest.cfg" />
148150
<Content Include="game_kingofthebubble.cfg" />

SBA_Serv/game_thehungerbaubles.cfg

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[Planet]
2+
number = 1
3+
4+
[BlackHole]
5+
number = 1
6+
7+
[Asteroid]
8+
number = 4
9+
spawn_keep_max = 10
10+
spawn_time_num = 1
11+
spawn_time_min = 20
12+
spawn_time_max = 30
13+
14+
[Bauble]
15+
number = 10
16+
buffer_object = 80
17+
buffer_edge = 30
18+
spawn_keep_min = 12
19+
spawn_keep_max = 48
20+
spawn_on_player_num = 1
21+
spawn_on_player_start = true
22+
spawn_on_player_respawn = false
23+
spawn_time_num = 1
24+
spawn_time_min = 10
25+
spawn_time_max = 15
26+
27+
[Game]
28+
game = TheHungerBaubles
29+
reset_score_on_death = true
30+
primary_victory_attr = bestscore
31+
secondary_victory_attr = collected
32+
33+
[BaubleGame]
34+
bauble_points = 1, 2, 3, 4, 5, 6, 7
35+
bauble_percent = 0.4, 0.2, 0.15, 0.1, 0.075, 0.05, 0.025
36+
bauble_invert_ratio_percent = 0.1, 0.2, 0.4, 0.5, 0.6, 0.8, 0.9
37+
bauble_weights = 1, 3, 5
38+
bauble_weight_percent = 0.7, 0.2, 0.1
39+
40+
[TheHungerBaubles]
41+
ship_cargo_size = 25
42+
respawn_bauble_on_collect = true
43+
cornucopia_radius = 200
44+
cornucopia_buffer_edge = 300
45+
cornucopia_buffer_object = 250

changelog.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
v1.2 : Planned - May 2016 [Season 5]
1+
v1.2 : Planned - May 2016 [Season 5] - The Hunger Baubles
22
----
3-
* Added Worm Holes (teleports objects across space)
4-
* Added Deployable Space Mines
3+
* Added **The Hunger Baubles** Subgame
4+
* Bauble Games can now spawn any number of different valued Baubles.
5+
* Bauble Games can now spawn different weights of Baubles.
6+
* Added Worm Holes (teleports objects across space)
7+
* Added Deployable Space Mines
58
* Updated Client Angle/Point Methods
69
* Orientations are always integers now and should be between 0-360
710
* Rotate and Steer Command parameters updated
@@ -38,8 +41,6 @@ v1.2 : Planned - May 2016 [Season 5]
3841
* Made **Hungry Hungry Baubles** a Basic Game by creating a *getObjectiveLocation()* method on BasicGameInfo (instead of *getGoldenBaublePosition()*). This is now also used by **Bauble Hunt** and **Discovery Quest** instead of *getHomeBasePosition()*.
3942
* Hungry Hungry Baubles has new options for configuration (default is similar to previous incarnation).
4043
* Hungry Hungry Baubles and Bauble Hunt now share new *[BaubleGame]* point/percentage spawning parameters.
41-
* Bauble Games can now spawn any number of different valued Baubles.
42-
* Bauble Games can now spawn different weights of Baubles.
4344
* **Bauble Hunt** now respects weight not number carried for *ship_cargo_size*. Default weights are set to 1 though to behave in same manner as previously.
4445
* *BaubleHuntGameInfo* has *getBaublesCarriedWeight* method now.
4546
* RotateCommand/Orientation Related Client code now uses **int** vs. **double**.

doc/games/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ outline:
1010
- { url: "combatexercise.html", title: "Combat Exercise" }
1111
- { url: "hungryhungrybaubles.html", title: "Hungry Hungry Baubles" }
1212
- { url: "baublehunt.html", title: "Bauble Hunt" }
13+
- { url: "thehungerbaubles.html", title: "The Hunger Baubles" }
1314
- { url: "kingofthebubble.html", title: "King of the Bubble" }
1415
- { url: "kingofthebubble.html#kos", title: "King of Space" }
1516
- { url: "discoveryquest.html", title: "Discovery Quest" }

doc/games/thehungerbaubles.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: The Hunger Baubles
3+
nav:
4+
- { url: "index.html", title: "Competitions" }
5+
outline-header: Outline
6+
outline:
7+
- { url: "#overview", title: "Overview" }
8+
- { url: "#config", title: "Configuration" }
9+
---
10+
11+
The Hunger Baubles
12+
=============
13+
14+
<a name="overview"></a>Overview
15+
-----------
16+
**The Hunger Baubles** is a more complex version of the [Bauble Hunt](baublehunt.html) game.
17+
18+
The Hunger Baubles are a game where you must hunt for the best collection of baubles.
19+
20+
Baubles have varying values and weights, and your ship can only carry so many. You must use the Collect and Eject commands effectively in order to pick and choose your baubles.
21+
22+
Your cargo hold has a maximum weight capacity of 25.
23+
24+
Blue Baubles are worth 1 point.
25+
Green Baubles are worth 2 points.
26+
Golden Baubles are worth 3 points.
27+
Orange Baubles are worth 4 points.
28+
Red Baubles are worth 5 points.
29+
Purple Baubles are worth 6 points.
30+
Cyan Baubles are worth 7 points.
31+
32+
If your ship is destroyed, the Baubles it was carrying will be dropped. However, your score is the best score you've achieved.
33+
34+
In the case of a tie, who ever has the fewest baubles collected will be the winner (i.e. density of points is rewarded in a tie).
35+
36+
Control Bauble spawning behavior by using the standard [Spawn Manager](../server/config.html#spawnmanager) properties.
37+
38+
<a name="config"></a>Configuration
39+
-----------
40+
41+
##[BaubleGame]
42+
43+
###bauble_points = list[int]
44+
List of points each progressive bauble is worth. **Note:** *modifying the point values requires that adequate images be placed in the GUI/Graphics/Games folder to represent that value.*
45+
46+
###bauble_percent = list[float]
47+
The percentage of baubles which should generate as the corresponding value. Each value should be from [0.0-1.0]. The total of all values provided in this list should equal 1.0.
48+
49+
###bauble_weights = list[int]
50+
List of weight values to use for Bauble Generation (defaults to 1).
51+
52+
###bauble_weight_percent = list[float]
53+
Percentage that each of corresponding weighted baubles in the *bauble_weights* should appear. Each value should be from [0.0-1.0]. The total of all weights provided in this list should equal 1.0.
54+
55+
###bauble_invert_ratio_percent = list[float]
56+
Each float in this list corresponds to a value of bauble in the *bauble_points* list (i.e. you should have the same number of floats in this list as values of baubles). The value [0.0-1.0] for each bauble specifies the percent chance that the weight percentage used from *bauble_weight_percent* is inverted (i.e. 0.8, 0.2 becomes 0.2, 0.8 for that bauble value). E.g. set to 1.0 if you want the weight percentages to always be opposite for that value of bauble. If this option is not specified, it will be set to 0.0 for all bauble values.
57+
58+
59+
##[TheHungerBaubles]
60+
61+
###ship_cargo_size = int
62+
The maximum number of baubles each ship can carry.
63+
64+
###respawn_bauble_on_collect = boolean
65+
Should a new bauble be spawned every time one is collected?
66+
67+
###cornucopia_radius = int
68+
How big should the cornucopia area be.
69+
70+
###cornucopia_buffer_edge = int
71+
How far should the cornucopia be from the edge of the world.
72+
73+
###cornucopia_buffer_object = int
74+
How far should the cornucopia be from the edge of other objects.

doc/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Documentation
6262
* [Combat Exercise](games/combatexercise.html)
6363
* [Hungry Hungry Baubles](games/hungryhungrybaubles.html)
6464
* [Bauble Hunt](games/baublehunt.html)
65+
* [The Hunger Baubles](games/thehungerbaubles.html)
6566
* [King of the Bubble](games/kingofthebubble.html)
6667
* [King of Space (Variant)](games/kingofthebubble.html#kos)
6768
* [Discovery Quest](games/discoveryquest.html)

0 commit comments

Comments
 (0)