Advertisement
Guest User

Push game mode

a guest
Apr 25th, 2013
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.73 KB | None | 0 0
  1. """
  2. push.py last modified 2013-04-26 02:19:51
  3. Contributors: danhezee, StackOverflow, izzy, Danke, noway421
  4.  
  5. The concept:
  6.    Each team spawns at a set location with the enemy intel.
  7.    They must "push" the intel towards their control point, which is also at a
  8.    set location.
  9.  
  10. How to setup new maps:
  11.    Spawn and CP locations must be configured via extensions in the map's
  12.    map_name.txt metadata. Example:
  13.  
  14. extensions = {
  15.    'push': True,
  16.    'push_spawn_range' : 5,
  17.    'push_blue_spawn' : (91, 276, 59),
  18.    'push_blue_cp' : (91, 276, 59),
  19.    'push_green_spawn' : (78, 86, 59),
  20.    'push_green_cp' : (78, 86, 59),
  21.    'water_damage' : 100
  22. }
  23. """
  24.  
  25. from pyspades.constants import *
  26. from random import randint
  27. from commands import add, admin
  28. from twisted.internet.task import LoopingCall
  29. from pyspades.common import make_color
  30. from pyspades.server import set_color, block_action
  31.  
  32. import colorsys
  33.  
  34.  
  35. def byte_rgb_to_hls(color):
  36.     (h, l, s) = colorsys.rgb_to_hls(
  37.         color[0] / 255.0,
  38.         color[1] / 255.0,
  39.         color[2] / 255.0)
  40.     return (
  41.         int(round(h * 255)),
  42.         int(round(l * 255)),
  43.         int(round(s * 255)))
  44.  
  45.  
  46. def byte_hls_to_rgb(color):
  47.     (r, g, b) = colorsys.hls_to_rgb(
  48.         color[0] / 255.0,
  49.         color[1] / 255.0,
  50.         color[2] / 255.0)
  51.     return (
  52.         int(round(r * 255)),
  53.         int(round(g * 255)),
  54.         int(round(b * 255)))
  55.  
  56.  
  57. def byte_middle_range(byte):
  58.     half = 85 / 2.0  # half of third byte
  59.     min = byte - half
  60.     max = byte + half
  61.     if min < 0:
  62.         min = 0
  63.         max = half
  64.     elif max > 255:
  65.         min = 255 - half
  66.         max = 255
  67.     return int(round(min)), int(round(max))
  68.  
  69.  
  70. # If ALWAYS_ENABLED is False, then the 'push' key must be set to True in
  71. # the 'extensions' dictionary in the map's map_name.txt metadata
  72. ALWAYS_ENABLED = True
  73. CANT_DESTROY = "You can't destroy your team's blocks. Attack the enemy!"
  74.  
  75. # team is associated intel team
  76.  
  77.  
  78. def reset_intel(protocol, team):
  79.     extensions = protocol.map_info.extensions
  80.  
  81.     if team is protocol.green_team and 'push_blue_spawn' in extensions:
  82.         z = protocol.map.get_z(*extensions.get('push_blue_spawn'))
  83.         pos = (
  84.             extensions.get('push_blue_spawn')[0],
  85.             extensions.get('push_blue_spawn')[1],
  86.             z)
  87.  
  88.     if team is protocol.blue_team and 'push_green_spawn' in extensions:
  89.         z = protocol.map.get_z(*extensions.get('push_green_spawn'))
  90.         pos = (
  91.             extensions.get('push_green_spawn')[0],
  92.             extensions.get('push_green_spawn')[1],
  93.             z)
  94.  
  95.     team.flag.set(*pos)
  96.     team.flag.update()
  97.     protocol.send_chat("The %s intel has been reset." % team.name)
  98.  
  99.  
  100. @admin
  101. def resetblueintel(connection):
  102.     reset_intel(connection.protocol, connection.protocol.blue_team)
  103.  
  104.  
  105. @admin
  106. def resetgreenintel(connection):
  107.     reset_intel(connection.protocol, connection.protocol.green_team)
  108.  
  109.  
  110. add(resetblueintel)
  111. add(resetgreenintel)
  112.  
  113.  
  114. def get_entity_location(self, entity_id):
  115.     extensions = self.protocol.map_info.extensions
  116.  
  117.     if entity_id == BLUE_BASE and 'push_blue_cp' in extensions:
  118.         return extensions['push_blue_cp']
  119.     elif entity_id == GREEN_BASE and 'push_green_cp' in extensions:
  120.         return extensions['push_green_cp']
  121.     # this next part might seem counter intuitive but you need the blue intel
  122.     # to spawn near the greens and vice versa
  123.     elif entity_id == BLUE_FLAG and 'push_green_spawn' in extensions:
  124.         return extensions['push_green_spawn']
  125.     elif entity_id == GREEN_FLAG and 'push_blue_spawn' in extensions:
  126.         return extensions['push_blue_spawn']
  127.  
  128.  
  129. def get_spawn_location(connection):
  130.     extensions = connection.protocol.map_info.extensions
  131.     #distance from spawn center to randomly spawn in
  132.     spawn_range = 5
  133.     if 'push_spawn_range' in extensions:
  134.         spawn_range = extensions['push_spawn_range']
  135.  
  136.     if connection.team is connection.protocol.blue_team:
  137.         if 'push_blue_spawn' in extensions:
  138.             xb = extensions.get('push_blue_spawn')[0]
  139.             yb = extensions.get('push_blue_spawn')[1]
  140.             xb += randint(-spawn_range, spawn_range)
  141.             yb += randint(-spawn_range, spawn_range)
  142.             return (xb, yb, connection.protocol.map.get_z(xb, yb))
  143.  
  144.     if connection.team is connection.protocol.green_team:
  145.         if 'push_green_spawn' in extensions:
  146.             xb = extensions.get('push_green_spawn')[0]
  147.             yb = extensions.get('push_green_spawn')[1]
  148.             xb += randint(-spawn_range, spawn_range)
  149.             yb += randint(-spawn_range, spawn_range)
  150.             return (xb, yb, connection.protocol.map.get_z(xb, yb))
  151.  
  152.  
  153. def apply_script(protocol, connection, config):
  154.     class PushConnection(connection):
  155.         def on_login(self, name):
  156.             self.mylastblocks = [
  157.                 (-4, -1, -14),
  158.                 (-11, -5, -9),
  159.                 (-19, -20, -8),
  160.                 (-5, -2, -5),
  161.                 (-19, -20, 0)]
  162.             return connection.on_login(self, name)
  163.  
  164.         def random_color(self):
  165.             (h, l, s) = self.team.hls
  166.             l = randint(self.team.light_range[0], self.team.light_range[1])
  167.             color = byte_hls_to_rgb((h, l, s))
  168.  
  169.             self.color = color
  170.             set_color.player_id = self.player_id
  171.             set_color.value = make_color(*color)
  172.             self.send_contained(set_color)
  173.             self.protocol.send_contained(set_color, save=True)
  174.  
  175.         def build_block(self, x, y, z, looped=False):
  176.             if ((x < 0 or x > 511 or
  177.                 y < 0 or y > 511 or
  178.                 z < 1 or z > 61)
  179.                     is False):
  180.                 self.protocol.map.set_point(x, y, z, self.color)
  181.                 block_action.x = x
  182.                 block_action.y = y
  183.                 block_action.z = z
  184.                 block_action.value = BUILD_BLOCK
  185.                 block_action.player_id = self.player_id
  186.                 self.protocol.send_contained(block_action, save=True)
  187.  
  188.         def on_line_build_attempt(self, points):
  189.             if connection.on_line_build_attempt(self, points) is not False:
  190.                 for point in points:
  191.                     x, y, z = point[0], point[1], point[2]
  192.                     self.mylastblocks.pop(0)
  193.                     self.mylastblocks.append((x, y, z))
  194.                     self.random_color()
  195.                     self.build_block(x, y, z)
  196.             return False
  197.  
  198.         def on_block_build_attempt(self, x, y, z):
  199.             if connection.on_block_build_attempt(self, x, y, z) is not False:
  200.                 self.mylastblocks.pop(0)
  201.                 self.mylastblocks.append((x, y, z))
  202.                 self.random_color()
  203.                 self.build_block(x, y, z)
  204.             return False
  205.  
  206.         def on_block_destroy(self, x, y, z, value):
  207.             if not (self.admin or
  208.                     self.user_types.moderator or
  209.                     self.user_types.guard or
  210.                     self.user_types.trusted):
  211.                 if value == DESTROY_BLOCK:
  212.                     blocks = ((x, y, z),)
  213.                 elif value == SPADE_DESTROY:
  214.                     blocks = ((x, y, z), (x, y, z + 1), (x, y, z - 1))
  215.                 elif value == GRENADE_DESTROY:
  216.                     blocks = []
  217.                     for nade_x in xrange(x - 1, x + 2):
  218.                         for nade_y in xrange(y - 1, y + 2):
  219.                             for nade_z in xrange(z - 1, z + 2):
  220.                                 blocks.append((nade_x, nade_y, nade_z))
  221.                 for block in blocks:
  222.                     for lastblock in self.mylastblocks:
  223.                         if lastblock == block:
  224.                             self.mylastblocks.remove(lastblock)
  225.                             self.mylastblocks.append((-1, -1, -1))
  226.                             return connection.on_block_destroy(
  227.                                 self,
  228.                                 x, y, z,
  229.                                 value)
  230.  
  231.                     block_info = self.protocol.map.get_point(
  232.                         block[0],
  233.                         block[1],
  234.                         block[2])
  235.  
  236.                     if block_info[0] is True:
  237.                         block_hls = byte_rgb_to_hls(block_info[1])
  238.  
  239.                         if self.team is self.protocol.blue_team:
  240.                             team_hls = self.protocol.blue_team.hls
  241.                             # if hue and saturation match
  242.                             if (block_hls[0] == team_hls[0] and
  243.                                     block_hls[2] == team_hls[2]):
  244.                                 self.send_chat(CANT_DESTROY)
  245.                                 return False
  246.                         elif self.team is self.protocol.green_team:
  247.                             team_hls = self.protocol.green_team.hls
  248.                             if (block_hls[0] == team_hls[0] and
  249.                                     block_hls[2] == team_hls[2]):
  250.                                 self.send_chat(CANT_DESTROY)
  251.                                 return False
  252.  
  253.             return connection.on_block_destroy(self, x, y, z, value)
  254.  
  255.     class PushProtocol(protocol):
  256.         game_mode = CTF_MODE
  257.         push = False
  258.         check_loop = None
  259.  
  260.         def __init__(self, *arg, **kw):
  261.             protocol.__init__(self, *arg, **kw)
  262.             self.blue_team.hls = byte_rgb_to_hls(self.blue_team.color)
  263.             self.blue_team.light_range = byte_middle_range(
  264.                 self.blue_team.hls[1])
  265.  
  266.             self.green_team.hls = byte_rgb_to_hls(self.green_team.color)
  267.             self.green_team.light_range = byte_middle_range(
  268.                 self.green_team.hls[1])
  269.  
  270.         def check_intel_locations(self):
  271.             if self.blue_team.flag is not None:
  272.                 if self.blue_team.flag.get()[2] >= 63:
  273.                     reset_intel(self, self.blue_team)
  274.             if self.green_team.flag is not None:
  275.                 if self.green_team.flag.get()[2] >= 63:
  276.                     reset_intel(self, self.green_team)
  277.  
  278.         def on_map_change(self, map):
  279.             extensions = self.map_info.extensions
  280.             if ALWAYS_ENABLED:
  281.                 self.push = True
  282.             else:
  283.                 if 'push' in extensions:
  284.                     self.push = extensions['push']
  285.                 else:
  286.                     self.push = False
  287.             if self.push:
  288.                 self.map_info.get_entity_location = get_entity_location
  289.                 self.map_info.get_spawn_location = get_spawn_location
  290.                 self.check_loop = LoopingCall(self.check_intel_locations)
  291.                 self.check_loop.start(0.5)
  292.             return protocol.on_map_change(self, map)
  293.  
  294.     return PushProtocol, PushConnection
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement