gameobs.py
上传用户:ghyvgy
上传日期:2009-05-26
资源大小:547k
文件大小:9k
源码类别:

其他游戏

开发平台:

Python

  1. # gameobs.py
  2. #
  3. # Implements various game objects used by the demo
  4. # server. Most important are the Player and Room
  5. # classes. All game objects derive from GameObject,
  6. # which has an id that is used for addressing 
  7. # deferred method calls.
  8. # Author: Matthew Walker
  9. #         mwalker@softhome.net
  10. #
  11. import safesandbox
  12. import objmgr
  13. import eventbroadcaster
  14. import gameevents
  15. import gameeventkeys
  16. import request
  17. #
  18. # Basic game objects
  19. #
  20. class GameObject:
  21.   """
  22.   Base class for all game objects. Has object id
  23.   for tracking by the objmgr module.
  24.   """
  25.   def __init__(self, id):
  26.     self.id = id
  27. class Player(GameObject):
  28.   """
  29.   Represents a player in the game. This class is intended
  30.   to be used both outside and inside a SafeSandbox. When
  31.   used within a sandbox, it is protected by a Bastion
  32.   wrapper class, which prevents direct access to attributes
  33.   and methods that are prefixed by an underscore ('_') 
  34.   character.
  35.   """
  36.   def __init__(self, name, id, clientid):
  37.     GameObject.__init__(self, id)
  38.     self.name = name
  39.     self.currentRoom = None
  40.     self.clientid = clientid
  41.     self.health = 100
  42.     self.weaponid = None
  43.     self.inventory = []
  44.   def GetName(self):
  45.     """
  46.     Provide access to the name from within a Bastion-protected instance.
  47.     """
  48.     return self.name
  49.   def GetHealth(self):
  50.     """
  51.     Provide access to health from within a Bastion-protected instance.
  52.     """
  53.     return self.health
  54.   def _AddToInventory(self, item):
  55.     """
  56.     Protected.
  57.     Put an item into inventory.
  58.     """
  59.     self.inventory.append(item.id)
  60.   def _RemoveFromInventory(self, item):
  61.     """
  62.     Protected.
  63.     Remove an item into inventory.
  64.     """
  65.     self.inventory.remove(item.id)
  66.   def _AcquireItem(self, item):
  67.     """
  68.     Protected.
  69.     Take ownership of an item.
  70.     """
  71.     if self.currentRoom:
  72.       room = objmgr.GetObject(self.currentRoom)
  73.       if item.id in room.itemids:
  74.         room.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.ACTION_TAKE_OBJECT, self.id, item.id), 0.0)
  75.         return 1
  76.       else:
  77.         return 0
  78.   def _ReleaseItem(self, item):
  79.     """
  80.     Protected.
  81.     Release ownership of an item.
  82.     """
  83.     if self.currentRoom:
  84.       room = objmgr.GetObject(self.currentRoom)
  85.       if item.id in self.inventory:
  86.         room.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.ACTION_PLACE_OBJECT, self.id, item.id), 0.0)
  87.         return 1
  88.       else:
  89.         return 0
  90.   def _OnEnterRoom(self, room):
  91.     """
  92.     Protected.
  93.     Called by the room we enter; register handlers.
  94.     """
  95.     self.currentRoom = room.id
  96.     room.eventManager.RegisterHandler(gameeventkeys.ByEventAndSubject(gameevents.ACTION_WAVE, self.id), self._OnWaveAtMe)
  97.     room.eventManager.RegisterHandler(gameeventkeys.ByEventAndSubject(gameevents.ACTION_ATTACK_SUCCESS, self.id), self._OnAttackMe)
  98.     room.eventManager.RegisterHandler(gameeventkeys.ByEventAndSubject(gameevents.PLAYER_EXITS_ROOM, self.id), self._OnExitRoom2)
  99.   def _OnExitRoom(self, room):
  100.     """
  101.     Protected.
  102.     Called by the room we exit; unregister handlers.
  103.     """
  104.     self.currentRoom = None
  105.     room.eventManager.UnregisterHandler(gameeventkeys.ByEventAndSubject(gameevents.ACTION_WAVE, self.id), self._OnWaveAtMe)
  106.     room.eventManager.UnregisterHandler(gameeventkeys.ByEventAndSubject(gameevents.ACTION_ATTACK_SUCCESS, self.id), self._OnAttackMe)
  107.     room.eventManager.UnregisterHandler(gameeventkeys.ByEventAndSubject(gameevents.PLAYER_EXITS_ROOM, self.id), self._OnExitRoom2)
  108.   def _OnExitRoom2(self, key):
  109.     """
  110.     Event handler for when I leave a room.
  111.     """
  112.     self.health = 100  # regain health
  113.   def _EquipWeapon(self, weapon):
  114.     """
  115.     Protected.
  116.     Arm ourself.
  117.     """
  118.     if weapon.id in self.inventory:
  119.       self.weaponid = weapon.id
  120.       return 1
  121.     else:
  122.       return 0
  123.   def _GetWeapon(self):
  124.     """
  125.     Protected.
  126.     Access our weapon.
  127.     """
  128.     return objmgr.GetObject(self.weaponid)
  129.   def _Wave(self, targetPlayerId):
  130.     """
  131.     Protected.
  132.     Wave at the targetPlayer.
  133.     """
  134.     if self.currentRoom:
  135.       room = objmgr.GetObject(self.currentRoom)
  136.       room.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.ACTION_WAVE, self.id, targetPlayerId), 0.0)
  137.    
  138.   def _OnWaveAtMe(self, key):
  139.     """
  140.     Protected.
  141.     Event handler activated when someone waves at me.
  142.     """
  143.     srcname = objmgr.GetObject(key.src).name
  144.     request.ClientMessage(self.id, '%s just waved at you.' % (srcname,))
  145.   def _Attack(self, targetPlayerId):
  146.     """
  147.     Protected.
  148.     Attack the target player with your weapon.
  149.     """
  150.     if self.currentRoom:
  151.       room = objmgr.GetObject(self.currentRoom)
  152.       weapon = self._GetWeapon() 
  153.       if not weapon:
  154.         request.ClientMessage(self.id, 'You have no weapon equipped.')
  155.         return
  156.       targetPlayer = objmgr.GetObject(targetPlayerId)
  157.       if targetPlayer.currentRoom != self.currentRoom:
  158.         request.ClientMessage(self.id, 'You are not in the same room as %s' % (targetPlayer.name))
  159.         return
  160.        
  161.       print 'here'
  162.       # compute success
  163.       import random
  164.       if random.random() > weapon.tohit:
  165.         # compute damage
  166.         damage = random.randint(weapon.mindamage, weapon.maxdamage)
  167.         # notify whoever cares; note that damage is an arg
  168.         room.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.ACTION_ATTACK_SUCCESS, self.id, targetPlayerId), 0.0, damage)
  169.         request.ClientMessage(self.id, 'You attacked %s for %s damage.' % (targetPlayer.name, damage))
  170.       else:
  171.         room.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.ACTION_ATTACK_FAILURE, self.id, targetPlayerId), 0.0)
  172.         request.ClientMessage(self.id, 'You missed.')
  173.   def _OnAttackMe(self, key, damage):
  174.     """
  175.     Protected.
  176.     Event handler activated when someone attacks me.
  177.     """
  178.     srcname = objmgr.GetObject(key.src).name
  179.     self.health -= damage
  180.     if self.health <= 0:
  181.       request.ClientMessage(self.id, 'You were killed by %s.' % (srcname,))
  182.       room = objmgr.GetObject(self.currentRoom)
  183.       room.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.PLAYER_DIES, self.id), 0.0)
  184.       room.ExitRoom(self)
  185.     else: 
  186.       request.ClientMessage(self.id, '%s just attacked you for %s.' % (srcname, damage))
  187. class Item(GameObject):
  188.   """
  189.   Represents an item you can touch.
  190.   This class is protected by the Bastion when inside
  191.   a SafeSandbox.
  192.   """
  193.   def __init__(self, name, id):
  194.     GameObject.__init__(self, id)
  195.     self.name = name
  196.     self.currentRoom = None
  197.     self.ownerid = None
  198.   def _AssignOwner(self, ownerid):
  199.     self.ownerid = ownerid
  200.   def GetName(self):
  201.     # provide access to the name from within a Bastion-protected instance.
  202.     return self.name
  203. class Weapon(Item):
  204.   """
  205.   You can hurt somebody with this.
  206.   """
  207.   def __init__(self, name, id):
  208.     Item.__init__(self, name, id)
  209.     self.mindamage = 5
  210.     self.maxdamage = 20
  211.     self.tohit = 0.50
  212.     self.range = 2
  213. #
  214. # Environment / world game object
  215. #
  216. class Room(GameObject):
  217.   """
  218.   Identifies a region in the game in which players
  219.   can interact with each other and the 'world'.
  220.   Has a SafeSandbox which prevents game errant code from
  221.   disrupting the integrity of the server.
  222.   """
  223.   def __init__(self, name, id):
  224.     GameObject.__init__(self, id)
  225.     # for tracking items and players in this room
  226.     self.playerids = []
  227.     self.itemids = []
  228.     # add event broadcaster to global object mananger so it can receive deferred calls
  229.     eventManagerId = objmgr.NextId()
  230.     self.eventManager = eventbroadcaster.EventBroadcaster(eventManagerId)
  231.     objmgr.AddObject(self.eventManager, eventManagerId) 
  232.     # our safe sandbox, where game code runs
  233.     self.sandbox = safesandbox.CreateSafeSandbox(self, self.eventManager, name)
  234.     self.name = self.sandbox.__class__.__name__
  235.   def EnterRoom(self, player):
  236.     if not player.id in self.playerids:
  237.       self.playerids.append(player.id)
  238.       player._OnEnterRoom(self)
  239.       # post a game event to notify whoever cares; spoof the sandbox as the source,
  240.       # because restricted code may handle this event.
  241.       self.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.PLAYER_ENTERS_ROOM, self.sandbox, player.id), 0.0)
  242.     else: 
  243.       raise RuntimeError('Player %s is already in the room', (playerid,))
  244.   def ExitRoom(self, player):
  245.     if not player.id in self.playerids:
  246.       raise RuntimeError('Player %s is not in the room', (playerid,))
  247.     else: 
  248.       self.playerids.remove(player.id)
  249.       player._OnExitRoom(self)
  250.       # post a game event to notify whoever cares; spoof the sandbox as the source,
  251.       # because restricted code may handle this event.
  252.       self.eventManager.PostGameEvent(gameeventkeys.GameEventKey(gameevents.PLAYER_EXITS_ROOM, self.sandbox, player.id), 0.0)
  253. #
  254. # Utility
  255. #
  256. def CreateRoom(roomname):
  257.   """
  258.   Factory function: Create an instance of the 
  259.   room identified by the roomname. 
  260.   """
  261.   roomid = objmgr.NextId()
  262.   room = Room(roomname, roomid)
  263.   objmgr.AddObject(room, roomid)
  264.   objmgr.RegisterRoom(room)