1515from BaubleGame import *
1616from Utils import CallbackTimer
1717from World .Entities import Entity , PhysicalRound
18- from World .WorldEntities import Ship
18+ from World .WorldEntities import Ship , Weapon , Torpedo , SpaceMine , Dragon , Asteroid
1919from GUI .ObjWrappers .GUIEntity import GUIEntity , wrapcircle
2020from World .WorldMath import intpos , friendly_type , PlayerStat , aligninstances , getPositionAwayFromOtherObjects
2121from GUI .GraphicsCache import Cache
2222from GUI .Helpers import debugfont
2323from ThreadStuff .ThreadSafe import ThreadSafeDict
24+ from World .WorldCommands import FireTorpedoCommand , DeploySpaceMineCommand
25+ from World .Messaging import OneTimeCommand
2426import logging
2527import pygame
2628import random
2729import thread
2830import math
2931from operator import attrgetter
3032
33+ GAME_CMD_COLLECT = "COLCT"
34+ GAME_CMD_EJECT = "EJECT"
35+
3136class 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 )
0 commit comments