def _HandleFighting(client, actor): """ If there is someone to fight, fight them to the death. Let everyone know who died. """ print g_programName + 'actor [%s] attempting to fight...' % (actor.GetId()) if len(g_actorDict) == 1: print g_programName + 'no other actor found! The air is harmlessly punched...' return deadActor = None otherActor = _GetOtherActor(actor) print g_programName + 'and proceeds to attack actor [%s]' % ( actor.GetId(), ) print g_programName + 'The fighting is fierce...' roll = random.randint(1, 10) # arbitrarily, the attacker has the upper hand if roll < 7: deadActor = otherActor print g_programName + 'and the opponent is overcome, actor [%s] dies' % ( otherActor.GetId(), ) else: deadActor = actor print g_programName + 'and the opponent overcomes the attacker, actor [%s]' % ( actor.GetId()) # attacker is dead deadActor.TransitionTo(_dead) # NOTE: to force a correction to happen, you can comment # out this next line, and then try to do a state change # on the dead actor client. You will see a correction, # and subsequent failure on state change request, since # the blocks were transmitted in the _SendStateCorrection # method and the dead actor client is synced up. _BroadcastDeathToAll(deadActor)
def _ActorStateChange(client): """ Handles an actor state change request. If it is valid, broadcast the change to all other clients. if it is not, send a correction back to the originating client. """ if g_actorDict.has_key(client): actor = g_actorDict[client] data = client.read_exactly(1) if data is None: client.close() return (stateId, ) = struct.unpack("B", data) state = shared._GetStateModuleById(stateId) print g_programName + 'state change request from actor [%s] to state [%s]' % ( actor.GetId(), _ParseStateName(state)) if actor.RequestStateChange(state): print g_programName + 'state change ok, broadcasting' _BroadcastStateChange(client, actor) if state == _casting: _HandleCasting(client, actor) elif state == _fighting: _HandleFighting(client, actor) else: print g_programName + 'state change denied, sending correction' _SendStateCorrection(client, actor) _PrintActorList() else: print g_programName + 'unable to retrieve client entry %s' % (client, )
def _BroadcastStateChange(client, actor): """ Broadcast the state change of the specfied actor to all clients except the one specfified, """ for otherClient in g_actorDict.keys(): if client != otherClient: p, m, a = actor.GetAllStateIds() otherClient.send( struct.pack("<BBBBB", MSG_TYPE_STATE_CHANGE, actor.GetId(), p, m, a))
def close(self): """ Get rid of the client, actor entry when the connection is closed, let all remaining clients know that this actor has left. """ global g_actorDict if g_actorDict.has_key(self): actor = g_actorDict[self] del g_actorDict[self] for currentClient, currentActor in g_actorDict.items(): currentClient.send( struct.pack("<BB", MSG_TYPE_ACTOR_LEFT, actor.GetId())) actor = None asyncore.dispatcher.close(self)
def _HandleCasting(client, actor): """ If there is someone to freeze, the freeze them and let everyone know about it. """ print g_programName + 'actor [%s] attempting to cast FREEZE spell...' % ( actor.GetId()) if len(g_actorDict) == 1: print g_programName + 'no target found, the spell fizzles...' return otherActor = _GetOtherActor(actor) print g_programName + 'the spell freezes actor [%s] and prevents their movement!' % ( otherActor.GetId(), ) # they can't move any more otherActor.ForceDefaultStates() otherActor.BlockMovement() # let everyone know _BroadcastFrozenToAll(otherActor)
def _BroadcastDeathToAll(actor): """ Broadcast that an actor died to all clients """ for client in g_actorDict.keys(): client.send(struct.pack("<BB", MSG_TYPE_ACTOR_DEAD, actor.GetId()))
def _BroadcastFrozenToAll(actor): """ Broadcast that an actor got frozen to all clients """ for client in g_actorDict.keys(): client.send(struct.pack("<BB", MSG_TYPE_ACTOR_FROZEN, actor.GetId()))