Initial commit

master
entuland 2018-06-20 00:59:31 +02:00
commit 0835ad092a
14 changed files with 2231 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 entuland
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

77
README.md Normal file
View File

@ -0,0 +1,77 @@
# Rhotator Screwdriver (rhotator)
A different twist at Minetest screwdriving.
Developed and tested on Minetest 0.4.16 - try in other versions at your own risk :)
If you like my contributions you may consider reading http://entuland.com/en/support-entuland
# Why yet another screwdriver?
The default screwdriver included in minetest_game, as well as any other screwdriver mod I have found, operate differently depending on the node's direction and rotation. This means that any given click on a node may produce different results which you cannot predict at a glance.
The Rhotator Screwdriver uses a different approach: the direction and orientation of the node make absolutely no difference.
These are the factors that affect the results of a click:
- the face you point at
- where on that face you point
- what button you click
You will always be able to predict exactly the effect of the Rhotator Screwdriver.
Four consecutive clicks of the same button on the same position will always bring the node back to its original direction / orientation.
### Why is it called "Rhotator" and not "Rotator"?
In mathematics, the greek letter *Rho* is used to indicate some stuff associated to certain types of matrices. Since I'm using matrices to compute the various rotations in the game I thought about including it in the mod's name to reduce the chance of naming conflicts.
# Appearance
Here you can see the Rhotator Screwdriver along with the Testing Cube.
*The testing cube is just an addition to help practicing with this screwdriver.*
The Rhotator Screwdriver will rotate ANY node where `paramtype2 == "facedir"`
More node types will be supported in the future.
![Preview](/screenshots/preview.png)
# Usage
Pretty simple:
- a right click will rotate the face you're pointing in clockwise direction
- the arrow in the Testing Cube shows how the face will rotate when right-clicked
- `RT` in the tool stands for `rotate`
- a left click will rotate the node as if you "pushed" the closest edge you're pointing at
- the colored edges in the Testing Cube indicate the color of the face you'll see when left-clicking near that edge
- `PS` in the tool stands for `push`
The left-click interaction area is not limited to the edges you can see in the Testing Cube. In reality you can click anywhere in a triangle like this (highlighted here just for convenience, you won't see anything like this in the game):
![Interaction triangle](/screenshots/interaction-triangle.png)
# Non-full nodes
Nodes that don't occupy a full cube (such as slabs and stairs) can still be rotated properly, it's enough that you pay attention to the direction of the part you're pointing at - the "stomp" parts of the stairs will behave as the "top" face, the "rise" parts will behave as the "front" face. With the Rhotator Screwdriver there never really is a "top" or a "front" or whatever: the only thing that matters is the face you're pointing at.
# Crafting
Rhotator Screwdriver: a stick and a copper ingot;
![Screwdriver crafting](/screenshots/screwdriver-crafting.png)
Rhotator Testing Cube: a Rhotator Screwdriver and any wool block
![Testing cube crafting](/screenshots/testcube-crafting.png)
# Usage feedback
At the beginning of [init.lua](/init.lua) there is a line reading `local enable_chat_notifications = false` - set it to `true` if you want the tool to send you chat messages about the operations it performs and in particular about nodes that aren't currently supported (if you enable the chat notifications you'll receive messages like these:
- Pushed closest edge (left click)
- Rotated pointed face (right click)
- Cannot rotate node with paramtype2 == glasslikeliquidlevel

268
init.lua Normal file
View File

@ -0,0 +1,268 @@
rhotator = {}
rhotator.mod_path = minetest.get_modpath(minetest.get_current_modname())
local matrix = dofile(rhotator.mod_path .. "/lib/matrix.lua")
local enable_chat_notifications = true
-- constants
local POS = {}
local NEG = {}
POS.Y = 0
POS.Z = 1
NEG.Z = 2
POS.X = 3
NEG.X = 4
NEG.Y = 5
PRIMARY_BTN = 1
SECONDARY_BTN = 2
-- helper tables
local rot_matrices = {}
local dir_matrices = {}
-- init
local function init_transforms()
local rot = {}
local dir = {}
-- no rotation
rot[0] = matrix{{ 1, 0, 0},
{ 0, 1, 0},
{ 0, 0, 1}}
-- 90 degrees clockwise
rot[1] = matrix{{ 0, 0, 1},
{ 0, 1, 0},
{ -1, 0, 0}}
-- 180 degrees
rot[2] = matrix{{ -1, 0, 0},
{ 0, 1, 0},
{ 0, 0, -1}}
-- 270 degrees clockwise
rot[3] = matrix{{ 0, 0, -1},
{ 0, 1, 0},
{ 1, 0, 0}}
rot_matrices = rot
-- directions
-- Y+
dir[0] = matrix{{ 1, 0, 0},
{ 0, 1, 0},
{ 0, 0, 1}}
-- Z+
dir[1] = matrix{{ 1, 0, 0},
{ 0, 0, -1},
{ 0, 1, 0}}
-- Z-
dir[2] = matrix{{ 1, 0, 0},
{ 0, 0, 1},
{ 0, -1, 0}}
-- X+
dir[3] = matrix{{ 0, 1, 0},
{ -1, 0, 0},
{ 0, 0, 1}}
-- X-
dir[4] = matrix{{ 0, -1, 0},
{ 1, 0, 0},
{ 0, 0, 1}}
-- Y-
dir[5] = matrix{{ -1, 0, 0},
{ 0, -1, 0},
{ 0, 0, 1}}
dir_matrices = dir
rhotator._facedir_transform = {}
rhotator._matrix_to_facedir = {}
for facedir = 0, 23 do
local direction = math.floor(facedir / 4)
local rotation = facedir % 4
local transform = dir[direction] * rot[rotation]
rhotator._facedir_transform[facedir] = transform
rhotator._matrix_to_facedir[transform:tostring():gsub("%-0", "0")] = facedir
end
end
init_transforms()
-- helper functions
local function cross_product(a, b)
return vector.new(
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x
)
end
local function extract_main_axis(dir)
local axes = { "x", "y", "z" }
local axis = 1
local max = 0
for i = 1, 3 do
local abs = math.abs(dir[axes[i]])
if abs > max then
axis = i
max = abs
end
end
return axes[axis]
end
local function sign(num)
return (num < 0) and -1 or 1
end
local function extract_unit_vectors(player, pointed_thing)
assert(pointed_thing.type == "node")
local abs_face_pos = minetest.pointed_thing_to_face_pos(player, pointed_thing)
local pos = pointed_thing.under
local f = vector.subtract(abs_face_pos, pos)
local facedir = 0
local primary = 0
local m1, m2
local unit_direction = vector.new()
local unit_rotation = vector.new()
local rotation = vector.new()
if math.abs(f.y) == 0.5 then
unit_direction.y = sign(f.y)
rotation.x = f.x
rotation.z = f.z
elseif math.abs(f.z) == 0.5 then
unit_direction.z = sign(f.z)
rotation.x = f.x
rotation.y = f.y
else
unit_direction.x = sign(f.x)
rotation.y = f.y
rotation.z = f.z
end
local main_axis = extract_main_axis(rotation)
unit_rotation[main_axis] = sign(rotation[main_axis])
return {
back = unit_direction,
wrap = unit_rotation,
thumb = cross_product(unit_direction, unit_rotation),
}
end
local function get_facedir_transform(facedir)
return rhotator._facedir_transform[facedir] or rhotator._facedir_transform[0]
end
local function matrix_to_facedir(mtx)
local key = mtx:tostring():gsub("%-0", "0")
if not rhotator._matrix_to_facedir[key] then
error("Unsupported matrix:\n" .. key)
end
return rhotator._matrix_to_facedir[key]
end
local function notify(playername, message)
if enable_chat_notifications then
minetest.chat_send_player(playername, "[rhotator] " .. message)
end
end
local function vector_to_dir_index(vec)
local main_axis = extract_main_axis(vec)
if main_axis == "x" then return (vec.x > 0) and POS.X or NEG.X end
if main_axis == "z" then return (vec.z > 0) and POS.Z or NEG.Z end
return (vec.y > 0) and POS.Y or NEG.Y
end
-- rhotator main
local function interact(itemstack, player, pointed_thing, click)
if pointed_thing.type ~= "node" then
return
end
local node = minetest.get_node_or_nil(pointed_thing.under)
local def = minetest.registered_nodes[node.name]
if not node or not def then
notify(player:get_player_name(), "Unsupported node type: " .. node.name)
return
end
if def.paramtype2 ~= "facedir" then
notify(player:get_player_name(), "Cannot rotate node with paramtype2 == " .. def.paramtype2)
return
end
local unit = extract_unit_vectors(player, pointed_thing)
local transform = false
if click == PRIMARY_BTN then
transform = dir_matrices[vector_to_dir_index(unit.thumb)]
notify(player:get_player_name(), "Pushed closest edge (left click)")
else
transform = dir_matrices[vector_to_dir_index(unit.back)]
notify(player:get_player_name(), "Rotated pointed face (right click)")
end
local start = get_facedir_transform(node.param2)
local stop = transform * rot_matrices[1] * transform:invert() * start
minetest.set_node(pointed_thing.under,{
name = node.name,
param1 = node.param1,
param2 = matrix_to_facedir(stop),
})
end
minetest.register_tool("rhotator:screwdriver", {
description = "Rhotator Screwdriver (left-click pushes edge, right-click rotates face)",
inventory_image = "rhotator.png",
on_use = function(itemstack, player, pointed_thing)
interact(itemstack, player, pointed_thing, PRIMARY_BTN)
return itemstack
end,
on_place = function(itemstack, player, pointed_thing)
interact(itemstack, player, pointed_thing, SECONDARY_BTN)
return itemstack
end,
})
minetest.register_craft({
output = "rhotator:screwdriver",
recipe = {
{"default:copper_ingot"},
{"group:stick"}
}
})
minetest.register_node("rhotator:cube", {
drawtype = "mesh",
mesh = "rhotocube.obj",
tiles = { "rhotocube.png" },
paramtype2 = "facedir",
description = "Rhotator Testing Cube",
walkable = true,
groups = { snappy = 2, choppy = 2, oddly_breakable_by_hand = 3 },
})
minetest.register_craft({
output = "rhotator:cube",
recipe = {
{"group:wool"},
{"rhotator:screwdriver"},
}
})

1251
lib/matrix.lua Normal file

File diff suppressed because it is too large Load Diff

1
mod.conf Normal file
View File

@ -0,0 +1 @@
name = rhotator

43
models/rhotocube.obj Normal file
View File

@ -0,0 +1,43 @@
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.499999 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 0.500000 0.500000
vt 0.666667 -0.000000
vt 0.666667 0.500000
vt 0.333333 0.500000
vt 0.333333 -0.000000
vt 0.666667 1.000000
vt 0.333333 1.000000
vt 0.333333 0.500000
vt 0.666667 0.500000
vt 0.333333 0.500000
vt 0.333333 1.000000
vt -0.000000 1.000000
vt 0.000000 0.500000
vt 1.000000 0.000000
vt 1.000000 0.500000
vt 0.666667 0.500000
vt 0.666667 -0.000000
vt 0.333333 -0.000000
vt 0.000000 0.500000
vt -0.000000 -0.000000
vt 0.666667 0.500000
vt 1.000000 0.500000
vt 1.000000 1.000000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 -0.0000
vn 0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 0.0000
vn -0.0000 0.0000 1.0000
s off
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 8/6/2 7/7/2 6/8/2
f 1/9/3 5/10/3 6/11/3 2/12/3
f 2/13/4 6/14/4 7/15/4 3/16/4
f 3/17/5 7/7/5 8/18/5 4/19/5
f 5/5/6 1/20/6 4/21/6 8/22/6

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

BIN
screenshots/preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
textures/rhotator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

BIN
textures/rhotocube.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

568
textures/rhotocube.svg Normal file
View File

@ -0,0 +1,568 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="793.70081"
height="1122.5197"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
sodipodi:docname="rhotocube.svg"
inkscape:version="0.92.1 r15371">
<defs
id="defs2">
<marker
inkscape:stockid="EmptyTriangleOutM"
orient="auto"
refY="0.0"
refX="0.0"
id="EmptyTriangleOutM"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4789"
d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
style="fill-rule:evenodd;fill:#ffffff;stroke:#000000;stroke-width:1pt;stroke-opacity:0.99595139;fill-opacity:1"
transform="scale(0.4) translate(-4.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lend"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path4647"
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:0.99595139;fill:#ffffff;fill-opacity:1"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) rotate(180) translate(1,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="221.73519"
inkscape:cy="671.72158"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-nodes="false"
inkscape:snap-others="false"
showguides="true"
inkscape:guide-bbox="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid4513"
empspacing="4"
dotted="false" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Livello 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.98758966;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="rect6076"
width="25.4"
height="16.933338"
x="47.625"
y="116.02499"
inkscape:export-xdpi="192"
inkscape:export-ydpi="192" />
<rect
style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
id="rect4496"
width="8.4666662"
height="8.4666653"
x="-56.091667"
y="-124.49165"
ry="0"
rx="0"
transform="scale(-1)" />
<g
id="g4579"
transform="rotate(-180,51.858333,120.25833)"
style="stroke:#ffffff;stroke-opacity:0.99595141;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4517"
d="m 47.625,116.02499 h 8.466667 l -1.058334,1.05834 h -6.35 z"
style="opacity:1;fill:#ff00ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
style="opacity:1;fill:#00ff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 47.625,124.49167 h 8.466667 l -1.058334,-1.05834 h -6.35 z"
id="path4519"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:1;fill:#0000ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="M 47.624993,124.49166 V 116.025 l 1.05834,1.05833 v 6.35 z"
id="path4521"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4523"
d="M 56.091673,124.49166 V 116.025 l -1.05834,1.05833 v 6.35 z"
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
</g>
<rect
rx="0"
ry="0"
y="-124.49165"
x="-64.558334"
height="8.4666653"
width="8.4666662"
id="rect4525"
style="opacity:1;fill:#ff00ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
transform="scale(-1)" />
<g
id="g4585"
transform="rotate(-180,60.325,120.25833)"
style="stroke:#ffffff;stroke-opacity:0.99595141;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none">
<path
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 56.091667,116.02499 h 8.466667 L 63.5,117.08333 h -6.35 z"
id="path4527"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4529"
d="m 56.091667,124.49167 h 8.466667 L 63.5,123.43333 h -6.35 z"
style="opacity:1;fill:#0000ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4531"
d="M 56.09166,124.49166 V 116.025 l 1.05834,1.05833 v 6.35 z"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="M 64.55834,124.49166 V 116.025 L 63.5,117.08333 v 6.35 z"
id="path4533"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
<rect
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
id="rect4535"
width="8.4666662"
height="8.4666653"
x="-73.025002"
y="-124.49164"
ry="0"
rx="0"
transform="scale(-1)" />
<g
id="g4591"
transform="rotate(-180,68.791667,120.25833)"
style="stroke:#ffffff;stroke-opacity:0.99595141;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4537"
d="m 64.558334,116.02499 h 8.466667 l -1.058334,1.05834 h -6.35 z"
style="opacity:1;fill:#ff00ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
style="opacity:1;fill:#00ff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 64.558334,124.49167 h 8.466667 l -1.058334,-1.05834 h -6.35 z"
id="path4539"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="M 64.558327,124.49166 V 116.025 l 1.05834,1.05833 v 6.35 z"
id="path4541"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4543"
d="M 73.025007,124.49166 V 116.025 l -1.05834,1.05833 v 6.35 z"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
</g>
<rect
rx="0"
ry="0"
y="-132.9583"
x="-56.091667"
height="8.4666653"
width="8.4666662"
id="rect4545"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
transform="scale(-1)" />
<g
id="g4597"
transform="rotate(-180,51.858333,128.72499)"
style="stroke:#ffffff;stroke-opacity:0.99595141;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none">
<path
style="opacity:1;fill:#ff00ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 47.625,124.49165 h 8.466667 l -1.058334,1.05834 h -6.35 z"
id="path4547"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4549"
d="m 47.625,132.95833 h 8.466667 l -1.058334,-1.05834 h -6.35 z"
style="opacity:1;fill:#00ff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4551"
d="m 47.624993,132.95832 v -8.46666 l 1.05834,1.05833 v 6.35 z"
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
style="opacity:1;fill:#0000ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 56.091673,132.95832 v -8.46666 l -1.05834,1.05833 v 6.35 z"
id="path4553"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
<rect
style="opacity:1;fill:#00ff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
id="rect4555"
width="8.4666662"
height="8.4666653"
x="-64.558334"
y="-132.9583"
ry="0"
rx="0"
transform="scale(-1)" />
<g
id="g4603"
transform="rotate(-180,60.325,128.72499)"
style="stroke:#ffffff;stroke-opacity:0.99595141;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4557"
d="m 56.091667,124.49165 h 8.466667 L 63.5,125.54999 h -6.35 z"
style="opacity:1;fill:#0000ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
style="opacity:1;fill:#ffff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 56.091667,132.95833 h 8.466667 L 63.5,131.89999 h -6.35 z"
id="path4559"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 56.09166,132.95832 v -8.46666 l 1.05834,1.05833 v 6.35 z"
id="path4561"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4563"
d="m 64.55834,132.95832 v -8.46666 L 63.5,125.54999 v 6.35 z"
style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
</g>
<rect
rx="0"
ry="0"
y="-132.9583"
x="-73.025002"
height="8.4666653"
width="8.4666662"
id="rect4565"
style="opacity:1;fill:#0000ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
transform="scale(-1)" />
<g
id="g4609"
transform="rotate(-180,68.791667,128.72499)"
style="stroke:#ffffff;stroke-opacity:0.99595141;stroke-width:0.26458333;stroke-miterlimit:4;stroke-dasharray:none">
<path
style="opacity:1;fill:#ff00ff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 64.558334,124.49165 h 8.466667 l -1.058334,1.05834 h -6.35 z"
id="path4567"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4569"
d="m 64.558334,132.95833 h 8.466667 l -1.058334,-1.05834 h -6.35 z"
style="opacity:1;fill:#00ff00;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4571"
d="m 64.558327,132.95832 v -8.46666 l 1.05834,1.05833 v 6.35 z"
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
d="m 73.025007,132.95832 v -8.46666 l -1.05834,1.05833 v 6.35 z"
id="path4573"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
<image
y="98.033318"
x="47.625"
id="image4619"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABACAYAAADlNHIOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gYSDR8sFVKLswAAAB1pVFh0Q29tbWVudAAAAAAAQ3Jl
YXRlZCB3aXRoIEdJTVBkLmUHAAADFUlEQVR42u1b7ZKFIAiVxvd/ZfbHbq25gGCK3RVm7kzjpcKD
8nEqSIiYFgpCWiuLDThSSDggHBASDggHhCyRfB0BUw1wRVKtj/g9duqDUF0Q14TE62Nq62t0RF2F
udyUNbrc1DMLYGmZdkyyXOGYExhIcDumgK1BpMYwoV4X29OidKgpWuC0hyDqqucdHVoKCrwSbE+B
jtvVuyZyQAPc2Wsqq2J7V4eJpnFqVUvjq1f1GQi4gNDvAC6oWSxey250JWxtEp2/A1pZRAL76XKY
JD27yGsahyljcGPOYGoro7fmltuavdjQut5qZSNN6FHolGQkBSwHam8f8EfvxwBLJP0DorIqJyEK
Ojro6OCCQsIB20pW1fdUUuay1KBStEygZeLkxmdVQz0cpWX6R7MQrq/GjU+q3SmCzbtDPmmuGXSX
vQ9wbLaomt+73tcQwXNzQOmEBZ1u6YTVzdaM6Wf1MpDuTu2SgT09x+tzDVcrT8xwTO/0s8n10rOA
BSGKS9IzQJem9WT6h+nOi3mg1/A3AyE4zG7fzAmzN3S7D+Dc7xRqynh+Hr/1IU3f/IKMCypiZwkH
hAP2FsC09jke4AsQiB0QISgkHBAOCAkH7Cf5tyUmmkSydRaayg695gnI9vCyntEALdPO6ZeEcf2/
9N5Qrm2CJNelyOhIDoTq2Hzh3jGDATWAJdCWDzO463HX/7wQxK0QbKz6QcKRwS3CjjvvGIFHSukD
3sp0WBtgA/8WgnqBN8V5jaPAesJYA7TveFp2jOSE3LvrUemIx8CB7/Ya/TI49Y3Z0BAUoWe3PoBL
tk47RftwXnvuxYZqYzoYdoFGF1qxrLcPMBrwtA+gwo00fpWnQUcHHR05ICQcsK1kTT+EivEplMNS
A1JXch62A5CZI3rNfbkBd7DLn1sIokpu18Z0uQHzP5M+LBg4z/0lBswDX8wBFAaWhmtomF5uQF+e
0OQKExknUfHL6YmFq//Jrji04HMheQepwXf7RoyjoWFj8N37AGDKcLd8CMQx+jvB3QHdT7Q+ML5b
ytCgIv6ZhAPCAXvLFwofumwLVu7LAAAAAElFTkSuQmCC
"
preserveAspectRatio="none"
height="16.933338"
width="25.4" />
<g
id="g6074">
<g
id="g6024">
<path
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.4887619;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="path4624"
sodipodi:type="arc"
sodipodi:cx="60.32415"
sodipodi:cy="120.25902"
sodipodi:rx="1.8731251"
sodipodi:ry="1.8715475"
sodipodi:start="0"
sodipodi:end="5.4462849"
sodipodi:open="true"
d="m 62.197275,120.25902 a 1.8731251,1.8715475 0 0 1 -1.484073,1.83073 1.8731251,1.8715475 0 0 1 -2.100563,-1.07024 1.8731251,1.8715475 0 0 1 0.611491,-2.27531 1.8731251,1.8715475 0 0 1 2.354579,0.12506" />
<path
sodipodi:type="star"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25464383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="path6020"
sodipodi:sides="3"
sodipodi:cx="61.567265"
sodipodi:cy="118.84226"
sodipodi:r1="0.79779702"
sodipodi:r2="1.5294462"
sodipodi:arg1="0.58222612"
sodipodi:arg2="1.6294236"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 62.233617,119.28096 -1.379451,-0.081 0.759844,-1.15415 z"
inkscape:transform-center-x="-0.01153964"
inkscape:transform-center-y="-0.061119819" />
</g>
<g
transform="translate(-8.4652927,4.788369e-6)"
id="g6030">
<path
d="m 62.197275,120.25902 a 1.8731251,1.8715475 0 0 1 -1.484073,1.83073 1.8731251,1.8715475 0 0 1 -2.100563,-1.07024 1.8731251,1.8715475 0 0 1 0.611491,-2.27531 1.8731251,1.8715475 0 0 1 2.354579,0.12506"
sodipodi:open="true"
sodipodi:end="5.4462849"
sodipodi:start="0"
sodipodi:ry="1.8715475"
sodipodi:rx="1.8731251"
sodipodi:cy="120.25902"
sodipodi:cx="60.32415"
sodipodi:type="arc"
id="path6026"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.4887619;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139" />
<path
inkscape:transform-center-y="-0.061119819"
inkscape:transform-center-x="-0.01153964"
d="m 62.233617,119.28096 -1.379451,-0.081 0.759844,-1.15415 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="1.6294236"
sodipodi:arg1="0.58222612"
sodipodi:r2="1.5294462"
sodipodi:r1="0.79779702"
sodipodi:cy="118.84226"
sodipodi:cx="61.567265"
sodipodi:sides="3"
id="path6028"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25464383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
sodipodi:type="star" />
</g>
<g
id="g6036"
transform="translate(8.4620276,4.788369e-6)">
<path
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.4887619;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="path6032"
sodipodi:type="arc"
sodipodi:cx="60.32415"
sodipodi:cy="120.25902"
sodipodi:rx="1.8731251"
sodipodi:ry="1.8715475"
sodipodi:start="0"
sodipodi:end="5.4462849"
sodipodi:open="true"
d="m 62.197275,120.25902 a 1.8731251,1.8715475 0 0 1 -1.484073,1.83073 1.8731251,1.8715475 0 0 1 -2.100563,-1.07024 1.8731251,1.8715475 0 0 1 0.611491,-2.27531 1.8731251,1.8715475 0 0 1 2.354579,0.12506" />
<path
sodipodi:type="star"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25464383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="path6034"
sodipodi:sides="3"
sodipodi:cx="61.567265"
sodipodi:cy="118.84226"
sodipodi:r1="0.79779702"
sodipodi:r2="1.5294462"
sodipodi:arg1="0.58222612"
sodipodi:arg2="1.6294236"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 62.233617,119.28096 -1.379451,-0.081 0.759844,-1.15415 z"
inkscape:transform-center-x="-0.01153964"
inkscape:transform-center-y="-0.061119819" />
</g>
<g
transform="translate(0.00137403,8.4666715)"
id="g6042">
<path
d="m 62.197275,120.25902 a 1.8731251,1.8715475 0 0 1 -1.484073,1.83073 1.8731251,1.8715475 0 0 1 -2.100563,-1.07024 1.8731251,1.8715475 0 0 1 0.611491,-2.27531 1.8731251,1.8715475 0 0 1 2.354579,0.12506"
sodipodi:open="true"
sodipodi:end="5.4462849"
sodipodi:start="0"
sodipodi:ry="1.8715475"
sodipodi:rx="1.8731251"
sodipodi:cy="120.25902"
sodipodi:cx="60.32415"
sodipodi:type="arc"
id="path6038"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.4887619;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139" />
<path
inkscape:transform-center-y="-0.061119819"
inkscape:transform-center-x="-0.01153964"
d="m 62.233617,119.28096 -1.379451,-0.081 0.759844,-1.15415 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="1.6294236"
sodipodi:arg1="0.58222612"
sodipodi:r2="1.5294462"
sodipodi:r1="0.79779702"
sodipodi:cy="118.84226"
sodipodi:cx="61.567265"
sodipodi:sides="3"
id="path6040"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25464383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
sodipodi:type="star" />
</g>
<g
id="g6048"
transform="translate(-8.4639187,8.4666763)">
<path
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.4887619;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="path6044"
sodipodi:type="arc"
sodipodi:cx="60.32415"
sodipodi:cy="120.25902"
sodipodi:rx="1.8731251"
sodipodi:ry="1.8715475"
sodipodi:start="0"
sodipodi:end="5.4462849"
sodipodi:open="true"
d="m 62.197275,120.25902 a 1.8731251,1.8715475 0 0 1 -1.484073,1.83073 1.8731251,1.8715475 0 0 1 -2.100563,-1.07024 1.8731251,1.8715475 0 0 1 0.611491,-2.27531 1.8731251,1.8715475 0 0 1 2.354579,0.12506" />
<path
sodipodi:type="star"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.25464383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595139"
id="path6046"
sodipodi:sides="3"
sodipodi:cx="61.567265"
sodipodi:cy="118.84226"
sodipodi:r1="0.79779702"
sodipodi:r2="1.5294462"
sodipodi:arg1="0.58222612"
sodipodi:arg2="1.6294236"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 62.233617,119.28096 -1.379451,-0.081 0.759844,-1.15415 z"
inkscape:transform-center-x="-0.01153964"
inkscape:transform-center-y="-0.061119819" />
</g>
<g
style="fill:#ffffff"
transform="translate(8.4634016,8.4666763)"
id="g6054">
<path
d="m 62.197275,120.25902 a 1.8731251,1.8715475 0 0 1 -1.484073,1.83073 1.8731251,1.8715475 0 0 1 -2.100563,-1.07024 1.8731251,1.8715475 0 0 1 0.611491,-2.27531 1.8731251,1.8715475 0 0 1 2.354579,0.12506"
sodipodi:open="true"
sodipodi:end="5.4462849"
sodipodi:start="0"
sodipodi:ry="1.8715475"
sodipodi:rx="1.8731251"
sodipodi:cy="120.25902"
sodipodi:cx="60.32415"
sodipodi:type="arc"
id="path6050"
style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.4887619;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141" />
<path
inkscape:transform-center-y="-0.061119819"
inkscape:transform-center-x="-0.01153964"
d="m 62.233617,119.28096 -1.379451,-0.081 0.759844,-1.15415 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="1.6294236"
sodipodi:arg1="0.58222612"
sodipodi:r2="1.5294462"
sodipodi:r1="0.79779702"
sodipodi:cy="118.84226"
sodipodi:cx="61.567265"
sodipodi:sides="3"
id="path6052"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.25464383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99595141"
sodipodi:type="star" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 28 KiB