Esempio n. 1
0
    def draw_artifact_card(self, metadata, card, svg, svg_group):
        id = metadata['id']
        name = card[0]
        attrs = card[1]

        # Validate attributes
        self.validate_attrs(name, attrs)

        # Build list of template ids and then load from svg file.
        svg_ids = []
        svg_ids.append('artifact-title')
        svg_ids.extend(['icon-star-{0}'.format(n) for n in [1,2,3]])
        svg_ids.append('artifact-description')
        svg_ids.append('artifact-extra-action')
        svg_ids.append('artifact-bonus')
        svg_ids.append('artifact-bonus-border')
        svg_ids.append('artifact-flavor')
        #svg_ids.append('separator')
        svg_ids.extend(['op-{0}'.format(op) for op in valid_ops])
        svg.load_ids(WovenArtifactCards.CARD_TEMPLATE, svg_ids)

        # Add Op masters (hidden, used for cloning).
        g_masters = SVG.group('masters')
        g_masters.set_style("display:none")
        SVG.add_node(svg_group, g_masters)
        for e in [
                'op-tapestry', 'op-eye', 'op-mmove', 'op-thread', 'op-action',
                ]:
            svg.add_loaded_element(g_masters, e)

        # Draw artifact title.
        title = svg.add_loaded_element(svg_group, 'artifact-title')
        SVG.set_text(title, name)

        self.draw_description(attrs, 'description', svg, svg_group)
        svg.add_loaded_element(svg_group, 'artifact-extra-action')
        self.draw_bonus(attrs, 'bonus', svg, svg_group)
        self.draw_flavor(attrs, 'flavor', svg, svg_group)
        
        #svg.add_loaded_element(svg_group, 'separator')

        # Draw alternate action.
        #svg.add_loaded_element(svg_group, 'op-{0}'.format(attrs['op']))

        self.draw_vp(attrs['vp'], svg, svg_group)
Esempio n. 2
0
    def pre_card(self):
        if self._called_pre_card:
            raise Exception("pre_card() should only be called once per card")

        if self.curr_filename == '':
            self.curr_file += 1
            self.curr_filename = 'out{0:02d}'.format(self.curr_file)
            self.__create_svg_file()
            self.curr_card += 1

        layer = self.svg.add_inkscape_layer(
            'card{0:02d}'.format(self.curr_card),
            "Card {0}".format(self.curr_card))

        cut_line = SVG.rect_round(0, 0, 0, self.card_width, self.card_height,
                                  3)
        style = Style()
        style.set('fill', "#ffffff")
        style.set('stroke', "none")
        cut_line.set_style(style)
        SVG.add_node(layer, cut_line)

        self._called_pre_card = True
        return (self.svg, layer)
class Sketch:
    def __init__(self, width=600, height=600):
        self.width = width
        self.height = height
        self.svg = SVG(viewBox=f"0 0 {width} {height}",
                       style="stroke: black; fill: none;")
        self.background("white")
        self.tcount = 0

    def background(self, color):
        self.svg.rect(x=0,
                      y=0,
                      width=self.width,
                      height=self.height,
                      fill=color,
                      stroke="none")

    def circle(self, x, y, d):
        self.svg.circle(cx=x, cy=y, r=d / 2)

    def line(self, x1, y1, x2, y2, **kwargs):
        self.svg.line(x1=x1, y1=y1, x2=x2, y2=y2, **kwargs)

    def rect(self, x, y, w, h):
        self.svg.rect(x=x, y=y, width=w, height=h)

    def path(self, d):
        self.svg.path(d=d, stroke="black")

    def show(self, node, margin=0, scale=False, size=260):
        if margin or scale:
            s = (self.width - 2 * margin) / size if scale else 1
            g = Node(
                "g",
                transform=f"translate({margin}, {margin}) scale({s}, {s})")
            g.add_node(node)
            self.svg.add_node(g)
        else:
            self.svg.add_node(node)

    def transform(self, node, dx, dy, sx, sy):
        g = Node("g", transform=f"translate({dx}, {dy}) scale({sx}, {sy})")
        g.add_node(node)
        return g

    def thumbnail(self, shape):
        size = 260 / 4
        x = self.tcount * (size + 20) + 20
        y = 10
        self.show(self.transform(shape, x, y, 0.25, 0.25))
        self.tcount += 1

    def clear():
        self.tcount = 0

    def tostring(self):
        return self.svg.tostring()

    def render(self, code):
        g = self.get_globals()
        exec(code, g, g)
        return self.tostring()

    def show_grid(self):
        size = 100
        for y in range(0, self.height + 1, size):
            self.line(0, y, self.width, y, stroke="#ccc")

        for x in range(0, self.width + 1, size):
            self.line(x, 0, x, self.height, stroke="#ccc")

    def get_globals(self):
        return {
            "circle": self.circle,
            "rect": self.rect,
            "line": self.line,
            "path": self.path,
            "width": self.width,
            "height": self.height,
            "show_grid": self.show_grid,
            "Node": Node,
            "show": self.show,
            "thumbnail": self.thumbnail,
            **g.exports
        }
Esempio n. 4
0
    def draw_pattern(self, id, pattern_raw, element, svg_group):
        pattern = [x.split() for x in pattern_raw]
        pheight = len(pattern)
        if pheight == 0:
            raise Exception("Missing pattern for {0}".format(id))
        if pheight > 3:
            raise Exception("Tall pattern for {0}".format(id))
        pwidth = len(pattern[0])

        # Max pattern size that fits on the card.
        max_width = 7
        max_height = 3

        # Center of pattern area.
        pcenter_x = self.width / 2
        pcenter_y = 22.4

        # Size and spacing for each box in pattern.
        box_size = 5.5
        box_spacing = 7

        # Upper left corner of pattern area
        px0 = pcenter_x - (((max_width - 1) * box_spacing) + box_size) / 2
        py0 = pcenter_y - (((max_height - 1) * box_spacing) + box_size) / 2

        # Calc offsets to center the patterns that are less than max size.
        if pwidth % 2 == 0:
            px0 += box_spacing / 2
            max_width = 6
        else:
            max_width = 7
        if pheight % 2 == 0:
            py0 += box_spacing / 2
            max_height = 2
        else:
            max_height = 3

        dot_x0 = px0 + (box_size / 2)
        dot_y0 = py0 + (box_size / 2)

        # The x,y ranges for this pattern (to center on the card)
        x_begin = int((max_width - pwidth) / 2)
        x_end = x_begin + pwidth
        y_begin = int((max_height - pheight) / 2)
        y_end = y_begin + pheight

        for iy in range(0, max_height):
            for ix in range(0, max_width):
                if ix >= x_begin and ix < x_end and iy >= y_begin and iy < y_end:
                    x = ix * box_spacing
                    y = iy * box_spacing

                    col = ix - x_begin
                    row = iy - y_begin
                    cell = pattern[row][col]
                    if cell == '@':
                        elemaster = '#element-{0}'.format(element)
                        eleclone = SVG.clone(0, elemaster, px0 + x, py0 + y)
                        SVG.add_node(svg_group, eleclone)
                    elif cell == 'X':
                        box = SVG.rect(0, px0 + x, py0 + y, box_size, box_size)

                        style_box = Style()
                        style_box.set_fill("none")
                        style_box.set_stroke("#000000", 0.5)
                        style_box.set('stroke-linecap', "round")
                        style_box.set('stroke-miterlimit', 2)
                        box.set_style(style_box)

                        SVG.add_node(svg_group, box)
                    elif cell == '.':
                        dot = SVG.circle(0, dot_x0 + x, dot_y0 + y, 0.8)

                        style_dot = Style()
                        style_dot.set_fill("#c0c0c0")
                        style_dot.set_stroke("none")
                        dot.set_style(style_dot)

                        SVG.add_node(svg_group, dot)
                    else:
                        raise Exception(
                            "Unrecognized pattern symbol: {0}".format(cell))
Esempio n. 5
0
    def draw_spell_card(self, metadata, card, svg, svg_group):
        id = metadata['id']
        name = card[0]
        attrs = card[1]
        desc = card[2]

        # Validate attributes
        if attrs['category'] != 'blank':
            self.validate_attrs(name, attrs)
        pattern_id = attrs['pattern']
        pattern = self.card_patterns[pattern_id]['pattern']
        if attrs['category'] != 'blank':
            self.record_spell_info(name, pattern, attrs, desc)

        if attrs['category'] != 'blank' and pattern_id != 'blank':
            pe_tag = self.pattern_key(pattern) + '-' + attrs['element']
            if pe_tag in self.pattern_elements:
                raise Exception(
                    'Pattern for "{0:s}" already used for "{1:s}"'.format(
                        name, self.pattern_elements[pe_tag]))
            self.pattern_elements[pe_tag] = name

        # Validate desc
        self.validate_desc(name, desc)

        # Verify pattern matches spell element
        element = attrs['element']
        pelem_data = self.card_patterns[pattern_id]['elements']
        pelems = []
        if pelem_data == "none":
            pelems.append("none")
        else:
            pelems = [elem_map[p] for p in pelem_data]
        if not element in pelems:
            raise Exception(
                "{0:s}: Spell pattern does not match element {1:s}".format(
                    name, element))

        # Build list of template ids and then load from svg file.
        svg_ids = []
        svg_ids.extend(['element-{0}'.format(elem_map[e]) for e in elem_map])
        svg_ids.append('spell-title')
        svg_ids.append('spell-pattern-border')
        svg_ids.append('spell-description')
        svg_ids.append('spell-id')
        svg_ids.extend(['icon-star-{0}'.format(n) for n in [1, 2, 3]])
        svg_ids.append('icon-vp')
        svg_ids.append('spell-flavor')
        svg_ids.append('separator')
        svg_ids.extend(['op-{0}'.format(op) for op in valid_ops])
        svg.load_ids(WovenSpellCards.CARD_TEMPLATE, svg_ids)

        # Add Element and Op masters (hidden, used for cloning).
        g_masters = SVG.group('masters')
        g_masters.set_style("display:none")
        SVG.add_node(svg_group, g_masters)
        for e in [
                'op-tapestry',
                'op-eye',
                'op-mmove',
                'op-thread',
                'op-action',
                'element-air',
                'element-earth',
                'element-fire',
                'element-water',
        ]:
            svg.add_loaded_element(g_masters, e)

        if attrs['category'] != 'blank':
            # Draw spell title.
            title = svg.add_loaded_element(svg_group, 'spell-title')
            SVG.set_text(title, name)

            # Draw elements in title bar
            elemaster = '#element-{0}'.format(element)
            SVG.add_node(svg_group, SVG.clone(0, elemaster, 4, 4))
            SVG.add_node(svg_group, SVG.clone(0, elemaster, 54, 4))

            # Draw spell id.
            id_text = svg.add_loaded_element(svg_group, 'spell-id')
            SVG.set_text(
                id_text, "{0:d}/{1:d}".format(spell_card_revision,
                                              attrs['id']))

            # Draw flavor text (if present).
            if 'flavor' in attrs:
                flavor_text = svg.add_loaded_element(svg_group, 'spell-flavor')
                SVG.set_text(flavor_text, attrs['flavor'])

            svg.add_loaded_element(svg_group, 'separator')

            # Draw alternate action.
            svg.add_loaded_element(svg_group, 'op-{0}'.format(attrs['op']))

        # Add spell pattern.
        self.draw_pattern(pattern_id, pattern, element, svg_group)
        svg.add_loaded_element(svg_group, 'spell-pattern-border')

        if attrs['category'] != 'blank':
            self.draw_description(attrs['id'], desc, svg, svg_group)

        self.draw_vp(attrs['vp'], svg, svg_group)