def __init__(self, pos, world): super(Ship, self).__init__(28, 500, pos) self._world = world # NOTE: The ONLY reason this is here/needed is because the ship is creating a Torpedo from it's command system... self.energyRechargeRate = 4 self.body.velocity_limit = 100 # Ship Specific self.commandQueue = CommandSystem(self, 4) self.shield = PlayerStat(100) self.shieldConversionRate = 1.0 # Amount of Shield Recovered Per Energy (Higher Better) self.shieldDamageReduction = 0.8 # Amount Damage is Multiplied by and taken from Shields before health is touched (Higher Better) self.radarRange = 300 self.energy = PlayerStat(100) self.energyRechargeRate = 4 self.thrusterForce = 3500 self.rotationAngle = random.randint(0, 359) self.rotationSpeed = 120 #self.resources = PlayerStat(1000) #self.resources.empty() #self.miningSpeed = 8 self.tractorbeamForce = 10000 self.lasernodes = [] # extra state self.killed = False # forcibly removed object 'for good'
def __init__(self): self.id = Entity.IDs Entity.IDs += random.randint(1, 8) # Prevent guessing of id assignments self.messageQueue = MessageQueue() self.health = PlayerStat(100) self.energy = PlayerStat(0) self.energyRechargeRate = 0 # Amount of Energy Recovered Per Second self.timealive = 0 self.TTL = None # None means will live 'forever', otherwise if timealive > TTL (time to live), then the object will be automatically cleaned up in gameloop and destroyed. self.in_celestialbody = [ ] # keeps track of celestial bodies this object is in self.destroyed = False # keeps track of if the object has been destroyed and needs to be removed from the world in the next gameloop.
def setCommandBufferSize(self, size): old = self.commandQueue[:] self.commandQueue = MessageQueue(size) self.commandQueue.extend(old)
class Ship(PhysicalRound): """ A Ship is the main entity a player controls in the world. Attributes: killed: boolean different than destroyed, represents an object forcibly removed from the world (by GUI or end of round), should NOT respawn """ def __init__(self, pos, world): super(Ship, self).__init__(28, 500, pos) self._world = world # NOTE: The ONLY reason this is here/needed is because the ship is creating a Torpedo from it's command system... self.energyRechargeRate = 4 self.body.velocity_limit = 100 # Ship Specific self.commandQueue = CommandSystem(self, 4) self.shield = PlayerStat(100) self.shieldConversionRate = 1.0 # Amount of Shield Recovered Per Energy (Higher Better) self.shieldDamageReduction = 0.8 # Amount Damage is Multiplied by and taken from Shields before health is touched (Higher Better) self.radarRange = 300 self.energy = PlayerStat(100) self.energyRechargeRate = 4 self.thrusterForce = 3500 self.rotationAngle = random.randint(0, 359) self.rotationSpeed = 120 #self.resources = PlayerStat(1000) #self.resources.empty() #self.miningSpeed = 8 self.tractorbeamForce = 10000 self.lasernodes = [] # extra state self.killed = False # forcibly removed object 'for good' def setCommandBufferSize(self, size): old = self.commandQueue[:] self.commandQueue = MessageQueue(size) self.commandQueue.extend(old) def take_damage(self, damage, by=None, force=False): logging.debug("Ship #%d taking damage %d", self.id, damage) if self.commandQueue.containstype(RaiseShieldsCommand, force) and self.shield.value > 0: logging.debug("Shields of #%d absorbed %d damage", self.id, damage * self.shieldDamageReduction) self.shield -= damage * self.shieldDamageReduction super(Ship, self).take_damage( damage * (1.0 - self.shieldDamageReduction), by) else: super(Ship, self).take_damage(damage, by) #eif if self.health == 0: if self.killedby != None: if isinstance(self.killedby, Star): self.player.sound = "BURN" elif isinstance(self.killedby, BlackHole): self.player.sound = "CRUSH" else: self.player.sound = "EXPLODE" else: self.player.sound = "EXPLODE" elif by != None: if isinstance(by, Dragon): self.player.sound = "CHOMP" elif isinstance(by, Weapon): self.player.sound = "IMPACT" elif not isinstance(by, Star): self.player.sound = "HIT" def update(self, t): super(Ship, self).update(t) if len(self.commandQueue) > 0: self.commandQueue.update(t) self.TTL = None elif self.TTL == None and hasattr( self, "player" ) and self.player.netid >= 0: # if we're a human player, make sure we issue another command within 10 seconds, or kill scuttle the ship. logging.info( "Ship #%d on clock for not issuing a command in given time.", self.id) self.TTL = self.timealive + 10 self.energy += self.energyRechargeRate * t def getExtraInfo(self, objData, player): objData["RADARRANGE"] = self.radarRange objData["ROTATION"] = int(self.rotationAngle) % 360 objData["ROTATIONSPEED"] = self.rotationSpeed objData["CURSHIELD"] = self.shield.value objData["MAXSHIELD"] = self.shield.maximum # Only show some properties to the owner of the ship if player != None and hasattr( self, "player" ) and self.player != None and self.player.netid == player.netid: objData["CMDQ"] = self.commandQueue.getRadarRepr() else: # Remove this property for other ships del objData["CURENERGY"]
class Ship(PhysicalRound): """ A Ship is the main entity a player controls in the world. Attributes: killed: boolean different than destroyed, represents an object forcibly removed from the world (by GUI or end of round), should NOT respawn """ def __init__(self, pos, world): super(Ship, self).__init__(28, 500, pos) self._world = world # NOTE: The ONLY reason this is here/needed is because the ship is creating a Torpedo from it's command system... self.energyRechargeRate = 4 self.body.velocity_limit = 100 # Ship Specific self.commandQueue = CommandSystem(self, 4) self.shield = PlayerStat(100) self.shieldConversionRate = 1.0 # Amount of Shield Recovered Per Energy (Higher Better) self.shieldDamageReduction = 0.8 # Amount Damage is Multiplied by and taken from Shields before health is touched (Higher Better) self.radarRange = 300 self.energy = PlayerStat(100) self.energyRechargeRate = 4 self.thrusterForce = 3500 self.rotationAngle = random.randint(0, 359) self.rotationSpeed = 120 #self.resources = PlayerStat(1000) #self.resources.empty() #self.miningSpeed = 8 self.tractorbeamForce = 10000 self.lasernodes = [] # extra state self.killed = False # forcibly removed object 'for good' def setCommandBufferSize(self, size): old = self.commandQueue[:] self.commandQueue = MessageQueue(size) self.commandQueue.extend(old) def take_damage(self, damage, by=None, force=False): logging.debug("Ship #%d taking damage %d", self.id, damage) if self.commandQueue.containstype(RaiseShieldsCommand, force) and self.shield.value > 0: logging.debug("Shields of #%d absorbed %d damage", self.id, damage * self.shieldDamageReduction) self.shield -= damage * self.shieldDamageReduction super(Ship, self).take_damage(damage * (1.0 - self.shieldDamageReduction), by) else: super(Ship, self).take_damage(damage, by) #eif if self.health == 0: if self.killedby != None: if isinstance(self.killedby, Star): self.player.sound = "BURN" elif isinstance(self.killedby, BlackHole): self.player.sound = "CRUSH" else: self.player.sound = "EXPLODE" else: self.player.sound = "EXPLODE" elif by != None: if isinstance(by, Dragon): self.player.sound = "CHOMP" elif isinstance(by, Weapon): self.player.sound = "IMPACT" elif not isinstance(by, Star): self.player.sound = "HIT" def update(self, t): super(Ship, self).update(t) if len(self.commandQueue) > 0: self.commandQueue.update(t) self.TTL = None elif self.TTL == None and hasattr(self, "player") and self.player.netid >= 0: # if we're a human player, make sure we issue another command within 10 seconds, or kill scuttle the ship. logging.info("Ship #%d on clock for not issuing a command in given time.", self.id) self.TTL = self.timealive + 10 self.energy += self.energyRechargeRate * t def getExtraInfo(self, objData, player): objData["RADARRANGE"] = self.radarRange objData["ROTATION"] = int(self.rotationAngle) % 360 objData["ROTATIONSPEED"] = self.rotationSpeed objData["CURSHIELD"] = self.shield.value objData["MAXSHIELD"] = self.shield.maximum # Only show some properties to the owner of the ship if player != None and hasattr(self, "player") and self.player != None and self.player.netid == player.netid: objData["CMDQ"] = self.commandQueue.getRadarRepr() else: # Remove this property for other ships del objData["CURENERGY"]
def __init__(self, parent, size): self.__parent = parent self.__queue = MessageQueue(size) self.__queueSemaphore = threading.Semaphore()
class CommandSystem(object): """ The Command System is a special system build around a MessageQueue it keeps track of running commands for periods of time and continues to execute commands until their execution time is complete it will not process new commands while a blocking command was taken from the queue """ def __init__(self, parent, size): self.__parent = parent self.__queue = MessageQueue(size) self.__queueSemaphore = threading.Semaphore() def __len__(self): return len(self.__queue) def __contains__(self, item): found = False self.__queueSemaphore.acquire() for cmd in self.__queue: if item == cmd: found = True break self.__queueSemaphore.release() return found def containstype(self, cmdtype, force=False): found = None if not force: self.__queueSemaphore.acquire() for cmd in self.__queue: if isinstance(cmd, cmdtype): found = cmd break if not force: self.__queueSemaphore.release() return found def __getitem__(self, key): return self.__queue[key] def append(self, cmd): if isinstance(cmd, Command): logging.debug("Added Command to Queue: %s", repr(cmd)) self.__queueSemaphore.acquire() self.__queue.append(cmd) self.__queueSemaphore.release() def update(self, t): self.__queueSemaphore.acquire() thrust = self.__parent.thrusterForce for i in xrange(len(self) - 1, -1, -1): cmd = self.__queue[i] if cmd.initialrequiredenergy > 0 and self.__parent.energy.value < cmd.initialrequiredenergy: logging.info("#%d Not Enough Energy To Start: %s", self.__parent.id, repr(self.__queue[i])) del self.__queue[i] else: self.__parent.energy -= cmd.initialrequiredenergy cmd.initialrequiredenergy = 0 # spent cost preven = self.__parent.energy #TODO: This is over eager, could slice more energy on hiccup... self.__parent.energy -= cmd.energycost * t if cmd.isExpired() or cmd.isComplete( ) or self.__parent.energy.value == 0: logging.info("Finished Executing Command: %s", repr(self.__queue[i])) if self.__parent.energy.value == 0: logging.info("#%d Out of Energy", self.__parent.id) del self.__queue[i] logging.info("#%d Commands in Queue: %d", self.__parent.id, len(self)) else: nt = t # Limit Thrust, TODO: Abstract if cmd.NAME == "THRST": thmod = self.__parent.thrusterForce * cmd.power if thmod > thrust: nt = t * (thrust / thmod) logging.info( "#%d Limiting Thrust time from %f to %f", self.__parent.id, t, nt) self.__parent.energy = preven else: thrust -= thmod logging.debug("Thrust Left %f", float(thrust)) cmd.execute(t) #eif #eif self.__queueSemaphore.release() """ if len(self) == 0 or not self.isBlockingCommandOnTop(): nmsg = self.__queue.getNextMessage() if nmsg != None: logging.info("Activating Command: %s", nmsg) self.__activeCommandsSemaphore.acquire() self.__activeCommands.append(nmsg) self.__activeCommandsSemaphore.release() """ def isBlockingCommandOnTop(self): # Returns True if there's a blocking command on top of the stack self.__queueSemaphore.acquire() x = (len(self.__queue) > 0 and self.__queue[len(self.__queue) - 1].blocking) self.__queueSemaphore.release() return x def getRadarRepr(self): # Returns a short form of list with just the command names lst = [] self.__queueSemaphore.acquire() for cmd in self.__queue: lst.append(cmd.NAME) self.__queueSemaphore.release() return lst def __repr__(self): return "CommandSystem(" + repr(self.__queue) + ")"
class CommandSystem(object): """ The Command System is a special system build around a MessageQueue it keeps track of running commands for periods of time and continues to execute commands until their execution time is complete it will not process new commands while a blocking command was taken from the queue """ def __init__(self, parent, size): self.__parent = parent self.__queue = MessageQueue(size) self.__queueSemaphore = threading.Semaphore() def __len__(self): return len(self.__queue) def __contains__(self, item): found = False self.__queueSemaphore.acquire() for cmd in self.__queue: if item == cmd: found = True break self.__queueSemaphore.release() return found def containstype(self, cmdtype, force=False): found = None if not force: self.__queueSemaphore.acquire() for cmd in self.__queue: if isinstance(cmd, cmdtype): found = cmd break if not force: self.__queueSemaphore.release() return found def __getitem__(self, key): return self.__queue[key] def append(self, cmd): if isinstance(cmd, Command): logging.debug("Added Command to Queue: %s", repr(cmd)) self.__queueSemaphore.acquire() self.__queue.append(cmd) self.__queueSemaphore.release() def update(self, t): self.__queueSemaphore.acquire() thrust = self.__parent.thrusterForce for i in xrange(len(self)-1, -1, -1): cmd = self.__queue[i] if cmd.initialrequiredenergy > 0 and self.__parent.energy.value < cmd.initialrequiredenergy: logging.info("#%d Not Enough Energy To Start: %s", self.__parent.id, repr(self.__queue[i])) del self.__queue[i] else: self.__parent.energy -= cmd.initialrequiredenergy cmd.initialrequiredenergy = 0 # spent cost preven = self.__parent.energy #TODO: This is over eager, could slice more energy on hiccup... self.__parent.energy -= cmd.energycost * t if cmd.isExpired() or cmd.isComplete() or self.__parent.energy.value == 0: logging.info("Finished Executing Command: %s", repr(self.__queue[i])) if self.__parent.energy.value == 0: logging.info("#%d Out of Energy", self.__parent.id) del self.__queue[i] logging.info("#%d Commands in Queue: %d", self.__parent.id, len(self)) else: nt = t # Limit Thrust, TODO: Abstract if cmd.NAME == "THRST": thmod = self.__parent.thrusterForce * cmd.power if thmod > thrust: nt = t * (thrust / thmod) logging.info("#%d Limiting Thrust time from %f to %f", self.__parent.id, t, nt) self.__parent.energy = preven else: thrust -= thmod logging.debug("Thrust Left %f", float(thrust)) cmd.execute(t) #eif #eif self.__queueSemaphore.release() """ if len(self) == 0 or not self.isBlockingCommandOnTop(): nmsg = self.__queue.getNextMessage() if nmsg != None: logging.info("Activating Command: %s", nmsg) self.__activeCommandsSemaphore.acquire() self.__activeCommands.append(nmsg) self.__activeCommandsSemaphore.release() """ def isBlockingCommandOnTop(self): # Returns True if there's a blocking command on top of the stack self.__queueSemaphore.acquire() x = (len(self.__queue) > 0 and self.__queue[len(self.__queue)-1].blocking) self.__queueSemaphore.release() return x def getRadarRepr(self): # Returns a short form of list with just the command names lst = [] self.__queueSemaphore.acquire() for cmd in self.__queue: lst.append(cmd.NAME) self.__queueSemaphore.release() return lst def __repr__(self): return "CommandSystem(" + repr(self.__queue) + ")"
class Ship(PhysicalRound): """ A Ship is the main entity a player controls in the world. Attributes: killed: boolean different than destroyed, represents an object forcibly removed from the world (by GUI or end of round), should NOT respawn """ def __init__(self, pos, world): super(Ship, self).__init__(28, 500, pos) self._world = world # NOTE: The ONLY reason this is here/needed is because the ship is creating a Torpedo from it's command system... self.energyRechargeRate = 4 self.body.velocity_limit = 100 # Ship Specific self.commandQueue = CommandSystem(self, 4) self.shield = PlayerStat(100) self.shieldConversionRate = 1.0 # Amount of Shield Recovered Per Energy (Higher Better) self.shieldDamageReduction = 0.8 # Amount Damage is Multiplied by and taken from Shields before health is touched (Higher Better) self.radarRange = 300 self.energy = PlayerStat(100) self.energyRechargeRate = 4 self.thrusterForce = 3500 self.rotationAngle = random.randint(0, 359) self.rotationSpeed = 120 #self.resources = PlayerStat(1000) #self.resources.empty() #self.miningSpeed = 8 self.tractorbeamForce = 10000 self.lasernodes = [] # extra state self.killed = False # forcibly removed object def setCommandBufferSize(self, size): old = self.commandQueue[:] self.commandQueue = MessageQueue(size) self.commandQueue.extend(old) def update(self, t): super(Ship, self).update(t) if len(self.commandQueue) > 0: self.commandQueue.update(t) self.TTL = None elif self.TTL == None and hasattr(self, "player") and self.player.netid >= 0: # if we're a human player, make sure we issue another command within 10 seconds, or kill scuttle the ship. logging.info("Ship #%d on clock for not issuing a command in given time.", self.id) self.TTL = self.timealive + 10 self.energy += self.energyRechargeRate * t def getExtraInfo(self, objData): objData["RADARRANGE"] = self.radarRange objData["ROTATION"] = self.rotationAngle objData["ROTATIONSPEED"] = self.rotationSpeed objData["CURSHIELD"] = self.shield.value objData["MAXSHIELD"] = self.shield.maximum