Esempio n. 1
0
 def console_get_char_background(self,con,x,y):
     if con == 0:
         col = libtcod.console_get_char_background(0,x,y)
         return libtcod.color_get_hsv(col)
     else:
         col = libtcod.console_get_char_background(self.mConsole[con-1],x,y)
         return libtcod.color_get_hsv(col)
Esempio n. 2
0
    def draw(self):
        """Draw this map tile"""
        # NB. this gets called a lot!
        if not self.is_visible:
            return

        if self.visible_to_player:
            if self.map.player.has_effect(
                    StatusEffect.INFRAVISION) and not self.remains_in_place:
                c = libtcod.white
            else:
                c = self.light_colour  # this is slow
            l = libtcod.color_get_hsv(c)[
                2]  # this is copied from .light_level for performance
            if self.map.player.has_effect(StatusEffect.NIGHT_VISION):
                l = 1.0 - l
                c = libtcod.white - c
            if l > LightSource.INTENSITY_L_CLAMP:
                colour = self.colour * c
                symbol = self.symbol
            else:
                if self.has_been_seen and self.remains_in_place:
                    colour = self.unseen_colour
                    symbol = self.unseen_symbol
                else:
                    return
        else:
            if self.has_been_seen and self.remains_in_place:
                colour = self.unseen_colour
                symbol = self.unseen_symbol
            else:
                return
        libtcod.console_put_char_ex(0, self.pos.x, self.pos.y, symbol, colour,
                                    libtcod.BKGND_NONE)
        self.has_been_seen = True
Esempio n. 3
0
    def draw(self):
        """Draw this map tile"""
        # NB. this gets called a lot!
        if not self.is_visible:
            return

        if self.visible_to_player:
            if self.map.player.has_effect(StatusEffect.INFRAVISION) and not self.remains_in_place:
                c = libtcod.white
            else:
                c = self.light_colour        # this is slow
            l = libtcod.color_get_hsv(c)[2]  # this is copied from .light_level for performance
            if self.map.player.has_effect(StatusEffect.NIGHT_VISION):
                l = 1.0 - l
                c = libtcod.white - c
            if l > LightSource.INTENSITY_L_CLAMP:
                colour = self.colour * c
                symbol = self.symbol
            else:
                if self.has_been_seen and self.remains_in_place:
                    colour = self.unseen_colour
                    symbol = self.unseen_symbol
                else:
                    return
        else:
            if self.has_been_seen and self.remains_in_place:
                colour = self.unseen_colour
                symbol = self.unseen_symbol
            else:
                return
        libtcod.console_put_char_ex(0, self.pos.x, self.pos.y, symbol, colour, libtcod.BKGND_NONE)
        self.has_been_seen = True
Esempio n. 4
0
def test_color():
    color_a = libtcodpy.Color(0, 1, 2)
    assert list(color_a) == [0, 1, 2]
    assert color_a[0] == color_a.r
    assert color_a[1] == color_a.g
    assert color_a[2] == color_a.b

    color_a[1] = 3
    color_a['b'] = color_a['b']
    assert list(color_a) == [0, 3, 2]

    assert color_a == color_a

    color_b = libtcodpy.Color(255, 255, 255)
    assert color_a != color_b

    color = libtcodpy.color_lerp(color_a, color_b, 0.5)
    libtcodpy.color_set_hsv(color, 0, 0, 0)
    libtcodpy.color_get_hsv(color)
    libtcodpy.color_scale_HSV(color, 0, 0)
Esempio n. 5
0
    def __init__(self, tile_type):
        self.blocked = False
        self.block_sight = None
        self.type = tile_type

        # all tiles start unexplored
        self.explored = False

        if self.type == tile_types.CAVE_FLOOR:
            self.hot_cold = -1
            self.wet_dry = -1
            self.color_in_FOV = libtcod.light_grey
        elif self.type == tile_types.CAVE_WALL:
            self.hot_cold = -1
            self.wet_dry = -1
            self.blocked = True
            self.color_in_FOV = libtcod.grey
        elif self.type == tile_types.GRASS:
            self.hot_cold = 0
            self.wet_dry = 0
            self.color_in_FOV = libtcod.desaturated_green
        elif self.type == tile_types.SAND:
            self.hot_cold = 2
            self.wet_dry = -2
            self.color_in_FOV = libtcod.light_orange
        elif self.type == tile_types.SHALLOW_WATER:
            self.hot_cold = -4
            self.wet_dry = 5
            self.color_in_FOV = libtcod.light_sky
        elif self.type == tile_types.DEEP_WATER:
            self.hot_cold = -6
            self.wet_dry = 8
            self.blocked = True
            self.block_sight = False
            self.color_in_FOV = libtcod.dark_sky

        # the following assignments depend on assignments
        # in the tile_type tests, so they come after the tests

        # by default, a tile blocks sight if it is blocked and vice versa
        if self.block_sight is None:
            self.block_sight = self.blocked

        # set tile color outside of FOV as desaturated
        # and darker than color in FOV
        hsv = libtcod.color_get_hsv(self.color_in_FOV)  # returns [h,s,v]
        # Colors are passed by reference,
        # so we have to create a whole new Color object.
        self.color_out_FOV = libtcod.Color(self.color_in_FOV.r,
                                           self.color_in_FOV.g,
                                           self.color_in_FOV.b)
        # Desaturate and darken color (unseen by default)
        libtcod.color_set_hsv(self.color_out_FOV,
                              hsv[0], hsv[1] / 4, hsv[2] / 4)
Esempio n. 6
0
def get_cylindrical_projection(stars, width=360, height=180):
    """
    Return a tcod console instance of width and height that renders an equirectangular projection of the given list of stars.
    """
    console = tcod.console_new(width, height)

    for star in stars:
        azimuthal = int((star.azimuthal * width) / (2 * math.pi))
        polar = int((star.polar / math.pi) * height)

        # Color Work
        rgb = temperature_to_rgb(random.uniform(4000, 20000))
        brightness = 1.0 - star.radial * 0.75

        color = tcod.Color(rgb[0], rgb[1], rgb[2])
        (h, s, v) = tcod.color_get_hsv(color)
        tcod.color_set_hsv(color, h, s, brightness)

        tcod.console_put_char_ex(console, azimuthal, polar, star.sprite, color,
                                 tcod.black)

    # Background Texture
    noise3d = tcod.noise_new(3)
    for map_x in range(width):
        for map_y in range(height):
            azimuthal = (map_x / (width * 1.0)) * 2.0 * math.pi
            polar = (map_y / (height * 1.0)) * math.pi
            x = math.sin(polar) * math.cos(azimuthal)
            y = math.sin(polar) * math.sin(azimuthal)
            z = math.cos(polar)
            blue = int(
                tcod.noise_get_turbulence(noise3d, [x, y, z], 32.0) * 16.0 +
                16.0)
            green = int(tcod.noise_get(noise3d, [x, y, z]) * 8.0 + 8.0)
            red = int(tcod.noise_get_fbm(noise3d, [x, y, z], 32.0) * 4.0 + 4.0)
            background = tcod.Color(red, green, blue)

            if map_y == height / 2 or map_x == 0 or map_x == width / 2:
                background = tcod.darkest_yellow

            tcod.console_set_char_background(console, map_x, map_y, background)

    tcod.noise_delete(noise3d)
    return console
Esempio n. 7
0
class LightSource(Mappable):
    """Light emitted from a single point"""
    INTENSITY_L_CLAMP = libtcod.color_get_hsv(Mappable.LIGHT_L_CLAMP)[2]
    INTENSITY_H_CLAMP = libtcod.color_get_hsv(Mappable.LIGHT_H_CLAMP)[2]
    INTENSITY_VISIBLE = libtcod.color_get_hsv(Mappable.LIGHT_VISIBLE)[2]

    def __init__(self,
                 radius=0,
                 intensity=1.0,
                 light_colour=Mappable.LIGHT_H_CLAMP):
        self._radius = radius == 0 and 100 or radius  # TODO: more sensible behaviour for infinite r
        self.intensity = intensity
        self.raw_light_colour = light_colour
        self.light_enabled = True
        self.__tcod_light_map = libtcod.map_new(radius * 2 + 1, radius * 2 + 1)
        self.__tcod_light_image = libtcod.image_new(radius * 2 + 1,
                                                    radius * 2 + 1)

    @property
    def radius(self):
        """Set light radius"""
        return self._radius

    @radius.setter
    def radius(self, r):
        """Change light radius"""
        if r == self._radius:
            return  # because this is slow!
        e = self.light_enabled
        self.close()
        self.light_enabled = e
        self._radius = r
        self.__tcod_light_map = libtcod.map_new(r * 2 + 1, r * 2 + 1)
        self.__tcod_light_image = libtcod.image_new(r * 2 + 1, r * 2 + 1)
        self.reset_map()

    def prepare_fov(self, light_walls=False):
        """Calculate light's distribution"""
        libtcod.map_compute_fov(self.__tcod_light_map, self.radius + 1,
                                self.radius + 1, self.radius, light_walls,
                                libtcod.FOV_BASIC)

    def reset_map(self, pos=None):
        """Reset light map.
        If pos is a list of Positions, only reset those areas"""
        if not self.light_enabled:
            libtcod.image_clear(self.__tcod_light_image, libtcod.black)
            libtcod.image_set_key_color(self.__tcod_light_image, libtcod.black)
            return
        assert not self.pos is None and not self.map is None, "resetting LightSource that is not placed on map"

        # [re-]calculating FOV of light within its map
        if pos is None:
            libtcod.map_clear(self.__tcod_light_map, False, False)
            cov = {}
            for o in self.map.find_all_within_r(self, Transparent,
                                                self.radius):
                # if there's something here already and it blocks light, light is blocked at pos
                if cov.get(o.pos, True):
                    cov[o.pos] = not o.blocks_light()

            for (p, is_transparent) in cov.items():
                # we're using the walkable bit to show that there is a tile that could be lit
                libtcod.map_set_properties(self.__tcod_light_map,
                                           self.radius + p.x - self.pos.x,
                                           self.radius + p.y - self.pos.y,
                                           is_transparent, True)

        else:
            if not isinstance(pos, list):
                pos = [pos]
            skip_calc = True
            for p in pos:
                if self.pos.distance_to(p) > self.radius:
                    # pos isn't covered by this light; do nothing
                    pass

                else:
                    skip_calc = False
                    is_transparent = True
                    for o in self.map.find_all_at_pos(p):
                        if isinstance(o, Transparent) and o.blocks_light():
                            is_transparent = False
                            break
                    libtcod.map_set_properties(self.__tcod_light_map,
                                               self.radius + p.x - self.pos.x,
                                               self.radius + p.y - self.pos.y,
                                               is_transparent, True)

            if skip_calc:
                # all pos were outside of light radius!
                return

        self.prepare_fov(
            False
        )  # TODO: calculate both True and False; use True only if light in LOS of player

        # use FOV data to create an image of light intensity, masked by opaque tiles
        # can optimise based on pos P: only need to recalculate area X
        #   ---        ---XX            ---        --XXX
        #  /   \      /   XX           /   \      /  XXX     do this by splitting into quarters
        # |    P|    |    PX          |     |    |   XXX     and working out which to recalculate
        # |  L  |    |  L  |          |  LP |    |  LPXX     based on P-L
        # |     |    |     |          |     |    |   XXX
        #  \   /      \   /            \   /      \  XXX
        #   ---        ---              ---        --XXX
        libtcod.image_clear(self.__tcod_light_image, libtcod.black)
        libtcod.image_set_key_color(self.__tcod_light_image, libtcod.black)
        r = self.radius
        rd2 = r / 2
        i1 = self.raw_light_colour * self.intensity
        for x in range(r * 2 + 1):
            for y in range(r * 2 + 1):
                #print("(%d,%d)"%(x,y))
                if libtcod.map_is_in_fov(self.__tcod_light_map, x, y):
                    d = hypot(r - x, r - y)
                    if d > rd2:
                        libtcod.image_put_pixel(self.__tcod_light_image, x, y,
                                                i1 * (1.0 - (d - rd2) / rd2))
                        #print("  %s %s"%(d,i1*(1.0-(d-rd2)/rd2)))
                    else:
                        libtcod.image_put_pixel(self.__tcod_light_image, x, y,
                                                i1)
                        #print("  %s %s"%(d,i1))

    def blit_to(self, tcod_console, ox=0, oy=0, sx=-1, sy=-1):
        """Copy lighting information to libtcod console"""
        libtcod.image_blit_rect(
            self.__tcod_light_image,
            tcod_console,
            self.pos.x + ox - self.radius,
            self.pos.y + oy - self.radius,
            #self.radius*2+1-ox, self.radius*2+1-oy,
            sx,
            sy,
            libtcod.BKGND_ADD)

    def lights(self, pos, test_los=True):
        """Does this light light pos?
        If test_los is False; don't bother checking line of sight"""
        if not self.light_enabled:
            return False
        if self.pos.distance_to(pos) > self.radius:
            return False
        if not test_los:
            return True

        #print("does %s light pos %s?"%(self,pos))
        #print("%d < %d" %(self.pos.distance_to(pos),self.radius))
        #print("%d,%d"%(1+self.radius+pos.x-self.pos.x,1+self.radius+pos.y-self.pos.y))

        return libtcod.map_is_in_fov(self.__tcod_light_map,
                                     self.radius + pos.x - self.pos.x,
                                     self.radius + pos.y - self.pos.y)

    def close(self):
        """Clean up lighting assets prior to deleting object"""
        libtcod.map_delete(self.__tcod_light_map)
        libtcod.image_delete(self.__tcod_light_image)
        self.light_enabled = False

    def __del__(self):
        """del light"""
        self.close()