示例#1
0
class UIInteractiveElement:
    def __init__(self):
        self.name = None

        self.assigned_item = None

        self.box = None
        self.select_timer = ActionTimer("Click", 0.2)

        self.animations = {}
        self.anim = 0

        self.selected = False
        self.already_over = False

        self.draw_x, self.draw_y = 0, 0

    def update(self, mpos, mpress, at_mouse, can, le):
        self.select_timer.update()

        for a in self.animations.values():
            a.update()

        x, y = mpos

        x, y = x - self.draw_x, y - self.draw_y

        mouseover = False
        curr_select = False
        if self.box.collidepoint((x, y)):
            if mpress[0] == 0:
                self.already_over = True
            mouseover = True
            if self.select_timer.ticked and mpress[0] == 1 and self.already_over and (can or le):
                curr_select = True
                self.selected = True - self.selected
                self.select_timer.reset()
                self.already_over = False
        else:
            self.already_over = False

        if self.selected:
            self.anim = self.animations["sel"]
        else:
            self.anim = self.animations["desel"]

        select = False
        if curr_select and self.selected == True:
            select = True
        return mouseover, select

    def get_frame(self):
        return self.anim.get_frame()
示例#2
0
class Collar:
    def __init__(self, spawn_pos, bub_json):
        self.pos = spawn_pos
        self.frames = {"0": 292, "1": 293}

        self.bubbles_paths = bub_json["Farmhouse"]["Collar"]
        self.load_bubble_images()
        self.bubble_frame = 0

        self.bubble_timer = ActionTimer("", 1.5)

        self.should_draw_bub = False

        self.type = "collar"

    def load_bubble_images(self):
        self.bubbles_imgs = {}
        for k, e in self.bubbles_paths.items():
            i = pygame.image.load("speech/bubbles/{0}".format(e))
            self.bubbles_imgs[k] = i

    def get_frame(self):
        return self.frames["0"]

    def get_bubble_frame(self):
        return self.bubbles_imgs[str(self.bubble_frame)]

    def update(self, g_obj, mpos, mpress, ui):
        self.bubble_timer.update()

        if in_range(self.pos, g_obj.mc.pos, 2):
            if self.should_draw_bub == False:
                self.bubble_timer.reset()
                self.bubble_frame = 0
                self.should_draw_bub = True
        else:
            self.should_draw_bub = False

        if self.bubble_timer.ticked:
            self.bubble_timer.reset()
            self.bubble_frame += 1
            if self.bubble_frame >= len(self.bubbles_imgs.keys()):
                self.bubble_frame = 0
示例#3
0
class Menu:
    def __init__(self, g_obj):
        self.menu_items = []
        # instantiate buttons
        self.menu_items.append(NewGameButton())
        self.menu_items.append(ContinueButton())
        self.menu_items.append(ExitButton())
        self.menu_items.reverse()

        self.timer = ActionTimer("", 0.25)

    def update(self, mpos, mpress, ui):
        self.timer.update()

        if mpress[0] == 0 or not ui.get_selected()=="in game menu":
            return

        for mi in self.menu_items:
            if mi.rect == None:
                continue
            if mi.rect.collidepoint(mpos) and self.timer.ticked:
                mi.on_mouse_click()
                self.timer.reset()
示例#4
0
class Music:
    # plays music according to stage.
    # doesn't always play something;
    # think Minecraft - it only plays
    # a song occasionally
    def __init__(self):
        self.songs = {}

        self.song_playing = False

        self.intermezzo = False
        self.intermezzo_range = (10, 60)

        self.timer = ActionTimer("silence timer", 10)

        self.fade_timer = ActionTimer("fade", 10)

        self.current_stage = None

        self.stage_conversion = {0: "farm", 1: "bubbas", 2: "cave", 3: "park"}

        self.rel = None

        self.fade_type = None

        self.muted = False

    def play_new_song(self):
        stage_actual = self.stage_conversion[self.current_stage]
        song = choice(self.songs[stage_actual])
        pygame.mixer.music.load(self.rel + song)
        pygame.mixer.music.play()

    def update(self):
        self.timer.update()
        self.fade_timer.update()
        if self.intermezzo:
            if self.timer.ticked:
                self.intermezzo = False
        else:
            if self.song_playing == False:
                self.play_new_song()
                self.song_playing = True
                pygame.mixer.music.set_volume(0)
                self.fade_timer.reset()
                self.fade_type = 1
            else:
                if not pygame.mixer.music.get_busy():
                    self.song_playing = False
                    self.intermezzo = True
                    intermezzo_time = randint(*self.intermezzo_range)
                    self.timer.dt = intermezzo_time
                    self.timer.reset()
                else:
                    if not self.fade_timer.ticked:
                        if self.fade_type == 1:
                            volume = self.fade_timer.get_progress()
                        elif self.fade_type == -1:
                            volume = 1 - self.fade_timer.get_progress()
                        pygame.mixer.music.set_volume(volume)
                    else:
                        if pygame.mixer.music.get_volume() != 1:
                            pygame.mixer.music.set_volume(1)
                        song_pos_secs = pygame.mixer.music.get_pos() / 1000
                        if 90 - self.fade_timer.dt <= song_pos_secs:
                            self.fade_timer.reset()
                            self.fade_type = -1

                    if self.muted:
                        pygame.mixer.music.set_volume(0)
示例#5
0
class Controller:
    def __init__(self):
        self.state = "idling"
        self.last_action = "wait"

        self.last_dest_pos = None

        self.action_delay = ActionTimer("", 0.05)

        self.controller_type = None

        self.unit = None

        self.spot_range = 15

        self.con_act = {"do": "nothing"}
        self.l_con_act = None
        self.l_move_con_act = None

    def action(self, c_ap, c_hp_self, m_hp_self, c_pos_enemy, c_hp_enemy,
               u_state, c_state, l_action, c_type):
        if u_state in ("dying", "dead") or u_state != "idle":
            return "wait", c_state, {}

        flee_per = 0.3
        if c_hp_self / m_hp_self < flee_per:
            c_state = "fleeing"
        else:
            pass

        if c_ap < 1 and c_state != "fleeing":
            return "pass", c_state, {}

        if c_state == "fleeing":
            available_abis = get_available_abis(
                self.unit, c_ap,
                ["heal", "buff"])  # returns a list of cast-able abilities
            if len(available_abis) == 0:
                return "walk", c_state, {"walk_command": "away_from_enemy"}
            else:
                abi_choice = choice(available_abis)
                return "cast", c_state, {"cast_ability": abi_choice}
            pass  # check if we have heal/buff available, then go into that state
            # otherwise stay in this state and keep running away.

        elif c_state == "idling":
            if in_range(self.unit.pos, c_pos_enemy, self.spot_range):
                c_state = "approaching"
                return "wait", c_state, {}
            else:
                return "pass", c_state, {}
            pass  # check if enemy is within range, if so- go out of idle state.

        elif c_state == "approaching":
            cur_max_range_self = get_max_range_of(self.unit)
            if in_range(self.unit.pos, c_pos_enemy, cur_max_range_self):
                c_state = "attacking"
                return "wait", c_state, {}
            else:
                return "walk", c_state, {"walk_command": "toward_enemy"}
            pass  # if you're too far away from enemy to attack - approach; walk toward
            # otherwise; go into attack state.

        elif c_state == "kiting":
            pass  # if you're ranged and your range is greater than the enemies, then
            # move a little back, otherwise go into a state of attacking.

        elif c_state == "attacking":
            available_abis = get_available_abis(self.unit, c_ap,
                                                ["ranged", "melee"])
            in_range_abis = get_in_range_abis(available_abis, self.unit,
                                              c_pos_enemy)
            in_range_attacks = get_in_range_atks(self.unit, c_pos_enemy)

            if len(in_range_abis) != 0 and False:  # ignore abilites for now
                use_abi = choice(in_range_abis)
                return "cast", c_state, {"use_ability": use_abi}
            elif len(in_range_attacks) != 0:
                use_weapon = choice(in_range_attacks)
                return "smack", c_state, {"use_weapon": use_weapon}
            else:
                c_state = "approaching"
                return "wait", c_state, {}
            pass  # here we can use a ranged or melee ability, or ranged or melee basic attack.

        return "wait", c_state, {}

    def update(self, g_obj, mc, mpos, mpress, ui, fighting):
        self.action_delay.update()

        con_act = {"do": "nothing"}

        if self.unit.end_turn == True:
            return
        elif self.action_delay.ticked:
            c_ap = self.unit.ap.get_ap()
            m_hp_self = self.unit.get_health()
            dmg = self.unit.damage_taken
            c_hp_self = m_hp_self - dmg
            c_hp_enemy = mc.get_health()
            u_state = self.unit.state
            c_state = self.state
            l_action = self.last_action
            c_type = self.controller_type
            c_pos_enemy = mc.pos
            action, c_state, commands = self.action(c_ap, c_hp_self, m_hp_self, c_pos_enemy, \
                c_hp_enemy, u_state, c_state, l_action, c_type)

            self.state = c_state
            self.l_action = action

            if action == "pass":
                self.unit.end_turn = True
            elif action == "wait":
                pass
            elif action == "walk":
                con_act["do"] = "walk"
                w_comm = commands["walk_command"]
                if w_comm == "away_from_enemy":
                    dest_pos = get_walkable_pos(mc.pos,
                                                self.unit,
                                                g_obj,
                                                eval_func=max)
                elif w_comm == "toward_enemy":
                    dest_pos = get_walkable_pos(mc.pos,
                                                self.unit,
                                                g_obj,
                                                eval_func=min)
                con_act["dest"] = dest_pos
                #self.state = "attacking"
                if dest_pos == self.last_dest_pos and w_comm == "away_from_enemy":
                    self.unit.end_turn = True
                    #self.con_act = {"do": "nothing"}
                self.last_dest_pos = dest_pos
                self.action_delay.reset()
                self.l_move_con_act = con_act
            elif action == "cast":
                pass
            elif action == "smack":
                con_act["do"] = "smack"
                weapon = commands["use_weapon"]
                dest_pos = c_pos_enemy
                con_act["dest"] = dest_pos
                con_act["weapon"] = weapon
                con_act["at_mouse"] = {}
                con_act["at_mouse"]["unit"] = mc
                con_act["at_mouse"]["units"] = get_units_list_at(
                    g_obj.units, dest_pos)
                con_act["at_mouse"]["mapped"] = dest_pos
                self.action_delay.reset()

            self.con_act = con_act

        else:
            self.con_act = {"do": "nothing"}


# 5 action types
# smack; use attack - ranged / melee; depending on its weapon, range to enemy, and cds, it will try to attack
# cast; use ability (4 ability categories)
# - heal
# - buff
# - ranged
# - melee
# walk; move somewhere, either toward player (melee attack / ranged attack but too far) or away from player (kiting / fleeing)
# wait; wait until unit finishes its' current action, or enemy is in sight
# pass; end turn

# state types
# idle
# approaching
# kiting
# attacking
# heal/buff
# fleeing
示例#6
0
class Bed:
    def __init__(self, room, rw, rh, sound):
        self.room = room
        self.rw, self.rh = rw, rh

        self.pos = None, None
        self.set_pos()

        self.has_used = False
        self.done_resting = False
        self.sound = sound

        self.rest_timer = ActionTimer("", 2)

    def set_pos(self):
        cox, coy = 13, 4
        cw, ch = 6, 6

        room = self.room
        gx, gy = room.grid_pos
        ox, oy = gx * self.rw, gy * self.rh
        self.pos = ox + cox + cw // 2 - 0.5, oy + coy + ch // 2 - 0.5

    def close_to_bed(self, g_obj, mpos):
        return in_range(self.pos, g_obj.mc.pos, 2)

    def update(self, g_obj, mpos, mpress, ui, fighting):
        if fighting:
            return

        self.rest_timer.update()

        # if not fighting:
        #    return

        #if not self.open_timer.ticked:
        #    return

        #if not ui.get_selected() == None:
        #    return

        if self.has_used and self.rest_timer.ticked and not self.done_resting:
            self.done_resting = True
            g_obj.mc.labels.add_label("Rested",
                                      g_obj.mc.pos[0],
                                      g_obj.mc.pos[1],
                                      delay=0)
            g_obj.mc.heal("percentage", 1, delay=0.5)

        am = ui.at_mouse
        """
        m = am["mapped"]
        if self.check_mouseover(g_obj, mpos):
            if self.is_closed == True:
                self.is_closed = False
                self.sound.play_sound_now("door open")
            elif self.is_closed == False:
                self.is_closed = True
                self.sound.play_sound_now("door close")

            self.open_timer.reset()
        """
        m = am["mapped"]
        if self.close_to_bed(g_obj, mpos) and not self.has_used:
            g_obj.mc.current_bed = self
            g_obj.mc.state = "resting"
            self.sound.play_sound_now("rest")
            self.has_used = True
            self.rest_timer.reset()