# elim by Chambahs # 1st try mar 22/23 2005 (all night'r, eheh) # with help from smong # mar 24 2005 revision 1 smong # mar 30 2005 revision 2 smong # apr 10 2005 revision 3 smong # june 10 2005 revision 4 smong # feb 5 2008 revision 5 smong (cleaned tabs/spaces) from asss import * chat = get_interface(I_CHAT) game = get_interface(I_GAME) #stats = get_interface(I_STATS) cfg = get_interface(I_CONFIG) # util def count_playing_freq(arena, freq): players = [ 0 ] def cb_count(p): if p.arena == arena and p.ship < SHIP_SPEC and p.freq == freq: players[0] += 1 for_each_player(cb_count) return players[0] def count_playing(arena): players = [ 0 ] def cb_count(p): if p.arena == arena and p.ship < SHIP_SPEC: players[0] += 1 for_each_player(cb_count) return players[0] # vote # allows players to say any positive number into pub chat and it will get # recorded as a vote. def vote_chatmsg(p, mtype, sound, to, freq, text): if mtype == MSG_PUB: value = 0 try: value = int(text) except: pass if value > 0: p.vote_value = value def vote_make_timer(arena, maxoption, timelimit, callback): def vote_timer(): # stop allowing votes arena.vote_ref1 = None arena.vote_ref2 = None # initialise the array sums = [] for i in range(maxoption): sums.append(0) # count the votes def cb_count_votes(p): if p.arena == arena and \ p.vote_value > 0 and \ p.vote_value <= maxoption: sums[p.vote_value - 1] += 1 for_each_player(cb_count_votes) # find the most popular vote besti = -1 best = 0 for i in range(maxoption): if sums[i] > best: best = sums[i] besti = i callback(arena, best, besti + 1) #arena.vote_ref3 = None return 0 return set_timer(vote_timer, timelimit, 1000) def vote_paction(p, action, arena): if action == PA_ENTERARENA: p.vote_value = 0 def vote_start(arena, question, maxoption, timelimit, callback): # reset all votes for this arena def cb_reset_votes(p): if p.arena == arena: p.vote_value = 0 for_each_player(cb_reset_votes) chat.SendArenaMessage(arena, "%s" % question) arena.vote_ref1 = reg_callback(CB_CHATMSG, vote_chatmsg, arena) arena.vote_ref2 = reg_callback(CB_PLAYERACTION, vote_paction, arena) arena.vote_ref3 = vote_make_timer(arena, maxoption, timelimit, callback) # stops the voting process def vote_stop(arena): arena.vote_ref1 = None arena.vote_ref2 = None arena.vote_ref3 = None # elim # don't add/remove or change the order without fixing some other code (you'll # have to find that 'some other code' muhahahaa). #elim_game_names = [ "elim", "team elim", "spiders", "race", "conquer" ] elim_game_names = [ "elim", "team elim", "spiders", "race" ] # vcb = vote call back def vcb_game(arena, votes, vid): # default game if vid == 0: vid = 1 arena.elim_game = vid chat.SendArenaMessage(arena, "game %d:%s (votes %d)" \ % (vid, elim_game_names[vid - 1], votes)) if arena.elim_game == 3: # zombies, no death vote arena.elim_deaths = 1 # 10 seconds until the game start for real chat.SendArenaMessage(arena, "game starts in 10 seconds") arena.elim_timerref = make_start_timer(arena, 1000) elif arena.elim_game != 4: # anything but race # start the death count vote vote_start(arena, "how many deaths? (1-10)", 10, 1000, vcb_death) else: # start the kill count vote vote_start(arena, "how many kills? (1-10)", 10, 1000, vcb_kill) def vcb_death(arena, votes, vid): # default deaths if vid == 0: vid = 10 arena.elim_deaths = vid chat.SendArenaMessage(arena, "deaths %d (votes %d)" % (vid, votes)) # 10 seconds until the game start for real chat.SendArenaMessage(arena, "game starts in 10 seconds") arena.elim_timerref = make_start_timer(arena, 1000) def vcb_kill(arena, votes, vid): # default kills if vid == 0: vid = 10 arena.elim_kills = vid chat.SendArenaMessage(arena, "kills %d (votes %d)" % (vid, votes)) # 10 seconds until the game start for real chat.SendArenaMessage(arena, "game starts in 10 seconds") arena.elim_timerref = make_start_timer(arena, 1000) def make_start_timer(arena, time): def start_timer(): # reset everyones stats def cb_reset(p): p.elim_deaths = p.elim_kills = 0 # stats.ScoreReset(p, INTERVAL_RESET) for_each_player(cb_reset) # stats.SendUpdates() # setup the needed callbacks arena.elim_killcb = reg_callback(CB_KILL, kill, arena) # setup the stuff needed for the game if arena.elim_game == 1 or arena.elim_game == 4: # elim or race # configure freqman cfg.SetInt(arena.cfg, "Team", "MaxPerTeam", 1, "elim.py", 0) cfg.SetInt(arena.cfg, "Team", "DesiredTeams", 9999, "elim.py", 0) # set ships/freqs counter = [ 0 ] def cb_1perfreq(p): if p.ship != SHIP_SPEC and p.arena == arena: game.SetFreq(p, counter[0]) game.ShipReset(p) counter[0] += 1 for_each_player(cb_1perfreq) elif arena.elim_game == 2: # team elim # configure freqman cfg.SetInt(arena.cfg, "Team", "MaxPerTeam", 9999, "elim.py", 0) cfg.SetInt(arena.cfg, "Team", "DesiredTeams", 2, "elim.py", 0) # set ships/freqs counter = [ 0 ] def cb_2teams(p): if p.ship != SHIP_SPEC and p.arena == arena: game.SetFreq(p, counter[0] % 2) game.ShipReset(p) counter[0] += 1 for_each_player(cb_2teams) elif arena.elim_game == 3: # zombies # configure freqman cfg.SetInt(arena.cfg, "Team", "MaxPerTeam", 1, "elim.py", 0) cfg.SetInt(arena.cfg, "Team", "DesiredTeams", 2, "elim.py", 0) # set ships/freqs counter = [ 0 ] def cb_allvs1(p): if p.ship != SHIP_SPEC and p.arena == arena: if counter[0] == 0: game.SetFreqAndShip(p, SHIP_SPIDER, 1) elif p.ship == SHIP_SPIDER: game.SetFreqAndShip(p, SHIP_WARBIRD, 0) else: game.SetFreq(p, 0) game.ShipReset(p) counter[0] += 1 for_each_player(cb_allvs1) # notify # fixme, change '1' to '0' on final release # chat.SendArenaMessage(arena, "debug: LockArena") game.LockArena(arena, 1, 0, 0, 0) # chat.SendArenaMessage(arena, "debug: GivePrize") game.GivePrize(arena, PRIZE_WARP, 1) # chat.SendArenaMessage(arena, "debug: gogogo msg + sound") chat.SendArenaSoundMessage(arena, SOUND_GOAL, "GO! GO! GO! GO! (sound)") return 0 return set_timer(start_timer, time, 1000) # keeps track of wins/losses a specs players after a certain amount of deaths def kill(arena, killer, killed, bounty, flags, pts, green): # increment stats killed.elim_deaths += 1 killer.elim_kills += 1 # see if they are out (elim, team elim) if arena.elim_game == 1 or arena.elim_game == 2: if killed.elim_deaths >= arena.elim_deaths: chat.SendArenaMessage(arena, "%s is out (%d:%d)" \ % (killed.name, killed.elim_kills, killed.elim_deaths)) # check for win condition if arena.elim_game == 1: # elim if count_playing(arena) == 2: chat.SendArenaMessage(arena, "elim game over.") elim_stop(arena) elif arena.elim_game == 2: # team elim if count_playing_freq(arena, killed.freq) == 1: chat.SendArenaMessage(arena, "team elim game over.") elim_stop(arena) # remove them from the game game.SetShip(killed, SHIP_SPEC) elif arena.elim_game == 3: # zombies if killed.freq != 1: # make them into a zombie game.SetFreqAndShip(killed, SHIP_SPIDER, 1) # check for win condition left = count_playing(arena) - count_playing_freq(arena, 1) if left == 1: chat.SendArenaMessage(arena, "spiders game over.") elim_stop(arena) elif left < 1: # there were only 2 players chat.SendArenaMessage(arena, "spiders game over.") elim_stop(arena) # since no one gets specced we need to force a vote # if there is no active game (or vote) try and start one if arena.elim_game == 0 and count_playing(arena) > 1: start_votes(arena) elif arena.elim_game == 4: # race # just check for win condition if killer.elim_kills >= arena.elim_kills: chat.SendArenaMessage(arena, "race game over. %s wins." % killer.name) elim_stop(arena) # since no one gets specced we need to force a vote # if there is no active game (or vote) try and start one if arena.elim_game == 0 and count_playing(arena) > 1: start_votes(arena) return pts, green # starts the voting process (game, deaths) def start_votes(arena): # make the message msg = "choose a game." for i in range(len(elim_game_names)): msg += " %s=%d" % (elim_game_names[i], i + 1) vote_start(arena, "%s" % msg, len(elim_game_names), 1000, vcb_game) # mark something so we don't keep sending the 'when 2 players or more' message arena.elim_game = -1 # clean up a currently running game def elim_stop(arena): arena.elim_killcb = None arena.elim_timerref = None arena.elim_game = 0 game.UnlockArena(arena, 1, 0) def shipchange(p, newship, newfreq): if newship != SHIP_SPEC: # if there is no active game (or vote) try and start one if p.arena.elim_game == 0 and count_playing(p.arena) > 1: start_votes(p.arena) #chat.SendArenaMessage(p.arena, "sc: playing: %d" % count_playing(p.arena)) elif count_playing(p.arena) < 2: if p.arena.elim_game > 0: chat.SendArenaMessage(p.arena, "game over.") # fixme: work out who the winner is elim_stop(p.arena) elif p.arena.elim_game == -1: # cancel any votes vote_stop(p.arena) def paction(p, action, arena): if action == PA_ENTERARENA: # if there is no active game (or vote) try and start one if arena.elim_game == 0: #chat.SendArenaMessage(arena, "enter: playing: %d" % count_playing(arena)) if count_playing(arena) >= 2: start_votes(arena) else: chat.SendArenaMessage(arena, "game starts when two or more players enter") elif arena.elim_game > 0: chat.SendMessage(p, "game in progress.") elif action == PA_LEAVEARENA: # see if we should cancel the currently running game if count_playing(arena) < 2: if arena.elim_game > 0: chat.SendArenaMessage(arena, "game aborted.") elim_stop(arena) elif arena.elim_game == -1: # cancel any votes vote_stop(arena) def mm_attach(arena): arena.elim_ref1 = reg_callback(CB_PLAYERACTION, paction, arena) arena.elim_ref2 = reg_callback(CB_SHIPCHANGE, shipchange, arena) arena.elim_killcb = None arena.elim_timerref = None arena.elim_game = 0 arena.elim_deaths = 0 arena.elim_kills = 0 chat.SendArenaMessage(arena, "game starts when two or more players enter") def mm_detach(arena): vote_stop(arena) elim_stop(arena) arena.vote_ref1 = None arena.vote_ref2= None arena.vote_ref3 = None arena.elim_ref1 = None arena.elim_ref2 = None arena.elim_killcb = None arena.elim_timerref = None arena.elim_game = 0 arena.elim_deaths = 0