예제 #1
0
    def reload_animation(self):
        if SETTINGS.held_ammo[self.ammo_type] > 0 or SETTINGS.unlimited_ammo:
            #Change sprite list to reload.
            if self.current_img not in self.reload:
                self.current_img = self.reload[0]
                SOUND.play_sound(random.choice(self.sounds['magout']), 0)

            self.reload_busy = True
            #Make sure the magazine is out of view for some time.
            if (self.current_img == self.reload[3] and self.timer >
                    self.rlspeed) or (self.current_img != self.reload[-1]
                                      and self.current_img != self.reload[3]
                                      and self.timer >= 0.15):
                x = self.reload.index(self.current_img) + 1
                self.current_img = self.reload[x]
                self.timer = 0
            elif self.current_img == self.reload[-1] and self.timer >= 0.15:
                #Done reloading
                self.current_img = self.aim[0]
                self.reload_busy = False
                self.timer = 0
                SOUND.play_sound(random.choice(self.sounds['magin']), 0)
                #Change actual ammo
                if not SETTINGS.unlimited_ammo:
                    taken_ammo = self.mag_size - self.current_mag
                    if SETTINGS.held_ammo[self.ammo_type] >= taken_ammo:
                        self.current_mag = self.mag_size
                        SETTINGS.held_ammo[self.ammo_type] -= taken_ammo
                    elif SETTINGS.held_ammo[self.ammo_type] < taken_ammo:
                        self.current_mag = SETTINGS.held_ammo[
                            self.ammo_type] + self.current_mag
                        SETTINGS.held_ammo[self.ammo_type] = 0
                else:
                    self.current_mag = self.mag_size
예제 #2
0
    def do_call_for_help(self, number_of_allies):
        if self.can_call_for_help():
            SOUND.play_sound(self.sounds['spot'], self.dist_from_player)
            self.seen_player()
            self.add_message("calling for backup")
            self.call_allies(id(self), number_of_allies, "hostile", SEARCHING, self.last_seen_player_position)

            return True

        return False
예제 #3
0
파일: MENU.py 프로젝트: TaliSman1007/Meta3A
 def get_clicked(self):
     if self.rect.collidepoint(pygame.mouse.get_pos()):
         if pygame.mouse.get_pressed()[0]:
             self.clicked = True
         if not pygame.mouse.get_pressed()[0] and self.clicked:
             self.clicked = False
             SOUND.play_sound(self.sound, 0)
             return True
         else:
             return False
     else:
         return False
예제 #4
0
    def damage(self):
        if SETTINGS.middle_slice_len:
            target_npcs = [x for x in SETTINGS.npc_list if x.hit_rect.colliderect(self.hit_rect) and x.dist < SETTINGS.middle_slice_len]
        else:
            target_npcs = [x for x in SETTINGS.npc_list if x.hit_rect.colliderect(self.hit_rect)]

        if len(target_npcs) > 3:
            target_npcs = sorted(target_npcs, key=lambda x: x.sprite.theta)[:3]
            
        for npc in target_npcs:
            if npc.dist <= self.range and not npc.dead:
                if npc.dist <= SETTINGS.tile_size*2:
                    cap = 100
                else:
                    cap = (self.hit_percent * 0.96 ** (npc.dist*((100-self.hit_percent)/100)))
                        
                if cap >= random.randint(0,int(npc.dist*(1/self.range))):
                    SOUND.play_sound(self.hit_marker, 0)

                    #Damage less if NPC is far away from center.
                    if self.hit_rect.width < 120 or (npc.hit_rect.centerx > self.hit_rect.left + self.hit_rect.width/3 and npc.hit_rect.centerx < self.hit_rect.right - self.hit_rect.width/3):
                        #Critical hit
            
                        if (npc.state == 'idle' or npc.state == 'patrouling') and not npc.player_in_view:
                            npc.health -= self.dmg * 2
                            SETTINGS.statistics['last ddealt'] += self.dmg*2
                        else:
                            npc.health -= self.dmg
                            SETTINGS.statistics['last ddealt'] += self.dmg
                    else:
                        if (npc.state == 'idle' or npc.state == 'patrouling') and not npc.player_in_view:
                            npc.health -= self.dmg
                            SETTINGS.statistics['last ddealt'] += self.dmg*2
                        else:
                            npc.health -= self.dmg / 2
                            SETTINGS.statistics['last ddealt'] += self.dmg
                    npc.timer = 0
                    npc.hurting = True
                    if npc.health <= 0:
                        npc.knockback = self.dmg * (SETTINGS.tile_size/2)
예제 #5
0
    def sesam_luk_dig_op(self):
        if self.open > SETTINGS.tile_size:
            self.open = SETTINGS.tile_size
        elif self.open < 0:
            self.open = 0
            
        if self.state == 'closed':
            self.state = 'opening'
            
        elif self.state == 'opening':
            if self.open == 0:
                SOUND.play_sound(self.open_sound, self.distance)
                
            if self.open < SETTINGS.tile_size:
                self.open += SETTINGS.tile_size * SETTINGS.dt
            else:
                self.state = 'open'
                self.solid = False
            if self.open > SETTINGS.tile_size/1.4:
                self.solid = False

        elif self.state == 'open':
            self.timer += SETTINGS.dt
            if self.timer > 5 and not self.rect.colliderect(SETTINGS.player_rect):
                for i in SETTINGS.npc_list:
                    if self.rect.colliderect(i.rect):
                        break
                else:   
                    self.state = 'closing'
                    self.solid = True
                    self.timer = 0

        elif self.state == 'closing':
            if self.open >= SETTINGS.tile_size:
                SOUND.play_sound(self.close_sound, self.distance)
            if self.open > 0:
                self.open -= SETTINGS.tile_size * SETTINGS.dt
            else:
                self.state = 'closed'
예제 #6
0
    def __init__(self, name):
        """Construtor da classe
        :Param name: Nome do cômodo a ser criado
        :Type name: String 
        """
        self.__rooms = {}
        self.__port = None
        self.__name = name
        self.__numberOfPeoples = 0
        self.__equipments = {}
        self.addEquipment("tv", TV())
        self.addEquipment("som", SOUND())
        self.__control = False

        self.__eventTimer = sched.scheduler(time.time, time.sleep)
        self.__cancelEventTimer = None
예제 #7
0
    def control(self, canvas):
        #Make sure the collide list is complete
        if len(self.collide_list) != len(SETTINGS.all_solid_tiles +
                                         SETTINGS.npc_list):
            self.collide_list = SETTINGS.all_solid_tiles + SETTINGS.npc_list
        elif self.current_level != SETTINGS.current_level:
            self.collide_list = SETTINGS.all_solid_tiles + SETTINGS.npc_list
            self.current_level = SETTINGS.current_level
        elif self.update_collide_list:
            self.collide_list = SETTINGS.all_solid_tiles + SETTINGS.npc_list
            self.update_collide_list = False

        #Update health
        if self.health != SETTINGS.player_health and SETTINGS.player_states[
                'heal']:
            self.health = SETTINGS.player_health

        key = pygame.key.get_pressed()

        #Movement controls (WASD)
        if not SETTINGS.player_states['dead']:
            #Inventory open
            if not SETTINGS.player_states['invopen']:

                if SETTINGS.aiming:
                    self.sensitivity = SETTINGS.sensitivity / 3
                    self.max_speed = SETTINGS.player_speed / 3
                    if self.speed > self.max_speed:
                        self.speed = self.max_speed
                else:
                    self.sensitivity = SETTINGS.sensitivity
                    self.max_speed = SETTINGS.player_speed

                if key[pygame.K_a] or key[pygame.K_d] or key[
                        pygame.K_w] or key[pygame.K_s]:
                    if self.speed < self.max_speed:
                        self.speed += 50
                        if self.speed > self.max_speed:
                            self.speed = self.max_speed

                else:
                    if self.speed > 0:
                        if self.last_call == 0:
                            self.move(self.direction(90, self.speed * 0.8))
                        elif self.last_call == 1:
                            self.move(self.direction(-90, self.speed * 0.8))
                        elif self.last_call == 2:
                            self.move(self.direction(0, self.speed))
                        elif self.last_call == 3:
                            self.move(self.direction(0, -self.speed * 0.5))

                        self.speed -= 80

                        if self.speed < 1:
                            self.speed = 0

                if key[pygame.K_a]:
                    self.move(self.direction(90, self.speed * 0.8))
                    self.last_call = 0
                if key[pygame.K_d]:
                    self.move(self.direction(-90, self.speed * 0.8))
                    self.last_call = 1
                if key[pygame.K_w]:
                    self.move(self.direction(0, self.speed))
                    self.last_call = 2
                if key[pygame.K_s]:
                    self.move(self.direction(0, -self.speed * 0.5))
                    self.last_call = 3

                SETTINGS.player_states['cspeed'] = self.speed

                #Shoot gun (Mouse input)
                if pygame.mouse.get_pressed()[2] and self.mouse2 < 1:
                    SETTINGS.mouse2_btn_active = True
                    self.mouse2 += 1
                elif self.mouse2 >= 1:
                    SETTINGS.mouse2_btn_active = False
                if not pygame.mouse.get_pressed()[2]:
                    self.mouse2 = 0

                if pygame.mouse.get_pressed(
                )[0] and not SETTINGS.player_states['dead']:
                    SETTINGS.mouse_btn_active = True
                else:
                    SETTINGS.mouse_btn_active = False

                if key[pygame.K_r]:
                    SETTINGS.reload_key_active = True
                else:
                    SETTINGS.reload_key_active = False

        #Change gun
                if key[pygame.K_1] and SETTINGS.inventory['primary']:
                    SETTINGS.next_gun = SETTINGS.inventory['primary']
                elif key[pygame.K_2] and SETTINGS.inventory['secondary']:
                    SETTINGS.next_gun = SETTINGS.inventory['secondary']
                elif key[pygame.K_3] and SETTINGS.inventory['melee']:
                    SETTINGS.next_gun = SETTINGS.inventory['melee']

        #Keep angle in place
                if self.angle >= 360:
                    self.angle = 0
                elif self.angle < 0:
                    self.angle = 359

        #Interact
                if key[pygame.K_e]:
                    if SETTINGS.middle_slice:
                        if SETTINGS.middle_slice_len <= SETTINGS.tile_size * 1.5 and (
                                SETTINGS.middle_slice.type == 'vdoor'
                                or SETTINGS.middle_slice.type == 'hdoor'):
                            SETTINGS.middle_slice.sesam_luk_dig_op()
                        elif SETTINGS.middle_slice_len <= SETTINGS.tile_size and SETTINGS.middle_slice.type == 'end' and not SETTINGS.player_states[
                                'fade']:
                            SETTINGS.player_states['fade'] = True
                            SETTINGS.changing_level = True
                            SOUND.play_sound(self.change_level, 0)

                madd = self.mouse.get_rel()[0] * self.sensitivity
                if madd > 38:
                    madd = 38
                elif madd < -38:
                    madd = -38
                self.angle -= madd

                SETTINGS.player_angle = self.angle
                add_event_single(EVENT_PLAYER_VIEW_CHANGED,
                                 {'value': self.angle})

        #Open inventory
            if key[pygame.K_i] and self.inventory < 1:
                if SETTINGS.player_states['invopen']:
                    SETTINGS.player_states['invopen'] = False
                    SETTINGS.inv_strings_updated = False
                else:
                    SETTINGS.player_states['invopen'] = True

                self.inventory += 1
            elif not key[pygame.K_i]:
                self.inventory = 0

        #Use escape to close inventory
            if key[pygame.K_ESCAPE] and SETTINGS.player_states['invopen']:
                SETTINGS.player_states['invopen'] = False
                SETTINGS.inv_strings_updated = False
                self.dont_open_menu = True

            elif not key[
                    pygame.K_ESCAPE] and not SETTINGS.player_states['invopen']:
                self.dont_open_menu = False

        #Show menu
            if key[pygame.K_ESCAPE] and not self.dont_open_menu:
                self.esc_pressed = True

            elif self.esc_pressed and not self.dont_open_menu:
                SETTINGS.menu_showing = True
                self.esc_pressed = False

        #Is the player dead or taking damage?
        if self.health > SETTINGS.player_health:
            SETTINGS.statistics['last dtaken'] += (self.health -
                                                   SETTINGS.player_health)
            self.health = SETTINGS.player_health
            SETTINGS.player_states['hurt'] = True
            SOUND.play_sound(self.hurt_sound, 0)
        if SETTINGS.player_health <= 0 and not SETTINGS.godmode:
            self.dead = True
            SETTINGS.player_states['dead'] = True
        if SETTINGS.player_health < 0:
            SETTINGS.player_health = 0

        if SETTINGS.menu_showing or SETTINGS.player_states['invopen']:
            pygame.event.set_grab(False)
            self.mouse.set_visible(True)
#     elif key[pygame.K_q]:
#         pygame.event.set_grab(True)
#         self.mouse.set_visible(False)
        else:
            pygame.event.set_grab(True)
            self.mouse.set_visible(False)
예제 #8
0
    def damage(self):
        if SETTINGS.middle_slice_len:
            target_npcs = [
                x for x in SETTINGS.npc_list
                if x.hit_rect.colliderect(self.hit_rect)
                and x.dist < SETTINGS.middle_slice_len
            ]
        else:
            target_npcs = [
                x for x in SETTINGS.npc_list
                if x.hit_rect.colliderect(self.hit_rect)
            ]

        if len(target_npcs) > 3:
            target_npcs = sorted(target_npcs, key=lambda x: x.sprite.theta)[:3]

        for npc in target_npcs:
            if npc.dist <= self.range and not npc.dead:
                if npc.dist <= SETTINGS.tile_size * 2:
                    cap = 100
                else:
                    cap = (self.hit_percent *
                           0.96**(npc.dist * ((100 - self.hit_percent) / 100)))

                if cap >= random.randint(0, int(npc.dist * (1 / self.range))):
                    SOUND.play_sound(self.hit_marker, 0)

                    damage_to_be_done = self.dmg

                    in_center = self.hit_rect.width < 120 or (
                        npc.hit_rect.centerx > self.hit_rect.left +
                        self.hit_rect.width / 3 and npc.hit_rect.centerx <
                        self.hit_rect.right - self.hit_rect.width / 3)
                    #Damage less if NPC is far away from center.
                    if in_center:
                        #Critical hit

                        if (npc.state == IDLE or npc.state
                                == PATROLLING) and not npc.player_in_view:
                            damage_to_be_done = damage_to_be_done * 2
                        else:
                            pass
                    else:
                        if (npc.state == IDLE or npc.state
                                == PATROLLING) and not npc.player_in_view:
                            pass
                        else:
                            damage_to_be_done = damage_to_be_done / 2

                    if npc.side == SIDE_BACK and npc.state != ATTACKING:
                        if in_center:
                            if not npc.is_searching_for_player():
                                npc.add_message("instakill")
                                damage_to_be_done = npc.health
                            else:
                                npc.add_message("I expected that attack")
                                damage_to_be_done = damage_to_be_done * 1.5

                    SETTINGS.statistics['last ddealt'] += damage_to_be_done
                    npc.health -= damage_to_be_done

                    npc.timer = 0
                    npc.hurting = True
                    if npc.health <= 0:
                        npc.knockback = self.dmg * (SETTINGS.tile_size / 2)
예제 #9
0
    def shoot_animation(self):
        if self.current_mag > 0 or self.guntype == 'melee':
            if self.firetimer >= self.firerate:
                #Hitscan gun animation
                if not self.aim_is_up and self.guntype != 'melee':
                    #Hip fire
                    if self.current_img not in self.hipfire:
                        self.current_img = self.hipfire[random.randint(0, 1)]
                        self.shoot_busy = True
                        SOUND.play_sound(random.choice(self.sounds['shot']), 0)
                        SETTINGS.screen_shake = self.dmg * 2
                        self.damage()
                        self.timer = 0

                    elif self.hipfire.index(
                            self.current_img
                    ) <= 1 and self.timer >= self.shoottime:
                        self.current_img = self.hipfire[-1]
                        self.timer = 0
                    elif self.current_img == self.hipfire[
                            -1] and self.timer >= self.shoottime:
                        self.current_img = self.aim[0]
                        self.shoot_busy = False
                        self.current_mag -= 1
                        SETTINGS.statistics['last shots'] += 1
                        if self.stats['magsize'] == 3.1415:
                            self.current_mag -= 1
                            SETTINGS.statistics['last shots'] += 1
                        self.firetimer = 0

                #Melee weapon animation
                elif self.guntype == 'melee':
                    if self.current_img not in self.hipfire:
                        self.current_img = self.hipfire[0]
                        self.shoot_busy = True
                        SOUND.play_sound(random.choice(self.sounds['shot']), 0)
                        self.damage()
                        self.timer = 0

                    elif self.hipfire.index(
                            self.current_img
                    ) < 2 and self.timer >= self.shoottime:
                        self.current_img = self.hipfire[
                            self.hipfire.index(self.current_img) + 1]
                        self.timer = 0
                    elif self.current_img == self.hipfire[
                            -1] and self.timer >= self.shoottime:
                        self.current_img = self.aim[0]
                        self.shoot_busy = False
                        self.firetimer = 0

                elif self.aim_is_up:
                    #ADS fire
                    if self.current_img not in self.aimdown:
                        self.current_img = self.aimdown[random.randint(0, 1)]
                        self.shoot_busy = True
                        SOUND.play_sound(random.choice(self.sounds['shot']), 0)
                        SETTINGS.screen_shake = self.dmg * 2
                        self.damage()
                        self.timer = 0

                    elif self.aimdown.index(
                            self.current_img
                    ) <= 1 and self.timer >= self.shoottime:
                        self.current_img = self.aimdown[-1]
                        self.timer = 0
                    elif self.current_img == self.aimdown[
                            -1] and self.timer >= self.shoottime:
                        self.current_img = self.aim[-1]
                        self.shoot_busy = False
                        self.current_mag -= 1
                        SETTINGS.statistics['last shots'] += 1
                        if self.stats['magsize'] == 3.1415:
                            self.current_mag -= 1
                            SETTINGS.statistics['last shots'] += 1
                        self.firetimer = 0
        else:
            if self.firetimer >= self.firerate:
                SOUND.play_sound(random.choice(self.sounds['click']), 0)
                self.firetimer = 0
예제 #10
0
    def attack(self):
        if self.attack_move:
            self.move()
        else:
            if self.atcktype == 'melee':
                #Move close to player and keep attacking
                if self.dist <= SETTINGS.tile_size*0.7:
                    self.set_path([])
                    self.moving = False
                    if not self.attacking:
                        if self.timer >= self.frame_interval * self.atckrate:
                            self.attacking = True
                            self.timer = 0
                    else:
                        #Make the NPC not flinch when attacking
                        if self.hurting:
                            if random.randint(0,2) != 2 or self.attacking:
                                self.animate(ATTACKING)
                                self.hurting = False
                                if random.randint(0,2) == 2:
                                    SOUND.play_sound(random.choice(self.sounds['damage']), self.dist)
                        else:
                            self.animate(ATTACKING)

                else:
                    if self.dist_from_player > SETTINGS.tile_size * 0.7 and not self.has_a_path():
                        self.set_path_to_player()

                    elif self.has_a_path():
                        try:
                            if self.path[-1].map_pos != self.last_seen_player_position:
                                near_conditions = [
                                    self.dist_from_player <= (SETTINGS.render / 2) * SETTINGS.tile_size,
                                    random.randint(0, 5) == 5
                                ]
                                if all(near_conditions):
                                    self.set_path_to_player()
                                elif random.randint(0, 10) >= 8:
                                    self.set_path_to_player()
                            else:
                                self.move()
                        except:
                            pass
                
            elif self.atcktype == 'hitscan':
                # Move somewhat close to player and change position after attacking
                if self.dist_from_player <= SETTINGS.tile_size * self.range and (
                        self.dist_from_player >= SETTINGS.tile_size * 1.5 or (
                        SETTINGS.current_gun and SETTINGS.current_gun.guntype == 'melee')) and not self.attack_move:
                    self.path = []
                    self.moving = False
                    if not self.attacking:
                        if random.randint(0, self.atckchance) == 5 and self.detect_player():
                            self.attacking = True
                            self.atckchance += int(self.atckrate)
                            self.movechance = 10
                        else:
                            if random.randint(0, self.movechance) == 10:

                                move_tile = PATHFINDING.find_walkable_tile_near_position(self.map_pos)
                                self.set_path(move_tile.map_pos)
                                self.attacking = False
                                self.attack_move = True
                                # This variable is to make sure the NPC doesn't just walk around without attacking.
                                self.movechance += 3
                                self.atckchance = 5

                    # There is a chance the NPC will not flinch when shot while attacking
                    elif self.attacking:
                        if self.hurting:
                            if random.randint(0,5) >= 3:
                                self.animate(ATTACKING)
                                self.hurting = False
                                if random.randint(0,2) == 2:
                                    SOUND.play_sound(random.choice(self.sounds['damage']), self.dist)
                        else:
                            self.animate(ATTACKING)

                # Move away from player if too close
                elif self.dist_from_player < SETTINGS.tile_size * 1.5 and self.health <= 6:
                    if self.rect.centerx > SETTINGS.player_rect.centerx:
                        self.collide_update(self.speed, 0)
                        self.animate(WALKING)
                    elif self.rect.centerx < SETTINGS.player_rect.centerx:
                        self.collide_update(-self.speed, 0)
                        self.animate(WALKING)
                    if self.rect.centery > SETTINGS.player_rect.centery:
                        self.collide_update(0, self.speed)
                        self.animate(WALKING)
                    elif self.rect.centery < SETTINGS.player_rect.centery:
                        self.collide_update(0, -self.speed)
                        self.animate(WALKING)

                else:
                    if not self.attack_move:
                        if self.dist_from_player >= SETTINGS.tile_size * 2.5 and not self.has_a_path():
                            self.set_path_to_player()

                        elif self.has_a_path():
                            try:
                                if self.path[-1].map_pos != self.last_seen_player_position:
                                    near_conditions = [
                                        self.dist_from_player <= (SETTINGS.render / 2) * SETTINGS.tile_size,
                                        random.randint(0, 5) == 5
                                    ]
                                    if all(near_conditions):
                                        self.set_path_to_player()
                                    elif random.randint(0, 10) == 10:
                                        self.set_path_to_player()
                                else:
                                    self.move()
                            except:
                                pass
예제 #11
0
    def animate(self, animation):
        '''== Animate NPC ==\nanimation -> dying, walking, attacking, hurting'''
        if self.running_animation != animation:
            self.sprite.current_frame = 0
            self.running_animation = animation
            
        #walk animation
        if animation == 'walking':
            self.sprite.texture = self.get_direction_texture()[self.sprite.current_frame]

            if self.timer >= self.frame_interval:
                self.sprite.last_frame = self.sprite.current_frame
                self.sprite.current_frame += 1
                self.timer = 0
                if self.sprite.current_frame == len(self.front_texture)-1:
                    self.sprite.current_frame = 0
        
        #die animation
        elif animation == 'dying':
            self.sprite.texture = self.die_texture[self.sprite.current_frame]
            if self.sprite.current_frame == 0 and not self.mein_leben:
                self.mein_leben = True
                SOUND.play_sound(random.choice(self.sounds['die']), self.dist)
            if self.timer >= self.frame_interval and self.sprite.current_frame < len(self.die_texture)-1:
                self.sprite.current_frame += 1
                self.timer = 0
            elif self.sprite.current_frame == len(self.die_texture)-1 and self.knockback == 0:
                self.dead = True
                self.drop_item()
                SETTINGS.statistics['last enemies'] += 1
            elif self.knockback > 0:
                self.collide_update(-cos_radians(self.postheta)*self.knockback, 0)
                self.collide_update(0, sin_radians(self.postheta)*self.knockback)
                self.knockback = int(self.knockback*0.8)
                
        #hurt animation
        elif animation == 'hurting':
            self.sprite.texture = self.hurt_texture[0]
            self.moving = False
            if self.timer >= self.frame_interval*2:
                self.side = None
                self.hurting = False
                self.timer = 0
                SOUND.play_sound(random.choice(self.sounds['damage']), self.dist_from_player)

                change_direction_conditions = [
                    self.state == IDLE,
                    self.state == PATROLLING,
                    self.state == FLEEING,
                    self.state == SEARCHING,
                ]

                if any(change_direction_conditions):
                    self.change_facing_direction()

        # attack animation
        elif animation == ATTACKING:
            # at the moment the only attack animation
            # is directly facing the player
            self.set_side(SIDE_FRONT)

            self.sprite.texture = self.hit_texture[self.sprite.current_frame]
            self.moving = False
            if self.timer >= self.frame_interval:
                self.sprite.current_frame += 1
                self.timer = 0
                if self.sprite.current_frame == len(self.hit_texture):
                    SOUND.play_sound(self.sounds['attack'], self.dist)
                    self.sprite.texture = self.stand_texture[0]
                    self.sprite.current_frame = 0
                    self.attacking = False
                    if random.randint(0,8) != 8: #A chance to miss
                        if self.damage_player():
                            self.add_message("Did damage to player")
                            self.seen_player()
                        else:
                            self.add_message("tried to attack but I don't have LOS?")
예제 #12
0
    def animate(self, animation):
        '''== Animate NPC ==\nanimation -> dying, walking, attacking, hurting'''
        if self.running_animation != animation:
            self.current_frame = 0
            self.running_animation = animation

        #walk animation
        if animation == 'walking':
            if self.side == 'front':
                self.sprite.texture = self.front_texture[self.current_frame]
            elif self.side == 'frontleft':
                self.sprite.texture = self.frontleft_texture[
                    self.current_frame]
            elif self.side == 'left':
                self.sprite.texture = self.left_texture[self.current_frame]
            elif self.side == 'backleft':
                self.sprite.texture = self.backleft_texture[self.current_frame]
            elif self.side == 'back':
                self.sprite.texture = self.back_texture[self.current_frame]
            elif self.side == 'backright':
                self.sprite.texture = self.backright_texture[
                    self.current_frame]
            elif self.side == 'right':
                self.sprite.texture = self.right_texture[self.current_frame]
            elif self.side == 'frontright':
                self.sprite.texture = self.frontright_texture[
                    self.current_frame]

            if self.timer >= self.frame_interval:
                self.current_frame += 1
                self.timer = 0
                if self.current_frame == len(self.front_texture) - 1:
                    self.current_frame = 0

        #die animation
        elif animation == 'dying':
            self.sprite.texture = self.die_texture[self.current_frame]
            if self.current_frame == 0 and not self.mein_leben:
                self.mein_leben = True
                SOUND.play_sound(random.choice(self.sounds['die']), self.dist)
            if self.timer >= self.frame_interval and self.current_frame < len(
                    self.die_texture) - 1:
                self.current_frame += 1
                self.timer = 0
            elif self.current_frame == len(
                    self.die_texture) - 1 and self.knockback == 0:
                self.dead = True
                self.drop_item()
                SETTINGS.statistics['last enemies'] += 1
            elif self.knockback > 0:
                self.collide_update(
                    -math.cos(math.radians(self.postheta)) * self.knockback, 0)
                self.collide_update(
                    0,
                    math.sin(math.radians(self.postheta)) * self.knockback)
                self.knockback = int(self.knockback * 0.8)

        #hurt animation
        elif animation == 'hurting':
            self.sprite.texture = self.hurt_texture[0]
            self.moving = False
            if self.timer >= self.frame_interval * 2:
                self.side = None
                self.hurting = False
                self.timer = 0
                SOUND.play_sound(random.choice(self.sounds['damage']),
                                 self.dist)
                if self.state == 'idle' or self.state == 'patrouling' or self.state == 'fleeing':
                    self.face = self.face + self.theta
                    if self.face >= 360:
                        self.face -= 360
                    self.face = min([0, 90, 180, 270, 359],
                                    key=lambda x: abs(x - self.face))

        #attack animation
        elif animation == 'attacking':
            self.sprite.texture = self.hit_texture[self.current_frame]
            self.moving = False
            if self.timer >= self.frame_interval:
                self.current_frame += 1
                self.timer = 0
                if self.current_frame == len(self.hit_texture):
                    SOUND.play_sound(self.sounds['attack'], self.dist)
                    self.sprite.texture = self.stand_texture[0]
                    self.current_frame = 0
                    self.attacking = False
                    if random.randint(0, 8) != 8:  #A chance to miss
                        if SETTINGS.player_armor > 0:
                            SETTINGS.player_health -= int(self.dmg * 0.65)
                            if SETTINGS.player_armor >= self.dmg * 2:
                                SETTINGS.player_armor -= self.dmg * 2
                            else:
                                SETTINGS.player_armor = 0
                        else:
                            SETTINGS.player_health -= self.dmg
예제 #13
0
    def attack(self):
        if self.attack_move:
            self.move()
        else:
            if self.atcktype == 'melee':
                #Move close to player and keep attacking
                if self.dist <= SETTINGS.tile_size * 0.7:
                    self.path = []
                    self.moving = False
                    if not self.attacking:
                        if self.timer >= self.frame_interval * self.atckrate:
                            self.attacking = True
                            self.timer = 0
                    else:
                        #Make the NPC not flinch when attacking
                        if self.hurting:
                            if random.randint(0, 2) != 2 or self.attacking:
                                self.animate('attacking')
                                self.hurting = False
                                if random.randint(0, 2) == 2:
                                    SOUND.play_sound(
                                        random.choice(self.sounds['damage']),
                                        self.dist)
                        else:
                            self.animate('attacking')

                else:
                    if self.dist > SETTINGS.tile_size*0.7 and self.path == []:
                        self.path_progress = 0
                        self.path = PATHFINDING.pathfind(
                            self.map_pos, SETTINGS.player_map_pos)

                    elif self.path != []:
                        try:
                            if self.path[-1].map_pos != SETTINGS.player_map_pos:
                                if self.dist <= (
                                        SETTINGS.render / 2
                                ) * SETTINGS.tile_size and random.randint(
                                        0, 5) == 5:
                                    self.path_progress = 0
                                    self.path = PATHFINDING.pathfind(
                                        self.map_pos, SETTINGS.player_map_pos)
                                elif random.randint(0, 10) >= 8:
                                    self.path_progress = 0
                                    self.path = PATHFINDING.pathfind(
                                        self.map_pos, SETTINGS.player_map_pos)
                            else:
                                self.move()
                        except:
                            pass

            elif self.atcktype == 'hitscan':
                #Move somewhat close to player and change position after attacking
                if self.dist <= SETTINGS.tile_size * self.range and (
                        self.dist >= SETTINGS.tile_size * 1.5 or
                    (SETTINGS.current_gun and SETTINGS.current_gun.guntype
                     == 'melee')) and not self.attack_move:
                    self.path = []
                    self.moving = False
                    if not self.attacking:
                        if random.randint(
                                0,
                                self.atckchance) == 5 and self.detect_player():
                            self.attacking = True
                            self.atckchance += int(self.atckrate)
                            self.movechance = 10
                        else:
                            if random.randint(0, self.movechance) == 10:
                                move_pos = random.choice([
                                    x for x in SETTINGS.walkable_area
                                    if (x.map_pos[0] <= self.map_pos[0] + 1
                                        and x.map_pos[0] >= self.map_pos[0] - 1
                                        ) and
                                    (x.map_pos[1] <= self.map_pos[1] +
                                     1 and x.map_pos[1] >= self.map_pos[1] - 1)
                                ])
                                self.path_progress = 0
                                self.path = PATHFINDING.pathfind(
                                    self.map_pos, move_pos.map_pos)
                                self.attacking = False
                                self.attack_move = True
                                #This variable is to make sure the NPC doesn't just walk around without attacking.
                                self.movechance += 3
                                self.atckchance = 5

                    #There is a chance the NPC will not flinch when shot while attacking
                    elif self.attacking:
                        if self.hurting:
                            if random.randint(0, 5) >= 3:
                                self.animate('attacking')
                                self.hurting = False
                                if random.randint(0, 2) == 2:
                                    SOUND.play_sound(
                                        random.choice(self.sounds['damage']),
                                        self.dist)
                        else:
                            self.animate('attacking')

                #Move away from player if too close
                elif self.dist < SETTINGS.tile_size * 1.5 and self.health <= 6:
                    if self.rect.centerx > SETTINGS.player_rect.centerx:
                        self.collide_update(self.speed, 0)
                        self.animate('walking')
                    elif self.rect.centerx < SETTINGS.player_rect.centerx:
                        self.collide_update(-self.speed, 0)
                        self.animate('walking')
                    if self.rect.centery > SETTINGS.player_rect.centery:
                        self.collide_update(0, self.speed)
                        self.animate('walking')
                    elif self.rect.centery < SETTINGS.player_rect.centery:
                        self.collide_update(0, -self.speed)
                        self.animate('walking')

                else:
                    if not self.attack_move:
                        if self.dist >= SETTINGS.tile_size * 2.5 and self.path == []:
                            self.path_progress = 0
                            self.path = PATHFINDING.pathfind(
                                self.map_pos, SETTINGS.player_map_pos)

                        elif self.path != []:
                            try:
                                if self.path[
                                        -1].map_pos != SETTINGS.player_map_pos:
                                    if self.dist <= (
                                            SETTINGS.render / 2
                                    ) * SETTINGS.tile_size and random.randint(
                                            0, 5) == 5:
                                        self.path_progress = 0
                                        self.path = PATHFINDING.pathfind(
                                            self.map_pos,
                                            SETTINGS.player_map_pos)
                                    elif random.randint(0, 10) == 10:
                                        self.path_progress = 0
                                        self.path = PATHFINDING.pathfind(
                                            self.map_pos,
                                            SETTINGS.player_map_pos)
                                else:
                                    self.move()
                            except:
                                pass
예제 #14
0
    def think(self):
        self.map_pos = [
            int(self.rect.centerx / SETTINGS.tile_size),
            int(self.rect.centery / SETTINGS.tile_size)
        ]
        if self.state == 'attacking' or self.state == 'fleeing':
            self.speed = self.OG_speed * 2

        if not self.dead:
            self.timer += SETTINGS.dt
            self.update_timer += SETTINGS.dt
            if self.update_timer >= 2:
                self.update_timer = 0

        if not self.dead and self.health > 0 and not SETTINGS.player_states[
                'dead']:
            self.render()

            if self.dist and self.dist <= SETTINGS.render * SETTINGS.tile_size * 1.2:

                #PASSIVE
                if self.mind == 'passive':
                    if self.state == 'idle':
                        self.idle()

                    elif self.state == 'patrouling':
                        self.move()

                #HOSTILE
                elif self.mind == 'hostile':
                    if self.state == 'idle':
                        self.idle()
                        if not SETTINGS.ignore_player:
                            if self.player_in_view:
                                if self.detect_player():
                                    self.path = []
                                    SOUND.play_sound(self.sounds['spot'],
                                                     self.dist)
                                    self.state = 'attacking'

                    elif self.state == 'patrouling':
                        if self.player_in_view and not SETTINGS.ignore_player and self.detect_player(
                        ):
                            self.path = []
                            SOUND.play_sound(self.sounds['spot'], self.dist)
                            self.state = 'attacking'
                        elif self.dist <= SETTINGS.tile_size / 2 and not SETTINGS.ignore_player:
                            state = 'attacking'
                        else:
                            self.move()

                    elif self.state == 'attacking':
                        self.attack()

                #SHY
                elif self.mind == 'shy':
                    if self.state == 'idle':
                        self.idle()
                        if not SETTINGS.ignore_player:
                            if self.player_in_view:
                                if self.detect_player():
                                    self.path = []
                                    SOUND.play_sound(self.sounds['spot'],
                                                     self.dist)
                                    self.state = 'fleeing'
                            elif self.dist <= SETTINGS.tile_size / 2:
                                state = 'attacking'

                    elif self.state == 'patrouling':
                        if self.player_in_view:
                            if not SETTINGS.ignore_player:
                                if self.detect_player():
                                    self.path = []
                                    SOUND.play_sound(self.sounds['spot'],
                                                     self.dist)
                                    self.state = 'fleeing'
                        elif self.dist <= SETTINGS.tile_size / 2:
                            if not SETTINGS.ignore_player:
                                state = 'attacking'
                        else:
                            self.move()

                    elif self.state == 'fleeing':
                        self.move()

            #Run animations
            if self.hurting:
                self.animate('hurting')
            elif self.moving:
                self.animate('walking')

        if SETTINGS.player_states['dead']:
            self.face += 10
            if self.face >= 360:
                self.face -= 360
            self.render()

        elif self.health <= 0 and not self.dead:
            self.animate('dying')
            self.render()
예제 #15
0
    def update(self):
        remove = False
        if self.rect:
            if SETTINGS.player_rect.colliderect(self.rect):
                if self.item_type == 'health':
                    if SETTINGS.player_health < 100:
                        SETTINGS.player_health += self.effect
                        if SETTINGS.player_health > 100:
                            SETTINGS.player_health = 100
                        SETTINGS.player_states['heal'] = True
                        remove = True

                elif self.item_type == 'armor':
                    if SETTINGS.player_armor < 100:
                        SETTINGS.player_armor += self.effect
                        if SETTINGS.player_armor > 100:
                            SETTINGS.player_armor = 100
                        SETTINGS.player_states['armor'] = True
                        remove = True

                elif self.item_type == 'bullet' or self.item_type == 'shell' or self.item_type == 'ferromag':
                    if SETTINGS.held_ammo[self.item_type] < SETTINGS.max_ammo[
                            self.item_type]:
                        SETTINGS.held_ammo[self.item_type] += self.effect
                        if SETTINGS.held_ammo[
                                self.item_type] > SETTINGS.max_ammo[
                                    self.item_type]:
                            SETTINGS.held_ammo[
                                self.item_type] = SETTINGS.max_ammo[
                                    self.item_type]
                        #Same effect as armor
                        SETTINGS.player_states['armor'] = True
                        remove = True

                elif self.item_type == 'primary':
                    if not SETTINGS.inventory['primary']:
                        SETTINGS.inventory['primary'] = self.effect
                        SETTINGS.next_gun = self.effect
                        SETTINGS.player_states['armor'] = True
                        remove = True
                    else:
                        SETTINGS.ground_weapon = self.effect

                elif self.item_type == 'secondary':
                    if not SETTINGS.inventory['secondary']:
                        SETTINGS.inventory['secondary'] = self.effect
                        SETTINGS.next_gun = self.effect
                        SETTINGS.player_states['armor'] = True
                        remove = True
                    else:
                        SETTINGS.ground_weapon = self.effect

                elif self.item_type == 'melee':
                    if not SETTINGS.inventory['melee']:
                        SETTINGS.inventory['melee'] = self.effect
                        SETTINGS.next_gun = self.effect
                        SETTINGS.player_states['armor'] = True
                        remove = True
                    else:
                        SETTINGS.ground_weapon = self.effect

                #Remove sprite and rect
                if self.sprite in SETTINGS.all_sprites and remove:
                    SOUND.play_sound(self.sound, 0)
                    SETTINGS.all_sprites.remove(self.sprite)
                    self.rect = None