Skip to content

Commit

Permalink
Initial SpaceMine Prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkerm committed May 2, 2016
1 parent f75faf7 commit b29bb70
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 18 deletions.
Binary file modified SBA_Serv/GUI/Graphics/Mines/Mine.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions SBA_Serv/GUI/ObjWrappers/WeaponWrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,24 @@ def draw(self, surface, flags):
surface.blit(debugfont().render("#"+str(self._worldobj.id), False, (192, 192, 192)), (bp[0]-4, bp[1]+self._worldobj.radius+4))

#super(TorpedoGUI, self).draw(surface, flags)

class SpaceMineGUI(GUIEntity):
_mine_surface = None

def __init__(self, obj, world):
super(SpaceMineGUI, self).__init__(obj, world)
if SpaceMineGUI._mine_surface == None:
SpaceMineGUI._mine_surface = Cache().getImage("Mines/Mine")

def draw(self, surface, flags):
bp = intpos(self._worldobj.body.position)
surface.blit(SpaceMineGUI._mine_surface.subsurface(pygame.Rect(16 * (self._worldobj.active + (self._worldobj.target != None)), 0, 16, 16)), (bp[0] - 8, bp[1] - 8))

if flags["DEBUG"]:
# position text
if self._worldobj.mode == 3:
surface.blit(debugfont().render(repr(self._worldobj.target), False, (192, 192, 192)), (bp[0]-30, bp[1]-self._worldobj.radius-4))
# id text
surface.blit(debugfont().render("#"+str(self._worldobj.id)+" "+repr(self._worldobj.mode), False, (192, 192, 192)), (bp[0]-8, bp[1]+self._worldobj.radius+4))

#super(TorpedoGUI, self).draw(surface, flags)
Binary file added SBA_Serv/GUI/Sounds/MINE.WAV
Binary file not shown.
6 changes: 6 additions & 0 deletions SBA_Serv/GUI/Sounds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ Played when a Ship fires a torpedo.

*JM_NOIZ_Laser 02* by **Julien Matthey**

[MINE](https://www.freesound.org/people/Blockfighter298/sounds/317827/)
-----
Played when a Ship deploys a mine.

*Weapon Pickup* by **Blockfighter298**

[SHIELD](https://www.freesound.org/people/thehorriblejoke/sounds/198969/)
------
Played when a Ship raises its shield.
Expand Down
8 changes: 6 additions & 2 deletions SBA_Serv/GUI/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
from ObjWrappers.PlanetWrapper import PlanetGUI
from ObjWrappers.AsteroidWrapper import AsteroidGUI
from ObjWrappers.WormHoleWrapper import WormHoleGUI
from ObjWrappers.WeaponWrappers import TorpedoGUI
from ObjWrappers.WeaponWrappers import TorpedoGUI, SpaceMineGUI
from Game.Utils import SpawnManager
from GraphicsCache import Cache
from World.WorldEntities import Ship, Planet, Asteroid, Torpedo, BlackHole, Nebula, Star, Dragon, WormHole
from World.WorldEntities import Ship, Planet, Asteroid, Torpedo, SpaceMine, BlackHole, Nebula, Star, Dragon, WormHole
from Server.MWNL2 import getIPAddress
from pymunk import Vec2d
from Helpers import infofont
Expand Down Expand Up @@ -119,6 +119,10 @@ def addorremove(obj, added):
logging.debug("GUI: Adding Torpedo #%d", obj.id)
objects[obj.id] = TorpedoGUI(obj, world)
logging.debug("GUI: Added Torpedo #%d", obj.id)
elif isinstance(obj, SpaceMine):
logging.debug("GUI: Adding SpaceMine #%d", obj.id)
objects[obj.id] = SpaceMineGUI(obj, world)
logging.debug("GUI: Added SpaceMine #%d", obj.id)
else:
logging.debug("GUI: Adding %s #%d", repr(obj), obj.id)
objects[obj.id] = obj.WRAPPERCLASS(obj, world)
Expand Down
8 changes: 6 additions & 2 deletions SBA_Serv/Game/Game.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
The full text of the license is available online: http://opensource.org/licenses/GPL-2.0
"""

from World.WorldEntities import Ship, BlackHole, Nebula
from World.WorldEntities import Ship, BlackHole, Nebula, SpaceMine
from Players import Player
import random, logging, time
from World.WorldMath import friendly_type
Expand Down Expand Up @@ -370,7 +370,7 @@ def _game_add_ship_for_player(self, netid, roundstart=False):
self._players[netid].object.ship_added() # tell AI ship to start
else:
self._players[netid].object = Ship(self.player_get_start_position(True), self.world)
logging.info("Adding Ship for Player %d (%s) id #%d with Name %s", netid, self._players[netid].object.id, self._players[netid].name)
logging.info("Adding Ship for Player %d id #%d with Name %s", netid, self._players[netid].object.id, self._players[netid].name)
self._players[netid].object.player = self._players[netid]
self._players[netid].object.owner = self._players[netid].object # Make ships owners of themselves for easier logic with ownership?
self._players[netid].roundover = False
Expand Down Expand Up @@ -557,6 +557,10 @@ def world_add_remove_object(self, wobj, added):
killed ships will not return (used to prevent respawn)
"""
logging.debug("[Game] Add Object(%s): #%d (%s)", repr(added), wobj.id, friendly_type(wobj))
if not added and isinstance(wobj, SpaceMine) and wobj.active:
self.world.causeExplosion(wobj.body.position, SpaceMine.RADIUS, SpaceMine.FORCE, True)
# TODO: Cause splash damage?

if not added and isinstance(wobj, Ship) and wobj.player.netid in self._players:
nid = wobj.player.netid

Expand Down
2 changes: 1 addition & 1 deletion SBA_Serv/Tests/defaulttest.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ range_min=112
range_max=192
pull_min=8
pull_max=24
pull_torpedo = False
pull_weapon = False

[BlackHole]
number = 0
Expand Down
44 changes: 43 additions & 1 deletion SBA_Serv/World/WorldCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
SHIP_CMD_WARP = "WARP"

SHIP_CMD_TORPEDO = "FIRE"
SHIP_CMD_MINE = "MINE"
SHIP_CMD_SPACEMINE = "MINE"

SHIP_CMD_SHIELD = "SHLD"
SHIP_CMD_CLOAK = "CLOAK"
Expand Down Expand Up @@ -130,6 +130,28 @@ def ConvertNetworkMessageToCommand(ship, cmdname, cmddict):
else:
return "Firing a torpedo requires a direction 'F'orward or 'B'ackwards"
#eif
elif cmdname == SHIP_CMD_SPACEMINE:
if cmddict.has_key("MODE") and cmddict.has_key("DELAY") and isinstance(cmddict["DELAY"], float) and cmddict["DELAY"] > 0:
if cmddict["MODE"] not in [WorldEntities.SpaceMine.STATIONARY, WorldEntities.SpaceMine.AUTONOMOUS, WorldEntities.SpaceMine.HOMING]:
return "Invalid Mine Mode, use 1, 2, or 3"
elif cmddict["MODE"] == WorldEntities.SpaceMine.AUTONOMOUS:
if cmddict.has_key("SPEED") and cmddict.has_key("DUR") and cmddict.has_key("DIR"):
if isinstance(cmddict["SPEED"], int) and isinstance(cmddict["DUR"], float) and isinstance(cmddict["DIR"], int):
if cmddict["SPEED"] > 0 and cmddict["SPEED"] <= 5:
if cmddict["DUR"] > 0:
return DeploySpaceMineCommand(ship, cmddict["DELAY"], cmddict["MODE"], cmddict["DIR"], cmddict["SPEED"], cmddict["DUR"])
else:
return "Must have positive mine duration"
else:
return "Invalid Mine Speed use 1-5"
else:
return "Mine paramter type incorrect"
else:
return "Missing Parameter for Auto Mine"
else:
return DeploySpaceMineCommand(ship, cmddict["DELAY"], cmddict["MODE"])
else:
return "Mines need a mode and positive float delay"
elif cmdname == SHIP_CMD_REPAIR:
if cmddict.has_key("AMT") and isinstance(cmddict["AMT"], int) and cmddict["AMT"] > 0:
return RepairCommand(ship, cmddict["AMT"])
Expand Down Expand Up @@ -432,6 +454,26 @@ def onetime(self):
self._obj._world.append(WorldEntities.Torpedo(self._obj.body.position, self._obj.rotationAngle - 180, self._obj))
#eif

class DeploySpaceMineCommand(OneTimeCommand):
NAME = SHIP_CMD_SPACEMINE

def __init__(self, ship, delay, wmode, direction=None, speed=None, duration=None):
self.__delay = delay
self.__wmode = wmode
self.__direction = direction
self.__speed = speed
self.__duration = duration
super(DeploySpaceMineCommand, self).__init__(ship, DeploySpaceMineCommand.NAME, required=(33 + self.__wmode * 11))

def onetime(self):
self._obj.player.sound = "MINE"
if self.__wmode == WorldEntities.SpaceMine.STATIONARY:
self._obj._world.append(WorldEntities.SpaceMine(self._obj.body.position, self.__delay, WorldEntities.SpaceMine.STATIONARY, owner=self._obj))
elif self.__wmode == WorldEntities.SpaceMine.HOMING:
self._obj._world.append(WorldEntities.SpaceMine(self._obj.body.position, self.__delay, WorldEntities.SpaceMine.HOMING, owner=self._obj))
elif self.__wmode == WorldEntities.SpaceMine.AUTONOMOUS:
self._obj._world.append(WorldEntities.SpaceMine(self._obj.body.position, self.__delay, WorldEntities.SpaceMine.AUTONOMOUS, self.__direction, self.__speed, self.__duration, owner=self._obj))

class RepairCommand(Command):
NAME = SHIP_CMD_REPAIR

Expand Down
101 changes: 93 additions & 8 deletions SBA_Serv/World/WorldEntities.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def take_damage(self, damage, by=None, force=False):
elif by != None:
if isinstance(by, Dragon):
self.player.sound = "CHOMP"
elif isinstance(by, Torpedo):
elif isinstance(by, Weapon):
self.player.sound = "IMPACT"
elif not isinstance(by, Star):
self.player.sound = "HIT"
Expand Down Expand Up @@ -237,7 +237,7 @@ def __init__(self, pos, size=128, pull=15, radius=60, torpedo=False, mass=-1):
self.influence_range = size
#self.resources = PlayerStat(random.randint(500, 2000))

self.effect_torpedo = torpedo
self.effect_weapon = torpedo

def getExtraInfo(self, objData, player):
objData["PULL"] = self.pull
Expand All @@ -247,14 +247,14 @@ def getExtraInfo(self, objData, player):

def apply_influence(self, otherobj, mapped_pos, t):
# apply 'gravity' pull amount force towards planet's center if not a Torpedo (hard math) or another Planet thing (fixed)
if self.effect_torpedo or not isinstance(otherobj, Torpedo):
if self.effect_weapon or not isinstance(otherobj, Weapon):
otherobj.body.apply_impulse((mapped_pos - self.body.position) * -self.pull * t, (0,0))

@staticmethod
def spawn(world, cfg, pos=None):
if pos == None:
pos = getPositionAwayFromOtherObjects(world, cfg.getint("Planet", "buffer_object"), cfg.getint("Planet", "buffer_edge"))
p = Planet(pos, cfg_rand_min_max(cfg, "Planet", "range"), cfg_rand_min_max(cfg, "Planet", "pull"), torpedo=cfg.getboolean("Planet", "pull_torpedo"))
p = Planet(pos, cfg_rand_min_max(cfg, "Planet", "range"), cfg_rand_min_max(cfg, "Planet", "pull"), torpedo=cfg.getboolean("Planet", "pull_weapon"))
world.append(p)
return p

Expand Down Expand Up @@ -284,7 +284,7 @@ def update(self, t):
def spawn(world, cfg, pos=None):
if pos == None:
pos = getPositionAwayFromOtherObjects(world, cfg.getint("BlackHole", "buffer_object"), cfg.getint("BlackHole", "buffer_edge"))
bh = BlackHole(pos, cfg_rand_min_max(cfg, "BlackHole", "range"), cfg_rand_min_max(cfg, "BlackHole", "pull"), cfg.getfloat("BlackHole", "crush_time"), cfg.getboolean("Planet", "pull_torpedo"))
bh = BlackHole(pos, cfg_rand_min_max(cfg, "BlackHole", "range"), cfg_rand_min_max(cfg, "BlackHole", "pull"), cfg.getfloat("BlackHole", "crush_time"), cfg.getboolean("Planet", "pull_weapon"))
world.append(bh)
return bh

Expand Down Expand Up @@ -317,7 +317,7 @@ def update(self, t):
def spawn(world, cfg, pos=None):
if pos == None:
pos = getPositionAwayFromOtherObjects(world, cfg.getint("Star", "buffer_object"), cfg.getint("Star", "buffer_edge"))
s = Star(pos, cfg_rand_min_max(cfg, "Star", "range"), cfg_rand_min_max(cfg, "Star", "pull"), cfg.getfloat("Star", "dmg_mod"), cfg.getboolean("Planet", "pull_torpedo"))
s = Star(pos, cfg_rand_min_max(cfg, "Star", "range"), cfg_rand_min_max(cfg, "Star", "pull"), cfg.getfloat("Star", "dmg_mod"), cfg.getboolean("Planet", "pull_weapon"))
world.append(s)
return s

Expand Down Expand Up @@ -475,7 +475,7 @@ def _get_next_attack(self):
def collide_start(self, otherobj):
otherobj.dr_timer = 0
super(Dragon, self).collide_start(otherobj)
if isinstance(otherobj, Torpedo): # Torpedos can hit Dragons
if isinstance(otherobj, Weapon): # Torpedos & SpaceMines can hit Dragons
return True

return False
Expand Down Expand Up @@ -537,7 +537,11 @@ def spawn(world, cfg, pos=None):
world.append(d)
return d

class Torpedo(PhysicalRound):
class Weapon(PhysicalRound):
def __init__(self, radius, mass, position):
super(Weapon, self).__init__(radius, mass, position)

class Torpedo(Weapon):
"""
Torpedos are weapons which are launched from ships at a given position and direction
"""
Expand All @@ -558,3 +562,84 @@ def __init__(self, pos, direction, owner=None):

def getExtraInfo(self, objData, player):
objData["OWNERID"] = self.owner.id

class SpaceMine(Influential, Weapon):
"""
SpaceMines are weapons which are dropped from a ship
"""

STATIONARY = 1
AUTONOMOUS = 2
HOMING = 3

RADIUS = 128
FORCE = 600

def __init__(self, pos, delay, wmode, direction=None, speed=None, duration=None, owner=None):
super(SpaceMine, self).__init__(7, 120, pos)
self.shape.elasticity = 0.7
self.health = PlayerStat(1)
self.owner = owner
self.explodable = False
self.delay = delay
self.active = False
self.mode = wmode
self.direction = direction
self.speed = speed
self.duration = duration
self.influence_range = 96
self.attack_speed = 5
self.target = None
self.lv = self.body.velocity.normalized()

def collide_start(self, otherobj):
if not self.active:
return False

return super(SpaceMine, self).collide_start(otherobj)

def update(self, t):
super(SpaceMine, self).update(t)
self.delay -= t

if self.delay <= 0:
if self.mode == SpaceMine.AUTONOMOUS and not self.active:
v = 500 * self.speed
self.body.apply_impulse((math.cos(math.radians(-self.direction)) * v,
math.sin(math.radians(-self.direction)) * v), (0,0))
self.TTL = self.timealive + self.duration
elif self.mode == SpaceMine.HOMING:
if self.target != None:
# turn towards target
nang = self.body.velocity.get_angle_degrees_between(self.target - self.body.position)
self.body.velocity.angle_degrees += nang * t

# clear target as we'll reaquire to 'readjust course' for moving object...
if self.body.position.get_dist_sqrd(self.target) < 300:
if self.body.velocity.length > self.attack_speed:
self.body.velocity.length -= self.attack_speed
self.target = None
self.active = True

def apply_influence(self, otherobj, mapped_pos, t):
if not self.active or self.mode != SpaceMine.HOMING:
return

# get closest ship though cloak protects ship from dragon 'seeing' it
if isinstance(otherobj, Ship) and not otherobj.commandQueue.containstype(CloakCommand) and \
(self.target == None or self.body.position.get_dist_sqrd(mapped_pos) < self.body.position.get_dist_sqrd(self.target)):
if self.target == None:
if self.body.velocity.length < 1:
if self.body.velocity.length == 0:
nang = 0
else:
nang = self.body.velocity.get_angle_degrees_between(mapped_pos - self.body.position)
self.body.apply_impulse((math.cos(math.radians(nang)) * self.attack_speed * 100,
math.sin(math.radians(nang)) * self.attack_speed * 100), (0,0))
else:
self.body.velocity.length += self.attack_speed
self.lv = self.body.velocity.normalized()
self.target = pymunk.Vec2d(mapped_pos)

def getExtraInfo(self, objData, player):
objData["OWNERID"] = self.owner.id
2 changes: 1 addition & 1 deletion SBA_Serv/buildnum
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1111
1112
2 changes: 1 addition & 1 deletion SBA_Serv/default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ range_min=112
range_max=192
pull_min=8
pull_max=24
pull_torpedo = False
pull_weapon = False

[BlackHole]
number = 1
Expand Down
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
v1.2 : Planned - May 2016 [Season 5]
----
* Added Worm Holes (teleports objects across space)
* Added Deployable Space Mines
* Added option for Torpedoes to be effected by gravity
* Split 'explodable' from 'gravitable' for Entities, two separate object flags now.
* Separated option for 'showip' in Application settings to decouple from showing statistics, no longer always show IP in Debug mode.
Expand Down
4 changes: 2 additions & 2 deletions doc/server/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ see pull_max
###pull_max = integer
These two values correspond to the amount of pull the gravity will have on ships. Larger values mean ships will get pulled in quicker and will have a harder time escaping. A random value will be generated between **pull_min** and **pull_max**. These are typically **8** and **24**. Setting pull to zero, will turn off gravity.

###pull_torpedo = boolean
If enabled, Planets', BlackHoles', and Stars' gravity wells will effect torpedos.
###pull_weapon = boolean
If enabled, Planets', BlackHoles', and Stars' gravity wells will effect torpedos and space mines.


<a name="blackhole"></a>[BlackHole]
Expand Down
Loading

0 comments on commit b29bb70

Please sign in to comment.