# bounty rabbit 15/11/04 smong
# add Misc:BountyRabbit=1 to activate in your arena
# revision 1
# revision 2 (02/12/04)
# revision 3 (12/01/05)
# revision 4 (13/01/05)
# revision 5 (17/01/05)
# revision 6 (20/01/05)
# revision 7 (25/01/05)
# revision 8,9 (28/01/05)
# revision 10 (05/02/05)

# todo: use ?time

from asss import *

game = get_interface(I_GAME)
chat = get_interface(I_CHAT)
prng = get_interface(I_PRNG)
cfg = get_interface(I_CONFIG)

def aaction(a, action):
    if action == AA_CREATE:
        # initialising all per-arena data here to avoid confusion later
        a.br_rabbit = None
        a.br_ref = None
    elif action == AA_DESTROY:
        a.br_ref = None

cb1 = reg_callback(CB_ARENAACTION, aaction)

def paction(p, action, arena):
    if action == PA_ENTERGAME:
        if arena.br_rabbit == None and count_players(arena) >= 2:
            if cfg.GetInt(arena.cfg, "Misc", "BountyRabbit", 0) == 1:
                # this function announces for us.
                new_pick(arena)
    elif action == PA_LEAVEARENA:
        playing = count_players(arena)
        if arena.br_rabbit == p:
            arena.br_rabbit = None
            arena.br_ref = None

            if playing > 2: # still in arena
                # this function announces for us.
                new_pick(arena)
            else:
	        chat.SendArenaMessage(arena, "Game stopped.")
        elif playing < 2 and arena.br_rabbit != None:
            arena.br_rabbit = None
            arena.br_ref = None
	    chat.SendArenaMessage(arena, "Game stopped.")

cb2 = reg_callback(CB_PLAYERACTION, paction)

def kill(arena, killer, killed, bty, flags, pts, green):
    if killed == arena.br_rabbit:
        arena.br_rabbit = killer
        arena.br_ref = None

        # prize
        if arena.br_rabbit.position[5] < 5000:
            game.GivePrize(arena.br_rabbit, 0, 5000)

        # start timer
        arena.br_ref = None
        arena.br_ref = make_rabbit_timer(60000, 1000, arena)

        # announce
        make_remark(killer, killed)
    return pts, green

cb3 = reg_callback(CB_KILL_POST_NOTIFY, kill)

def shipchange(p, newship, newfreq):
    old = p.arena.br_rabbit
    players = count_players(p.arena)
    picknew = 0
    stopped = 0

    if p == p.arena.br_rabbit and newship == SHIP_SPEC:
        # rabbit specs, pick a new one
        p.arena.br_rabbit = None
        p.arena.br_ref = None
        if players > 2:
            picknew = 1
        else:
            stopped = 1
    elif newship == SHIP_SPEC and players <= 2:
        # not enough players to continue. stop game.
        if p.arena.br_rabbit != None:
            p.arena.br_rabbit = None
            p.arena.br_ref = None
            stopped = 1
    elif players >= 2:
        # start a game if not already running
        if p.arena.br_rabbit == None:
            picknew = 1

    # take action
    if picknew == 1:
        if cfg.GetInt(p.arena.cfg, "Misc", "BountyRabbit", 0) == 1:
            # this function announces for us.
            new_pick(p.arena)
            if p.arena.br_rabbit == None:
                # failed to find a new rabbit
                stopped = 1

    if stopped == 1:
        chat.SendArenaMessage(p.arena, "Game stopped.")

cb4 = reg_callback(CB_SHIPCHANGE, shipchange)

def safezone(p, x, y, entering):
   if p == p.arena.br_rabbit:
       if entering:
           p.arena.br_sref = make_safety_timer(2000, 1000, p.arena)
       else:
           p.arena.br_sref = None

cb5 = reg_callback(CB_SAFEZONE, safezone)


def make_rabbit_timer(initial, interval, arena):
    def rabbit_timer():
        if arena.br_rabbit:
            # announce
            chat.SendArenaSoundMessage(arena, SOUND_HALLELLULA,
                arena.br_rabbit.name + " has survived the 10-minute duration as "
                "Bounty Rabbit!  Congratulations on becoming an Uberabbit!")
        # pick new rabbit. this function announces for us.
        new_pick(arena)
        return 0
    return set_timer(rabbit_timer, initial, interval)

def make_safety_timer(initial, interval, arena):
    def safety_timer():
        if arena.br_rabbit:
            # announce
            chat.SendArenaMessage(arena, arena.br_rabbit.name
	        + " overstayed his welcome in the safety zone.")
        # pick new rabbit. this function announces for us.
        new_pick(arena)
        return 0
    return set_timer(safety_timer, initial, interval)


def count_players(arena):
    players = [ 0 ]
    def cb_count(p):
        if p.arena == arena and p.ship < 8:
             players[0] = players[0] + 1
    for_each_player(cb_count)
    return players[0]

def get_random_player(arena, exclude):
    players = count_players(arena)
    if exclude != None:
    	players = players - 1

    random = [ prng.Number(0, players - 1) ]
    theplayer = [ None ]

    def cb_grab(p):
        if p.arena == arena and p != exclude and p.ship < 8:
            if random[0] == 0:
                theplayer[0] = p
            random[0] = random[0] - 1
    for_each_player(cb_grab)
    return theplayer[0]

# messages and sounds from mervbot bounty rabbit
def make_remark(new, old):
    remark = prng.Number(0, 12)
    s = ""
    sound = 0

    if remark == 0:
        s += "The BountyRabbit(tm) has struck again! Zone in panic! "
        s += new.name
        s += " now at large! $5000 reward!"
        sound = SOUND_CHURCHILL
    elif remark == 1:
        s += "Hop. hop. hop. Another rabbit bit the dust. "
        s += new.name
        s += " now holds the 5000 bounty!"
        sound = SOUND_INCONCEIVABLE
    elif remark == 2:
        if old:
            s += old.name
            s += "(old rabbit) kb "
	s += new.name
        s += "(new rabbit with 5000 bounty)"
        sound = SOUND_AWW
    elif remark == 3:
        s += "Uh oh, "
        s += new.name
        s += " is growing ears! He's contracted the BountyRabbit(tm) virus"
        if old:
            s += " from "
            s += old.name
        s += "!";
        sound = SOUND_SCREAM
    elif remark == 4:
        s += new.name;
        s += " is now the BountyRabbit! Type ?target=5000 for a Big Light Blue"
	s += " indicator on your radar"
        sound = SOUND_OOO
    elif remark == 5:
        s += new.name
        s += " has been rabbitified!"
	# fixme. fixme game_timer.
	# s += " Type ?time to check how much time is left until he wins"
        sound = SOUND_GEE
    elif remark == 6:
        s += "Another waskalie wabbit has been sighted: "
        s += new.name
        s += ". And it's wabbit-hunting season!"
        sound = SOUND_GIBBERISH
    elif remark == 7:
        s += new.name
        s += " has vanquished the villainous old rabbit! He has been granted a $5000 reward"
        sound = SOUND_REAGAN
    elif remark == 8:
        s += "A new bounty rabbit has been born and it ain't pretty! "
        s += new.name
        s += " holds the sucker"
        sound = SOUND_CRYING
    elif remark == 9:
        s += "Uh oh, "
        s += new.name
        s += " is growing ears! He's contracted the BountyRabbit(tm) virus from "
        s += old.name
        s += "!"
        sound = SOUND_VIOLENT
    elif remark == 10:
        s += "The BountyRabbit(tm) has struck again! Zone in panic! "
        s += new.name
        s += " now at large! $5000 reward!"
        sound = SOUND_WORLDATTACK
    elif remark == 11:
        s += "Zee rebbeet, "
        s += new.name
        s += ", veell be-a in zee stoo suun inuoogh. $5000 preece-a teg"
        sound = SOUND_OHH
    elif remark == 12:
        s += "Psst! "
        s += new.name[1:32]
        s += new.name[0:1]
        s += "ay has ethay OuntyRabbitbay irusvay! Asspay it onyay!"
        sound = SOUND_PHONE
    else:
        s += "New bountyrabbit: "
        s += new.name
        sound = SOUND_MUSICONCE

    chat.SendArenaSoundMessage(new.arena, sound, "%s" % s)

def new_pick(arena):
    old = arena.br_rabbit

    # pick random
    arena.br_rabbit = get_random_player(arena, arena.br_rabbit)

    if arena.br_rabbit != None:
        # prize
        if arena.br_rabbit.position[5] < 5000:
            game.GivePrize(arena.br_rabbit, 0, 5000)

        # start timer
        arena.br_ref = None
	arena.br_sref = None
        arena.br_ref = make_rabbit_timer(60000, 1000, arena)

        # announce
	chat.SendArenaMessage(arena, "New rabbit: " + arena.br_rabbit.name)

def c_newpick(cmd, params, p, targ):
    """\
Module: <py> bountyrabbit
Targets: none
Choose a new bounty rabbit.
One player is chosen at random to become bounty rabbit with 5000 bounty.
If he can survive 10 minutes, he is an uberabbit.
"""
    if cfg.GetInt(p.arena.cfg, "Misc", "BountyRabbit", 0) == 1:
        # this function announces for us.
        new_pick(p.arena)

        if p.arena.br_rabbit == None:
            chat.SendMessage(p, "Not enough players to choose a new rabbit.")
    else:
        chat.SendMessage(p, "Bounty Rabbit has been disabled in this arena.")

cmd1 = add_command("newpick", c_newpick)
