Issues (838)

tcod/libtcodpy.py (1 issue)

1
"""This module handles backward compatibility with the ctypes libtcodpy module.
2
"""
3
4
from __future__ import absolute_import as _
5
6
import os
7
import sys
8
9
import threading as _threading
10
11
import numpy as _np
0 ignored issues
show
The import numpy could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
12
13
from tcod.libtcod import *
14
15
from tcod.tcod import _int, _unpack_char_p
16
from tcod.tcod import _bytes, _unicode, _fmt_bytes, _fmt_unicode
17
from tcod.tcod import _CDataWrapper
18
from tcod.tcod import _PropagateException
19
from tcod.tcod import _console
20
21
import tcod.bsp
22
from tcod.color import *
23
import tcod.console
24
import tcod.image
25
import tcod.map
26
import tcod.noise
27
import tcod.path
28
import tcod.random
29
30
Bsp = tcod.bsp.BSP
31
32
33
class ConsoleBuffer(object):
34
    """Simple console that allows direct (fast) access to cells. simplifies
35
    use of the "fill" functions.
36
37
    Args:
38
        width (int): Width of the new ConsoleBuffer.
39
        height (int): Height of the new ConsoleBuffer.
40
        back_r (int): Red background color, from 0 to 255.
41
        back_g (int): Green background color, from 0 to 255.
42
        back_b (int): Blue background color, from 0 to 255.
43
        fore_r (int): Red foreground color, from 0 to 255.
44
        fore_g (int): Green foreground color, from 0 to 255.
45
        fore_b (int): Blue foreground color, from 0 to 255.
46
        char (AnyStr): A single character str or bytes object.
47
    """
48
    def __init__(self, width, height, back_r=0, back_g=0, back_b=0, fore_r=0, fore_g=0, fore_b=0, char=' '):
49
        """initialize with given width and height. values to fill the buffer
50
        are optional, defaults to black with no characters.
51
        """
52
        self.width = width
53
        self.height = height
54
        self.clear(back_r, back_g, back_b, fore_r, fore_g, fore_b, char)
55
56
    def clear(self, back_r=0, back_g=0, back_b=0, fore_r=0, fore_g=0, fore_b=0, char=' '):
57
        """Clears the console.  Values to fill it with are optional, defaults
58
        to black with no characters.
59
60
        Args:
61
            back_r (int): Red background color, from 0 to 255.
62
            back_g (int): Green background color, from 0 to 255.
63
            back_b (int): Blue background color, from 0 to 255.
64
            fore_r (int): Red foreground color, from 0 to 255.
65
            fore_g (int): Green foreground color, from 0 to 255.
66
            fore_b (int): Blue foreground color, from 0 to 255.
67
            char (AnyStr): A single character str or bytes object.
68
        """
69
        n = self.width * self.height
70
        self.back_r = [back_r] * n
71
        self.back_g = [back_g] * n
72
        self.back_b = [back_b] * n
73
        self.fore_r = [fore_r] * n
74
        self.fore_g = [fore_g] * n
75
        self.fore_b = [fore_b] * n
76
        self.char = [ord(char)] * n
77
78
    def copy(self):
79
        """Returns a copy of this ConsoleBuffer.
80
81
        Returns:
82
            ConsoleBuffer: A new ConsoleBuffer copy.
83
        """
84
        other = ConsoleBuffer(0, 0)
85
        other.width = self.width
86
        other.height = self.height
87
        other.back_r = list(self.back_r)  # make explicit copies of all lists
88
        other.back_g = list(self.back_g)
89
        other.back_b = list(self.back_b)
90
        other.fore_r = list(self.fore_r)
91
        other.fore_g = list(self.fore_g)
92
        other.fore_b = list(self.fore_b)
93
        other.char = list(self.char)
94
        return other
95
96
    def set_fore(self, x, y, r, g, b, char):
97
        """Set the character and foreground color of one cell.
98
99
        Args:
100
            x (int): X position to change.
101
            y (int): Y position to change.
102
            r (int): Red foreground color, from 0 to 255.
103
            g (int): Green foreground color, from 0 to 255.
104
            b (int): Blue foreground color, from 0 to 255.
105
            char (AnyStr): A single character str or bytes object.
106
        """
107
        i = self.width * y + x
108
        self.fore_r[i] = r
109
        self.fore_g[i] = g
110
        self.fore_b[i] = b
111
        self.char[i] = ord(char)
112
113
    def set_back(self, x, y, r, g, b):
114
        """Set the background color of one cell.
115
116
        Args:
117
            x (int): X position to change.
118
            y (int): Y position to change.
119
            r (int): Red background color, from 0 to 255.
120
            g (int): Green background color, from 0 to 255.
121
            b (int): Blue background color, from 0 to 255.
122
            char (AnyStr): A single character str or bytes object.
123
        """
124
        i = self.width * y + x
125
        self.back_r[i] = r
126
        self.back_g[i] = g
127
        self.back_b[i] = b
128
129
    def set(self, x, y, back_r, back_g, back_b, fore_r, fore_g, fore_b, char):
130
        """Set the background color, foreground color and character of one cell.
131
132
        Args:
133
            x (int): X position to change.
134
            y (int): Y position to change.
135
            back_r (int): Red background color, from 0 to 255.
136
            back_g (int): Green background color, from 0 to 255.
137
            back_b (int): Blue background color, from 0 to 255.
138
            fore_r (int): Red foreground color, from 0 to 255.
139
            fore_g (int): Green foreground color, from 0 to 255.
140
            fore_b (int): Blue foreground color, from 0 to 255.
141
            char (AnyStr): A single character str or bytes object.
142
        """
143
        i = self.width * y + x
144
        self.back_r[i] = back_r
145
        self.back_g[i] = back_g
146
        self.back_b[i] = back_b
147
        self.fore_r[i] = fore_r
148
        self.fore_g[i] = fore_g
149
        self.fore_b[i] = fore_b
150
        self.char[i] = ord(char)
151
152
    def blit(self, dest, fill_fore=True, fill_back=True):
153
        """Use libtcod's "fill" functions to write the buffer to a console.
154
155
        Args:
156
            dest (Console): Console object to modify.
157
            fill_fore (bool):
158
                If True, fill the foreground color and characters.
159
            fill_back (bool):
160
                If True, fill the background color.
161
        """
162
        if not dest:
163
            dest = tcod.console.Console._from_cdata(ffi.NULL)
164
        if (dest.width != self.width or
165
            dest.height != self.height):
166
            raise ValueError('ConsoleBuffer.blit: Destination console has an incorrect size.')
167
168
        if fill_back:
169
            bg = dest.bg.ravel()
170
            bg[0::3] = self.back_r
171
            bg[1::3] = self.back_g
172
            bg[2::3] = self.back_b
173
174
        if fill_fore:
175
            fg = dest.fg.ravel()
176
            fg[0::3] = self.fore_r
177
            fg[1::3] = self.fore_g
178
            fg[2::3] = self.fore_b
179
            dest.ch.ravel()[:] = self.char
180
181
class Dice(_CDataWrapper):
182
    """
183
184
    Args:
185
        nb_dices (int): Number of dice.
186
        nb_faces (int): Number of sides on a die.
187
        multiplier (float): Multiplier.
188
        addsub (float): Addition.
189
190
    .. deprecated:: 2.0
191
        You should make your own dice functions instead of using this class
192
        which is tied to a CData object.
193
    """
194
195
    def __init__(self, *args, **kargs):
196
        super(Dice, self).__init__(*args, **kargs)
197
        if self.cdata == ffi.NULL:
198
            self._init(*args, **kargs)
199
200
    def _init(self, nb_dices=0, nb_faces=0, multiplier=0, addsub=0):
201
        self.cdata = ffi.new('TCOD_dice_t*')
202
        self.nb_dices = nb_dices
203
        self.nb_faces = nb_faces
204
        self.multiplier = multiplier
205
        self.addsub = addsub
206
207
    def _get_nb_dices(self):
208
        return self.nb_rolls
209
    def _set_nb_dices(self, value):
210
        self.nb_rolls = value
211
    nb_dices = property(_get_nb_dices, _set_nb_dices)
212
213
    def __str__(self):
214
        add = '+(%s)' % self.addsub if self.addsub != 0 else ''
215
        return '%id%ix%s%s' % (self.nb_dices, self.nb_faces,
216
                               self.multiplier, add)
217
218
    def __repr__(self):
219
        return ('%s(nb_dices=%r,nb_faces=%r,multiplier=%r,addsub=%r)' %
220
                (self.__class__.__name__, self.nb_dices, self.nb_faces,
221
                 self.multiplier, self.addsub))
222
223
224
# reverse lookup table for KEY_X attributes, used by Key.__repr__
225
_LOOKUP_VK = {
226
    value:'KEY_%s' % key[6:] for key,value in lib.__dict__.items()
227
    if key.startswith('TCODK')
228
    }
229
230
class Key(_CDataWrapper):
231
    """Key Event instance
232
233
    Attributes:
234
        vk (int): TCOD_keycode_t key code
235
        c (int): character if vk == TCODK_CHAR else 0
236
        text (Text): text[TCOD_KEY_TEXT_SIZE]; text if vk == TCODK_TEXT else text[0] == '\0'
237
        pressed (bool): does this correspond to a key press or key release event ?
238
        lalt (bool): True when left alt is held.
239
        lctrl (bool): True when left control is held.
240
        lmeta (bool): True when left meta key is held.
241
        ralt (bool): True when right alt is held.
242
        rctrl (bool): True when right control is held.
243
        rmeta (bool): True when right meta key is held.
244
        shift (bool): True when any shift is held.
245
    """
246
247
    _BOOL_ATTRIBUTES = ('lalt', 'lctrl', 'lmeta',
248
                        'ralt', 'rctrl', 'rmeta', 'pressed', 'shift')
249
250
    def __init__(self, *args, **kargs):
251
        super(Key, self).__init__(*args, **kargs)
252
        if self.cdata == ffi.NULL:
253
            self.cdata = ffi.new('TCOD_key_t*')
254
255
    def __getattr__(self, attr):
256
        if attr in self._BOOL_ATTRIBUTES:
257
            return bool(getattr(self.cdata, attr))
258
        if attr == 'c':
259
            return ord(getattr(self.cdata, attr))
260
        if attr == 'text':
261
            return _unpack_char_p(getattr(self.cdata, attr))
262
        return super(Key, self).__getattr__(attr)
263
264
    def __repr__(self):
265
        """Return a representation of this Key object."""
266
        params = []
267
        params.append('pressed=%r, vk=tcod.%s' %
268
                      (self.pressed, _LOOKUP_VK[self.vk]))
269
        if self.c:
270
            params.append('c=ord(%r)' % chr(self.c))
271
        if self.text:
272
            params.append('text=%r' % self.text)
273
        for attr in ['shift', 'lalt', 'lctrl', 'lmeta',
274
                     'ralt', 'rctrl', 'rmeta']:
275
            if getattr(self, attr):
276
                params.append('%s=%r' % (attr, getattr(self, attr)))
277
        return 'tcod.Key(%s)' % ', '.join(params)
278
279
280
class Mouse(_CDataWrapper):
281
    """Mouse event instance
282
283
    Attributes:
284
        x (int): Absolute mouse position at pixel x.
285
        y (int):
286
        dx (int): Movement since last update in pixels.
287
        dy (int):
288
        cx (int): Cell coordinates in the root console.
289
        cy (int):
290
        dcx (int): Movement since last update in console cells.
291
        dcy (int):
292
        lbutton (bool): Left button status.
293
        rbutton (bool): Right button status.
294
        mbutton (bool): Middle button status.
295
        lbutton_pressed (bool): Left button pressed event.
296
        rbutton_pressed (bool): Right button pressed event.
297
        mbutton_pressed (bool): Middle button pressed event.
298
        wheel_up (bool): Wheel up event.
299
        wheel_down (bool): Wheel down event.
300
    """
301
302
    def __init__(self, *args, **kargs):
303
        super(Mouse, self).__init__(*args, **kargs)
304
        if self.cdata == ffi.NULL:
305
            self.cdata = ffi.new('TCOD_mouse_t*')
306
307
    def __repr__(self):
308
        """Return a representation of this Mouse object."""
309
        params = []
310
        for attr in ['x', 'y', 'dx', 'dy', 'cx', 'cy', 'dcx', 'dcy']:
311
            if getattr(self, attr) == 0:
312
                continue
313
            params.append('%s=%r' % (attr, getattr(self, attr)))
314
        for attr in ['lbutton', 'rbutton', 'mbutton',
315
                     'lbutton_pressed', 'rbutton_pressed', 'mbutton_pressed',
316
                     'wheel_up', 'wheel_down']:
317
            if getattr(self, attr):
318
                params.append('%s=%r' % (attr, getattr(self, attr)))
319
        return 'tcod.Mouse(%s)' % ', '.join(params)
320
321
322
def bsp_new_with_size(x, y, w, h):
323
    """Create a new BSP instance with the given rectangle.
324
325
    Args:
326
        x (int): Rectangle left coordinate.
327
        y (int): Rectangle top coordinate.
328
        w (int): Rectangle width.
329
        h (int): Rectangle height.
330
331
    Returns:
332
        BSP: A new BSP instance.
333
334
    .. deprecated:: 2.0
335
       Call the :any:`BSP` class instead.
336
    """
337
    return Bsp(x, y, w, h)
338
339
def bsp_split_once(node, horizontal, position):
340
    """
341
    .. deprecated:: 2.0
342
       Use :any:`BSP.split_once` instead.
343
    """
344
    node.split_once(horizontal, position)
345
346
def bsp_split_recursive(node, randomizer, nb, minHSize, minVSize, maxHRatio,
347
                        maxVRatio):
348
    """
349
    .. deprecated:: 2.0
350
       Use :any:`BSP.split_recursive` instead.
351
    """
352
    node.split_recursive(nb, minHSize, minVSize,
353
                         maxHRatio, maxVRatio, randomizer)
354
355
def bsp_resize(node, x, y, w, h):
356
    """
357
    .. deprecated:: 2.0
358
        Assign directly to :any:`BSP` attributes instead.
359
    """
360
    node.x = x
361
    node.y = y
362
    node.width = w
363
    node.height = h
364
365
def bsp_left(node):
366
    """
367
    .. deprecated:: 2.0
368
       Use :any:`BSP.children` instead.
369
    """
370
    return None if not node.children else node.children[0]
371
372
def bsp_right(node):
373
    """
374
    .. deprecated:: 2.0
375
       Use :any:`BSP.children` instead.
376
    """
377
    return None if not node.children else node.children[1]
378
379
def bsp_father(node):
380
    """
381
    .. deprecated:: 2.0
382
       Use :any:`BSP.parent` instead.
383
    """
384
    return node.parent
385
386
def bsp_is_leaf(node):
387
    """
388
    .. deprecated:: 2.0
389
       Use :any:`BSP.children` instead.
390
    """
391
    return not node.children
392
393
def bsp_contains(node, cx, cy):
394
    """
395
    .. deprecated:: 2.0
396
       Use :any:`BSP.contains` instead.
397
    """
398
    return node.contains(cx, cy)
399
400
def bsp_find_node(node, cx, cy):
401
    """
402
    .. deprecated:: 2.0
403
       Use :any:`BSP.find_node` instead.
404
    """
405
    return node.find_node(cx, cy)
406
407
def _bsp_traverse(node_iter, callback, userData):
408
    """pack callback into a handle for use with the callback
409
    _pycall_bsp_callback
410
    """
411
    for node in node_iter:
412
        callback(node, userData)
413
414
def bsp_traverse_pre_order(node, callback, userData=0):
415
    """Traverse this nodes hierarchy with a callback.
416
417
    .. deprecated:: 2.0
418
       Use :any:`BSP.walk` instead.
419
    """
420
    _bsp_traverse(node._iter_pre_order(), callback, userData)
421
422
def bsp_traverse_in_order(node, callback, userData=0):
423
    """Traverse this nodes hierarchy with a callback.
424
425
    .. deprecated:: 2.0
426
       Use :any:`BSP.walk` instead.
427
    """
428
    _bsp_traverse(node._iter_in_order(), callback, userData)
429
430
def bsp_traverse_post_order(node, callback, userData=0):
431
    """Traverse this nodes hierarchy with a callback.
432
433
    .. deprecated:: 2.0
434
       Use :any:`BSP.walk` instead.
435
    """
436
    _bsp_traverse(node._iter_post_order(), callback, userData)
437
438
def bsp_traverse_level_order(node, callback, userData=0):
439
    """Traverse this nodes hierarchy with a callback.
440
441
    .. deprecated:: 2.0
442
       Use :any:`BSP.walk` instead.
443
    """
444
    _bsp_traverse(node._iter_level_order(), callback, userData)
445
446
def bsp_traverse_inverted_level_order(node, callback, userData=0):
447
    """Traverse this nodes hierarchy with a callback.
448
449
    .. deprecated:: 2.0
450
       Use :any:`BSP.walk` instead.
451
    """
452
    _bsp_traverse(node._iter_inverted_level_order(), callback, userData)
453
454
def bsp_remove_sons(node):
455
    """Delete all children of a given node.  Not recommended.
456
457
    .. note::
458
       This function will add unnecessary complexity to your code.
459
       Don't use it.
460
461
    .. deprecated:: 2.0
462
       BSP deletion is automatic.
463
    """
464
    node.children = ()
465
466
def bsp_delete(node):
467
    """Exists for backward compatibility.  Does nothing.
468
469
    BSP's created by this library are automatically garbage collected once
470
    there are no references to the tree.
471
    This function exists for backwards compatibility.
472
473
    .. deprecated:: 2.0
474
       BSP deletion is automatic.
475
    """
476
    pass
477
478
def color_lerp(c1, c2, a):
479
    """Return the linear interpolation between two colors.
480
481
    ``a`` is the interpolation value, with 0 returing ``c1``,
482
    1 returning ``c2``, and 0.5 returing a color halfway between both.
483
484
    Args:
485
        c1 (Union[Tuple[int, int, int], Sequence[int]]):
486
            The first color.  At a=0.
487
        c2 (Union[Tuple[int, int, int], Sequence[int]]):
488
            The second color.  At a=1.
489
        a (float): The interpolation value,
490
491
    Returns:
492
        Color: The interpolated Color.
493
    """
494
    return Color._new_from_cdata(lib.TCOD_color_lerp(c1, c2, a))
495
496
def color_set_hsv(c, h, s, v):
497
    """Set a color using: hue, saturation, and value parameters.
498
499
    Does not return a new Color.  ``c`` is modified inplace.
500
501
    Args:
502
        c (Union[Color, List[Any]]): A Color instance, or a list of any kind.
503
        h (float): Hue, from 0 to 360.
504
        s (float): Saturation, from 0 to 1.
505
        v (float): Value, from 0 to 1.
506
    """
507
    new_color = ffi.new('TCOD_color_t*')
508
    lib.TCOD_color_set_HSV(new_color, h, s, v)
509
    c[:] = new_color.r, new_color.g, new_color.b
510
511
def color_get_hsv(c):
512
    """Return the (hue, saturation, value) of a color.
513
514
    Args:
515
        c (Union[Tuple[int, int, int], Sequence[int]]):
516
            An (r, g, b) sequence or Color instance.
517
518
    Returns:
519
        Tuple[float, float, float]:
520
            A tuple with (hue, saturation, value) values, from 0 to 1.
521
    """
522
    hsv = ffi.new('float [3]')
523
    lib.TCOD_color_get_HSV(c, hsv, hsv + 1, hsv + 2)
524
    return hsv[0], hsv[1], hsv[2]
525
526
def color_scale_HSV(c, scoef, vcoef):
527
    """Scale a color's saturation and value.
528
529
    Does not return a new Color.  ``c`` is modified inplace.
530
531
    Args:
532
        c (Union[Color, List[int]]): A Color instance, or an [r, g, b] list.
533
        scoef (float): Saturation multiplier, from 0 to 1.
534
                       Use 1 to keep current saturation.
535
        vcoef (float): Value multiplier, from 0 to 1.
536
                       Use 1 to keep current value.
537
    """
538
    color_p = ffi.new('TCOD_color_t*')
539
    color_p.r, color_p.g, color_p.b = c.r, c.g, c.b
540
    lib.TCOD_color_scale_HSV(color_p, scoef, vcoef)
541
    c[:] = color_p.r, color_p.g, color_p.b
542
543
def color_gen_map(colors, indexes):
544
    """Return a smoothly defined scale of colors.
545
546
    If ``indexes`` is [0, 3, 9] for example, the first color from ``colors``
547
    will be returned at 0, the 2nd will be at 3, and the 3rd will be at 9.
548
    All in-betweens will be filled with a gradient.
549
550
    Args:
551
        colors (Iterable[Union[Tuple[int, int, int], Sequence[int]]]):
552
            Array of colors to be sampled.
553
        indexes (Iterable[int]): A list of indexes.
554
555
    Returns:
556
        List[Color]: A list of Color instances.
557
558
    Example:
559
        >>> tcod.color_gen_map([(0, 0, 0), (255, 128, 0)], [0, 5])
560
        [Color(0,0,0), Color(51,25,0), Color(102,51,0), Color(153,76,0), \
561
Color(204,102,0), Color(255,128,0)]
562
    """
563
    ccolors = ffi.new('TCOD_color_t[]', colors)
564
    cindexes = ffi.new('int[]', indexes)
565
    cres = ffi.new('TCOD_color_t[]', max(indexes) + 1)
566
    lib.TCOD_color_gen_map(cres, len(colors), ccolors, cindexes)
567
    return [Color._new_from_cdata(cdata) for cdata in cres]
568
569
570
def console_init_root(w, h, title=None, fullscreen=False,
571
                      renderer=RENDERER_SDL, order='C'):
572
    """Set up the primary display and return the root console.
573
574
    .. versionchanged:: 4.3
575
        Added `order` parameter.
576
        `title` parameter is now optional.
577
578
    Args:
579
        w (int): Width in character tiles for the root console.
580
        h (int): Height in character tiles for the root console.
581
        title (Optional[AnyStr]):
582
            This string will be displayed on the created windows title bar.
583
        renderer: Rendering mode for libtcod to use.
584
        order (str): Which numpy memory order to use.
585
586
    Returns:
587
        Console:
588
            Returns a special Console instance representing the root console.
589
    """
590
    if title is None:
591
        # Use the scripts filename as the title.
592
        title = os.path.basename(sys.argv[0])
593
    lib.TCOD_console_init_root(w, h, _bytes(title), fullscreen, renderer)
594
    return tcod.console.Console._from_cdata(ffi.NULL, order)
595
596
597
def console_set_custom_font(fontFile, flags=FONT_LAYOUT_ASCII_INCOL,
598
                            nb_char_horiz=0, nb_char_vertic=0):
599
    """Load a custom font file.
600
601
    Call this before function before calling :any:`tcod.console_init_root`.
602
603
    Flags can be a mix of the following:
604
605
    * tcod.FONT_LAYOUT_ASCII_INCOL
606
    * tcod.FONT_LAYOUT_ASCII_INROW
607
    * tcod.FONT_TYPE_GREYSCALE
608
    * tcod.FONT_TYPE_GRAYSCALE
609
    * tcod.FONT_LAYOUT_TCOD
610
611
    Args:
612
        fontFile (AnyStr): Path to a font file.
613
        flags (int):
614
        nb_char_horiz (int):
615
        nb_char_vertic (int):
616
    """
617
    lib.TCOD_console_set_custom_font(_bytes(fontFile), flags,
618
                                     nb_char_horiz, nb_char_vertic)
619
620
621
def console_get_width(con):
622
    """Return the width of a console.
623
624
    Args:
625
        con (Console): Any Console instance.
626
627
    Returns:
628
        int: The width of a Console.
629
630
    .. deprecated:: 2.0
631
        Use `Console.get_width` instead.
632
    """
633
    return lib.TCOD_console_get_width(_console(con))
634
635
def console_get_height(con):
636
    """Return the height of a console.
637
638
    Args:
639
        con (Console): Any Console instance.
640
641
    Returns:
642
        int: The height of a Console.
643
644
    .. deprecated:: 2.0
645
        Use `Console.get_hright` instead.
646
    """
647
    return lib.TCOD_console_get_height(_console(con))
648
649
def console_map_ascii_code_to_font(asciiCode, fontCharX, fontCharY):
650
    """Set a character code to new coordinates on the tile-set.
651
652
    `asciiCode` must be within the bounds created during the initialization of
653
    the loaded tile-set.  For example, you can't use 255 here unless you have a
654
    256 tile tile-set loaded.  This applies to all functions in this group.
655
656
    Args:
657
        asciiCode (int): The character code to change.
658
        fontCharX (int): The X tile coordinate on the loaded tileset.
659
                         0 is the leftmost tile.
660
        fontCharY (int): The Y tile coordinate on the loaded tileset.
661
                         0 is the topmost tile.
662
    """
663
    lib.TCOD_console_map_ascii_code_to_font(_int(asciiCode), fontCharX,
664
                                                              fontCharY)
665
666
def console_map_ascii_codes_to_font(firstAsciiCode, nbCodes, fontCharX,
667
                                    fontCharY):
668
    """Remap a contiguous set of codes to a contiguous set of tiles.
669
670
    Both the tile-set and character codes must be contiguous to use this
671
    function.  If this is not the case you may want to use
672
    :any:`console_map_ascii_code_to_font`.
673
674
    Args:
675
        firstAsciiCode (int): The starting character code.
676
        nbCodes (int): The length of the contiguous set.
677
        fontCharX (int): The starting X tile coordinate on the loaded tileset.
678
                         0 is the leftmost tile.
679
        fontCharY (int): The starting Y tile coordinate on the loaded tileset.
680
                         0 is the topmost tile.
681
682
    """
683
    lib.TCOD_console_map_ascii_codes_to_font(_int(firstAsciiCode), nbCodes,
684
                                              fontCharX, fontCharY)
685
686
def console_map_string_to_font(s, fontCharX, fontCharY):
687
    """Remap a string of codes to a contiguous set of tiles.
688
689
    Args:
690
        s (AnyStr): A string of character codes to map to new values.
691
                    The null character `'\x00'` will prematurely end this
692
                    function.
693
        fontCharX (int): The starting X tile coordinate on the loaded tileset.
694
                         0 is the leftmost tile.
695
        fontCharY (int): The starting Y tile coordinate on the loaded tileset.
696
                         0 is the topmost tile.
697
    """
698
    lib.TCOD_console_map_string_to_font_utf(_unicode(s), fontCharX, fontCharY)
699
700
def console_is_fullscreen():
701
    """Returns True if the display is fullscreen.
702
703
    Returns:
704
        bool: True if the display is fullscreen, otherwise False.
705
    """
706
    return bool(lib.TCOD_console_is_fullscreen())
707
708
def console_set_fullscreen(fullscreen):
709
    """Change the display to be fullscreen or windowed.
710
711
    Args:
712
        fullscreen (bool): Use True to change to fullscreen.
713
                           Use False to change to windowed.
714
    """
715
    lib.TCOD_console_set_fullscreen(fullscreen)
716
717
def console_is_window_closed():
718
    """Returns True if the window has received and exit event."""
719
    return lib.TCOD_console_is_window_closed()
720
721
def console_has_mouse_focus():
722
    """Return True if the window has mouse focus."""
723
    return lib.TCOD_console_has_mouse_focus()
724
725
def console_is_active():
726
    """Return True if the window has keyboard focus."""
727
    return lib.TCOD_console_is_active()
728
729
def console_set_window_title(title):
730
    """Change the current title bar string.
731
732
    Args:
733
        title (AnyStr): A string to change the title bar to.
734
    """
735
    lib.TCOD_console_set_window_title(_bytes(title))
736
737
def console_credits():
738
    lib.TCOD_console_credits()
739
740
def console_credits_reset():
741
    lib.TCOD_console_credits_reset()
742
743
def console_credits_render(x, y, alpha):
744
    return lib.TCOD_console_credits_render(x, y, alpha)
745
746
def console_flush():
747
    """Update the display to represent the root consoles current state."""
748
    lib.TCOD_console_flush()
749
750
# drawing on a console
751
def console_set_default_background(con, col):
752
    """Change the default background color for a console.
753
754
    Args:
755
        con (Console): Any Console instance.
756
        col (Union[Tuple[int, int, int], Sequence[int]]):
757
            An (r, g, b) sequence or Color instance.
758
    """
759
    lib.TCOD_console_set_default_background(_console(con), col)
760
761
def console_set_default_foreground(con, col):
762
    """Change the default foreground color for a console.
763
764
    Args:
765
        con (Console): Any Console instance.
766
        col (Union[Tuple[int, int, int], Sequence[int]]):
767
            An (r, g, b) sequence or Color instance.
768
    """
769
    lib.TCOD_console_set_default_foreground(_console(con), col)
770
771
def console_clear(con):
772
    """Reset a console to its default colors and the space character.
773
774
    Args:
775
        con (Console): Any Console instance.
776
777
    .. seealso::
778
       :any:`console_set_default_background`
779
       :any:`console_set_default_foreground`
780
    """
781
    return lib.TCOD_console_clear(_console(con))
782
783
def console_put_char(con, x, y, c, flag=BKGND_DEFAULT):
784
    """Draw the character c at x,y using the default colors and a blend mode.
785
786
    Args:
787
        con (Console): Any Console instance.
788
        x (int): Character x position from the left.
789
        y (int): Character y position from the top.
790
        c (Union[int, AnyStr]): Character to draw, can be an integer or string.
791
        flag (int): Blending mode to use, defaults to BKGND_DEFAULT.
792
    """
793
    lib.TCOD_console_put_char(_console(con), x, y, _int(c), flag)
794
795
def console_put_char_ex(con, x, y, c, fore, back):
796
    """Draw the character c at x,y using the colors fore and back.
797
798
    Args:
799
        con (Console): Any Console instance.
800
        x (int): Character x position from the left.
801
        y (int): Character y position from the top.
802
        c (Union[int, AnyStr]): Character to draw, can be an integer or string.
803
        fore (Union[Tuple[int, int, int], Sequence[int]]):
804
            An (r, g, b) sequence or Color instance.
805
        back (Union[Tuple[int, int, int], Sequence[int]]):
806
            An (r, g, b) sequence or Color instance.
807
    """
808
    lib.TCOD_console_put_char_ex(_console(con), x, y, _int(c), fore, back)
809
810
def console_set_char_background(con, x, y, col, flag=BKGND_SET):
811
    """Change the background color of x,y to col using a blend mode.
812
813
    Args:
814
        con (Console): Any Console instance.
815
        x (int): Character x position from the left.
816
        y (int): Character y position from the top.
817
        col (Union[Tuple[int, int, int], Sequence[int]]):
818
            An (r, g, b) sequence or Color instance.
819
        flag (int): Blending mode to use, defaults to BKGND_SET.
820
    """
821
    lib.TCOD_console_set_char_background(_console(con), x, y, col, flag)
822
823
def console_set_char_foreground(con, x, y, col):
824
    """Change the foreground color of x,y to col.
825
826
    Args:
827
        con (Console): Any Console instance.
828
        x (int): Character x position from the left.
829
        y (int): Character y position from the top.
830
        col (Union[Tuple[int, int, int], Sequence[int]]):
831
            An (r, g, b) sequence or Color instance.
832
    """
833
    lib.TCOD_console_set_char_foreground(_console(con), x, y, col)
834
835
def console_set_char(con, x, y, c):
836
    """Change the character at x,y to c, keeping the current colors.
837
838
    Args:
839
        con (Console): Any Console instance.
840
        x (int): Character x position from the left.
841
        y (int): Character y position from the top.
842
        c (Union[int, AnyStr]): Character to draw, can be an integer or string.
843
    """
844
    lib.TCOD_console_set_char(_console(con), x, y, _int(c))
845
846
def console_set_background_flag(con, flag):
847
    """Change the default blend mode for this console.
848
849
    Args:
850
        con (Console): Any Console instance.
851
        flag (int): Blend mode to use by default.
852
    """
853
    lib.TCOD_console_set_background_flag(_console(con), flag)
854
855
def console_get_background_flag(con):
856
    """Return this consoles current blend mode.
857
858
    Args:
859
        con (Console): Any Console instance.
860
    """
861
    return lib.TCOD_console_get_background_flag(_console(con))
862
863
def console_set_alignment(con, alignment):
864
    """Change this consoles current alignment mode.
865
866
    * tcod.LEFT
867
    * tcod.CENTER
868
    * tcod.RIGHT
869
870
    Args:
871
        con (Console): Any Console instance.
872
        alignment (int):
873
    """
874
    lib.TCOD_console_set_alignment(_console(con), alignment)
875
876
def console_get_alignment(con):
877
    """Return this consoles current alignment mode.
878
879
    Args:
880
        con (Console): Any Console instance.
881
    """
882
    return lib.TCOD_console_get_alignment(_console(con))
883
884
def console_print(con, x, y, fmt):
885
    """Print a color formatted string on a console.
886
887
    Args:
888
        con (Console): Any Console instance.
889
        x (int): Character x position from the left.
890
        y (int): Character y position from the top.
891
        fmt (AnyStr): A unicode or bytes string optionaly using color codes.
892
    """
893
    lib.TCOD_console_print_utf(_console(con), x, y, _fmt_unicode(fmt))
894
895
def console_print_ex(con, x, y, flag, alignment, fmt):
896
    """Print a string on a console using a blend mode and alignment mode.
897
898
    Args:
899
        con (Console): Any Console instance.
900
        x (int): Character x position from the left.
901
        y (int): Character y position from the top.
902
    """
903
    lib.TCOD_console_print_ex_utf(_console(con),
904
                                  x, y, flag, alignment, _fmt_unicode(fmt))
905
906
def console_print_rect(con, x, y, w, h, fmt):
907
    """Print a string constrained to a rectangle.
908
909
    If h > 0 and the bottom of the rectangle is reached,
910
    the string is truncated. If h = 0,
911
    the string is only truncated if it reaches the bottom of the console.
912
913
914
915
    Returns:
916
        int: The number of lines of text once word-wrapped.
917
    """
918
    return lib.TCOD_console_print_rect_utf(
919
        _console(con), x, y, w, h, _fmt_unicode(fmt))
920
921
def console_print_rect_ex(con, x, y, w, h, flag, alignment, fmt):
922
    """Print a string constrained to a rectangle with blend and alignment.
923
924
    Returns:
925
        int: The number of lines of text once word-wrapped.
926
    """
927
    return lib.TCOD_console_print_rect_ex_utf(
928
        _console(con), x, y, w, h, flag, alignment, _fmt_unicode(fmt))
929
930
def console_get_height_rect(con, x, y, w, h, fmt):
931
    """Return the height of this text once word-wrapped into this rectangle.
932
933
    Returns:
934
        int: The number of lines of text once word-wrapped.
935
    """
936
    return lib.TCOD_console_get_height_rect_utf(
937
        _console(con), x, y, w, h, _fmt_unicode(fmt))
938
939
def console_rect(con, x, y, w, h, clr, flag=BKGND_DEFAULT):
940
    """Draw a the background color on a rect optionally clearing the text.
941
942
    If clr is True the affected tiles are changed to space character.
943
    """
944
    lib.TCOD_console_rect(_console(con), x, y, w, h, clr, flag)
945
946
def console_hline(con, x, y, l, flag=BKGND_DEFAULT):
947
    """Draw a horizontal line on the console.
948
949
    This always uses the character 196, the horizontal line character.
950
    """
951
    lib.TCOD_console_hline(_console(con), x, y, l, flag)
952
953
def console_vline(con, x, y, l, flag=BKGND_DEFAULT):
954
    """Draw a vertical line on the console.
955
956
    This always uses the character 179, the vertical line character.
957
    """
958
    lib.TCOD_console_vline(_console(con), x, y, l, flag)
959
960
def console_print_frame(con, x, y, w, h, clear=True, flag=BKGND_DEFAULT, fmt=b''):
961
    """Draw a framed rectangle with optinal text.
962
963
    This uses the default background color and blend mode to fill the
964
    rectangle and the default foreground to draw the outline.
965
966
    fmt will be printed on the inside of the rectangle, word-wrapped.
967
    """
968
    lib.TCOD_console_print_frame(
969
        _console(con), x, y, w, h, clear, flag, _fmt_bytes(fmt))
970
971
def console_set_color_control(con, fore, back):
972
    """Configure :any:`color controls`.
973
974
    Args:
975
        con (int): :any:`Color control` constant to modify.
976
        fore (Union[Tuple[int, int, int], Sequence[int]]):
977
            An (r, g, b) sequence or Color instance.
978
        back (Union[Tuple[int, int, int], Sequence[int]]):
979
            An (r, g, b) sequence or Color instance.
980
    """
981
    lib.TCOD_console_set_color_control(con, fore, back)
982
983
def console_get_default_background(con):
984
    """Return this consoles default background color."""
985
    return Color._new_from_cdata(
986
        lib.TCOD_console_get_default_background(_console(con)))
987
988
def console_get_default_foreground(con):
989
    """Return this consoles default foreground color."""
990
    return Color._new_from_cdata(
991
        lib.TCOD_console_get_default_foreground(_console(con)))
992
993
def console_get_char_background(con, x, y):
994
    """Return the background color at the x,y of this console."""
995
    return Color._new_from_cdata(
996
        lib.TCOD_console_get_char_background(_console(con), x, y))
997
998
def console_get_char_foreground(con, x, y):
999
    """Return the foreground color at the x,y of this console."""
1000
    return Color._new_from_cdata(
1001
        lib.TCOD_console_get_char_foreground(_console(con), x, y))
1002
1003
def console_get_char(con, x, y):
1004
    """Return the character at the x,y of this console."""
1005
    return lib.TCOD_console_get_char(_console(con), x, y)
1006
1007
def console_set_fade(fade, fadingColor):
1008
    lib.TCOD_console_set_fade(fade, fadingColor)
1009
1010
def console_get_fade():
1011
    return lib.TCOD_console_get_fade()
1012
1013
def console_get_fading_color():
1014
    return Color._new_from_cdata(lib.TCOD_console_get_fading_color())
1015
1016
# handling keyboard input
1017
def console_wait_for_keypress(flush):
1018
    """Block until the user presses a key, then returns a new Key.
1019
1020
    Args:
1021
        flush bool: If True then the event queue is cleared before waiting
1022
                    for the next event.
1023
1024
    Returns:
1025
        Key: A new Key instance.
1026
    """
1027
    k=Key()
1028
    lib.TCOD_console_wait_for_keypress_wrapper(k.cdata, flush)
1029
    return k
1030
1031
def console_check_for_keypress(flags=KEY_RELEASED):
1032
    k=Key()
1033
    lib.TCOD_console_check_for_keypress_wrapper(k.cdata, flags)
1034
    return k
1035
1036
def console_is_key_pressed(key):
1037
    return lib.TCOD_console_is_key_pressed(key)
1038
1039
# using offscreen consoles
1040
def console_new(w, h):
1041
    """Return an offscreen console of size: w,h."""
1042
    return tcod.console.Console(w, h)
1043
1044
def console_from_file(filename):
1045
    """Return a new console object from a filename.
1046
1047
    The file format is automactially determined.  This can load REXPaint `.xp`,
1048
    ASCII Paint `.apf`, or Non-delimited ASCII `.asc` files.
1049
1050
    Args:
1051
        filename (Text): The path to the file, as a string.
1052
1053
    Returns: A new :any`Console` instance.
1054
    """
1055
    return tcod.console.Console._from_cdata(
1056
        lib.TCOD_console_from_file(filename.encode('utf-8')))
1057
1058
def console_blit(src, x, y, w, h, dst, xdst, ydst, ffade=1.0,bfade=1.0):
1059
    """Blit the console src from x,y,w,h to console dst at xdst,ydst."""
1060
    lib.TCOD_console_blit(
1061
        _console(src), x, y, w, h,
1062
        _console(dst), xdst, ydst, ffade, bfade)
1063
1064
def console_set_key_color(con, col):
1065
    """Set a consoles blit transparent color."""
1066
    lib.TCOD_console_set_key_color(_console(con), col)
1067
    if hasattr(con, 'set_key_color'):
1068 View Code Duplication
        con.set_key_color(col)
1069
1070
def console_delete(con):
1071
    con = _console(con)
1072
    if con == ffi.NULL:
1073
        lib.TCOD_console_delete(con)
1074
1075
# fast color filling
1076
def console_fill_foreground(con, r, g, b):
1077
    """Fill the foregound of a console with r,g,b.
1078
1079
    Args:
1080
        con (Console): Any Console instance.
1081
        r (Sequence[int]): An array of integers with a length of width*height.
1082
        g (Sequence[int]): An array of integers with a length of width*height.
1083
        b (Sequence[int]): An array of integers with a length of width*height.
1084
    """
1085
    if len(r) != len(g) or len(r) != len(b):
1086
        raise TypeError('R, G and B must all have the same size.')
1087
    if (isinstance(r, _np.ndarray) and isinstance(g, _np.ndarray) and
1088
            isinstance(b, _np.ndarray)):
1089
        #numpy arrays, use numpy's ctypes functions
1090
        r = _np.ascontiguousarray(r, dtype=_np.intc)
1091
        g = _np.ascontiguousarray(g, dtype=_np.intc)
1092
        b = _np.ascontiguousarray(b, dtype=_np.intc)
1093
        cr = ffi.cast('int *', r.ctypes.data)
1094
        cg = ffi.cast('int *', g.ctypes.data)
1095
        cb = ffi.cast('int *', b.ctypes.data)
1096 View Code Duplication
    else:
1097
        # otherwise convert using ffi arrays
1098
        cr = ffi.new('int[]', r)
1099
        cg = ffi.new('int[]', g)
1100
        cb = ffi.new('int[]', b)
1101
1102
    lib.TCOD_console_fill_foreground(_console(con), cr, cg, cb)
1103
1104
def console_fill_background(con, r, g, b):
1105
    """Fill the backgound of a console with r,g,b.
1106
1107
    Args:
1108
        con (Console): Any Console instance.
1109
        r (Sequence[int]): An array of integers with a length of width*height.
1110
        g (Sequence[int]): An array of integers with a length of width*height.
1111
        b (Sequence[int]): An array of integers with a length of width*height.
1112
    """
1113
    if len(r) != len(g) or len(r) != len(b):
1114
        raise TypeError('R, G and B must all have the same size.')
1115
    if (isinstance(r, _np.ndarray) and isinstance(g, _np.ndarray) and
1116
            isinstance(b, _np.ndarray)):
1117
        #numpy arrays, use numpy's ctypes functions
1118
        r = _np.ascontiguousarray(r, dtype=_np.intc)
1119
        g = _np.ascontiguousarray(g, dtype=_np.intc)
1120
        b = _np.ascontiguousarray(b, dtype=_np.intc)
1121
        cr = ffi.cast('int *', r.ctypes.data)
1122
        cg = ffi.cast('int *', g.ctypes.data)
1123
        cb = ffi.cast('int *', b.ctypes.data)
1124
    else:
1125
        # otherwise convert using ffi arrays
1126
        cr = ffi.new('int[]', r)
1127
        cg = ffi.new('int[]', g)
1128
        cb = ffi.new('int[]', b)
1129
1130
    lib.TCOD_console_fill_background(_console(con), cr, cg, cb)
1131
1132
def console_fill_char(con,arr):
1133
    """Fill the character tiles of a console with an array.
1134
1135
    Args:
1136
        con (Console): Any Console instance.
1137
        arr (Sequence[int]): An array of integers with a length of width*height.
1138
    """
1139
    if isinstance(arr, _np.ndarray):
1140
        #numpy arrays, use numpy's ctypes functions
1141
        arr = _np.ascontiguousarray(arr, dtype=_np.intc)
1142
        carr = ffi.cast('int *', arr.ctypes.data)
1143
    else:
1144
        #otherwise convert using the ffi module
1145
        carr = ffi.new('int[]', arr)
1146
1147
    lib.TCOD_console_fill_char(_console(con), carr)
1148
1149
def console_load_asc(con, filename):
1150
    """Update a console from a non-delimited ASCII `.asc` file."""
1151
    return lib.TCOD_console_load_asc(_console(con), filename.encode('utf-8'))
1152
1153
def console_save_asc(con, filename):
1154
    """Save a console to a non-delimited ASCII `.asc` file."""
1155
    return lib.TCOD_console_save_asc(_console(con), filename.encode('utf-8'))
1156
1157
def console_load_apf(con, filename):
1158
    """Update a console from an ASCII Paint `.apf` file."""
1159
    return lib.TCOD_console_load_apf(_console(con), filename.encode('utf-8'))
1160
1161
def console_save_apf(con, filename):
1162
    """Save a console to an ASCII Paint `.apf` file."""
1163
    return lib.TCOD_console_save_apf(_console(con), filename.encode('utf-8'))
1164
1165
def console_load_xp(con, filename):
1166
    """Update a console from a REXPaint `.xp` file."""
1167
    return lib.TCOD_console_load_xp(_console(con), filename.encode('utf-8'))
1168
1169
def console_save_xp(con, filename, compress_level=9):
1170
    """Save a console to a REXPaint `.xp` file."""
1171
    return lib.TCOD_console_save_xp(
1172
        _console(con),
1173
        filename.encode('utf-8'),
1174
        compress_level,
1175
        )
1176
1177
def console_from_xp(filename):
1178
    """Return a single console from a REXPaint `.xp` file."""
1179
    return tcod.console.Console._from_cdata(
1180
        lib.TCOD_console_from_xp(filename.encode('utf-8')))
1181
1182
def console_list_load_xp(filename):
1183
    """Return a list of consoles from a REXPaint `.xp` file."""
1184
    tcod_list = lib.TCOD_console_list_from_xp(filename.encode('utf-8'))
1185
    if tcod_list == ffi.NULL:
1186
        return None
1187
    try:
1188
        python_list = []
1189
        lib.TCOD_list_reverse(tcod_list)
1190
        while not lib.TCOD_list_is_empty(tcod_list):
1191
            python_list.append(
1192
                tcod.console.Console._from_cdata(lib.TCOD_list_pop(tcod_list)),
1193
                )
1194
        return python_list
1195
    finally:
1196
        lib.TCOD_list_delete(tcod_list)
1197
1198
def console_list_save_xp(console_list, filename, compress_level=9):
1199
    """Save a list of consoles to a REXPaint `.xp` file."""
1200
    tcod_list = lib.TCOD_list_new()
1201
    try:
1202
        for console in console_list:
1203
            lib.TCOD_list_push(tcod_list, _console(console))
1204
        return lib.TCOD_console_list_save_xp(
1205
            tcod_list, filename.encode('utf-8'), compress_level
1206
            )
1207
    finally:
1208
        lib.TCOD_list_delete(tcod_list)
1209
1210
def path_new_using_map(m, dcost=1.41):
1211
    """Return a new AStar using the given Map.
1212
1213
    Args:
1214
        m (Map): A Map instance.
1215
        dcost (float): The path-finding cost of diagonal movement.
1216
                       Can be set to 0 to disable diagonal movement.
1217
    Returns:
1218
        AStar: A new AStar instance.
1219
    """
1220
    return tcod.path.AStar(m, dcost)
1221
1222
def path_new_using_function(w, h, func, userData=0, dcost=1.41):
1223
    """Return a new AStar using the given callable function.
1224
1225
    Args:
1226
        w (int): Clipping width.
1227
        h (int): Clipping height.
1228
        func (Callable[[int, int, int, int, Any], float]):
1229
        userData (Any):
1230
        dcost (float): A multiplier for the cost of diagonal movement.
1231
                       Can be set to 0 to disable diagonal movement.
1232
    Returns:
1233
        AStar: A new AStar instance.
1234
    """
1235
    return tcod.path.AStar(
1236
        tcod.path._EdgeCostFunc((func, userData), w, h),
1237
        dcost,
1238
        )
1239
1240
def path_compute(p, ox, oy, dx, dy):
1241
    """Find a path from (ox, oy) to (dx, dy).  Return True if path is found.
1242
1243
    Args:
1244
        p (AStar): An AStar instance.
1245
        ox (int): Starting x position.
1246
        oy (int): Starting y position.
1247
        dx (int): Destination x position.
1248
        dy (int): Destination y position.
1249
    Returns:
1250
        bool: True if a valid path was found.  Otherwise False.
1251
    """
1252
    return lib.TCOD_path_compute(p._path_c, ox, oy, dx, dy)
1253
1254
def path_get_origin(p):
1255
    """Get the current origin position.
1256
1257
    This point moves when :any:`path_walk` returns the next x,y step.
1258
1259
    Args:
1260
        p (AStar): An AStar instance.
1261
    Returns:
1262
        Tuple[int, int]: An (x, y) point.
1263
    """
1264
    x = ffi.new('int *')
1265
    y = ffi.new('int *')
1266
    lib.TCOD_path_get_origin(p._path_c, x, y)
1267
    return x[0], y[0]
1268
1269
def path_get_destination(p):
1270
    """Get the current destination position.
1271
1272
    Args:
1273
        p (AStar): An AStar instance.
1274
    Returns:
1275
        Tuple[int, int]: An (x, y) point.
1276
    """
1277
    x = ffi.new('int *')
1278
    y = ffi.new('int *')
1279
    lib.TCOD_path_get_destination(p._path_c, x, y)
1280
    return x[0], y[0]
1281
1282
def path_size(p):
1283
    """Return the current length of the computed path.
1284
1285
    Args:
1286
        p (AStar): An AStar instance.
1287
    Returns:
1288
        int: Length of the path.
1289
    """
1290
    return lib.TCOD_path_size(p._path_c)
1291
1292
def path_reverse(p):
1293
    """Reverse the direction of a path.
1294
1295
    This effectively swaps the origin and destination points.
1296
1297
    Args:
1298
        p (AStar): An AStar instance.
1299
    """
1300
    lib.TCOD_path_reverse(p._path_c)
1301
1302
def path_get(p, idx):
1303
    """Get a point on a path.
1304
1305
    Args:
1306
        p (AStar): An AStar instance.
1307
        idx (int): Should be in range: 0 <= inx < :any:`path_size`
1308
    """
1309
    x = ffi.new('int *')
1310
    y = ffi.new('int *')
1311
    lib.TCOD_path_get(p._path_c, idx, x, y)
1312
    return x[0], y[0]
1313
1314
def path_is_empty(p):
1315
    """Return True if a path is empty.
1316
1317
    Args:
1318
        p (AStar): An AStar instance.
1319
    Returns:
1320
        bool: True if a path is empty.  Otherwise False.
1321
    """
1322
    return lib.TCOD_path_is_empty(p._path_c)
1323
1324
def path_walk(p, recompute):
1325
    """Return the next (x, y) point in a path, or (None, None) if it's empty.
1326
1327
    When ``recompute`` is True and a previously valid path reaches a point
1328
    where it is now blocked, a new path will automatically be found.
1329
1330
    Args:
1331
        p (AStar): An AStar instance.
1332
        recompute (bool): Recompute the path automatically.
1333
    Returns:
1334
        Union[Tuple[int, int], Tuple[None, None]]:
1335
            A single (x, y) point, or (None, None)
1336
    """
1337
    x = ffi.new('int *')
1338
    y = ffi.new('int *')
1339
    if lib.TCOD_path_walk(p._path_c, x, y, recompute):
1340
        return x[0], y[0]
1341
    return None,None
1342
1343
def path_delete(p):
1344
    """Does nothing."""
1345
    pass
1346
1347
def dijkstra_new(m, dcost=1.41):
1348
    return tcod.path.Dijkstra(m, dcost)
1349
1350
def dijkstra_new_using_function(w, h, func, userData=0, dcost=1.41):
1351
    return tcod.path.Dijkstra(
1352
        tcod.path._EdgeCostFunc((func, userData), w, h),
1353
        dcost,
1354
        )
1355
1356
def dijkstra_compute(p, ox, oy):
1357
    lib.TCOD_dijkstra_compute(p._path_c, ox, oy)
1358
1359
def dijkstra_path_set(p, x, y):
1360
    return lib.TCOD_dijkstra_path_set(p._path_c, x, y)
1361
1362
def dijkstra_get_distance(p, x, y):
1363
    return lib.TCOD_dijkstra_get_distance(p._path_c, x, y)
1364
1365
def dijkstra_size(p):
1366
    return lib.TCOD_dijkstra_size(p._path_c)
1367
1368
def dijkstra_reverse(p):
1369
    lib.TCOD_dijkstra_reverse(p._path_c)
1370
1371
def dijkstra_get(p, idx):
1372
    x = ffi.new('int *')
1373
    y = ffi.new('int *')
1374
    lib.TCOD_dijkstra_get(p._path_c, idx, x, y)
1375
    return x[0], y[0]
1376
1377
def dijkstra_is_empty(p):
1378
    return lib.TCOD_dijkstra_is_empty(p._path_c)
1379
1380
def dijkstra_path_walk(p):
1381
    x = ffi.new('int *')
1382
    y = ffi.new('int *')
1383
    if lib.TCOD_dijkstra_path_walk(p._path_c, x, y):
1384
        return x[0], y[0]
1385
    return None,None
1386
1387
def dijkstra_delete(p):
1388
    pass
1389
1390
def _heightmap_cdata(array):
1391
    """Return a new TCOD_heightmap_t instance using an array.
1392
1393
    Formatting is verified during this function.
1394
    """
1395
    if not array.flags['C_CONTIGUOUS']:
1396
        raise ValueError('array must be a C-style contiguous segment.')
1397
    if array.dtype != _np.float32:
1398
        raise ValueError('array dtype must be float32, not %r' % array.dtype)
1399
    width, height = array.shape
1400
    pointer = ffi.cast('float *', array.ctypes.data)
1401
    return ffi.new('TCOD_heightmap_t *', (width, height, pointer))
1402
1403
def heightmap_new(w, h):
1404
    """Return a new numpy.ndarray formatted for use with heightmap functions.
1405
1406
    You can pass a numpy array to any heightmap function as long as all the
1407
    following are true::
1408
    * The array is 2 dimentional.
1409
    * The array has the C_CONTIGUOUS flag.
1410
    * The array's dtype is :any:`dtype.float32`.
1411
1412
    Args:
1413
        w (int): The width of the new HeightMap.
1414
        h (int): The height of the new HeightMap.
1415
1416
    Returns:
1417
        numpy.ndarray: A C-contiguous mapping of float32 values.
1418
    """
1419
    return _np.ndarray((h, w), _np.float32)
1420
1421
def heightmap_set_value(hm, x, y, value):
1422
    """Set the value of a point on a heightmap.
1423
1424
    Args:
1425
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1426
        x (int): The x position to change.
1427
        y (int): The y position to change.
1428
        value (float): The value to set.
1429
1430
    .. deprecated:: 2.0
1431
        Do ``hm[y, x] = value`` instead.
1432
    """
1433
    hm[y, x] = value
1434
1435
def heightmap_add(hm, value):
1436
    """Add value to all values on this heightmap.
1437
1438
    Args:
1439
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1440
        value (float): A number to add to this heightmap.
1441
1442
    .. deprecated:: 2.0
1443
        Do ``hm[:] += value`` instead.
1444
    """
1445
    hm[:] += value
1446
1447
def heightmap_scale(hm, value):
1448
    """Multiply all items on this heightmap by value.
1449
1450
    Args:
1451
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1452
        value (float): A number to scale this heightmap by.
1453
1454
    .. deprecated:: 2.0
1455
        Do ``hm[:] *= value`` instead.
1456
    """
1457
    hm[:] *= value
1458
1459
def heightmap_clear(hm):
1460
    """Add value to all values on this heightmap.
1461
1462
    Args:
1463
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1464
1465
    .. deprecated:: 2.0
1466
        Do ``hm.array[:] = 0`` instead.
1467
    """
1468
    hm[:] = 0
1469
1470
def heightmap_clamp(hm, mi, ma):
1471
    """Clamp all values on this heightmap between ``mi`` and ``ma``
1472
1473
    Args:
1474
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1475
        mi (float): The lower bound to clamp to.
1476
        ma (float): The upper bound to clamp to.
1477
1478
    .. deprecated:: 2.0
1479
        Do ``hm.clip(mi, ma)`` instead.
1480
    """
1481
    hm.clip(mi, ma)
1482
1483
def heightmap_copy(hm1, hm2):
1484
    """Copy the heightmap ``hm1`` to ``hm2``.
1485
1486
    Args:
1487
        hm1 (numpy.ndarray): The source heightmap.
1488
        hm2 (numpy.ndarray): The destination heightmap.
1489
1490
    .. deprecated:: 2.0
1491
        Do ``hm2[:] = hm1[:]`` instead.
1492
    """
1493
    hm2[:] = hm1[:]
1494
1495
def heightmap_normalize(hm,  mi=0.0, ma=1.0):
1496
    """Normalize heightmap values between ``mi`` and ``ma``.
1497
1498
    Args:
1499
        mi (float): The lowest value after normalization.
1500
        ma (float): The highest value after normalization.
1501
    """
1502
    lib.TCOD_heightmap_normalize(_heightmap_cdata(hm), mi, ma)
1503
1504
def heightmap_lerp_hm(hm1, hm2, hm3, coef):
1505
    """Perform linear interpolation between two heightmaps storing the result
1506
    in ``hm3``.
1507
1508
    This is the same as doing ``hm3[:] = hm1[:] + (hm2[:] - hm1[:]) * coef``
1509
1510
    Args:
1511
        hm1 (numpy.ndarray): The first heightmap.
1512
        hm2 (numpy.ndarray): The second heightmap to add to the first.
1513
        hm3 (numpy.ndarray): A destination heightmap to store the result.
1514
        coef (float): The linear interpolation coefficient.
1515
    """
1516
    lib.TCOD_heightmap_lerp_hm(_heightmap_cdata(hm1), _heightmap_cdata(hm2),
1517
                               _heightmap_cdata(hm3), coef)
1518
1519
def heightmap_add_hm(hm1, hm2, hm3):
1520
    """Add two heightmaps together and stores the result in ``hm3``.
1521
1522
    Args:
1523
        hm1 (numpy.ndarray): The first heightmap.
1524
        hm2 (numpy.ndarray): The second heightmap to add to the first.
1525
        hm3 (numpy.ndarray): A destination heightmap to store the result.
1526
1527
    .. deprecated:: 2.0
1528
        Do ``hm3[:] = hm1[:] + hm2[:]`` instead.
1529
    """
1530
    hm3[:] = hm1[:] + hm2[:]
1531
1532
def heightmap_multiply_hm(hm1, hm2, hm3):
1533
    """Multiplies two heightmap's together and stores the result in ``hm3``.
1534
1535
    Args:
1536
        hm1 (numpy.ndarray): The first heightmap.
1537
        hm2 (numpy.ndarray): The second heightmap to multiply with the first.
1538
        hm3 (numpy.ndarray): A destination heightmap to store the result.
1539
1540
    .. deprecated:: 2.0
1541
        Do ``hm3[:] = hm1[:] * hm2[:]`` instead.
1542
        Alternatively you can do ``HeightMap(hm1.array[:] * hm2.array[:])``.
1543
    """
1544
    hm3[:] = hm1[:] * hm2[:]
1545
1546
def heightmap_add_hill(hm, x, y, radius, height):
1547
    """Add a hill (a half spheroid) at given position.
1548
1549
    If height == radius or -radius, the hill is a half-sphere.
1550
1551
    Args:
1552
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1553
        x (float): The x position at the center of the new hill.
1554
        y (float): The y position at the center of the new hill.
1555
        radius (float): The size of the new hill.
1556
        height (float): The height or depth of the new hill.
1557
    """
1558
    lib.TCOD_heightmap_add_hill(_heightmap_cdata(hm), x, y, radius, height)
1559
1560
def heightmap_dig_hill(hm, x, y, radius, height):
1561
    """
1562
1563
    This function takes the highest value (if height > 0) or the lowest
1564
    (if height < 0) between the map and the hill.
1565
1566
    It's main goal is to carve things in maps (like rivers) by digging hills along a curve.
1567
1568
    Args:
1569
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1570
        x (float): The x position at the center of the new carving.
1571
        y (float): The y position at the center of the new carving.
1572
        radius (float): The size of the carving.
1573
        height (float): The height or depth of the hill to dig out.
1574
    """
1575
    lib.TCOD_heightmap_dig_hill(_heightmap_cdata(hm), x, y, radius, height)
1576
1577
def heightmap_rain_erosion(hm, nbDrops, erosionCoef, sedimentationCoef, rnd=None):
1578
    """Simulate the effect of rain drops on the terrain, resulting in erosion.
1579
1580
    ``nbDrops`` should be at least hm.size.
1581
1582
    Args:
1583
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1584
        nbDrops (int): Number of rain drops to simulate.
1585
        erosionCoef (float): Amount of ground eroded on the drop's path.
1586
        sedimentationCoef (float): Amount of ground deposited when the drops
1587
                                   stops to flow.
1588
        rnd (Optional[Random]): A tcod.Random instance, or None.
1589
    """
1590
    lib.TCOD_heightmap_rain_erosion(_heightmap_cdata(hm), nbDrops, erosionCoef,
1591
                                    sedimentationCoef, rnd.random_c if rnd else ffi.NULL)
1592
1593
def heightmap_kernel_transform(hm, kernelsize, dx, dy, weight, minLevel,
1594
                               maxLevel):
1595
    """Apply a generic transformation on the map, so that each resulting cell
1596
    value is the weighted sum of several neighbour cells.
1597
1598
    This can be used to smooth/sharpen the map.
1599
1600
    Args:
1601
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1602
        kernelsize (int): Should be set to the length of the parameters::
1603
                          dx, dy, and weight.
1604
        dx (Sequence[int]): A sequence of x coorinates.
1605
        dy (Sequence[int]): A sequence of y coorinates.
1606
        weight (Sequence[float]): A sequence of kernelSize cells weight.
1607
                                  The value of each neighbour cell is scaled by
1608
                                  its corresponding weight
1609
        minLevel (float): No transformation will apply to cells
1610
                          below this value.
1611
        maxLevel (float): No transformation will apply to cells
1612
                          above this value.
1613
1614
    See examples below for a simple horizontal smoothing kernel :
1615
    replace value(x,y) with
1616
    0.33*value(x-1,y) + 0.33*value(x,y) + 0.33*value(x+1,y).
1617
    To do this, you need a kernel of size 3
1618
    (the sum involves 3 surrounding cells).
1619
    The dx,dy array will contain
1620
    * dx=-1, dy=0 for cell (x-1, y)
1621
    * dx=1, dy=0 for cell (x+1, y)
1622
    * dx=0, dy=0 for cell (x, y)
1623
    * The weight array will contain 0.33 for each cell.
1624
1625
    Example:
1626
        >>> import numpy as np
1627
        >>> heightmap = np.zeros((3, 3), dtype=np.float32)
1628
        >>> heightmap[:,1] = 1
1629
        >>> dx = [-1, 1, 0]
1630
        >>> dy = [0, 0, 0]
1631
        >>> weight = [0.33, 0.33, 0.33]
1632
        >>> tcod.heightmap_kernel_transform(heightmap, 3, dx, dy, weight,
1633
        ...                                 0.0, 1.0)
1634
    """
1635
    cdx = ffi.new('int[]', dx)
1636
    cdy = ffi.new('int[]', dy)
1637
    cweight = ffi.new('float[]', weight)
1638
    lib.TCOD_heightmap_kernel_transform(_heightmap_cdata(hm), kernelsize,
1639
                                        cdx, cdy, cweight, minLevel, maxLevel)
1640
1641
def heightmap_add_voronoi(hm, nbPoints, nbCoef, coef, rnd=None):
1642
    """Add values from a Voronoi diagram to the heightmap.
1643
1644
    Args:
1645
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1646
        nbPoints (Any): Number of Voronoi sites.
1647
        nbCoef (int): The diagram value is calculated from the nbCoef
1648
                      closest sites.
1649
        coef (Sequence[float]): The distance to each site is scaled by the
1650
                                corresponding coef.
1651
                                Closest site : coef[0],
1652
                                second closest site : coef[1], ...
1653
        rnd (Optional[Random]): A Random instance, or None.
1654
    """
1655
    nbPoints = len(coef)
1656
    ccoef = ffi.new('float[]', coef)
1657
    lib.TCOD_heightmap_add_voronoi(_heightmap_cdata(hm), nbPoints,
1658
                                   nbCoef, ccoef, rnd.random_c if rnd else ffi.NULL)
1659
1660
def heightmap_add_fbm(hm, noise, mulx, muly, addx, addy, octaves, delta, scale):
1661
    """Add FBM noise to the heightmap.
1662
1663
    The noise coordinate for each map cell is
1664
    `((x + addx) * mulx / width, (y + addy) * muly / height)`.
1665
1666
    The value added to the heightmap is `delta + noise * scale`.
1667
1668
    Args:
1669
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1670
        noise (Noise): A Noise instance.
1671
        mulx (float): Scaling of each x coordinate.
1672
        muly (float): Scaling of each y coordinate.
1673
        addx (float): Translation of each x coordinate.
1674
        addy (float): Translation of each y coordinate.
1675
        octaves (float): Number of octaves in the FBM sum.
1676
        delta (float): The value added to all heightmap cells.
1677
        scale (float): The noise value is scaled with this parameter.
1678
    """
1679
    noise = noise.noise_c if noise is not None else ffi.NULL
1680
    lib.TCOD_heightmap_add_fbm(_heightmap_cdata(hm), noise,
1681
                               mulx, muly, addx, addy, octaves, delta, scale)
1682
1683
def heightmap_scale_fbm(hm, noise, mulx, muly, addx, addy, octaves, delta,
1684
                        scale):
1685
    """Multiply the heighmap values with FBM noise.
1686
1687
    Args:
1688
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1689
        noise (Noise): A Noise instance.
1690
        mulx (float): Scaling of each x coordinate.
1691
        muly (float): Scaling of each y coordinate.
1692
        addx (float): Translation of each x coordinate.
1693
        addy (float): Translation of each y coordinate.
1694
        octaves (float): Number of octaves in the FBM sum.
1695
        delta (float): The value added to all heightmap cells.
1696
        scale (float): The noise value is scaled with this parameter.
1697
    """
1698
    noise = noise.noise_c if noise is not None else ffi.NULL
1699
    lib.TCOD_heightmap_scale_fbm(_heightmap_cdata(hm), noise,
1700
                                 mulx, muly, addx, addy, octaves, delta, scale)
1701
1702
def heightmap_dig_bezier(hm, px, py, startRadius, startDepth, endRadius,
1703
                         endDepth):
1704
    """Carve a path along a cubic Bezier curve.
1705
1706
    Both radius and depth can vary linearly along the path.
1707
1708
    Args:
1709
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1710
        px (Sequence[int]): The 4 `x` coordinates of the Bezier curve.
1711
        py (Sequence[int]): The 4 `y` coordinates of the Bezier curve.
1712
        startRadius (float): The starting radius size.
1713
        startDepth (float): The starting depth.
1714
        endRadius (float): The ending radius size.
1715
        endDepth (float): The ending depth.
1716
    """
1717
    lib.TCOD_heightmap_dig_bezier(_heightmap_cdata(hm), px, py, startRadius,
1718
                                   startDepth, endRadius,
1719
                                   endDepth)
1720
1721
def heightmap_get_value(hm, x, y):
1722
    """Return the value at ``x``, ``y`` in a heightmap.
1723
1724
    Args:
1725
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1726
        x (int): The x position to pick.
1727
        y (int): The y position to pick.
1728
1729
    Returns:
1730
        float: The value at ``x``, ``y``.
1731
1732
    .. deprecated:: 2.0
1733
        Do ``value = hm[y, x]`` instead.
1734
    """
1735
    # explicit type conversion to pass test, (test should have been better.)
1736
    return float(hm[y, x])
1737
1738
def heightmap_get_interpolated_value(hm, x, y):
1739
    """Return the interpolated height at non integer coordinates.
1740
1741
    Args:
1742
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1743
        x (float): A floating point x coordinate.
1744
        y (float): A floating point y coordinate.
1745
1746
    Returns:
1747
        float: The value at ``x``, ``y``.
1748
    """
1749
    return lib.TCOD_heightmap_get_interpolated_value(_heightmap_cdata(hm),
1750
                                                     x, y)
1751
1752
def heightmap_get_slope(hm, x, y):
1753
    """Return the slope between 0 and (pi / 2) at given coordinates.
1754
1755
    Args:
1756
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1757
        x (int): The x coordinate.
1758
        y (int): The y coordinate.
1759
1760
    Returns:
1761
        float: The steepness at ``x``, ``y``.  From 0 to (pi / 2)
1762
    """
1763
    return lib.TCOD_heightmap_get_slope(_heightmap_cdata(hm), x, y)
1764
1765
def heightmap_get_normal(hm, x, y, waterLevel):
1766
    """Return the map normal at given coordinates.
1767
1768
    Args:
1769
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1770
        x (float): The x coordinate.
1771
        y (float): The y coordinate.
1772
        waterLevel (float): The heightmap is considered flat below this value.
1773
1774
    Returns:
1775
        Tuple[float, float, float]: An (x, y, z) vector normal.
1776
    """
1777
    cn = ffi.new('float[3]')
1778
    lib.TCOD_heightmap_get_normal(_heightmap_cdata(hm), x, y, cn, waterLevel)
1779
    return tuple(cn)
1780
1781
def heightmap_count_cells(hm, mi, ma):
1782
    """Return the number of map cells which value is between ``mi`` and ``ma``.
1783
1784
    Args:
1785
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1786
        mi (float): The lower bound.
1787
        ma (float): The upper bound.
1788
1789
    Returns:
1790
        int: The count of values which fall between ``mi`` and ``ma``.
1791
    """
1792
    return lib.TCOD_heightmap_count_cells(_heightmap_cdata(hm), mi, ma)
1793
1794
def heightmap_has_land_on_border(hm, waterlevel):
1795
    """Returns True if the map edges are below ``waterlevel``, otherwise False.
1796
1797
    Args:
1798
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1799
        waterLevel (float): The water level to use.
1800
1801
    Returns:
1802
        bool: True if the map edges are below ``waterlevel``, otherwise False.
1803
    """
1804
    return lib.TCOD_heightmap_has_land_on_border(_heightmap_cdata(hm),
1805
                                                 waterlevel)
1806
1807
def heightmap_get_minmax(hm):
1808
    """Return the min and max values of this heightmap.
1809
1810
    Args:
1811
        hm (numpy.ndarray): A numpy.ndarray formatted for heightmap functions.
1812
1813
    Returns:
1814
        Tuple[float, float]: The (min, max) values.
1815
1816
    .. deprecated:: 2.0
1817
        Do ``hm.min()`` or ``hm.max()`` instead.
1818
    """
1819
    mi = ffi.new('float *')
1820
    ma = ffi.new('float *')
1821
    lib.TCOD_heightmap_get_minmax(_heightmap_cdata(hm), mi, ma)
1822
    return mi[0], ma[0]
1823
1824
def heightmap_delete(hm):
1825
    """Does nothing.
1826
1827
    .. deprecated:: 2.0
1828
        libtcod-cffi deletes heightmaps automatically.
1829
    """
1830
    pass
1831
1832
def image_new(width, height):
1833
    return tcod.image.Image(width, height)
1834
1835
def image_clear(image, col):
1836
    image.clear(col)
1837
1838
def image_invert(image):
1839
    image.invert()
1840
1841
def image_hflip(image):
1842
    image.hflip()
1843
1844
def image_rotate90(image, num=1):
1845
    image.rotate90(num)
1846
1847
def image_vflip(image):
1848
    image.vflip()
1849
1850
def image_scale(image, neww, newh):
1851
    image.scale(neww, newh)
1852
1853
def image_set_key_color(image, col):
1854
    image.set_key_color(col)
1855
1856
def image_get_alpha(image, x, y):
1857
    image.get_alpha(x, y)
1858
1859
def image_is_pixel_transparent(image, x, y):
1860
    lib.TCOD_image_is_pixel_transparent(image.image_c, x, y)
1861
1862
def image_load(filename):
1863
    """Load an image file into an Image instance and return it.
1864
1865
    Args:
1866
        filename (AnyStr): Path to a .bmp or .png image file.
1867
    """
1868
    return tcod.image.Image._from_cdata(
1869
        ffi.gc(lib.TCOD_image_load(_bytes(filename)),
1870
               lib.TCOD_image_delete)
1871
        )
1872
1873
def image_from_console(console):
1874
    """Return an Image with a Consoles pixel data.
1875
1876
    This effectively takes a screen-shot of the Console.
1877
1878
    Args:
1879
        console (Console): Any Console instance.
1880
    """
1881
    return tcod.image.Image._from_cdata(
1882
        ffi.gc(
1883
            lib.TCOD_image_from_console(_console(console)),
1884
            lib.TCOD_image_delete,
1885
            )
1886
        )
1887
1888
def image_refresh_console(image, console):
1889
    image.refresh_console(console)
1890
1891
def image_get_size(image):
1892
    return image.width, image.height
1893
1894
def image_get_pixel(image, x, y):
1895
    return image.get_pixel(x, y)
1896
1897
def image_get_mipmap_pixel(image, x0, y0, x1, y1):
1898
    return image.get_mipmap_pixel(x0, y0, x1, y1)
1899
1900
def image_put_pixel(image, x, y, col):
1901
    image.put_pixel(x, y, col)
1902
1903
def image_blit(image, console, x, y, bkgnd_flag, scalex, scaley, angle):
1904
    image.blit(console, x, y, bkgnd_flag, scalex, scaley, angle)
1905
1906
def image_blit_rect(image, console, x, y, w, h, bkgnd_flag):
1907
    image.blit_rect(console, x, y, w, h, bkgnd_flag)
1908
1909
def image_blit_2x(image, console, dx, dy, sx=0, sy=0, w=-1, h=-1):
1910
    image.blit_2x(console, dx, dy, sx, sy, w, h)
1911
1912
def image_save(image, filename):
1913
    image.save_as(filename)
1914
1915
def image_delete(image):
1916
    pass
1917
1918
def line_init(xo, yo, xd, yd):
1919
    """Initilize a line whose points will be returned by `line_step`.
1920
1921
    This function does not return anything on its own.
1922
1923
    Does not include the origin point.
1924
1925
    Args:
1926
        xo (int): X starting point.
1927
        yo (int): Y starting point.
1928
        xd (int): X destination point.
1929
        yd (int): Y destination point.
1930
1931
    .. deprecated:: 2.0
1932
       Use `line_iter` instead.
1933
    """
1934
    lib.TCOD_line_init(xo, yo, xd, yd)
1935
1936
def line_step():
1937
    """After calling line_init returns (x, y) points of the line.
1938
1939
    Once all points are exhausted this function will return (None, None)
1940
1941
    Returns:
1942
        Union[Tuple[int, int], Tuple[None, None]]:
1943
            The next (x, y) point of the line setup by line_init,
1944
            or (None, None) if there are no more points.
1945
1946
    .. deprecated:: 2.0
1947
       Use `line_iter` instead.
1948
    """
1949
    x = ffi.new('int *')
1950
    y = ffi.new('int *')
1951
    ret = lib.TCOD_line_step(x, y)
1952
    if not ret:
1953
        return x[0], y[0]
1954
    return None,None
1955
1956
1957
def line(xo, yo, xd, yd, py_callback):
1958
    """ Iterate over a line using a callback function.
1959
1960
    Your callback function will take x and y parameters and return True to
1961
    continue iteration or False to stop iteration and return.
1962
1963
    This function includes both the start and end points.
1964
1965
    Args:
1966
        xo (int): X starting point.
1967
        yo (int): Y starting point.
1968
        xd (int): X destination point.
1969
        yd (int): Y destination point.
1970
        py_callback (Callable[[int, int], bool]):
1971
            A callback which takes x and y parameters and returns bool.
1972
1973
    Returns:
1974
        bool: False if the callback cancels the line interation by
1975
              returning False or None, otherwise True.
1976
1977
    .. deprecated:: 2.0
1978
       Use `line_iter` instead.
1979
    """
1980
    for x, y in line_iter(xo, yo, xd, yd):
1981
        if not py_callback(x, y):
1982
            break
1983
    else:
1984
        return True
1985
    return False
1986
1987
1988
def line_iter(xo, yo, xd, yd):
1989
    """ returns an iterator
1990
1991
    This iterator does not include the origin point.
1992
1993
    Args:
1994
        xo (int): X starting point.
1995
        yo (int): Y starting point.
1996
        xd (int): X destination point.
1997
        yd (int): Y destination point.
1998
1999
    Returns:
2000
        Iterator[Tuple[int,int]]: An iterator of (x,y) points.
2001
    """
2002
    data = ffi.new('TCOD_bresenham_data_t *')
2003
    lib.TCOD_line_init_mt(xo, yo, xd, yd, data)
2004
    x = ffi.new('int *')
2005
    y = ffi.new('int *')
2006
    yield xo, yo
2007
    while not lib.TCOD_line_step_mt(x, y, data):
2008
        yield (x[0], y[0])
2009
2010
FOV_BASIC = 0
2011
FOV_DIAMOND = 1
2012
FOV_SHADOW = 2
2013
FOV_PERMISSIVE_0 = 3
2014
FOV_PERMISSIVE_1 = 4
2015
FOV_PERMISSIVE_2 = 5
2016
FOV_PERMISSIVE_3 = 6
2017
FOV_PERMISSIVE_4 = 7
2018
FOV_PERMISSIVE_5 = 8
2019
FOV_PERMISSIVE_6 = 9
2020
FOV_PERMISSIVE_7 = 10
2021
FOV_PERMISSIVE_8 = 11
2022
FOV_RESTRICTIVE = 12
2023
NB_FOV_ALGORITHMS = 13
2024
2025
def map_new(w, h):
2026
    # type: (int, int) -> tcod.map.Map
2027
    """Return a :any:`tcod.map.Map` with a width and height.
2028
2029
    .. deprecated:: 4.5
2030
        Use the :any:`tcod.map` module for working with field-of-view,
2031
        or :any:`tcod.path` for working with path-finding.
2032
    """
2033
    return tcod.map.Map(w, h)
2034
2035
def map_copy(source, dest):
2036
    # type: (tcod.map.Map, tcod.map.Map) -> None
2037
    """Copy map data from `source` to `dest`.
2038
2039
    .. deprecated:: 4.5
2040
        Use Python's copy module, or see :any:`tcod.map.Map` and assign between
2041
        array attributes manually.
2042
    """
2043
    if source.width != dest.width or source.height != dest.height:
2044
        dest.__init__(source.width, source.height, source._order)
2045
    dest._Map__buffer[:] = source._Map__buffer[:]
2046
2047
def map_set_properties(m, x, y, isTrans, isWalk):
2048
    # type: (tcod.map.Map, int, int, bool, bool) -> None
2049
    """Set the properties of a single cell.
2050
2051
    .. note::
2052
        This function is slow.
2053
    .. deprecated:: 4.5
2054
        Use :any:`tcod.map.Map.transparent` and :any:`tcod.map.Map.walkable`
2055
        arrays to set these properties.
2056
    """
2057
    lib.TCOD_map_set_properties(m.map_c, x, y, isTrans, isWalk)
2058
2059
def map_clear(m, transparent=False, walkable=False):
2060
    # type: (tcod.map.Map, bool, bool) -> None
2061
    """Change all map cells to a specific value.
2062
2063
    .. deprecated:: 4.5
2064
        Use :any:`tcod.map.Map.transparent` and :any:`tcod.map.Map.walkable`
2065
        arrays to set these properties.
2066
    """
2067
    m.transparent[:] = transparent
2068
    m.walkable[:] = walkable
2069
2070
def map_compute_fov(m, x, y, radius=0, light_walls=True, algo=FOV_RESTRICTIVE ):
2071
    # type: (tcod.map.Map, int, int, int, bool, int) -> None
2072
    """Compute the field-of-view for a map instance.
2073
2074
    .. deprecated:: 4.5
2075
        Use :any:`tcod.map.Map.compute_fov` instead.
2076
    """
2077
    m.compute_fov(x, y, radius, light_walls, algo)
2078
2079
def map_is_in_fov(m, x, y):
2080
    # type: (tcod.map.Map, int, int) -> bool
2081
    """Return True if the cell at x,y is lit by the last field-of-view
2082
    algorithm.
2083
2084
    .. note::
2085
        This function is slow.
2086
    .. deprecated:: 4.5
2087
        Use :any:`tcod.map.Map.fov` to check this property.
2088
    """
2089
    return lib.TCOD_map_is_in_fov(m.map_c, x, y)
2090
2091
def map_is_transparent(m, x, y):
2092
    # type: (tcod.map.Map, int, int) -> bool
2093
    """
2094
    .. note::
2095
        This function is slow.
2096
    .. deprecated:: 4.5
2097
        Use :any:`tcod.map.Map.transparent` to check this property.
2098
    """
2099
    return lib.TCOD_map_is_transparent(m.map_c, x, y)
2100
2101
def map_is_walkable(m, x, y):
2102
    # type: (tcod.map.Map, int, int) -> bool
2103
    """
2104
    .. note::
2105
        This function is slow.
2106
    .. deprecated:: 4.5
2107
        Use :any:`tcod.map.Map.walkable` to check this property.
2108
    """
2109
    return lib.TCOD_map_is_walkable(m.map_c, x, y)
2110
2111
def map_delete(m):
2112
    """This function does nothing."""
2113
2114
def map_get_width(map):
2115
    # type: (tcod.map.Map) -> int
2116
    """Return the width of a map.
2117
2118
    .. deprecated:: 4.5
2119
        Check the :any:`tcod.map.Map.width` attribute instead.
2120
    """
2121
    return map.width
2122
2123
def map_get_height(map):
2124
    # type: (tcod.map.Map) -> int
2125
    """Return the height of a map.
2126
2127
    .. deprecated:: 4.5
2128
        Check the :any:`tcod.map.Map.height` attribute instead.
2129
    """
2130
    return map.height
2131
2132
def mouse_show_cursor(visible):
2133
    # type: (bool) -> None
2134
    """Change the visibility of the mouse cursor."""
2135
    lib.TCOD_mouse_show_cursor(visible)
2136
2137
def mouse_is_cursor_visible():
2138
    # type: () -> bool
2139
    """Return True if the mouse cursor is visible."""
2140
    return lib.TCOD_mouse_is_cursor_visible()
2141
2142
def mouse_move(x, y):
2143
    # type (int, int) -> None
2144
    lib.TCOD_mouse_move(x, y)
2145
2146
def mouse_get_status():
2147
    # type: () -> Mouse
2148
    return Mouse(lib.TCOD_mouse_get_status())
2149
2150
def namegen_parse(filename,random=None):
2151
    lib.TCOD_namegen_parse(_bytes(filename), random or ffi.NULL)
2152
2153
def namegen_generate(name):
2154
    return _unpack_char_p(lib.TCOD_namegen_generate(_bytes(name), False))
2155
2156
def namegen_generate_custom(name, rule):
2157
    return _unpack_char_p(lib.TCOD_namegen_generate(_bytes(name),
2158
                                                     _bytes(rule), False))
2159
2160
def namegen_get_sets():
2161
    sets = lib.TCOD_namegen_get_sets()
2162
    try:
2163
        lst = []
2164
        while not lib.TCOD_list_is_empty(sets):
2165
            lst.append(_unpack_char_p(ffi.cast('char *', lib.TCOD_list_pop(sets))))
2166
    finally:
2167
        lib.TCOD_list_delete(sets)
2168
    return lst
2169
2170
def namegen_destroy():
2171
    lib.TCOD_namegen_destroy()
2172
2173
def noise_new(dim, h=NOISE_DEFAULT_HURST, l=NOISE_DEFAULT_LACUNARITY,
2174
        random=None):
2175
    """Return a new Noise instance.
2176
2177
    Args:
2178
        dim (int): Number of dimensions.  From 1 to 4.
2179
        h (float): The hurst exponent.  Should be in the 0.0-1.0 range.
2180
        l (float): The noise lacunarity.
2181
        random (Optional[Random]): A Random instance, or None.
2182
2183
    Returns:
2184
        Noise: The new Noise instance.
2185
    """
2186
    return tcod.noise.Noise(dim, hurst=h, lacunarity=l, seed=random)
2187
2188
def noise_set_type(n, typ):
2189
    """Set a Noise objects default noise algorithm.
2190
2191
    Args:
2192
        typ (int): Any NOISE_* constant.
2193
    """
2194
    n.algorithm = typ
2195
2196
def noise_get(n, f, typ=NOISE_DEFAULT):
2197
    """Return the noise value sampled from the ``f`` coordinate.
2198
2199
    ``f`` should be a tuple or list with a length matching
2200
    :any:`Noise.dimensions`.
2201
    If ``f`` is shoerter than :any:`Noise.dimensions` the missing coordinates
2202
    will be filled with zeros.
2203
2204
    Args:
2205
        n (Noise): A Noise instance.
2206
        f (Sequence[float]): The point to sample the noise from.
2207
        typ (int): The noise algorithm to use.
2208
2209
    Returns:
2210
        float: The sampled noise value.
2211
    """
2212
    return lib.TCOD_noise_get_ex(n.noise_c, ffi.new('float[4]', f), typ)
2213
2214
def noise_get_fbm(n, f, oc, typ=NOISE_DEFAULT):
2215
    """Return the fractal Brownian motion sampled from the ``f`` coordinate.
2216
2217
    Args:
2218
        n (Noise): A Noise instance.
2219
        f (Sequence[float]): The point to sample the noise from.
2220
        typ (int): The noise algorithm to use.
2221
        octaves (float): The level of level.  Should be more than 1.
2222
2223
    Returns:
2224
        float: The sampled noise value.
2225
    """
2226
    return lib.TCOD_noise_get_fbm_ex(n.noise_c, ffi.new('float[4]', f),
2227
                                     oc, typ)
2228
2229
def noise_get_turbulence(n, f, oc, typ=NOISE_DEFAULT):
2230
    """Return the turbulence noise sampled from the ``f`` coordinate.
2231
2232
    Args:
2233
        n (Noise): A Noise instance.
2234
        f (Sequence[float]): The point to sample the noise from.
2235
        typ (int): The noise algorithm to use.
2236
        octaves (float): The level of level.  Should be more than 1.
2237
2238
    Returns:
2239
        float: The sampled noise value.
2240
    """
2241
    return lib.TCOD_noise_get_turbulence_ex(n.noise_c, ffi.new('float[4]', f),
2242
                                            oc, typ)
2243
2244
def noise_delete(n):
2245
    """Does nothing."""
2246
    pass
2247
2248
_chr = chr
2249
try:
2250
    _chr = unichr # Python 2
2251
except NameError:
2252
    pass
2253
2254
def _unpack_union(type_, union):
2255
    '''
2256
        unpack items from parser new_property (value_converter)
2257
    '''
2258
    if type_ == lib.TCOD_TYPE_BOOL:
2259
        return bool(union.b)
2260
    elif type_ == lib.TCOD_TYPE_CHAR:
2261
        return _unicode(union.c)
2262
    elif type_ == lib.TCOD_TYPE_INT:
2263
        return union.i
2264
    elif type_ == lib.TCOD_TYPE_FLOAT:
2265
        return union.f
2266
    elif (type_ == lib.TCOD_TYPE_STRING or
2267
         lib.TCOD_TYPE_VALUELIST15 >= type_ >= lib.TCOD_TYPE_VALUELIST00):
2268
         return _unpack_char_p(union.s)
2269
    elif type_ == lib.TCOD_TYPE_COLOR:
2270
        return Color._new_from_cdata(union.col)
2271
    elif type_ == lib.TCOD_TYPE_DICE:
2272
        return Dice(union.dice)
2273
    elif type_ & lib.TCOD_TYPE_LIST:
2274
        return _convert_TCODList(union.list, type_ & 0xFF)
2275
    else:
2276
        raise RuntimeError('Unknown libtcod type: %i' % type_)
2277
2278
def _convert_TCODList(clist, type_):
2279
    return [_unpack_union(type_, lib.TDL_list_get_union(clist, i))
2280
            for i in range(lib.TCOD_list_size(clist))]
2281
2282
def parser_new():
2283
    return ffi.gc(lib.TCOD_parser_new(), lib.TCOD_parser_delete)
2284
2285
def parser_new_struct(parser, name):
2286
    return lib.TCOD_parser_new_struct(parser, name)
2287
2288
# prevent multiple threads from messing with def_extern callbacks
2289
_parser_callback_lock = _threading.Lock()
2290
_parser_listener = None # temporary global pointer to a listener instance
2291
2292
@ffi.def_extern()
2293
def _pycall_parser_new_struct(struct, name):
2294
    return _parser_listener.end_struct(struct, _unpack_char_p(name))
2295
2296
@ffi.def_extern()
2297
def _pycall_parser_new_flag(name):
2298
    return _parser_listener.new_flag(_unpack_char_p(name))
2299
2300
@ffi.def_extern()
2301
def _pycall_parser_new_property(propname, type, value):
2302
    return _parser_listener.new_property(_unpack_char_p(propname), type,
2303
                                 _unpack_union(type, value))
2304
2305
@ffi.def_extern()
2306
def _pycall_parser_end_struct(struct, name):
2307
    return _parser_listener.end_struct(struct, _unpack_char_p(name))
2308
2309
@ffi.def_extern()
2310
def _pycall_parser_error(msg):
2311
    _parser_listener.error(_unpack_char_p(msg))
2312
2313
def parser_run(parser, filename, listener=None):
2314
    global _parser_listener
2315
    if not listener:
2316
        lib.TCOD_parser_run(parser, _bytes(filename), ffi.NULL)
2317
        return
2318
2319
    propagate_manager = _PropagateException()
2320
    propagate = propagate_manager.propagate
2321
2322
    clistener = ffi.new(
2323
        'TCOD_parser_listener_t *',
2324
        {
2325
            'new_struct': lib._pycall_parser_new_struct,
2326
            'new_flag': lib._pycall_parser_new_flag,
2327
            'new_property': lib._pycall_parser_new_property,
2328
            'end_struct': lib._pycall_parser_end_struct,
2329
            'error': lib._pycall_parser_error,
2330
        },
2331
    )
2332
2333
    with _parser_callback_lock:
2334
        _parser_listener = listener
2335
        with propagate_manager:
2336
            lib.TCOD_parser_run(parser, _bytes(filename), clistener)
2337
2338
def parser_delete(parser):
2339
    pass
2340
2341
def parser_get_bool_property(parser, name):
2342
    return bool(lib.TCOD_parser_get_bool_property(parser, _bytes(name)))
2343
2344
def parser_get_int_property(parser, name):
2345
    return lib.TCOD_parser_get_int_property(parser, _bytes(name))
2346
2347
def parser_get_char_property(parser, name):
2348
    return _chr(lib.TCOD_parser_get_char_property(parser, _bytes(name)))
2349
2350
def parser_get_float_property(parser, name):
2351
    return lib.TCOD_parser_get_float_property(parser, _bytes(name))
2352
2353
def parser_get_string_property(parser, name):
2354
    return _unpack_char_p(
2355
        lib.TCOD_parser_get_string_property(parser, _bytes(name)))
2356
2357
def parser_get_color_property(parser, name):
2358
    return Color._new_from_cdata(
2359
        lib.TCOD_parser_get_color_property(parser, _bytes(name)))
2360
2361
def parser_get_dice_property(parser, name):
2362
    d = ffi.new('TCOD_dice_t *')
2363
    lib.TCOD_parser_get_dice_property_py(parser, _bytes(name), d)
2364
    return Dice(d)
2365
2366
def parser_get_list_property(parser, name, type):
2367
    clist = lib.TCOD_parser_get_list_property(parser, _bytes(name), type)
2368
    return _convert_TCODList(clist, type)
2369
2370
RNG_MT = 0
2371
RNG_CMWC = 1
2372
2373
DISTRIBUTION_LINEAR = 0
2374
DISTRIBUTION_GAUSSIAN = 1
2375
DISTRIBUTION_GAUSSIAN_RANGE = 2
2376
DISTRIBUTION_GAUSSIAN_INVERSE = 3
2377
DISTRIBUTION_GAUSSIAN_RANGE_INVERSE = 4
2378
2379
def random_get_instance():
2380
    """Return the default Random instance.
2381
2382
    Returns:
2383
        Random: A Random instance using the default random number generator.
2384
    """
2385
    return tcod.random.Random._new_from_cdata(
2386
        ffi.cast('mersenne_data_t*', lib.TCOD_random_get_instance()))
2387
2388
def random_new(algo=RNG_CMWC):
2389
    """Return a new Random instance.  Using ``algo``.
2390
2391
    Args:
2392
        algo (int): The random number algorithm to use.
2393
2394
    Returns:
2395
        Random: A new Random instance using the given algorithm.
2396
    """
2397
    return tcod.random.Random(algo)
2398
2399
def random_new_from_seed(seed, algo=RNG_CMWC):
2400
    """Return a new Random instance.  Using the given ``seed`` and ``algo``.
2401
2402
    Args:
2403
        seed (Hashable): The RNG seed.  Should be a 32-bit integer, but any
2404
                         hashable object is accepted.
2405
        algo (int): The random number algorithm to use.
2406
2407
    Returns:
2408
        Random: A new Random instance using the given algorithm.
2409
    """
2410
    return tcod.random.Random(algo, seed)
2411
2412
def random_set_distribution(rnd, dist):
2413
    """Change the distribution mode of a random number generator.
2414
2415
    Args:
2416
        rnd (Optional[Random]): A Random instance, or None to use the default.
2417
        dist (int): The distribution mode to use.  Should be DISTRIBUTION_*.
2418
    """
2419
    lib.TCOD_random_set_distribution(rnd.random_c if rnd else ffi.NULL, dist)
2420
2421
def random_get_int(rnd, mi, ma):
2422
    """Return a random integer in the range: ``mi`` <= n <= ``ma``.
2423
2424
    The result is affacted by calls to :any:`random_set_distribution`.
2425
2426
    Args:
2427
        rnd (Optional[Random]): A Random instance, or None to use the default.
2428
        low (int): The lower bound of the random range, inclusive.
2429
        high (int): The upper bound of the random range, inclusive.
2430
2431
    Returns:
2432
        int: A random integer in the range ``mi`` <= n <= ``ma``.
2433
    """
2434
    return lib.TCOD_random_get_int(rnd.random_c if rnd else ffi.NULL, mi, ma)
2435
2436
def random_get_float(rnd, mi, ma):
2437
    """Return a random float in the range: ``mi`` <= n <= ``ma``.
2438
2439
    The result is affacted by calls to :any:`random_set_distribution`.
2440
2441
    Args:
2442
        rnd (Optional[Random]): A Random instance, or None to use the default.
2443
        low (float): The lower bound of the random range, inclusive.
2444
        high (float): The upper bound of the random range, inclusive.
2445
2446
    Returns:
2447
        float: A random double precision float
2448
               in the range ``mi`` <= n <= ``ma``.
2449
    """
2450
    return lib.TCOD_random_get_double(
2451
        rnd.random_c if rnd else ffi.NULL, mi, ma)
2452
2453
def random_get_double(rnd, mi, ma):
2454
    """Return a random float in the range: ``mi`` <= n <= ``ma``.
2455
2456
    .. deprecated:: 2.0
2457
        Use :any:`random_get_float` instead.
2458
        Both funtions return a double precision float.
2459
    """
2460
    return lib.TCOD_random_get_double(
2461
        rnd.random_c if rnd else ffi.NULL, mi, ma)
2462
2463
def random_get_int_mean(rnd, mi, ma, mean):
2464
    """Return a random weighted integer in the range: ``mi`` <= n <= ``ma``.
2465
2466
    The result is affacted by calls to :any:`random_set_distribution`.
2467
2468
    Args:
2469
        rnd (Optional[Random]): A Random instance, or None to use the default.
2470
        low (int): The lower bound of the random range, inclusive.
2471
        high (int): The upper bound of the random range, inclusive.
2472
        mean (int): The mean return value.
2473
2474
    Returns:
2475
        int: A random weighted integer in the range ``mi`` <= n <= ``ma``.
2476
    """
2477
    return lib.TCOD_random_get_int_mean(
2478
        rnd.random_c if rnd else ffi.NULL, mi, ma, mean)
2479
2480
def random_get_float_mean(rnd, mi, ma, mean):
2481
    """Return a random weighted float in the range: ``mi`` <= n <= ``ma``.
2482
2483
    The result is affacted by calls to :any:`random_set_distribution`.
2484
2485
    Args:
2486
        rnd (Optional[Random]): A Random instance, or None to use the default.
2487
        low (float): The lower bound of the random range, inclusive.
2488
        high (float): The upper bound of the random range, inclusive.
2489
        mean (float): The mean return value.
2490
2491
    Returns:
2492
        float: A random weighted double precision float
2493
               in the range ``mi`` <= n <= ``ma``.
2494
    """
2495
    return lib.TCOD_random_get_double_mean(
2496
        rnd.random_c if rnd else ffi.NULL, mi, ma, mean)
2497
2498
def random_get_double_mean(rnd, mi, ma, mean):
2499
    """Return a random weighted float in the range: ``mi`` <= n <= ``ma``.
2500
2501
    .. deprecated:: 2.0
2502
        Use :any:`random_get_float_mean` instead.
2503
        Both funtions return a double precision float.
2504
    """
2505
    return lib.TCOD_random_get_double_mean(
2506
        rnd.random_c if rnd else ffi.NULL, mi, ma, mean)
2507
2508
def random_save(rnd):
2509
    """Return a copy of a random number generator.
2510
2511
    Args:
2512
        rnd (Optional[Random]): A Random instance, or None to use the default.
2513
2514
    Returns:
2515
        Random: A Random instance with a copy of the random generator.
2516
    """
2517
    return tcod.random.Random._new_from_cdata(
2518
        ffi.gc(
2519
            ffi.cast('mersenne_data_t*',
2520
                     lib.TCOD_random_save(rnd.random_c if rnd else ffi.NULL)),
2521
            lib.TCOD_random_delete),
2522
        )
2523
2524
def random_restore(rnd, backup):
2525
    """Restore a random number generator from a backed up copy.
2526
2527
    Args:
2528
        rnd (Optional[Random]): A Random instance, or None to use the default.
2529
        backup (Random): The Random instance which was used as a backup.
2530
    """
2531
    lib.TCOD_random_restore(rnd.random_c if rnd else ffi.NULL,
2532
                            backup.random_c)
2533
2534
def random_delete(rnd):
2535
    """Does nothing."""
2536
    pass
2537
2538
def struct_add_flag(struct, name):
2539
    lib.TCOD_struct_add_flag(struct, name)
2540
2541
def struct_add_property(struct, name, typ, mandatory):
2542
    lib.TCOD_struct_add_property(struct, name, typ, mandatory)
2543
2544
def struct_add_value_list(struct, name, value_list, mandatory):
2545
    CARRAY = c_char_p * (len(value_list) + 1)
2546
    cvalue_list = CARRAY()
2547
    for i, value in enumerate(value_list):
2548
        cvalue_list[i] = cast(value, c_char_p)
2549
    cvalue_list[len(value_list)] = 0
2550
    lib.TCOD_struct_add_value_list(struct, name, cvalue_list, mandatory)
2551
2552
def struct_add_list_property(struct, name, typ, mandatory):
2553
    lib.TCOD_struct_add_list_property(struct, name, typ, mandatory)
2554
2555
def struct_add_structure(struct, sub_struct):
2556
    lib.TCOD_struct_add_structure(struct, sub_struct)
2557
2558
def struct_get_name(struct):
2559
    return _unpack_char_p(lib.TCOD_struct_get_name(struct))
2560
2561
def struct_is_mandatory(struct, name):
2562
    return lib.TCOD_struct_is_mandatory(struct, name)
2563
2564
def struct_get_type(struct, name):
2565
    return lib.TCOD_struct_get_type(struct, name)
2566
2567
# high precision time functions
2568
def sys_set_fps(fps):
2569
    """Set the maximum frame rate.
2570
2571
    You can disable the frame limit again by setting fps to 0.
2572
2573
    Args:
2574
        fps (int): A frame rate limit (i.e. 60)
2575
    """
2576
    lib.TCOD_sys_set_fps(fps)
2577
2578
def sys_get_fps():
2579
    """Return the current frames per second.
2580
2581
    This the actual frame rate, not the frame limit set by
2582
    :any:`tcod.sys_set_fps`.
2583
2584
    This number is updated every second.
2585
2586
    Returns:
2587
        int: The currently measured frame rate.
2588
    """
2589
    return lib.TCOD_sys_get_fps()
2590
2591
def sys_get_last_frame_length():
2592
    """Return the delta time of the last rendered frame in seconds.
2593
2594
    Returns:
2595
        float: The delta time of the last rendered frame.
2596
    """
2597
    return lib.TCOD_sys_get_last_frame_length()
2598
2599
def sys_sleep_milli(val):
2600
    """Sleep for 'val' milliseconds.
2601
2602
    Args:
2603
        val (int): Time to sleep for in milliseconds.
2604
2605
    .. deprecated:: 2.0
2606
       Use :any:`time.sleep` instead.
2607
    """
2608
    lib.TCOD_sys_sleep_milli(val)
2609
2610
def sys_elapsed_milli():
2611
    """Get number of milliseconds since the start of the program.
2612
2613
    Returns:
2614
        int: Time since the progeam has started in milliseconds.
2615
2616
    .. deprecated:: 2.0
2617
       Use :any:`time.clock` instead.
2618
    """
2619
    return lib.TCOD_sys_elapsed_milli()
2620
2621
def sys_elapsed_seconds():
2622
    """Get number of seconds since the start of the program.
2623
2624
    Returns:
2625
        float: Time since the progeam has started in seconds.
2626
2627
    .. deprecated:: 2.0
2628
       Use :any:`time.clock` instead.
2629
    """
2630
    return lib.TCOD_sys_elapsed_seconds()
2631
2632
def sys_set_renderer(renderer):
2633
    """Change the current rendering mode to renderer.
2634
2635
    .. deprecated:: 2.0
2636
       RENDERER_GLSL and RENDERER_OPENGL are not currently available.
2637
    """
2638
    lib.TCOD_sys_set_renderer(renderer)
2639
2640
def sys_get_renderer():
2641
    """Return the current rendering mode.
2642
2643
    """
2644
    return lib.TCOD_sys_get_renderer()
2645
2646
# easy screenshots
2647
def sys_save_screenshot(name=None):
2648
    """Save a screenshot to a file.
2649
2650
    By default this will automatically save screenshots in the working
2651
    directory.
2652
2653
    The automatic names are formatted as screenshotNNN.png.  For example:
2654
    screenshot000.png, screenshot001.png, etc.  Whichever is available first.
2655
2656
    Args:
2657
        file Optional[AnyStr]: File path to save screenshot.
2658
    """
2659
    if name is not None:
2660
        name = _bytes(name)
2661
    lib.TCOD_sys_save_screenshot(name or ffi.NULL)
2662
2663
# custom fullscreen resolution
2664
def sys_force_fullscreen_resolution(width, height):
2665
    """Force a specific resolution in fullscreen.
2666
2667
    Will use the smallest available resolution so that:
2668
2669
    * resolution width >= width and
2670
      resolution width >= root console width * font char width
2671
    * resolution height >= height and
2672
      resolution height >= root console height * font char height
2673
2674
    Args:
2675
        width (int): The desired resolution width.
2676
        height (int): The desired resolution height.
2677
    """
2678
    lib.TCOD_sys_force_fullscreen_resolution(width, height)
2679
2680
def sys_get_current_resolution():
2681
    """Return the current resolution as (width, height)
2682
2683
    Returns:
2684
        Tuple[int,int]: The current resolution.
2685
    """
2686
    w = ffi.new('int *')
2687
    h = ffi.new('int *')
2688
    lib.TCOD_sys_get_current_resolution(w, h)
2689
    return w[0], h[0]
2690
2691
def sys_get_char_size():
2692
    """Return the current fonts character size as (width, height)
2693
2694
    Returns:
2695
        Tuple[int,int]: The current font glyph size in (width, height)
2696
    """
2697
    w = ffi.new('int *')
2698
    h = ffi.new('int *')
2699
    lib.TCOD_sys_get_char_size(w, h)
2700
    return w[0], h[0]
2701
2702
# update font bitmap
2703
def sys_update_char(asciiCode, fontx, fonty, img, x, y):
2704
    """Dynamically update the current frot with img.
2705
2706
    All cells using this asciiCode will be updated
2707
    at the next call to :any:`tcod.console_flush`.
2708
2709
    Args:
2710
        asciiCode (int): Ascii code corresponding to the character to update.
2711
        fontx (int): Left coordinate of the character
2712
                     in the bitmap font (in tiles)
2713
        fonty (int): Top coordinate of the character
2714
                     in the bitmap font (in tiles)
2715
        img (Image): An image containing the new character bitmap.
2716
        x (int): Left pixel of the character in the image.
2717
        y (int): Top pixel of the character in the image.
2718
    """
2719
    lib.TCOD_sys_update_char(_int(asciiCode), fontx, fonty, img, x, y)
2720
2721
def sys_register_SDL_renderer(callback):
2722
    """Register a custom randering function with libtcod.
2723
2724
    Note:
2725
        This callback will only be called by the SDL renderer.
2726
2727
    The callack will receive a :any:`CData <ffi-cdata>` void* to an
2728
    SDL_Surface* struct.
2729
2730
    The callback is called on every call to :any:`tcod.console_flush`.
2731
2732
    Args:
2733
        callback Callable[[CData], None]:
2734
            A function which takes a single argument.
2735
    """
2736
    with _PropagateException() as propagate:
2737
        @ffi.def_extern(onerror=propagate)
2738
        def _pycall_sdl_hook(sdl_surface):
2739
            callback(sdl_surface)
2740
        lib.TCOD_sys_register_SDL_renderer(lib._pycall_sdl_hook)
2741
2742
def sys_check_for_event(mask, k, m):
2743
    """Check for and return an event.
2744
2745
    Args:
2746
        mask (int): :any:`Event types` to wait for.
2747
        k (Optional[Key]): A tcod.Key instance which might be updated with
2748
                           an event.  Can be None.
2749
        m (Optional[Mouse]): A tcod.Mouse instance which might be updated
2750
                             with an event.  Can be None.
2751
    """
2752
    return lib.TCOD_sys_check_for_event(
2753
        mask, k.cdata if k else ffi.NULL, m.cdata if m else ffi.NULL)
2754
2755
def sys_wait_for_event(mask, k, m, flush):
2756
    """Wait for an event then return.
2757
2758
    If flush is True then the buffer will be cleared before waiting. Otherwise
2759
    each available event will be returned in the order they're recieved.
2760
2761
    Args:
2762
        mask (int): :any:`Event types` to wait for.
2763
        k (Optional[Key]): A tcod.Key instance which might be updated with
2764
                           an event.  Can be None.
2765
        m (Optional[Mouse]): A tcod.Mouse instance which might be updated
2766
                             with an event.  Can be None.
2767
        flush (bool): Clear the event buffer before waiting.
2768
    """
2769
    return lib.TCOD_sys_wait_for_event(
2770
        mask, k.cdata if k else ffi.NULL, m.cdata if m else ffi.NULL, flush)
2771
2772
def sys_clipboard_set(text):
2773
    return lib.TCOD_sys_clipboard_set(text.encode('utf-8'))
2774
2775
def sys_clipboard_get():
2776
    return ffi.string(lib.TCOD_sys_clipboard_get()).decode('utf-8')
2777