Merge branch 'master' into lwplayer

This commit is contained in:
Aaron Suen 2019-03-02 09:03:08 -05:00
commit 34970e2696
185 changed files with 6894 additions and 0 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
version.lua export-subst

3
.luacheckrc Normal file
View File

@ -0,0 +1,3 @@
globals = {"minetest", "ItemStack", "VoxelArea", "vector", "nodecore", "include", "SecureRandom"}
color = false
quiet = 1

7
.lualocals Normal file
View File

@ -0,0 +1,7 @@
minetest
ItemStack
VoxelArea
vector
nodecore
include
SecureRandom

26
CONTRIBUTING Normal file
View File

@ -0,0 +1,26 @@
========================================================================
To contribute to this project, you must understand and agree to the
terms in this document at the time of contribution.
- A "contribution" consists of all files, patches and changes, source
control commits, comments and other metadata submitted to the project
maintainer(s) for inclusion or other use in the project.
- All contributions must consist only of your own original work, to
which you retain copyright, or to which copyright is not applicable.
- All copyrightable portions must be non-exclusively, perpetually and
irrevocably licensed under the same license terms as the overall
project.
- You will receive attribution in the project's license, in the form of
"Portions (C) ...", which shall cover all portions of all
contributions. You agree that this constitutes adequate attribution
under the terms of the license.
- You may request to be attributed pseudonymously at the time of
submission. Unless otherwise specified, source control metadata
will be used for attribution.
------------------------------------------------------------------------

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright (C)2018 Aaron Suen <warr1024@gmail.com>
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.

32
README Normal file
View File

@ -0,0 +1,32 @@
========================================================================
CORE DESIGN PRINCIPLES
------------------------------------------------------------------------
- Do as much in node-space in the world as possible.
- Minimize use of off-grid entities.
- Avoid encapsulating things in inventories, machines, GUIs.
- Crafting and transforming in-world.
- Minimal set of primitive composable functions.
- Each node should do one job (or one part of a job).
- Only include the most primitive, fungible components.
- Avoid redundant functionality, include fewest possible
different elements.
- Complex emergent gameplay by combining simple nodes.
- Challenging and constrained gameplay.
- Limited inventories, very restricted item storage, e.g. one
stack per node.
- Large, complex machines to design and build for resource
transformations.
- Subtle environmental hazards, like deadfalls and pestilence.
- Rich, subtle interactions.
- Digging, placing, punching and battering.
- Different effects from different tools (including empty hand).
- Different faces of node may have different effects.
- Focus on puzzle-oriented single-player/cooperative gameplay.
- Avoid dependence on action, combat, PvP.
- Slow-moving hazards, players have a chance to think and plan.
- Acessible for slow reflexes, slow networks, mobile devices.
........................................................................
========================================================================

85
docs/longterm.txt Normal file
View File

@ -0,0 +1,85 @@
========================================================================
LONG-TERM DESIGN IDEAS
------------------------------------------------------------------------
NEW CONTENT
- New materials to craft with.
- Dungeon materials, stonework?
- Decorations for dungeons
- Tree sap from stumps? Resin? Rubber? Shellac?
- Small plants? Reeds? Mallows?
- Sea stars, sponges, anenome, coral, other underwater things?
- Fungi, esp. tree-destroying ones, blight?
- Oil, natural gas? Fossils and fossil fuels?
- Geode, hydra crystals, radioactives?
- Shipwrecks or alien tech
- Spice worms
- Non-portable things, like "spawners" or wormholes
- Lightning, meteor strikes?
- Tubers and taproots, cacti, and other "defensive" plantlife
- System for transporting cargo.
- Trains of minecarts?
- Conveyors, elevators?
- Tool level differences.
- Advanced tools are NOT just the same as regular tools with
certain buffs.
- Different metals and materials require different processes.
Top-tier tools, e.g. diamond-tipped, are very different from
metal/stone/wood, require new processes.
- Higher-tier tools may "silk touch" and skip certain transforms
e.g. pick up stone as non-loose cobble or raw stone, so
players have a way to get some things in inventory.
- Sane indoor lighting.
- Maintaining fires or sunlight are not sustainable enough.
- Access to light is a barrier to deep mining.
- Use digital logic components for this?
- Hazards and "monsters".
- Cellular automata hazards.
- From exploration, deliving too deep, leaving things to rot, etc.
- Some spread explosively (fire), some creeping (blights).
- Healing, possibly from "relaxation" and peaceful environment.
- HC death/spawn.
- Cultivation and farming
- Plant-like CA animals, like bee nests and clouds of bees?
Termine mounds? Ant colonies? Coral?
- More biomes, exploration diversity.
- Water and lava springs.
- Lava deep underground as a bedrock replacement?
- Watershed mapgen?
------------------------------------------------------------------------
USABILITY
- Hint system updates.
- Need a "witness" system for spontaneous in-world processes,
such as tree growth or lode cooling. Credit players within
a certain distance and line-of-sight.
- Use recipes for hint guide instead of just items in hand.
- Feedback/issues URL?
- Look for new URL buttons in 5.0+
- Social features
- Randomize player appearance/colors.
- Players show damage on texture?
- Players show wielditem on texture or floating ent?
------------------------------------------------------------------------
REFACTORS AND REFINEMENTS
- Make neighbor/distance calcs consistent.
- We're using scan_flood in some places, face checks in others,
and find_nodes_in_area (cuboid) in others.
- Diamond shape would be most consistent.
- Should require face touching, not diagonal.
- Make item updates search farther after they've been settled
for longer. Allow some upwards motion...?
........................................................................
========================================================================

64
docs/roadmap.txt Normal file
View File

@ -0,0 +1,64 @@
========================================================================
ROADMAP (SHORT-TERM)
------------------------------------------------------------------------
- Fix bug allowing totes to be placed into shelves.
- Update README.
- Add "gameplay basics"
- Crafting in-world
- Pummeling
- Sensitivity to which node face
- Check inventory screen for hints
- Installation guide?
- Digital logic + lighting via optics.
- Mirrors
- Change light angle
- Focus sunlight?
- Prism Node
- 1 face (back) is VCC face, must be fed light to do anything.
- 3 faces (front, left, right) are output faces, emit collimated light.
- 2 faces (top, bottom) are interference faces, switch off output if fed light.
- Create a light source (airlike) wherever prism beams hit, if not another prism.
- Beams can pass through one another.
- Lamp Crystal Node
- Inert when placed, reverts to inert form when dug.
- When provided a light source over time, it starts to glow.
- Glows perpetually once charged, until dug.
- Light can be used as input for prisms.
- Buttons/touchplates, no switches (build a latch for state).
- Pistons or rack&pinions for affecting world stuff.
- Visceral threats.
- Need some kind of "oh shit"-factor hazards for e.g. deeper mining.
- Flammable gas? Toxic gas? Radioactives?
- Monsters: stone-lurkers, mimics.
- Fire tech.
- Fire rework.
- Migrate to first-class API.
- Proper API for burning up items
- on_burn? burns_to?
- Move heat and quench calcs all into API.
- Cumulative heat helpers?
- Maybe generalized time-cumulative helpers that
could be used with plant growth too?
- Unify heat transformations into recipe system with
cooking recipes?
- Make fuel consumed slower by reducing flame exposure.
- Encourages designing a better furnace.
- Smothering produces charcoal instead of ash.
- Can be reburned. Maybe easier to ignite?
Maybe rejuvenate fuel in exchange for effort?
- Make ash whiter, charcoal black.
- Plant life stuff
- Tree growth catchup.
- Set last time calc at place-time and in ABM
- Define growth rate as gaussian, compute cumulative
growth as a single box-mueller transform upon ABM
- Visually show progress, e.g. display a sprout or
something above, to give feedback.
- Require light.
- Leaves settle into grass as podzol? Composting/decay?
- Dirt/sand/etc should self-compact if buried or over time.
OR loose dirt should grow grass.
........................................................................
========================================================================

1
game.conf Normal file
View File

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

BIN
menu/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
menu/header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

227
menu/header.svg Normal file
View File

@ -0,0 +1,227 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="625.26715mm"
height="134.6713mm"
viewBox="0 0 1000.4274 215.47406"
version="1.1"
id="svg8"
sodipodi:docname="header.svg"
inkscape:version="0.92.1 r15371"
inkscape:export-filename="header.png"
inkscape:export-xdpi="41.599998"
inkscape:export-ydpi="41.599998">
<defs
id="defs2">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="16.93333 : 181.96188 : 1"
inkscape:vp_y="140.18095 : 489.6094 : 1"
inkscape:vp_z="328.74288 : 169.26187 : 1"
inkscape:persp3d-origin="168 : 158.39997 : 1"
id="perspective4485" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.175"
inkscape:cx="1208.5144"
inkscape:cy="234.92333"
inkscape:document-units="mm"
inkscape:current-layer="g4676"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:snap-bbox-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-global="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:pagecheckerboard="true"
scale-x="1.6" />
<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="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(235.51666,155.09466)">
<g
id="g4676"
transform="matrix(0.94952391,0,0,0.94978823,1.2397197,8.6363235)"
style="stroke-width:1.05301285">
<g
style="stroke:#ffffff;stroke-width:25.27230644;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="g4657-5">
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-5-48"
sodipodi:sides="6"
sodipodi:cx="28.273651"
sodipodi:cy="-58.95414"
sodipodi:r1="64.224815"
sodipodi:r2="55.620323"
sodipodi:arg1="-1.5707963"
sodipodi:arg2="-1.0471976"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 28.273653,-123.17896 55.620321,32.112414 -2e-6,64.224815 -55.620323,32.1124067 -55.62032,-32.1124097 1e-6,-64.224815 z"
inkscape:transform-center-x="1.0101525e-06"
inkscape:transform-center-y="-1.3577723e-06" />
<path
inkscape:connector-curvature="0"
id="path4516-1"
d="M 117.65593,-123.1792 V 5.270433 l 55.62032,-32.11241 v -64.224817 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
d="m 262.65853,-58.923867 h -55.24781 m 55.24781,-64.224813 -55.62032,32.112404 v 64.224819 l 55.62032,32.1124099"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4520-2" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path4515-5-4-8"
d="M 467.57949,-9.732521 382.02998,39.489085 296.48047,-9.7325256 V -108.17574 l 85.54951,-49.22163 85.54952,49.22163"
inkscape:transform-center-y="-5.1205033e-06"
inkscape:transform-center-x="1.5537137e-06"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-5-0-9"
sodipodi:sides="6"
sodipodi:cx="557.01379"
sodipodi:cy="-58.95414"
sodipodi:r1="64.224815"
sodipodi:r2="55.620323"
sodipodi:arg1="-1.5707963"
sodipodi:arg2="-1.0471976"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 557.0138,-123.17896 55.62032,32.112414 -1e-5,64.224815 -55.62032,32.1124067 -55.62032,-32.1124097 0,-64.224815 z"
inkscape:transform-center-x="1.0101525e-06"
inkscape:transform-center-y="-1.3577723e-06" />
<path
inkscape:connector-curvature="0"
id="path4554-3"
d="M 646.39652,5.2704448 V -123.1792 l 55.62032,32.112413 -55.62032,32.112412 55.62032,32.11241"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
d="m 791.45113,-58.923867 h -55.1483 m 55.1483,-64.224813 -55.62032,32.112402 v 64.224822 l 55.62032,32.1124089"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4520-5-6" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path4515-8"
d="m -148.90733,-159.66051 87.798708,50.35319 -9e-6,100.7063678 L -236.70605,-109.30733 V -8.6009522 l 87.79871,50.3531812"
inkscape:transform-center-y="-3.6452217e-06"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:25.27230644;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
</g>
<g
id="g4657">
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-5"
sodipodi:sides="6"
sodipodi:cx="28.273651"
sodipodi:cy="-58.95414"
sodipodi:r1="64.224815"
sodipodi:r2="55.620323"
sodipodi:arg1="-1.5707963"
sodipodi:arg2="-1.0471976"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 28.273653,-123.17896 55.620321,32.112414 -2e-6,64.224815 -55.620323,32.1124067 -55.62032,-32.1124097 1e-6,-64.224815 z"
inkscape:transform-center-x="1.0101525e-06"
inkscape:transform-center-y="-1.3577723e-06" />
<path
inkscape:connector-curvature="0"
id="path4516"
d="M 117.65593,-123.1792 V 5.270433 l 55.62032,-32.11241 v -64.224817 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
d="m 262.65853,-58.923867 h -55.24781 m 55.24781,-64.224813 -55.62032,32.112404 v 64.224819 l 55.62032,32.1124099"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4520" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path4515-5-4"
d="M 467.57949,-9.732521 382.02998,39.489085 296.48047,-9.7325256 V -108.17574 l 85.54951,-49.22163 85.54952,49.22163"
inkscape:transform-center-y="-5.1205033e-06"
inkscape:transform-center-x="1.5537137e-06"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-5-0"
sodipodi:sides="6"
sodipodi:cx="557.01379"
sodipodi:cy="-58.95414"
sodipodi:r1="64.224815"
sodipodi:r2="55.620323"
sodipodi:arg1="-1.5707963"
sodipodi:arg2="-1.0471976"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 557.0138,-123.17896 55.62032,32.112414 -1e-5,64.224815 -55.62032,32.1124067 -55.62032,-32.1124097 0,-64.224815 z"
inkscape:transform-center-x="1.0101525e-06"
inkscape:transform-center-y="-1.3577723e-06" />
<path
inkscape:connector-curvature="0"
id="path4554"
d="M 646.39652,5.2704448 V -123.1792 l 55.62032,32.112413 -55.62032,32.112412 55.62032,32.11241"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
d="m 791.45113,-58.923867 h -55.1483 m 55.1483,-64.224813 -55.62032,32.112402 v 64.224822 l 55.62032,32.1124089"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4520-5" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path4515"
d="m -148.90733,-159.66051 87.798708,50.35319 -9e-6,100.7063678 L -236.70605,-109.30733 V -8.6009522 l 87.79871,50.3531812"
inkscape:transform-center-y="-3.6452217e-06"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.42410278;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

BIN
menu/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

150
menu/icon.svg Normal file
View File

@ -0,0 +1,150 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128.00069mm"
height="128.00069mm"
viewBox="0 0 128.00069 128.00069"
version="1.1"
id="svg8"
sodipodi:docname="logo.svg"
inkscape:version="0.92.1 r15371">
<defs
id="defs2">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="10.583333 : 113.72617 : 1"
inkscape:vp_y="87.613098 : 306.0059 : 1"
inkscape:vp_z="205.4643 : 105.78867 : 1"
inkscape:persp3d-origin="105 : 98.99999 : 1"
id="perspective4485" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="240.27591"
inkscape:cy="134.88871"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:snap-bbox-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-global="false"
fit-margin-top="0"
fit-margin-left="8.187935"
fit-margin-right="8.187935"
fit-margin-bottom="0"
inkscape:pagecheckerboard="true" />
<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="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-13.373015,-46.997667)">
<g
id="g4676"
transform="matrix(0.94952391,0,0,0.94978823,1.2397197,8.6363235)"
style="stroke-width:1.05301285">
<path
inkscape:transform-center-y="-1.3577723e-06"
inkscape:transform-center-x="1.0101525e-06"
d="m 80.180857,43.548355 55.620323,32.112409 0,64.224816 -55.620327,32.11241 -55.620321,-32.11241 2e-6,-64.224819 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="-1.0471976"
sodipodi:arg1="-1.5707963"
sodipodi:r2="55.620323"
sodipodi:r1="64.224815"
sodipodi:cy="107.77317"
sodipodi:cx="80.180855"
sodipodi:sides="6"
id="path4515-2"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:6.31807709;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
sodipodi:type="star" />
<path
inkscape:transform-center-y="-1.3577723e-06"
inkscape:transform-center-x="1.0101525e-06"
d="m 80.180857,43.548355 55.620323,32.112409 0,64.224816 -55.620327,32.11241 -55.620321,-32.11241 2e-6,-64.224819 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="-1.0471976"
sodipodi:arg1="-1.5707963"
sodipodi:r2="55.620323"
sodipodi:r1="64.224815"
sodipodi:cy="107.77317"
sodipodi:cx="80.180855"
sodipodi:sides="6"
id="path4515"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.1060257;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
sodipodi:type="star" />
<path
inkscape:connector-curvature="0"
d="m 80.180857,43.548355 -10e-7,64.224815 m -55.620324,32.11241 55.620323,-32.11241 55.620325,32.11241"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.1060257;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-7" />
<g
style="stroke-width:1.60252047"
transform="matrix(-0.65797287,0,0,-0.65622484,59.253978,174.28727)"
id="g4650">
<circle
r="26.293394"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:12.82015705;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4570-5-2"
cx="-31.805071"
cy="101.3587" />
<circle
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6.41007853;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4570-5"
cx="-31.805073"
cy="101.3587"
r="26.293394" />
<g
style="stroke-width:3.20503926;stroke-miterlimit:4;stroke-dasharray:none"
id="g4641">
<path
d="m -31.805074,37.13389 v 64.22481 m -55.620325,32.11241 55.620323,-32.11241 55.620329,32.11241"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#feffff;stroke-width:12.82015705;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-7-5-6"
inkscape:connector-curvature="0" />
<path
d="m -31.805073,37.13389 v 64.22481 m -55.620325,32.11241 55.620323,-32.11241 55.620325,32.11241"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:6.41007853;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4515-7-5"
inkscape:connector-curvature="0" />
</g>
<circle
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:6.41007853;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:markers stroke fill;enable-background:accumulate"
id="path4570"
cx="-31.805073"
cy="101.3587"
r="6.1471992" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,35 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs
= math, minetest, nodecore, pairs
local math_ceil, math_floor, math_random
= math.ceil, math.floor, math.random
-- LUALOCALS > ---------------------------------------------------------
function nodecore.digparticles(nodedef, partdef)
local img = {}
if nodedef.tiles then
for i = 1, 6 do
img[#img + 1] = nodedef.tiles[i > #nodedef.tiles and #nodedef.tiles or i]
end
elseif nodedef.inventory_image then
img[1] = nodedef.inventory_image
end
if #img < 1 then return minetest.log("no pummel tile images found!") end
img = nodecore.pickrand(img)
if img.name then img = img.name end
partdef.amount = partdef.amount and math_ceil(partdef.amount / 4) or 4
local t = {}
for i = 1, 4 do
partdef.texture = img .. "^[mask:[combine\\:16x16\\:"
.. math_floor(math_random() * 12) .. ","
.. math_floor(math_random() * 12) .. "=nc_api_pummel.png"
t[#t + 1] = minetest.add_particlespawner(partdef)
end
return function()
for k, v in pairs(t) do
minetest.delete_particlespawner(v)
end
end
end

47
mods/nc_api/init.lua Normal file
View File

@ -0,0 +1,47 @@
-- LUALOCALS < ---------------------------------------------------------
-- SKIP: nodecore
local dofile, include, minetest, rawget, rawset, table
= dofile, include, minetest, rawget, rawset, table
local table_concat, table_insert
= table.concat, table.insert
-- LUALOCALS > ---------------------------------------------------------
local nodecore = rawget(_G, "nodecore") or {}
rawset(_G, "nodecore", nodecore)
local include = rawget(_G, "include") or function(...)
local parts = {...}
table_insert(parts, 1, minetest.get_modpath(minetest.get_current_modname()))
if parts[#parts]:sub(-4) ~= ".lua" then
parts[#parts] = parts[#parts] .. ".lua"
end
minetest.log(table_concat(parts, "/"))
return dofile(table_concat(parts, "/"))
end
rawset(_G, "include", include)
nodecore.version = include("version")
include("issue7020")
include("util_misc")
include("util_scan_flood")
include("util_logtrace")
include("util_node_is")
include("util_toolcaps")
include("util_stack")
include("util_phealth")
include("match")
include("fx_digparticles")
include("register_limited_abm")
include("mapgen_shared")
include("item_on_register")
include("item_drop_in_place")
include("item_falling_repose")
include("item_alternate_loose")
include("item_group_visinv")
include("item_oldnames")
include("item_tool_wears_to")

22
mods/nc_api/issue7020.lua Normal file
View File

@ -0,0 +1,22 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, pairs, setmetatable, type
= minetest, pairs, setmetatable, type
-- LUALOCALS > ---------------------------------------------------------
local bifn = minetest.registered_entities["__builtin:falling_node"]
local falling = {
set_node = function(self, node, meta, ...)
meta = meta or {}
if type(meta) ~= "table" then meta = meta:to_table() end
for k1, v1 in pairs(meta.inventory or {}) do
for k2, v2 in pairs(v1) do
if type(v2) == "userdata" then
v1[k2] = v2:to_string()
end
end
end
return bifn.set_node(self, node, meta, ...)
end
}
setmetatable(falling, bifn)
minetest.register_entity(":__builtin:falling_node", falling)

View File

@ -0,0 +1,89 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs, type
= minetest, nodecore, pairs, type
-- LUALOCALS > ---------------------------------------------------------
--[[
Nodes that have an "alternate_loose = { ... }" definition when
registered will be registered as a pair, one being the "loose" version
and the other being the normal "solid" one. Solid-specific attributes
can be set via "alternate_solid = { ... }". The solid version will
transform to the loose one when dug, and the loose to solid when
pummeled.
--]]
local looseimg = "^nc_api_loose.png"
local function can_repack(level)
return function(pos, node, stats)
return nodecore.toolspeed(stats.puncher:get_wielded_item(), {thumpy = level})
end
end
local function repack_node(mult, replace)
if type(replace) ~= "table" then replace = {name = replace} end
return function (pos, node, stats)
if stats.duration < (mult * stats.check) then return end
nodecore.wear_current_tool(stats.puncher, {thumpy = 1})
minetest.set_node(pos, replace)
return true
end
end
nodecore.register_on_register_item(function(name, def)
if def.type ~= "node" then return end
local loose = def.alternate_loose
if not loose then return end
if not loose.tiles then
loose.tiles = nodecore.underride({}, def.tiles)
for k, v in pairs(loose.tiles) do
if type(v) == "string" then
loose.tiles[k] = v .. looseimg
elseif type(v) == "table" then
loose.tiles[k] = underride({
name = v.name .. looseimg
}, v)
end
end
end
nodecore.underride(loose, def)
loose.name = name .. "_loose"
if loose.oldnames then
for k, v in pairs(loose.oldnames) do
loose.oldnames[k] = v .. "_loose"
end
end
loose.description = "Loose " .. loose.description
loose.groups = nodecore.underride({}, loose.groups or {})
loose.groups.falling_node = 1
if loose.groups.crumbly and not loose.no_repack then
minetest.after(0, function()
nodecore.register_craft({
label = "repack " .. loose.name,
action = "pummel",
nodes = {
{match = loose.name, replace = name}
},
toolgroups = {thumpy = loose.repack_level or 1},
})
end)
end
loose.alternate_loose = nil
loose.alternate_solid = nil
minetest.register_node(loose.name, loose)
local solid = nodecore.underride(def.alternate_solid or {}, def)
solid.drop_in_place = solid.drop_in_place or loose.name
solid.alternate_loose = nil
solid.alternate_solid = nil
minetest.register_node(name, solid)
return true
end)

View File

@ -0,0 +1,21 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, type
= minetest, nodecore, type
-- LUALOCALS > ---------------------------------------------------------
--[[
Nodes with a "drop_in_place" spec transform on node drop by dropping
into place of existing node instead of digger inventory.
--]]
nodecore.register_on_register_item(function(name, def)
if def.type ~= "node" then return end
local dip = def.drop_in_place
if dip then
if type(dip) ~= "table" then dip = {name = dip} end
def.drop = def.drop or ""
def.after_dig_node = def.after_dig_node or function(pos)
minetest.set_node(pos, dip)
end
end
end)

View File

@ -0,0 +1,110 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, type
= math, minetest, nodecore, pairs, type
local math_random
= math.random
-- LUALOCALS > ---------------------------------------------------------
--[[
Nodes with the "falling_repose" group will not only fall if unsupported
from below, but if there is a sufficient drop off the sides, so simulate
an "angle of repose."
--]]
function nodecore.falling_repose_drop(posfrom, posto, node)
minetest.spawn_falling_node(posto, node, minetest.get_meta(posfrom))
minetest.remove_node(posfrom)
posfrom.y = posfrom.y + 1
return minetest.check_for_falling(posfrom)
end
nodecore.register_on_register_item(function(name, def)
if def.type ~= "node" then return end
def.groups = def.groups or {}
if def.groups.falling_repose then def.groups.falling_node = 1 end
def.repose_drop = def.repose_drop or nodecore.falling_repose_drop
end)
function minetest.spawn_falling_node(pos, node, meta)
node = node or minetest.get_node(pos)
if node.name == "air" or node.name == "ignore" then
return false
end
local obj = minetest.add_entity(pos, "__builtin:falling_node")
if obj then
obj:get_luaentity():set_node(node, meta or minetest.get_meta(pos):to_table())
minetest.remove_node(pos)
return true
end
return false
end
local function check_empty(pos, dx, dy, dz)
for ndy = dy, 1 do
local p = {x = pos.x + dx, y = pos.y + ndy, z = pos.z + dz}
local node = minetest.get_node(p)
if not minetest.registered_nodes[node.name].buildable_to then return end
end
return {x = pos.x + dx, y = pos.y, z = pos.z + dz}
end
function nodecore.falling_repose_check(pos)
if minetest.check_single_for_falling(pos) then return end
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
local repose = def.groups.falling_repose
if not repose then return end
-- Reposing nodes can always sit comfortably atop
-- a non-moving node; it's only when stacked on other
-- falling nodes that they can slip off.
if not (minetest.registered_nodes[minetest.get_node(
{x = pos.x, y = pos.y - 1, z = pos.z}).name].groups
or {}).falling_node
then return end
local open = {}
local ok = check_empty(pos, 1, -repose, 0)
if ok then open[1] = ok end
ok = check_empty(pos, -1, -repose, 0)
if ok then open[#open + 1] = ok end
ok = check_empty(pos, 0, -repose, 1)
if ok then open[#open + 1] = ok end
ok = check_empty(pos, 0, -repose, -1)
if ok then open[#open + 1] = ok end
if #open < 1 then return end
return def.repose_drop(pos, open[math_random(1, #open)], node)
end
local reposeq
local qqty
local qmax = 100
local function reposeall()
for _, v in pairs(reposeq) do v() end
reposeq = nil
qqty = nil
end
nodecore.register_limited_abm({
label = "Falling Repose",
nodenames = {"group:falling_repose"},
neighbors = {"air"},
interval = 2,
chance = 5,
action = function(pos, node)
if not reposeq then
reposeq = {}
qqty = 0
minetest.after(0, reposeall)
end
local f = function() nodecore.falling_repose_check(pos) end
if #reposeq > qmax then
local i = math_random(1, qqty)
if i < qmax then reposeq[i] = f end
else
reposeq[#reposeq + 1] = f
end
qqty = qqty + 1
end
})

View File

@ -0,0 +1,158 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, type
= math, minetest, nodecore, pairs, type
local math_floor, math_pi, math_random, math_sqrt
= math.floor, math.pi, math.random, math.sqrt
-- LUALOCALS > ---------------------------------------------------------
--[[
Helpers for visible inventory. Use "visinv" node group.
Sets up on_construct, after_destruct and an ABM to manage
the visual entities.
--]]
local modname = minetest.get_current_modname()
------------------------------------------------------------------------
-- VISIBLE STACK ENTITY
local function stackentprops(stack, func, rot)
rot = rot or 1
local t = {
hp_max = 1,
physical = false,
collide_with_objects = false,
collisionbox = {0, 0, 0, 0, 0, 0},
visual = "wielditem",
visual_size = {x = 0.4, y = 0.4 },
textures = {""},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
is_visible = false
}
if stack then
t.is_visible = true
t.textures[1] = stack:get_name()
local s = 0.2 + 0.1 * stack:get_count() / stack:get_stack_max()
t.visual_size = {x = s, y = s}
local max = stack:get_stack_max()
local ratio = max / stack:get_count()
t.automatic_rotate = rot * (ratio == 1 and max > 1
and 0.05 or 0.15) * math_sqrt(ratio)
if func then func(s) end
end
return t
end
minetest.register_entity(modname .. ":stackent", {
initial_properties = stackentprops(),
is_stack = true,
itemcheck = function(self)
local pos = self.object:getpos()
local stack = nodecore.stack_get(pos)
if not stack or stack:is_empty() then return self.object:remove() end
self.rot = self.rot or math_random(1, 2) * 2 - 3
self.object:set_properties(stackentprops(stack, function(s)
pos.y = math_floor(pos.y + 0.5) - 0.5 + s
self.object:setpos(pos)
end, self.rot))
self.object:set_yaw(math_random() * math_pi * 2)
if pos.y - math_floor(pos.y) ~= 1/64 then
pos.y = pos.y + 1/64
self.object:setpos(pos)
end
end,
on_activate = function(self)
self.cktime = 0.00001
end,
on_step = function(self, dtime)
self.cktime = (self.cktime or 0) - dtime
if self.cktime > 0 then return end
self.cktime = 1
return self:itemcheck()
end
})
function nodecore.visinv_update_ents(pos, node)
node = node or minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
local max = def and def.groups and def.groups.visinv and 1 or 0
local found = {}
for k, v in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
if v and v.get_luaentity and v:get_luaentity()
and v:get_luaentity().is_stack then
found[#found + 1] = v
end
end
if #found < max then
minetest.add_entity(pos, modname .. ":stackent")
else
while #found > max do
found[#found]:remove()
found[#found] = nil
end
end
end
------------------------------------------------------------------------
-- NODE REGISTRATION HELPERS
function nodecore.visinv_on_construct(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("solo", 1)
nodecore.visinv_update_ents(pos)
end
function nodecore.visinv_after_destruct(pos)
nodecore.visinv_update_ents(pos)
minetest.after(0, function()
minetest.check_for_falling(pos)
end)
end
nodecore.register_on_register_item(function(name, def)
if def.type ~= "node" then return end
def.groups = def.groups or {}
if def.groups.visinv then
def.on_construct = def.on_construct or nodecore.visinv_on_construct
def.after_destruct = def.after_destruct or nodecore.visinv_after_destruct
end
end)
nodecore.register_limited_abm({
label = "VisInv Check",
nodenames = {"group:visinv"},
interval = 1,
chance = 1,
action = function(...) return nodecore.visinv_update_ents(...) end
})
------------------------------------------------------------------------
-- DIG INVENTORY
local digpos
local old_node_dig = minetest.node_dig
minetest.node_dig = function(pos, ...)
local function helper(...)
digpos = nil
return ...
end
digpos = pos
return helper(old_node_dig(pos, ...))
end
local old_get_node_drops = minetest.get_node_drops
minetest.get_node_drops = function(...)
local drops = old_get_node_drops(...)
if not digpos then return drops end
drops = drops or {}
local stack = nodecore.stack_get(digpos)
if stack and not stack:is_empty() then
drops[#drops + 1] = stack
end
return drops
end

View File

@ -0,0 +1,12 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs
= minetest, nodecore, pairs
-- LUALOCALS > ---------------------------------------------------------
nodecore.register_on_register_item(function(name, def)
if def.oldnames then
for k, v in pairs(def.oldnames) do
minetest.register_alias(v, name)
end
end
end)

View File

@ -0,0 +1,17 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, minetest, nodecore
= ipairs, minetest, nodecore
-- LUALOCALS > ---------------------------------------------------------
nodecore.register_on_register_item,
nodecore.registered_on_register_item
= nodecore.mkreg()
local oldreg = minetest.register_item
function minetest.register_item(name, def, ...)
for _, v in ipairs(nodecore.registered_on_register_item) do
local x = v(name, def, ...)
if x then return x end
end
return oldreg(name, def, ...)
end

View File

@ -0,0 +1,20 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, minetest, nodecore
= ItemStack, minetest, nodecore
-- LUALOCALS > ---------------------------------------------------------
nodecore.register_on_register_item(function(name, def)
if def.tool_wears_to then
def.after_use = def.after_use or function(what, who, node, dp)
what:add_wear(dp.wear)
if what:get_count() == 0 then
if def.sound and def.sound.breaks then
minetest.sound_play(def.sound.breaks,
{pos = who:get_pos(), gain = 0.5})
end
return ItemStack(def.tool_wears_to)
end
return what
end
end
end)

View File

@ -0,0 +1,43 @@
-- LUALOCALS < ---------------------------------------------------------
local VoxelArea, ipairs, math, minetest, nodecore, table
= VoxelArea, ipairs, math, minetest, nodecore, table
local math_floor, table_insert
= math.floor, table.insert
-- LUALOCALS > ---------------------------------------------------------
local mapgens = {}
nodecore.registered_mapgen_shared = mapgens
local prios = {}
function nodecore.register_mapgen_shared(func, prio)
prio = prio or 0
local min = 1
local max = #mapgens + 1
while max > min do
local try = math_floor((min + max) / 2)
local oldp = prios[try]
if prio < oldp then
min = try + 1
else
max = try
end
end
table_insert(mapgens, min, func)
table_insert(prios, min, prio)
end
minetest.register_on_generated(function(minp, maxp)
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local data = vm:get_data()
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
for _, v in ipairs(mapgens) do
v(minp, maxp, area, data, vm, emin, emax)
end
vm:set_data(data)
vm:set_lighting({day = 0, night = 0})
vm:calc_lighting()
vm:write_to_map()
end)

74
mods/nc_api/match.lua Normal file
View File

@ -0,0 +1,74 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs, type
= minetest, nodecore, pairs, type
-- LUALOCALS > ---------------------------------------------------------
local match_skip = {
name = true,
param2 = true,
param = true,
groups = true,
stack = true,
count = true,
wear = true
}
function nodecore.match(thing, crit)
if not thing then return end
if type(crit) == "string" then crit = {name = crit} end
thing.count = thing.count or 1
thing = nodecore.underride({}, thing)
if thing.stack then
thing.name = thing.stack:get_name()
thing.count = thing.stack:get_count()
thing.wear = thing.stack:get_wear()
thing.stacked = true
end
if not thing.name then
thing = nodecore.underride(thing, minetest.get_node(thing))
end
local def = minetest.registered_items[thing.name]
if (not thing.stacked) and def.groups and def.groups.is_stack_only then
local stack = nodecore.stack_get(thing)
if stack and not stack:is_empty() then
thing.name = stack:get_name()
def = minetest.registered_items[thing.name]
thing.count = stack:get_count()
thing.wear = stack:get_wear()
end
thing.stacked = true
end
if crit.name and thing.name ~= crit.name then return end
if crit.param2 and thing.param2 ~= crit.param2 then return end
if crit.param and thing.param ~= crit.param then return end
if crit.count and thing.count ~= crit.count then return end
if crit.count == nil and thing.count ~= 1 then return end
if crit.wear then
if crit.wear < 1 then crit.wear = crit.wear * 65535 end
if thing.wear > crit.wear then return end
end
if crit.groups then
if not def or not def.groups then return end
for k, v in pairs(crit.groups) do
if v == true then
if not def.groups[k] then return end
elseif v == false then
if def.groups[k] then return end
else
if def.groups[k] ~= v then return end
end
end
end
for k, v in pairs(crit) do
if not match_skip[k] then
if not def or def[k] ~= v then return end
end
end
return thing
end

View File

@ -0,0 +1,69 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, unpack
= math, minetest, nodecore, pairs, unpack
local math_random
= math.random
-- LUALOCALS > ---------------------------------------------------------
local genlabels = 0
function nodecore.register_limited_abm(def)
def = nodecore.underride(def, {
limited_queue = {},
limited_seen = {},
limited_qty = 0,
limited_max = 1000,
limited_interval = 1,
limited_jitter = 0.05,
limited_action = def.action or function() end,
catch_up = false
})
if not def.label then
def.label = minetest.get_current_modname() .. ":" .. genlabels
genlabels = genlabels + 1
end
def.limited_alert = def.limited_alert or def.limited_max
def.action = function(pos, ...)
local hash = minetest.hash_node_position(pos)
local seen = def.limited_seen
if seen[hash] then return end
seen[hash] = true
local q = def.limited_queue
local max = def.limited_max
local nqty = def.limited_qty + 1
if #q < max then
q[#q + 1] = {pos, ...}
else
local r = math_random(1, nqty)
if r <= #q then q[r] = {pos, ...} end
end
def.limited_qty = nqty
end
local function pumpq()
minetest.after(def.limited_interval
- def.limited_jitter
+ def.limited_jitter * math_random() * 2,
pumpq)
if def.limited_qty >= def.limited_alert then
minetest.log("limited abm \"" .. def.label .. "\" filled ("
.. def.limited_qty .. "/" .. def.limited_max .. ")")
end
local act = def.limited_action
for _, args in pairs(def.limited_queue) do
act(unpack(args))
end
def.limited_queue = {}
def.limited_seen = {}
def.limited_qty = 0
end
pumpq()
return minetest.register_abm(def)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

View File

@ -0,0 +1,47 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, minetest, nodecore, pairs, print, table, type
= ipairs, minetest, nodecore, pairs, print, table, type
local table_concat
= table.concat
-- LUALOCALS > ---------------------------------------------------------
minetest.register_privilege("logtrace", "Receive server debug/trace messages.")
core.register_chatcommand("logtrace", {
description = "Toggle debug trace messages",
privs = {logtrace = true},
func = function(name)
local player = minetest.get_player_by_name(name)
if not player then return end
local old = player:get_attribute("logtrace") or ""
return player:set_attribute("logtrace", (old == "") and "1" or "")
end,
})
function nodecore.logtrace(...)
local t = {"#", ...}
for i, v in ipairs(t) do
if type(v) == "table" then
t[i] = minetest.serialize(v):sub(("return "):length())
end
end
local msg = table_concat(t, " ")
for _, p in pairs(minetest.get_connected_players()) do
local n = p:get_player_name()
if minetest.get_player_privs(n).logtrace then
local a = p:get_attribute("logtrace")
if a and a ~= "" then
minetest.chat_send_player(n, msg)
end
end
end
end
local function tracify(func)
return function(...)
nodecore.logtrace(...)
return func(...)
end
end
print = tracify(print)
minetest.log = tracify(minetest.log)

203
mods/nc_api/util_misc.lua Normal file
View File

@ -0,0 +1,203 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, ipairs, math, minetest, nodecore, pairs, type
= ItemStack, ipairs, math, minetest, nodecore, pairs, type
local math_random
= math.random
-- LUALOCALS > ---------------------------------------------------------
for k, v in pairs(minetest) do
if type(v) == "function" then
-- Late-bind in case minetest methods overridden.
nodecore[k] = function(...) return minetest[k](...) end
else
nodecore[k] = v
end
end
local function underride(t, u, v, ...)
if v then underride(u, v, ...) end
for k, v in pairs(u) do
if t[k] == nil then
t[k] = v
elseif type(t[k]) == "table" and type(v) == "table" then
underride(t[k], v)
end
end
return t
end
nodecore.underride = underride
function nodecore.mkreg()
local t = {}
local f = function(x) t[#t + 1] = x end
return f, t
end
function nodecore.memoize(func)
local cache
return function()
if cache then return cache[1] end
cache = {func()}
return cache[1]
end
end
function nodecore.dirs()
return {
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y = -1, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z = -1}
}
end
function nodecore.pickrand(tbl, weight)
weight = weight or function() end
local t = {}
local max = 0
for k, v in pairs(tbl) do
local w = weight(v) or 1
if w > 0 then
max = max + w
t[#t + 1] = {w = w, k = k, v = v}
end
end
if max <= 0 then return end
max = math_random() * max
for i, v in ipairs(t) do
max = max - v.w
if max <= 0 then return v.v, v.k end
end
end
function nodecore.extend_item(name, func)
local orig = minetest.registered_items[name]
local copy = {}
for k, v in pairs(orig) do copy[k] = v end
copy = func(copy, orig) or copy
minetest.register_item(":" .. name, copy)
end
function nodecore.fixedbox(...) return {type = "fixed", fixed = {...}} end
function nodecore.interact(player)
if type(player) ~= "string" then
player = player:get_player_name()
end
return minetest.get_player_privs(player).interact
end
function nodecore.wieldgroup(who, group)
local wielded = who and who:get_wielded_item()
local nodedef = minetest.registered_nodes[wielded:get_name()]
if nodedef then return nodedef.groups and nodedef.groups[group] end
local caps = wielded and wielded:get_tool_capabilities()
return caps and caps.groupcaps and caps.groupcaps[group]
end
function nodecore.toolspeed(what, groups)
if not what then return end
local dg = what:get_tool_capabilities().groupcaps
local t
for gn, lv in pairs(groups) do
local gt = dg[gn]
gt = gt and gt.times
gt = gt and gt[lv]
if gt and (not t or t > gt) then t = gt end
end
return t
end
function nodecore.interval(after, func)
local function go()
minetest.after(after, go)
return func()
end
minetest.after(after, go)
end
function nodecore.wear_wield(player, groups, qty)
local wielded = player:get_wielded_item()
if wielded then
local wdef = wielded:get_definition()
local tp = wielded:get_tool_capabilities()
local dp = minetest.get_dig_params(groups, tp)
if wdef and wdef.after_use then
wielded = wdef.after_use(wielded, player, nil, dp) or wielded
else
if not minetest.settings:get_bool("creative_mode") then
wielded:add_wear(dp.wear * (qty or 1))
if wielded:get_count() <= 0 and wdef.sound
and wdef.sound.breaks then
minetest.sound_play(wdef.sound.breaks,
{pos = pos, gain = 0.5})
end
end
end
return player:set_wielded_item(wielded)
end
end
function nodecore.consume_wield(player, qty)
local wielded = player:get_wielded_item()
if wielded then
local wdef = wielded:get_definition()
if wdef.stack_max > 1 and qty then
local have = wielded:get_count() - qty
if have <= 0 then
wielded = ItemStack("")
else
wielded:set_count(have)
end
end
return player:set_wielded_item(wielded)
end
end
function nodecore.loaded_mods()
local t = {}
for _, v in pairs(minetest.get_modnames()) do
t[v] = true
end
return t
end
function nodecore.node_group(name, pos, node)
node = node or minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
return def and def.groups and def.groups[name]
end
function nodecore.item_eject(pos, stack, speed, qty, vel)
stack = ItemStack(stack)
speed = speed or 0
vel = vel or {x = 0, y = 0, z = 0}
if speed == 0 and vel.x == 0 and vel.y == 0 and vel.z == 0
and nodecore.place_stack and minetest.get_node(pos).name == "air" then
stack:set_count(stack:get_count() * (qty or 1))
return nodecore.place_stack(pos, stack)
end
for i = 1, (qty or 1) do
local v = {
x = vel.x + (math_random() - 0.5) * speed,
y = vel.y + math_random() * speed,
z = vel.z + (math_random() - 0.5) * speed,
}
local p = {
x = v.x > 0 and pos.x + 0.4 or v.x < 0 and pos.x - 0.4 or pos.x,
y = pos.y + 0.25,
z = v.z > 0 and pos.z + 0.4 or v.z < 0 and pos.z - 0.4 or pos.z,
}
local obj = minetest.add_item(p, stack)
if obj then obj:setvelocity(v) end
end
end
function nodecore.quenched(pos)
return #minetest.find_nodes_in_area(
{x = pos.x - 1, y = pos.y - 1, z = pos.z - 1},
{x = pos.x + 1, y = pos.y + 1, z = pos.z + 1},
{"group:coolant"}) > 0
end

View File

@ -0,0 +1,8 @@
-- LUALOCALS < ---------------------------------------------------------
local nodecore
= nodecore
-- LUALOCALS > ---------------------------------------------------------
function nodecore.buildable_to(node_or_pos)
return nodecore.match(node_or_pos, {buildable_to = true})
end

View File

@ -0,0 +1,26 @@
-- LUALOCALS < ---------------------------------------------------------
local math, nodecore, tonumber, tostring
= math, nodecore, tonumber, tostring
local math_ceil
= math.ceil
-- LUALOCALS > ---------------------------------------------------------
local function getphealth(player)
return player:get_hp()
+ tonumber(player:get_attribute("dhp") or "0")
end
nodecore.getphealth = getphealth
local function setphealth(player, hp)
if hp > 20 then hp = 20 end
if hp < 0 then hp = 0 end
local whole = math_ceil(hp)
local dhp = hp - whole
player:set_attribute("dhp", tostring(dhp))
return player:set_hp(whole)
end
nodecore.setphealth = setphealth
function nodecore.addphealth(player, hp)
return setphealth(player, getphealth(player) + hp)
end

View File

@ -0,0 +1,41 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, next, nodecore, pairs, table
= ipairs, math, minetest, next, nodecore, pairs, table
local math_random, table_insert
= math.random, table.insert
-- LUALOCALS > ---------------------------------------------------------
local dirs = nodecore.dirs()
function nodecore.scan_flood(pos, range, func)
local q = {pos}
local seen = { }
for d = 0, range do
local next = {}
for i, p in ipairs(q) do
local res = func(p, d)
if res then return res end
if res == nil then
for k, v in pairs(dirs) do
local np = {
x = p.x + v.x,
y = p.y + v.y,
z = p.z + v.z
}
local nk = minetest.hash_node_position(np)
if not seen[nk] then
seen[nk] = true
np.dir = v
table_insert(next, np)
end
end
end
end
if #next < 1 then break end
for i = 1, #next do
local j = math_random(1, #next)
next[i], next[j] = next[j], next[i]
end
q = next
end
end

View File

@ -0,0 +1,27 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, minetest, nodecore
= ItemStack, minetest, nodecore
-- LUALOCALS > ---------------------------------------------------------
function nodecore.node_inv(pos)
return minetest.get_meta(pos):get_inventory()
end
function nodecore.stack_get(pos)
return nodecore.node_inv(pos):get_stack("solo", 1)
end
function nodecore.stack_set(pos, stack)
return nodecore.node_inv(pos):set_stack("solo", 1, ItemStack(stack))
end
function nodecore.stack_add(pos, stack)
return nodecore.node_inv(pos):add_item("solo", ItemStack(stack))
end
function nodecore.stack_giveto(pos, player)
local stack = nodecore.stack_get(pos)
stack = player:get_inventory():add_item("main", stack)
nodecore.stack_set(pos, stack)
return stack:is_empty()
end

View File

@ -0,0 +1,35 @@
-- LUALOCALS < ---------------------------------------------------------
local math, nodecore, pairs
= math, nodecore, pairs
local math_pow
= math.pow
-- LUALOCALS > ---------------------------------------------------------
local basetimes = {
cracky = 3,
thumpy = 2,
choppy = 2,
crumbly = 0.5,
snappy = 0.4,
}
function nodecore.toolcaps(opts)
if opts.uses == nil then opts.uses = 1 end
local gcaps = {}
for gn, bt in pairs(basetimes) do
local lv = opts[gn]
if lv then
local times = {}
for n = 1, lv do
local tt = math_pow(0.5, lv - n) * bt
if tt < 0.25 then tt = 0.25 end
times[n] = tt
end
gcaps[gn] = {
times = times,
uses = 5 * math_pow(3, lv) * opts.uses
}
end
end
return { groupcaps = gcaps }
end

12
mods/nc_api/version.lua Normal file
View File

@ -0,0 +1,12 @@
-- LUALOCALS < ---------------------------------------------------------
local math, tonumber
= math, tonumber
local math_floor
= math.floor
-- LUALOCALS > ---------------------------------------------------------
local stamp = tonumber("$Format:%at$")
if not stamp then return end
stamp = math_floor((stamp - 1540612800) / 60)
stamp = ("00000000" .. stamp):sub(-8)
return stamp .. "-$Format:%h$"

View File

@ -0,0 +1,110 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, ipairs, minetest, nodecore, pairs, type
= ItemStack, ipairs, minetest, nodecore, pairs, type
-- LUALOCALS > ---------------------------------------------------------
local function craftcheck(recipe, pos, node, data, xx, xz, zx, zz)
local function rel(x, y, z)
return {
x = pos.x + xx * x + zx * z,
y = pos.y + y,
z = pos.z + xz * x + zz * z
}
end
data.wield = ItemStack(data.wield or data.crafter and data.crafter:get_wielded_item())
if recipe.check and not recipe.check(pos, data, rel) then return end
if recipe.wield and (not data.wield or not nodecore.match(
{stack = data.wield}, recipe.wield)) then return end
if recipe.normal then
if data.pointed.type ~= "node" or
recipe.normal.y ~= data.pointed.above.y - data.pointed.under.y then return end
local rx = recipe.normal.x * xx + recipe.normal.z * zx
if rx ~= data.pointed.above.x - data.pointed.under.x then return end
local rz = recipe.normal.x * xz + recipe.normal.z * zz
if rz ~= data.pointed.above.z - data.pointed.under.z then return end
end
local mindur = recipe.duration or 0
if recipe.toolgroups then
if not data.wield then return end
local dg = data.wield:get_tool_capabilities().groupcaps
local t
for gn, lv in pairs(recipe.toolgroups) do
local gt = dg[gn]
gt = gt and gt.times
gt = gt and gt[lv]
if gt and (not t or t > gt) then t = gt end
end
if not t then return end
mindur = mindur + t
end
if mindur > 0 and (not data.duration or data.duration < mindur) then
if data.inprogress then return data.inprogress(data, recipe) end
return
end
for _, v in pairs(recipe.nodes) do
if v ~= recipe.root and v.match then
local p = rel(v.x, v.y, v.z)
if not nodecore.match(p, v.match) then return end
end
end
if recipe.before then recipe.before(pos, rel, data) end
for _, v in pairs(recipe.nodes) do
if v.replace then
local p = rel(v.x, v.y, v.z)
local r = v.replace
while type(r) == "function" do
r = r(p, v)
end
if r and type(r) == "string" then
r = {name = r}
end
if r then minetest.set_node(p, r) end
end
end
if recipe.items then
for _, v in pairs(recipe.items) do
nodecore.item_eject(rel(v.x or 0, v.y or 0, v.z or 0),
v.name, v.scatter, v.count, v.velocity)
end
end
if recipe.consumewield then
nodecore.consume_wield(data.crafter, recipe.consumewield)
elseif recipe.toolgroups and recipe.toolwear and data.crafter then
nodecore.wear_wield(data.crafter, recipe.toolgroups, recipe.toolwear)
end
if recipe.after then recipe.after(pos, rel, data) end
if nodecore.player_stat_add then
nodecore.player_stat_add(1, data.crafter, "craft", recipe.label)
end
minetest.log((data.crafter and data.crafter:get_player_name() or "unknown")
.. " completed recipe \"" .. recipe.label .. "\" at " ..
minetest.pos_to_string(pos) .. " upon " .. node.name)
return true
end
function nodecore.craft_check(pos, node, data)
data = data or {}
local function go(rc, xx, xz, zx, zz)
return craftcheck(rc, pos, node, data, xx, xz, zx, zz)
end
node.x = pos.x
node.y = pos.y
node.z = pos.z
data.node = node
for _, rc in ipairs(nodecore.craft_recipes) do
if nodecore.match(node, rc.root.match) and data.action == rc.action then
if go(rc, 1, 0, 0, 1) then return true end
if not rc.norotate then
if go(rc, 0, -1, 1, 0) then return true end
if go(rc, -1, 0, 0, -1) then return true end
if go(rc, 0, 1, -1, 0) then return true end
if not rc.nomirror then
if go(rc, -1, 0, 0, 1) then return true end
if go(rc, 0, 1, 1, 0) then return true end
if go(rc, 1, 0, 0, -1) then return true end
if go(rc, 0, -1, -1, 0) then return true end
end
end
end
end
end

View File

@ -0,0 +1 @@
nc_api

View File

@ -0,0 +1,9 @@
-- LUALOCALS < ---------------------------------------------------------
local include
= include
-- LUALOCALS > ---------------------------------------------------------
include('register_craft')
include('craft_check')
include('item_place_node')
include('on_punchnode')

View File

@ -0,0 +1,25 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore
= minetest, nodecore
-- LUALOCALS > ---------------------------------------------------------
local old_place = minetest.item_place_node
function minetest.item_place_node(itemstack, placer, pointed_thing, ...)
local old_add = minetest.add_node
minetest.add_node = function(pos, node, ...)
local function helper2(...)
nodecore.craft_check(pos, node, {
action = "place",
crafter = placer,
pointed = pointed_thing
})
return ...
end
return helper2(old_add(pos, node, ...))
end
local function helper(...)
minetest.add_node = old_add
return ...
end
return helper(old_place(itemstack, placer, pointed_thing, ...))
end

View File

@ -0,0 +1,88 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, vector
= minetest, nodecore, vector
-- LUALOCALS > ---------------------------------------------------------
local function pummelparticles(data)
local pointed = data.pointed
local nodedef = data.nodedef
local pname = data.pname
local stack = nodecore.stack_get(data.node)
if stack and not stack:is_empty() then
nodedef = minetest.registered_items[stack:get_name()] or nodedef
end
local a = pointed.above
local b = pointed.under
local vel = vector.subtract(a, b)
local mid = vector.multiply(vector.add(a, b), 0.5)
local p1 = {x = vel.y, y = vel.z, z = vel.x}
local p2 = {x = vel.z, y = vel.x, z = vel.y}
local s1 = vector.add(vector.add(mid, vector.multiply(p1, 0.5)), vector.multiply(p2, 0.5))
local s2 = vector.add(vector.add(mid, vector.multiply(p1, -0.5)), vector.multiply(p2, -0.5))
vel = vector.multiply(vel, 0.5)
data.clearfx = nodecore.digparticles(nodedef, {
amount = 8,
time = 1.5,
minpos = s1,
maxpos = s2,
minvel = vel,
maxvel = vel,
minexptime = 0.4,
maxexptime = 0.9,
minsize = 1,
maxsize = 5,
playername = pname
})
end
local pummeling = {}
minetest.register_on_punchnode(function(pos, node, puncher, pointed)
if not puncher:is_player() then return end
local pname = puncher:get_player_name()
if not nodecore.interact(pname) then return end
node = node or minetest.get_node(pos)
local def = minetest.registered_items[node.name] or {}
local now = minetest.get_us_time() / 1000000
local pum = {
action = "pummel",
crafter = puncher,
pname = pname,
pos = pos,
pointed = pointed,
node = node,
nodedef = def,
start = now,
wield = puncher:get_wielded_item():to_string(),
count = 0,
inprogress = pummelparticles
}
local old = pummeling[pname]
if old and old.clearfx then old.clearfx() end
local hash = minetest.hash_node_position
if old and hash(old.pos) == hash(pum.pos)
and hash(old.pointed.above) == hash(pum.pointed.above)
and hash(old.pointed.under) == hash(pum.pointed.under)
and pum.wield == old.wield
and old.last >= (now - 2)
then pum = old end
pum.count = pum.count + 1
pum.last = now
pum.duration = now - pum.start - 1
pummeling[pname] = pum
if pum.count < 2 then return end
if nodecore.craft_check(pos, node, nodecore.underride({}, pum)) then
pummeling[pname] = nil
return
end
end)

View File

@ -0,0 +1,66 @@
-- LUALOCALS < ---------------------------------------------------------
local error, math, nodecore, pairs, table, type
= error, math, nodecore, pairs, table, type
local math_floor, table_insert
= math.floor, table.insert
-- LUALOCALS > ---------------------------------------------------------
local craft_recipes = {}
nodecore.craft_recipes = craft_recipes
local id = 0
function nodecore.register_craft(recipe)
recipe.action = recipe.action or "place"
local canrot
recipe.nodes = recipe.nodes or {}
for _, v in pairs(recipe.nodes) do
v.x = v.x or 0
v.y = v.y or 0
v.z = v.z or 0
canrot = canrot or v.x ~= 0 or v.z ~= 0
if v.x == 0 and v.y == 0 and v.z == 0 then
recipe.root = v
end
end
if not recipe.root or not recipe.root.match then
error "recipe.nodes must have a match for 0,0,0"
end
if not recipe.label then
id = id + 1
recipe.label = "unnamed " .. recipe.action .. " " .. id
end
if recipe.toolgroups and recipe.toolwear ~= false then
recipe.toolwear = 1
end
if not canrot then recipe.norotate = true end
if recipe.normal then
recipe.normal.x = recipe.normal.x or 0
recipe.normal.y = recipe.normal.y or 0
recipe.normal.z = recipe.normal.z or 0
end
if recipe.items then
for k, v in pairs(recipe.items) do
if type(v) == "string" then
recipe.items[k] = {name = v}
end
end
end
if recipe.wield and type(recipe.wield) == "table" then
recipe.wield.count = recipe.wield.count or false
end
local newp = recipe.priority or 0
local min = 1
local max = #craft_recipes + 1
while max > min do
local try = math_floor((min + max) / 2)
local oldp = craft_recipes[try].priority or 0
if newp < oldp then
min = try + 1
else
max = try
end
end
table_insert(craft_recipes, min, recipe)
end

88
mods/nc_fire/abm.lua Normal file
View File

@ -0,0 +1,88 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore
= math, minetest, nodecore
local math_pow, math_random
= math.pow, math.random
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local fueltest = {groups = {ember = true}}
nodecore.register_limited_abm({
label = "Fire Requires Embers",
interval = 1,
chance = 1,
nodenames = {modname .. ":fire"},
action = function(pos)
if not nodecore.match({x = pos.x, y = pos.y - 1, z = pos.z }, fueltest)
and not nodecore.match({x = pos.x + 1, y = pos.y, z = pos.z }, fueltest)
and not nodecore.match({x = pos.x - 1, y = pos.y, z = pos.z }, fueltest)
and not nodecore.match({x = pos.x, y = pos.y, z = pos.z + 1 }, fueltest)
and not nodecore.match({x = pos.x, y = pos.y, z = pos.z - 1 }, fueltest)
then return minetest.remove_node(pos) end
end
})
local function mkfire(pos, dx, dy, dz, testonly)
pos = {x = pos.x + dx, y = pos.y + dy, z = pos.z + dz}
if nodecore.match(pos, modname .. ":fire") then return true end
if nodecore.match(pos, "air") then
return testonly or minetest.set_node(pos, {name = modname .. ":fire"})
end
if nodecore.match(pos, "ignore") then return true end
if nodecore.match(pos, {groups = {flammable = true, fire_fuel = false}}) then
return testonly or minetest.set_node(pos, {name = modname .. ":fire"})
end
end
nodecore.register_limited_abm({
label = "Flammables Ignite",
interval = 5,
chance = 1,
nodenames = {"group:flammable"},
neighbors = {"group:igniter"},
action = function(pos, node)
-- Cannot be wet.
if nodecore.quenched(pos) then return end
-- Must have oxygen supply.
if not mkfire(pos, 0, 1, 0, true)
and not mkfire(pos, 1, 0, 0, true)
and not mkfire(pos, -1, 0, 0, true)
and not mkfire(pos, 0, 0, 1, true)
and not mkfire(pos, 0, 0, -1, true)
then return end
-- Get flammability level.
node = node or minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
local flam = def and def.groups and def.groups.flammable
if not flam then return end
-- Ignite randomly.
if math_random(1, flam) ~= 1 then return end
nodecore.ignite(pos, node)
end
})
nodecore.register_limited_abm({
label = "Fuel Burning/Snuffing",
interval = 1,
chance = 1,
nodenames = {"group:ember"},
action = function(pos, node)
if nodecore.quenched(pos) then
return nodecore.snuff(pos, node)
end
local f = mkfire(pos, 0, 1, 0)
f = mkfire(pos, 1, 0, 0) or f
f = mkfire(pos, -1, 0, 0) or f
f = mkfire(pos, 0, 0, 1) or f
f = mkfire(pos, 0, 0, -1) or f
if math_random(1, math_pow(2,
nodecore.node_group("ember", pos, node)
+ (f and 4 or 0))) == 1 then
return nodecore.snuff(pos, node)
end
end
})

35
mods/nc_fire/api.lua Normal file
View File

@ -0,0 +1,35 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore
= math, minetest, nodecore
local math_floor
= math.floor
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
function nodecore.ignite(pos, node)
local fuel = nodecore.node_group("fire_fuel", pos, node) or 0
if fuel < 0 then fuel = 0 end
if fuel > 6 then fuel = 6 end
fuel = math_floor(fuel)
local stack
if nodecore.node_group("eject_inv_on_burn", pos, node) then
stack = nodecore.stack_get(pos)
if stack and (not stack:is_empty()) then
local p = nodecore.scan_flood(pos, 2, nodecore.buildable_to)
nodecore.item_eject(p or pos, stack, 1)
end
end
minetest.set_node(pos, {name = modname .. ((fuel > 0)
and (":ember" .. fuel) or ":fire")})
minetest.after(0, function() minetest.check_for_falling(pos) end)
end
function nodecore.snuff(pos, node, groups)
local ember = nodecore.node_group("ember", pos, node)
if not ember then return end
ember = ember - 1
minetest.set_node(pos, {name = modname .. ((ember > 0)
and (":ember" .. ember) or ":ash")})
minetest.after(0, function() minetest.check_for_falling(pos) end)
end

2
mods/nc_fire/depends.txt Normal file
View File

@ -0,0 +1,2 @@
nc_api
nc_api_craft

View File

@ -0,0 +1,41 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, math, minetest, nodecore
= ItemStack, math, minetest, nodecore
local math_random
= math.random
-- LUALOCALS > ---------------------------------------------------------
nodecore.register_craft({
label = "stick fire starting",
action = "pummel",
wield = {
groups = {firestick = true}
},
nodes = {
{match = {groups = {firestick = true}}}
},
consumewield = 1,
duration = 5,
before = function(pos, rel, data)
local w = data.wield and ItemStack(data.wield):get_name() or ""
local wd = minetest.registered_items[w] or {}
local wg = wd.groups or {}
local fs = wg.firestick or 1
local nd = minetest.registered_items[data.node.name] or {}
local ng = nd.groups or {}
fs = fs * (ng.firestick or 1)
if math_random(1, 4) > fs then return end
minetest.set_node(pos, {name = "nc_fire:fire"})
if math_random(1, 4) > fs then return end
local dir = nodecore.pickrand(nodecore.dirs())
local below = {
x = pos.x + dir.x,
y = pos.y + dir.y,
z = pos.z + dir.z
}
if nodecore.match(below,
{groups = {flammable = 1}}) then
nodecore.ignite(below)
end
end
})

12
mods/nc_fire/init.lua Normal file
View File

@ -0,0 +1,12 @@
-- LUALOCALS < ---------------------------------------------------------
local include, minetest
= include, minetest
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local path = minetest.get_modpath(modname)
include('api')
include('node')
include('abm')
include('firestarting')

64
mods/nc_fire/node.lua Normal file
View File

@ -0,0 +1,64 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest
= minetest
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
minetest.register_node(modname .. ":fire", {
description = "Fire",
drawtype = "firelike",
visual_scale = 1.5,
tiles = {modname .. "_fire.png"},
paramtype = "light",
light_source = 12,
groups = {
igniter = 1,
flame = 1
},
damage_per_second = 2,
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
})
local function ember(n, t)
minetest.register_node(modname .. ":ember" .. n, {
description = "Burning Embers",
tiles = {t},
paramtype = "light",
light_source = 6,
groups = {
igniter = 1,
ember = n,
falling_node = 1
},
drop = "",
diggable = false,
on_punch = function(pos, node, puncher, ...)
puncher:set_hp(puncher:get_hp() - 1)
return minetest.node_punch(pos, node, puncher, ...)
end,
crush_damage = 1
})
end
ember(1, modname .. "_ash.png^(" .. modname .. "_ember1.png^[opacity:128)")
ember(2, modname .. "_ash.png^" .. modname .. "_ember1.png")
ember(3, modname .. "_ash.png^" .. modname .. "_ember1.png^(" .. modname .. "_ember2.png^[opacity:128)")
ember(4, modname .. "_ash.png^" .. modname .. "_ember2.png")
ember(5, modname .. "_ash.png^" .. modname .. "_ember2.png^(" .. modname .. "_ember3.png^[opacity:128)")
ember(6, modname .. "_ember3.png")
minetest.register_alias(modname .. ":fuel", modname .. ":ember2")
minetest.register_node(modname .. ":ash", {
description = "Ash",
tiles = {modname .. "_ash.png"},
groups = {
falling_node = 1,
falling_repose = 1,
crumbly = 1
},
crush_damage = 0.25
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

View File

@ -0,0 +1,2 @@
nc_stats
nc_player

263
mods/nc_guide/init.lua Normal file
View File

@ -0,0 +1,263 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, minetest, nodecore, pairs, type
= ipairs, minetest, nodecore, pairs, type
-- LUALOCALS > ---------------------------------------------------------
local function conv(spec)
if not spec then
return function() return true end
end
if type(spec) == "function" then return spec end
if type(spec) == "table" then
local f = spec[1]
if f == true then
return function(db)
for i = 2, #spec do
if db[spec[i]] then return true end
end
end
end
return function(db)
for i = 2, #spec do
if not db[spec[i]] then return end
end
return true
end
end
return function(db) return db[spec] end
end
local function addhint(text, goal, reqs)
local hints = nodecore.hints
local h = {
text = text,
goal = conv(goal),
reqs = conv(reqs)
}
hints[#hints + 1] = h
return h
end
nodecore.hints = {}
nodecore.addhint = addhint
addhint("dug up dirt",
"nc_terrain:dirt_loose")
addhint("dug up sand",
"nc_terrain:sand_loose")
addhint("found dry leaves",
"nc_tree:leaves_loose")
addhint("found eggcorns",
"nc_tree:eggcorn")
addhint("planted an eggcorn",
"nc_tree:eggcorn_planted",
"nc_tree:eggcorn")
addhint("found sticks",
"nc_tree:stick")
addhint("crafted a staff from sticks",
"nc_woodwork:staff",
"nc_tree:stick")
addhint("crafted an adze out of sticks",
"nc_woodwork:adze",
{true, "nc_tree:stick", "nc_woodwork:staff"})
addhint("constructed a wooden ladder",
"nc_woodwork:ladder",
{true, "nc_tree:stick", "nc_woodwork:staff"})
addhint("constructed a wooden frame",
"nc_woodwork:frame",
{true, "nc_tree:stick", "nc_woodwork:staff"})
addhint("split a tree trunk into planks",
"nc_woodwork:plank",
{true, "nc_woodwork:adze", "nc_woodwork:tool_hatchet"})
local woodhead = addhint("carved wooden tool heads from planks",
{true,
"nc_woodwork:toolhead_mallet",
"nc_woodwork:toolhead_spade",
"nc_woodwork:toolhead_hatchet",
"nc_woodwork:toolhead_pick",
},
"nc_woodwork:plank")
addhint("assembled a wooden tool",
{true,
"nc_woodwork:tool_mallet",
"nc_woodwork:tool_spade",
"nc_woodwork:tool_hatchet",
"nc_woodwork:tool_pick",
},
woodhead.goal)
addhint("made each kinds of wooden tool head",
{
"nc_woodwork:toolhead_mallet",
"nc_woodwork:toolhead_spade",
"nc_woodwork:toolhead_hatchet",
"nc_woodwork:toolhead_pick",
},
woodhead.goal)
addhint("cut down a tree",
"nc_tree:tree",
"nc_woodwork:tool_hatchet")
addhint("dug up stone",
"nc_terrain:cobble_loose",
"nc_woodwork:tool_pick")
addhint("broken cobble into chips",
"nc_stonework:chip",
"nc_terrain:cobble_loose")
addhint("put a stone tip onto a tool",
{true,
"nc_stonework:tool_mallet",
"nc_stonework:tool_spade",
"nc_stonework:tool_hatchet",
"nc_stonework:tool_pick"
},
"nc_stonework:chip")
local embers = addhint("made fire by rubbing sticks together",
{true,
"nc_fire:ember1",
"nc_fire:ember2",
"nc_fire:ember3",
"nc_fire:ember4",
"nc_fire:ember5",
"nc_fire:ember6",
"nc_fire:ash",
},
"nc_tree:stick")
addhint("set fire to long-lasting fuels",
{true,
"nc_fire:ember5",
"nc_fire:ember6",
"nc_fire:ash",
},
embers.goal)
addhint("found ash",
"nc_fire:ash",
embers.goal)
local lodefind = addhint("found a lode deposit",
{true,
"nc_lode:stone",
"nc_lode:ore"
})
local lodeore = addhint("found lode ore",
"nc_lode:ore",
lodefind.goal)
addhint("dug out lode ore",
"nc_lode:cobble_loose",
lodeore.goal)
local lodesmelt = addhint("melted down lode metal",
{true,
"nc_lode:prill_hot",
"nc_lode:prill_annealed",
"nc_lode:prill_tempered"
},
"nc_lode:cobble_loose")
local anvil = addhint("constructed a lode anvil",
"nc_lode:block_tempered",
lodesmelt.goal)
local annealhead = addhint("cold-forged a lode tool head",
{true,
"nc_lode:toolhead_mallet_annealed",
"nc_lode:toolhead_spade_annealed",
"nc_lode:toolhead_hatchet_annealed",
"nc_lode:toolhead_pick_annealed"
},
anvil.goal)
addhint("tempered a lode tool head",
{true,
"nc_lode:toolhead_mallet_tempered",
"nc_lode:toolhead_spade_tempered",
"nc_lode:toolhead_hatchet_tempered",
"nc_lode:toolhead_pick_tempered"
},
annealhead.goal)
addhint("constructed a shelf",
"nc_woodwork:shelf",
{ "nc_woodwork:frame", "nc_woodwork:plank" })
addhint("found sponges",
{ "nc_sponge:sponge", "nc_sponge:sponge_wet", "nc_sponge:sponge_living" })
local function sethint(player)
local pname = player:get_player_name()
local rawdb = nodecore.statsdb[pname] or {}
local db = {}
for _, r in ipairs({"inv", "punch", "dig", "place"}) do
for k, v in pairs(rawdb[r] or {}) do
db[k] = v
end
end
local done = 0
local found = {}
for _, hint in ipairs(nodecore.hints) do
if hint.goal(db) then
done = done + 1
elseif hint.reqs(db) then
found[#found + 1] = hint.text
end
end
local hint = nodecore.pickrand(found)
hint = hint and (hint .. " yet") or "checked for a new version recently"
local prog = #found
local left = #(nodecore.hints) - prog - done
local stats = left .. ":" .. prog .. ":" .. done
return player:set_inventory_formspec(nodecore.inventory_formspec
.. "label[0,3.1;"
.. minetest.formspec_escape("...have you " .. hint .. "...?")
.. "]label[7.1,3.1;"
.. minetest.formspec_escape(stats)
.. "]"
)
end
minetest.register_on_joinplayer(function(player)
minetest.after(0, function() sethint(player) end)
end)
local seen
minetest.register_globalstep(function()
if not seen then return end
for _, player in pairs(minetest.get_connected_players()) do
local n = player:get_player_name()
if not seen[n] then
seen[n] = true
return sethint(player)
end
end
seen = nil
end)
local function pump()
minetest.after(20, pump)
seen = seen or {}
end
pump()

View File

@ -0,0 +1,789 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="57.655682mm"
height="691.86823mm"
viewBox="0 0 57.655682 691.86823"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r15371"
sodipodi:docname="crack_anylength.svg"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hand/textures/crack_anylength.png"
inkscape:export-xdpi="14.097483"
inkscape:export-ydpi="14.097483">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.175"
inkscape:cx="-1079.1999"
inkscape:cy="1997.4307"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-global="false"
inkscape:pagecheckerboard="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<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="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-59.996567,-44.032281)">
<g
id="g297"
style="stroke:#000000;stroke-opacity:0">
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 96.188159,45.378239 116.30629,65.496375"
id="path4678" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,65.496375 -7.36375,27.481884"
id="path4680" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 108.94254,92.978259 81.46066,100.34201"
id="path4682" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,100.34201 61.342525,80.22387"
id="path4684" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,80.22387 7.36375,-27.481883"
id="path4686" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 68.706275,52.741987 96.188159,45.378239"
id="path4688" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 93.960033,53.693716 107.99081,67.7245"
id="path4692"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,67.7245 -5.13562,19.166407"
id="path4694"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 102.85519,86.890907 83.688785,92.026533"
id="path4696"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 69.658001,77.995745 74.793626,58.829339"
id="path4700"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 74.793626,58.829339 93.960033,53.693716"
id="path4702"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,103.03393 20.118131,20.11813"
id="path4708" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,123.15206 -7.36375,27.48189"
id="path4710" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 108.94254,150.63395 81.46066,157.9977"
id="path4712" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,157.9977 61.342525,137.87956"
id="path4714" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,137.87956 7.36375,-27.48189"
id="path4716" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,110.39767 27.481884,-7.36374"
id="path4718" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,111.3494 14.030777,14.03079"
id="path4722"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,125.38019 -5.13562,19.1664"
id="path4724"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,144.54659 -19.166405,5.13563"
id="path4726"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,135.65143 5.135625,-19.1664"
id="path4730"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,160.68961 20.118131,20.11813"
id="path4738" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,180.80774 -7.36375,27.48189"
id="path4740" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,208.28963 -27.48188,7.36375"
id="path4742" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,215.65338 61.342525,195.53524"
id="path4744" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,195.53524 7.36375,-27.48188"
id="path4746" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,168.05336 27.481884,-7.36375"
id="path4748" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,169.00509 14.030777,14.03078"
id="path4752"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 102.85519,202.20228 83.688785,207.3379"
id="path4756"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,193.30712 5.135625,-19.16641"
id="path4760"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,218.3453 20.118131,20.11813"
id="path4768" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,238.46343 -7.36375,27.48189"
id="path4770" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,265.94532 -27.48188,7.36375"
id="path4772" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,273.30907 61.342525,253.19093"
id="path4774" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 68.706275,225.70905 96.188159,218.3453"
id="path4778" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,226.66078 14.030777,14.03078"
id="path4782"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,259.85797 -19.166405,5.13562"
id="path4786"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 69.658001,250.96281 74.793626,231.7964"
id="path4790"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,296.11912 -7.36375,27.48189"
id="path4800" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,323.60101 -27.48188,7.36375"
id="path4802" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,330.96476 61.342525,310.84662"
id="path4804" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,283.36474 27.481884,-7.36375"
id="path4808" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,284.31647 14.030777,14.03078"
id="path4812"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,317.51366 -19.166405,5.13562"
id="path4816"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,308.6185 5.135625,-19.16641"
id="path4820"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,353.77481 -7.36375,27.48188"
id="path4830" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,388.62044 61.342525,368.5023"
id="path4834" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,341.02042 27.481884,-7.36375"
id="path4838" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,341.97215 14.030777,14.03078"
id="path4842"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,375.16934 -19.166405,5.13562"
id="path4846"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,366.27418 5.135625,-19.16641"
id="path4850"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,411.43049 -7.36375,27.48189"
id="path4860" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,446.27613 61.342525,426.15799"
id="path4864" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,398.67611 27.481884,-7.36375"
id="path4868" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,399.62784 14.030777,14.03078"
id="path4872"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,432.82503 -19.166405,5.13562"
id="path4876"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,469.08618 -7.36375,27.48189"
id="path4890" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,503.93182 61.342525,483.81368"
id="path4894" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,456.3318 27.481884,-7.36375"
id="path4898" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,490.48072 -19.166405,5.13562"
id="path4906"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,526.74186 -7.36375,27.48189"
id="path4920" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,561.5875 61.342525,541.46936"
id="path4924" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,513.98748 27.481884,-7.36375"
id="path4928" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,584.39755 -7.36375,27.48189"
id="path4950" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,571.64317 27.481884,-7.36375"
id="path4958" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,642.05325 -7.36375,27.48188"
id="path4980" />
</g>
<g
id="g229"
style="stroke:#000000;stroke-opacity:1">
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,92.026533 69.658001,77.995745"
id="path4698"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,149.68222 69.658001,135.65143"
id="path4728"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 74.793626,116.48503 93.960033,111.3494"
id="path4732"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,183.03587 -5.13562,19.16641"
id="path4754"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,207.3379 69.658001,193.30712"
id="path4758"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,174.14071 19.166407,-5.13562"
id="path4762"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,253.19093 7.36375,-27.48188"
id="path4776" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,240.69156 -5.13562,19.16641"
id="path4784"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,264.99359 69.658001,250.96281"
id="path4788"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,231.7964 19.166407,-5.13562"
id="path4792"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,276.00099 20.118131,20.11813"
id="path4798" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,310.84662 7.36375,-27.48188"
id="path4806" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,298.34725 -5.13562,19.16641"
id="path4814"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,322.64928 69.658001,308.6185"
id="path4818"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,289.45209 19.166407,-5.13562"
id="path4822"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,333.65667 20.118131,20.11814"
id="path4828" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,381.25669 -27.48188,7.36375"
id="path4832" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,368.5023 7.36375,-27.48188"
id="path4836" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,356.00293 -5.13562,19.16641"
id="path4844"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,380.30496 69.658001,366.27418"
id="path4848"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,347.10777 19.166407,-5.13562"
id="path4852"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,391.31236 20.118131,20.11813"
id="path4858" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,438.91238 -27.48188,7.36375"
id="path4862" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,426.15799 7.36375,-27.48188"
id="path4866" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,413.65862 -5.13562,19.16641"
id="path4874"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,437.96065 69.658001,423.92987"
id="path4878"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,423.92987 5.135625,-19.16641"
id="path4880"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,404.76346 19.166407,-5.13562"
id="path4882"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,448.96805 20.118131,20.11813"
id="path4888" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,496.56807 -27.48188,7.36375"
id="path4892" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,483.81368 7.36375,-27.48188"
id="path4896" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,457.28353 14.030777,14.03078"
id="path4902"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,471.31431 -5.13562,19.16641"
id="path4904"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,495.61634 69.658001,481.58556"
id="path4908"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,481.58556 5.135625,-19.16641"
id="path4910"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,462.41915 19.166407,-5.13562"
id="path4912"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,506.62373 20.118131,20.11813"
id="path4918" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 108.94254,554.22375 81.46066,561.5875"
id="path4922" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,541.46936 7.36375,-27.48188"
id="path4926" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,514.93921 14.030777,14.03078"
id="path4932"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,528.96999 -5.13562,19.16641"
id="path4934"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,548.1364 -19.166405,5.13562"
id="path4936"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,553.27202 69.658001,539.24124"
id="path4938"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,539.24124 5.135625,-19.16641"
id="path4940"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,520.07483 19.166407,-5.13562"
id="path4942"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,564.27942 20.118131,20.11813"
id="path4948" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,611.87944 -27.48188,7.36375"
id="path4952" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,619.24319 61.342525,599.12505"
id="path4954" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,599.12505 7.36375,-27.48188"
id="path4956" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,572.5949 14.030777,14.03078"
id="path4962"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,586.62568 -5.13562,19.16641"
id="path4964"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,605.79209 -19.166405,5.13562"
id="path4966"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,610.92771 69.658001,596.89693"
id="path4968"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,596.89693 5.135625,-19.16641"
id="path4970"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 74.793626,577.73052 93.960033,572.5949"
id="path4972"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,621.93511 20.118131,20.11814"
id="path4978" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,669.53513 -27.48188,7.36375"
id="path4982" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,676.89888 61.342525,656.78074"
id="path4984" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,656.78074 7.36375,-27.48188"
id="path4986" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,629.29886 27.481884,-7.36375"
id="path4988" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,630.25059 14.030777,14.03078"
id="path4992"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,644.28137 -5.13562,19.16641"
id="path4994"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 102.85519,663.44778 83.688785,668.5834"
id="path4996"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,668.5834 69.658001,654.55262"
id="path4998"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,654.55262 5.135625,-19.16641"
id="path5000"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,635.38621 19.166407,-5.13562"
id="path5002"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 96.188159,679.59079 20.118131,20.11813"
id="path5008" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 116.30629,699.70892 -7.36375,27.48189"
id="path5010" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 108.94254,727.19081 -27.48188,7.36375"
id="path5012" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 81.46066,734.55456 61.342525,714.43642"
id="path5014" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 61.342525,714.43642 7.36375,-27.48188"
id="path5016" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 68.706275,686.95454 27.481884,-7.36375"
id="path5018" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 93.960033,687.90627 14.030777,14.03078"
id="path5022"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 107.99081,701.93705 -5.13562,19.16641"
id="path5024"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 102.85519,721.10346 -19.166405,5.13562"
id="path5026"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="M 83.688785,726.23908 69.658001,712.2083"
id="path5028"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 69.658001,712.2083 5.135625,-19.16641"
id="path5030"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.66499972;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m 74.793626,693.04189 19.166407,-5.13562"
id="path5032"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -0,0 +1,69 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="179.31755mm"
height="179.31754mm"
viewBox="0 0 179.31755 179.31754"
version="1.1"
id="svg8"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hand/textures/nc_hand.png"
inkscape:export-xdpi="9.0699997"
inkscape:export-ydpi="9.0699997"
inkscape:version="0.92.1 r15371"
sodipodi:docname="nc_hand.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.5"
inkscape:cx="-239.9946"
inkscape:cy="483.86365"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-global="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-object-midpoints="true" />
<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="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(239.76414,60.614077)">
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#cfa463;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m -215.74004,-36.589993 -24.0241,89.658585 65.63488,65.634868 89.658584,-24.02408 24.024081,-89.6585909 -65.634865,-65.6348661 4.96649,75.513239 z"
id="path4818"
inkscape:connector-curvature="0"
inkscape:export-xdpi="4.3800001"
inkscape:export-ydpi="4.3800001"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

1
mods/nc_hand/depends.txt Normal file
View File

@ -0,0 +1 @@
nc_api

16
mods/nc_hand/init.lua Normal file
View File

@ -0,0 +1,16 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, type
= minetest, nodecore, type
-- LUALOCALS > ---------------------------------------------------------
minetest.register_item(":", {
type = "none",
wield_image = "nc_hand.png",
wield_scale = {x=1, y=1, z=2.5},
tool_capabilities = nodecore.toolcaps({
uses = 0,
crumbly = 1,
snappy = 1,
thumpy = 1
})
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

View File

@ -0,0 +1 @@
nc_api

120
mods/nc_health/init.lua Normal file
View File

@ -0,0 +1,120 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, vector
= math, minetest, nodecore, pairs, vector
local math_pow, math_random, math_sqrt
= math.pow, math.random, math.sqrt
-- LUALOCALS > ---------------------------------------------------------
local cache = {}
local function envcheck(player)
local stats = {}
local pos = player:getpos()
pos.y = pos.y + 1.6
stats.light = minetest.get_node_light(pos)
local target = vector.add(pos, {
x = math_random() * 128 - 64,
y = math_random() * 128 - 64,
z = math_random() * 128 - 64
})
local _, hit = minetest.line_of_sight(pos, target)
hit = hit or target
stats.space = vector.distance(pos, hit)
local node = minetest.get_node(hit)
local def = minetest.registered_items[node.name]
local groups = def.groups or {}
stats.green = groups.green or 0
stats.water = groups.water or 0 + stats.green / 5
local pname = player:get_player_name()
local agg = cache[pname]
if not agg then
agg = {}
local raw = player:get_attribute("healthenv")
if raw and raw ~= "" then
agg = minetest.deserialize(raw)
end
cache[pname] = agg
end
for k, v in pairs(stats) do
agg[k] = ((agg[k] or 0) * 99 + v) / 100
end
agg.dirty = (agg.dirty or 0) + 1
if agg.dirty >= 5 then
agg.dirty = nil
player:set_attribute("healthenv",
minetest.serialize(agg))
nodecore.addphealth(player, 0.005 + (agg.green + 0.02)
* (agg.water + 0.1)
* (agg.space + 5)
* (agg.light + 8) / 500)
end
end
local function setspeed(player, speed)
if speed > 1 then speed = 1 end
if speed < 0 then speed = 0 end
local phys = player:get_physics_override()
if phys.speed == speed then return end
phys.speed = speed
return player:set_physics_override(phys)
end
local function mobility(player)
local health = nodecore.getphealth(player) / 20
if health >= 1 then return setspeed(player, 1) end
local inv = player:get_inventory()
local encumb = 0
local invsize = inv:get_size("main")
for i = 1, invsize do
if not inv:get_stack("main", i):is_empty() then
encumb = encumb + 1
end
end
encumb = encumb / invsize
if encumb <= health then return setspeed(player, 1) end
return setspeed(player, math_pow(1 - math_sqrt(encumb - health) * 0.8,
math_random() * 2 + 1))
end
local t = 0
minetest.register_globalstep(function(dt)
t = t + dt
while t > 0.5 do
t = t - 0.5
for _, player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 then
envcheck(player)
mobility(player)
end
end
end
end)
minetest.register_on_dieplayer(function(player)
local inv = player:get_inventory()
local pos = player:getpos()
for i = 1, inv:get_size("main") do
nodecore.item_eject(pos, inv:get_stack("main", i), 10)
end
inv:set_list("main", {})
-- flush attributes
player:set_attribute("healthenv", "")
cache[player:get_player_name()] = nil
player:set_attribute("dhp", "0")
end)
minetest.register_on_respawnplayer(function(player)
nodecore.setphealth(player, 0.0001)
mobility(player)
end)

View File

@ -0,0 +1,435 @@
<?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="292.05151mm"
height="76.025345mm"
viewBox="0 0 292.05152 76.025346"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r15371"
sodipodi:docname="huds.svg">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4554">
<stop
style="stop-color:#000000;stop-opacity:0.25098041"
offset="0"
id="stop4550" />
<stop
style="stop-color:#000000;stop-opacity:0.97072071"
offset="1"
id="stop4552" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4546">
<stop
style="stop-color:#000000;stop-opacity:0.0518018"
offset="0"
id="stop4542" />
<stop
style="stop-color:#000000;stop-opacity:0.50196081"
offset="1"
id="stop4544" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4536">
<stop
style="stop-color:#000000;stop-opacity:0"
offset="0"
id="stop4532" />
<stop
style="stop-color:#000000;stop-opacity:0.9617117"
offset="1"
id="stop4534" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient910">
<stop
style="stop-color:#000000;stop-opacity:0.0627451"
offset="0"
id="stop906" />
<stop
id="stop914"
offset="0.80191457"
style="stop-color:#000000;stop-opacity:0.50196081" />
<stop
style="stop-color:#000000;stop-opacity:1"
offset="1"
id="stop908" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4705">
<stop
style="stop-color:#00ffff;stop-opacity:0.06880734"
offset="0"
id="stop4701" />
<stop
id="stop4709"
offset="0.70539105"
style="stop-color:#00ffff;stop-opacity:0.0627451" />
<stop
style="stop-color:#00ffff;stop-opacity:0.50196081"
offset="1"
id="stop4703" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4579">
<stop
style="stop-color:#ff8282;stop-opacity:0.00688073"
offset="0"
id="stop4575" />
<stop
style="stop-color:#ff0101;stop-opacity:0.25098041"
offset="1"
id="stop4577" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4541">
<stop
style="stop-color:#ff8282;stop-opacity:1"
offset="0"
id="stop4537" />
<stop
style="stop-color:#f10000;stop-opacity:1"
offset="1"
id="stop4539" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4541"
id="radialGradient4609"
cx="-182.1636"
cy="182.13722"
fx="-182.1636"
fy="182.13722"
r="16.684004"
gradientTransform="matrix(1.025516,-0.24201646,0.16228335,0.68765639,-25.183535,12.459809)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4579"
id="radialGradient4651"
cx="-177.22122"
cy="190.00739"
fx="-177.22122"
fy="190.00739"
r="16.530289"
gradientTransform="matrix(1,0,0,1.1547005,0,-29.394244)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4705"
id="radialGradient4707"
cx="-177.22122"
cy="190.00739"
fx="-177.22122"
fy="190.00739"
r="16.530289"
gradientTransform="matrix(1.0761681,0,0,1.1547005,13.4986,-29.394244)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4705"
id="radialGradient4707-2"
cx="-177.22122"
cy="190.00739"
fx="-177.22122"
fy="190.00739"
r="16.530289"
gradientTransform="matrix(0.8313127,-0.22274957,0.25720904,0.95991718,49.685709,-29.290499)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient910"
id="radialGradient912"
cx="-177.22122"
cy="190.00739"
fx="-177.22122"
fy="190.00739"
r="17.207113"
gradientTransform="matrix(1.0819089,0,0,1.1486149,14.516002,-28.237938)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4536"
id="radialGradient4540"
gradientUnits="userSpaceOnUse"
cx="-130.18127"
cy="234.74574"
fx="-130.18127"
fy="234.74574"
r="13.701371" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4546"
id="radialGradient4548"
cx="-177.22122"
cy="190.00739"
fx="-177.22122"
fy="190.00739"
r="16.530289"
gradientTransform="matrix(1,0,0,1.1547005,0,-29.394244)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4554"
id="radialGradient4556"
cx="-177.22122"
cy="190.00739"
fx="-177.22122"
fy="190.00739"
r="17.207113"
gradientTransform="matrix(1,0,0,1.1486149,0,-28.237938)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.5877407"
inkscape:cx="153.44602"
inkscape:cy="51.80646"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:object-paths="true"
inkscape:snap-global="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<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="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(184.98757,-176.70911)">
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient4609);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.30742687;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4601"
sodipodi:sides="6"
sodipodi:cx="-177.22122"
sodipodi:cy="190.00739"
sodipodi:r1="19.087534"
sodipodi:r2="16.530289"
sodipodi:arg1="-0.52359878"
sodipodi:arg2="0"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m -160.69093,180.46362 0,19.08753 -16.53029,9.54377 -16.53029,-9.54377 0,-19.08753 16.53029,-9.54377 z"
inkscape:transform-center-x="-1.489252e-06"
transform="matrix(0.83131272,-0.22274957,0.22274957,0.83131272,-64.117671,-4.8546905)"
inkscape:transform-center-y="-2.8249933e-06"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hud/textures/heart.png"
inkscape:export-xdpi="25.610001"
inkscape:export-ydpi="25.610001" />
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient4651);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.30742687;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4601-2"
sodipodi:sides="6"
sodipodi:cx="-177.22122"
sodipodi:cy="190.00739"
sodipodi:r1="19.087534"
sodipodi:r2="16.530289"
sodipodi:arg1="-0.52359878"
sodipodi:arg2="0"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m -160.69093,180.46362 0,19.08753 -16.53029,9.54377 -16.53029,-9.54377 0,-19.08753 16.53029,-9.54377 z"
inkscape:transform-center-x="-1.489252e-06"
transform="matrix(0.83131271,-0.22274957,0.22274957,0.83131271,-24.000744,-4.85469)"
inkscape:transform-center-y="-2.8249933e-06"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hud/textures/heart_bg.png"
inkscape:export-xdpi="25.610001"
inkscape:export-ydpi="25.610001" />
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient4707);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.30742687;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4601-2-2"
sodipodi:sides="6"
sodipodi:cx="-177.22122"
sodipodi:cy="190.00739"
sodipodi:r1="19.087534"
sodipodi:r2="16.530289"
sodipodi:arg1="-0.52359878"
sodipodi:arg2="0"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m -160.69093,180.46362 0,19.08753 -16.53029,9.54377 -16.53029,-9.54377 0,-19.08753 16.53029,-9.54377 z"
inkscape:transform-center-x="-1.489252e-06"
transform="matrix(0.83131271,-0.22274957,0.22274957,0.83131271,16.116187,-4.85469)"
inkscape:transform-center-y="-2.8249933e-06"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hud/textures/bubble.png"
inkscape:export-xdpi="25.610001"
inkscape:export-ydpi="25.610001" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:url(#radialGradient4707-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
d="m -53.020439,176.70911 -3.112987,3.11247 7.364407,-1.97301 z m 11.616346,3.11299 5.389851,5.38985 -1.138947,-4.2509 z m -20.119698,5.39036 -3.11299,3.11248 1.13946,4.25193 z m 27.483073,7.36441 -1.973524,7.36493 3.112989,-3.11299 z m -27.483073,7.36441 1.13895,4.25142 4.251415,1.13947 z m 20.119698,5.39037 -7.364926,1.97352 4.251939,1.13947 z"
id="path4601-2-2-7"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hud/textures/bubble_bg.png"
inkscape:export-xdpi="25.610001"
inkscape:export-ydpi="25.610001" />
<path
sodipodi:type="star"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient4556);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.35364652;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
id="path4601-5"
sodipodi:sides="6"
sodipodi:cx="-177.22122"
sodipodi:cy="190.00739"
sodipodi:r1="19.087534"
sodipodi:r2="16.530289"
sodipodi:arg1="-0.52359878"
sodipodi:arg2="0"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m -160.69093,180.46362 0,19.08753 -16.53029,9.54377 -16.53029,-9.54377 0,-19.08753 16.53029,-9.54377 z"
inkscape:transform-center-x="-3.3205021e-06"
transform="matrix(-0.83131271,-0.22274957,-0.22274957,0.83131271,-274.12205,39.435236)"
inkscape:transform-center-y="-2.8249933e-06"
inkscape:export-filename="/home/warr/.minetest/games/nodecore/mods/nc_hud/textures/nc_hud_sel.png"
inkscape:export-xdpi="24.704863"
inkscape:export-ydpi="24.704863" />
<g
id="g4733"
inkscape:export-filename="/home/warr/.minetest/games/nodecore/mods/nc_hud/textures/nc_hud_bg.png"
inkscape:export-xdpi="25.611759"
inkscape:export-ydpi="25.611759">
<g
inkscape:tile-y0="42.168923"
inkscape:tile-x0="38.938588"
inkscape:tile-h="31.73542"
inkscape:tile-w="31.73542"
inkscape:tile-cy="58.036633"
inkscape:tile-cx="54.806298"
style="stroke-width:0.86347502;fill-opacity:1;fill:url(#radialGradient4540)"
transform="matrix(1.1581111,0,0,1.1581111,20.583101,-37.115906)"
inkscape:export-ydpi="25.610001"
inkscape:export-xdpi="25.610001"
inkscape:export-filename="/home/warr/.minetest/games/nodecore/mods/nc_hud/textures/nc_hud_bg.png"
id="g4645">
<g
id="g904"
style="stroke:none;stroke-width:0.86347502;fill-opacity:1;fill:url(#radialGradient4540)"
inkscape:export-filename="/home/warr/.minetest/games/nodecore/mods/nc_hud/textures/nc_hud_bg.png"
inkscape:export-xdpi="25.610001"
inkscape:export-ydpi="25.610001"
transform="translate(-4.5158714,-13.997881)"
inkscape:tile-cx="96.101565"
inkscape:tile-cy="60.15763"
inkscape:tile-w="31.475583"
inkscape:tile-h="31.475581"
inkscape:tile-x0="80.363773"
inkscape:tile-y0="44.419839">
<path
inkscape:export-ydpi="25.610001"
inkscape:export-xdpi="25.610001"
inkscape:export-filename="/home/warr/git/gitlab.com/sztest/nodecore/mods/nc_hud/textures/heart.png"
inkscape:transform-center-y="-2.0272473e-06"
transform="matrix(-0.71781778,-0.19233869,-0.19233869,0.71781778,-216.33217,78.266446)"
d="m -160.69093,180.46362 0,19.08753 -16.53029,9.54377 -16.53029,-9.54377 0,-19.08753 16.53029,-9.54377 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="0"
sodipodi:arg1="-0.52359878"
sodipodi:r2="16.530289"
sodipodi:r1="19.087534"
sodipodi:cy="190.00739"
sodipodi:cx="-177.22122"
sodipodi:sides="6"
id="path4601-5-2"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient4548);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.30742687;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
sodipodi:type="star" />
</g>
</g>
<use
id="use4709"
transform="translate(31.73542)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
<use
id="use4711"
transform="translate(63.47084)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
<use
id="use4713"
transform="translate(95.20626)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
<use
id="use4715"
transform="translate(126.94168)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
<use
id="use4717"
transform="translate(158.6771)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
<use
id="use4719"
transform="translate(190.41252)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
<use
id="use4721"
transform="translate(222.14794)"
xlink:href="#g4645"
inkscape:tiled-clone-of="#g4645"
y="0"
x="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

1
mods/nc_hud/depends.txt Normal file
View File

@ -0,0 +1 @@
nc_api

47
mods/nc_hud/init.lua Normal file
View File

@ -0,0 +1,47 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest
= minetest
-- LUALOCALS > ---------------------------------------------------------
local health_bar_definition =
{
hud_elem_type = "statbar",
position = {x = 0.5, y = 1},
text = "heart_bg.png",
number = 20,
direction = 0,
size = {x = 24, y = 24},
offset = { x = (-10 * 24) - 25, y = -(48 + 24 + 16)},
}
local breath_bar_definition =
{
hud_elem_type = "statbar",
position = {x = 0.5, y = 1},
text = "bubble_bg.png",
number = 20,
direction = 0,
size = {x = 24, y = 24},
offset = {x = 25, y = -(48 + 24 + 16)},
}
local reg_bubbles = {}
local function checkbubbles(player)
local name = player:get_player_name()
if player:get_breath() < 11 then
reg_bubbles[name] = reg_bubbles[name] or player:hud_add(breath_bar_definition)
elseif reg_bubbles[name] then
player:hud_remove(reg_bubbles[name])
reg_bubbles[name] = nil
end
end
minetest.register_playerevent(checkbubbles)
minetest.register_on_joinplayer(function(player)
minetest.after(0, function()
player:hud_add(health_bar_definition)
checkbubbles(player)
end)
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,3 @@
nc_api
nc_api_craft
nc_fire?

179
mods/nc_items/init.lua Normal file
View File

@ -0,0 +1,179 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, math, minetest, nodecore, setmetatable, type, vector
= ItemStack, math, minetest, nodecore, setmetatable, type, vector
local math_random
= math.random
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local stackbox = nodecore.fixedbox(-0.4, -0.5, -0.4, 0.4, 0.3, 0.4)
local function invdef(pos)
local stack = nodecore.stack_get(pos)
if not stack or stack:is_empty() then return end
local def = minetest.registered_items[stack:get_name()]
return stack:get_count() == (def.pummel_stack or 1) and def or nil
end
minetest.register_node(modname .. ":stack", {
drawtype = "nodebox",
node_box = nodecore.fixedbox(
{-0.5, -0.5, -0.5, 0.5, -7/16, 0.5}
),
use_texture_alpha = true,
tiles = {
"nc_items_shadow.png",
"nc_items_blank.png",
},
walkable = true,
selection_box = stackbox,
collision_box = stackbox,
drop = {},
groups = {
snappy = 1,
falling_repose = 1,
visinv = 1,
is_stack_only = 1
},
paramtype = "light",
sunlight_propagates = true,
repose_drop = function(posfrom, posto, node)
local stack = nodecore.stack_get(posfrom)
if stack and not stack:is_empty() then
nodecore.item_eject(posto, stack)
end
return minetest.remove_node(posfrom)
end,
on_rightclick = function(pos, node, whom, stack, pointed, ...)
if not nodecore.interact(whom) then return stack end
return nodecore.stack_add(pos, stack)
end
})
function nodecore.place_stack(pos, stack, placer, pointed_thing)
stack = ItemStack(stack)
local name = stack:get_name()
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
if nodecore.match(below, {name = name, count = false}) then
stack = nodecore.stack_add(below, stack)
if stack:is_empty() then return end
end
minetest.set_node(pos, {name = modname .. ":stack"})
nodecore.stack_set(pos, stack)
if placer and pointed_thing then
nodecore.craft_check(pos, {name = stack:get_name()}, {
action = "place",
crafter = placer,
pointed = pointed_thing
})
end
return minetest.check_for_falling(pos)
end
local bii = minetest.registered_entities["__builtin:item"]
local item = {
on_step = function(self, dtime, ...)
bii.on_step(self, dtime, ...)
local pos = self.object:getpos()
if not self.oldpos or not vector.equals(pos, self.oldpos) then
self.oldpos = pos
self.sitting = 0
return
end
self.sitting = (self.sitting or 0) + dtime
if self.sitting < 0.25 then return end
pos = vector.round(pos)
local i = ItemStack(self.itemstring)
pos = nodecore.scan_flood(pos, 5,
function(p)
if p.y > pos.y then return end
i = nodecore.stack_add(p, i)
if i:is_empty() then return p end
if nodecore.buildable_to(p) then return p end
end)
if not pos then return end
if not i:is_empty() then nodecore.place_stack(pos, i) end
self.itemstring = ""
self.object:remove()
end,
on_punch = function(self, whom, ...)
if not nodecore.interact(whom) then return end
local r = bii.on_punch(self, whom, ...)
if self.itemstring ~= "" then
local v = self.object:get_velocity()
v.x = v.x + math_random() * 5 - 2.5
v.y = v.y + math_random() * 5 - 2.5
v.z = v.z + math_random() * 5 - 2.5
self.object:set_velocity(v)
end
end
}
setmetatable(item, bii)
minetest.register_entity(":__builtin:item", item)
local bifn = minetest.registered_entities["__builtin:falling_node"]
local falling = {
set_node = function(self, node, meta, ...)
if node and node.name == modname .. ":stack"
and meta and meta.inventory and meta.inventory.solo then
local stack = ItemStack(meta.inventory.solo[1] or "")
if not stack:is_empty() then
nodecore.item_eject(self.object:getpos(), stack,
nil, nil, {x = 0, y = 0.01, z = 0})
return self.object:remove()
end
end
return bifn.set_node(self, node, meta, ...)
end
}
setmetatable(falling, bifn)
minetest.register_entity(":__builtin:falling_node", falling)
function minetest.item_place(itemstack, placer, pointed_thing, param2)
if not nodecore.interact(placer) then return end
if pointed_thing.type == "node" and placer and
not placer:get_player_control().sneak then
local n = minetest.get_node(pointed_thing.under)
local nn = n.name
if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then
return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, n,
placer, itemstack, pointed_thing) or itemstack, false
end
end
if itemstack:get_definition().type == "node" then
return minetest.item_place_node(itemstack, placer, pointed_thing, param2)
end
if not itemstack:is_empty() then
local above = minetest.get_pointed_thing_position(pointed_thing, true)
if above and nodecore.buildable_to(above) then
nodecore.place_stack(above, itemstack:take_item(), placer, pointed_thing)
end
end
return itemstack
end
if nodecore.loaded_mods().nc_fire then
nodecore.register_limited_abm({
label = "Flammable ItemStacks Ignite",
interval = 5,
chance = 1,
nodenames = {modname .. ":stack"},
neighbors = {"group:igniter"},
action = function(pos, node)
if nodecore.quenched(pos) then return end
local def = invdef(pos)
local flam = def and def.groups and def.groups.flammable
if not flam then return end
if math_random(1, flam) ~= 1 then return end
nodecore.ignite(pos, node)
end
})
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

3
mods/nc_lode/depends.txt Normal file
View File

@ -0,0 +1,3 @@
nc_api
nc_items
nc_terrain

11
mods/nc_lode/init.lua Normal file
View File

@ -0,0 +1,11 @@
-- LUALOCALS < ---------------------------------------------------------
local include, minetest
= include, minetest
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local path = minetest.get_modpath(modname)
include("ore")
include("metallurgy")
include("tools")

165
mods/nc_lode/metallurgy.lua Normal file
View File

@ -0,0 +1,165 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs, type
= minetest, nodecore, pairs, type
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
function nodecore.register_lode(shape, rawdef)
for _, temper in pairs({"Hot", "Annealed", "Tempered"}) do
local def = nodecore.underride({}, rawdef)
def = nodecore.underride(def, {
description = temper .. " Lode " .. shape,
name = (shape .. "_" .. temper):lower():gsub(" ", "_"),
groups = { cracky = 3 },
["metal_temper_" .. temper:lower()] = true,
metal_alt_hot = modname .. ":" .. shape:lower() .. "_hot",
metal_alt_annealed = modname .. ":" .. shape:lower() .. "_annealed",
metal_alt_tempered = modname .. ":" .. shape:lower() .. "_tempered",
})
if temper ~= "Hot" then
def.light_source = nil
else
def.groups = def.groups or {}
def.groups.falling_node = 1
def.damage_per_second = 2
end
if def.tiles then
local t = {}
for k, v in pairs(def.tiles) do
t[k] = v:gsub("#", temper:lower())
end
def.tiles = t
end
for k, v in pairs(def) do
if type(v) == "string" then
def[k] = v:gsub("##", temper):gsub("#", temper:lower())
end
end
if def.bytemper then def.bytemper(temper, def) end
minetest.register_item(modname .. ":" .. def.name, def)
end
end
nodecore.register_lode("Block", {
type = "node",
tiles = { modname .. "_#.png" },
light_source = 8,
crush_damage = 4
})
nodecore.register_lode("Prill", {
type = "craft",
inventory_image = modname .. "_#.png^[mask:" .. modname .. "_mask_prill.png",
})
local flame = {groups = {flame = true}}
local function heated(pos)
if nodecore.quenched(pos) then return end
local f = 0
if nodecore.match({x = pos.x, y = pos.y - 1, z = pos.z}, flame)
then f = f + 1 end
if nodecore.match({x = pos.x + 1, y = pos.y, z = pos.z}, flame)
then f = f + 1 end
if nodecore.match({x = pos.x - 1, y = pos.y, z = pos.z}, flame)
then f = f + 1 end
if f >= 3 then return true end
if nodecore.match({x = pos.x, y = pos.y, z = pos.z + 1}, flame)
then f = f + 1 end
if f >= 3 then return true end
if nodecore.match({x = pos.x, y = pos.y, z = pos.z - 1}, flame)
then f = f + 1 end
if f >= 3 then return true end
end
local function timecounter(meta, max, check)
if not check then
local t = meta:to_table()
t.fields.time = nil
meta:from_table(t)
return
end
local t = (meta:get_int("time") or 0) + 1
if t >= max then return true end
meta:set_int("time", t)
end
nodecore.register_limited_abm({
label = "Lode Cobble to Prills",
interval = 1,
chance = 1,
nodenames = {modname .. ":cobble"},
neighbors = {"group:flame"},
action = function(pos, node)
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
if timecounter(minetest:get_meta(pos), 30,
not nodecore.match(below, {walkable = true}) and heated(pos)) then
nodecore.item_eject(below, modname .. ":prill_hot 2")
minetest:get_meta(pos):from_table({})
return nodecore.set_node(pos, {name = "nc_terrain:cobble"})
end
end})
local function replacestack(pos, name, stack)
nodecore.remove_node(pos)
return nodecore.item_eject(pos, name .. " " .. stack:get_count())
end
nodecore.register_limited_abm({
label = "Lode Stack Heating/Cooling",
interval = 1,
chance = 1,
nodenames = {"group:visinv"},
action = function(pos, node)
local stack = nodecore.stack_get(pos)
if stack:is_empty() then return end
local def = minetest.registered_items[stack:get_name()]
if not def then return end
if def.metal_temper_hot then
if nodecore.quenched(pos) then
return replacestack(pos, def.metal_alt_tempered, stack)
end
if timecounter(stack:get_meta(), 120, not heated(pos)) then
return replacestack(pos, def.metal_alt_annealed, stack)
end
elseif (def.metal_temper_annealed or def.metal_temper_tempered)
and timecounter(stack:get_meta(), 30, heated(pos)) then
return replacestack(pos, def.metal_alt_hot, stack)
end
return nodecore.stack_set(pos, stack)
end})
-- Because of how massive they are, forging a block is a hot-working process.
nodecore.register_craft({
label = "forge lode block",
action = "pummel",
toolgroups = {thumpy = 3},
nodes = {
{
match = {name = modname .. ":prill_hot", count = 8},
replace = "air"
}
},
items = {
modname .. ":block_hot"
}
})
-- Blocks can be chopped back into prills using only hardened tools.
nodecore.register_craft({
label = "break apart lode block",
action = "pummel",
toolgroups = {choppy = 5},
nodes = {
{
match = modname .. ":block_annealed",
replace = "air"
}
},
items = {
{name = modname .. ":prill_annealed", count = 8, scatter = 5}
}
})

133
mods/nc_lode/ore.lua Normal file
View File

@ -0,0 +1,133 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore
= minetest, nodecore
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local function reg(suff, def)
def = nodecore.underride(def, {
description = "Lode " .. suff,
name = suff:lower(),
is_ground_content = true,
groups = { cracky = 2 }
})
def.fullname = modname .. ":" .. def.name
def.oldnames = {"nc_iron:" .. def.name}
minetest.register_node(def.fullname, def)
return def.fullname
end
local stratstone = {}
local stratore = {}
local stone = reg("Stone", {
tiles = { "nc_terrain_stone.png^(" .. modname .. "_ore.png^[mask:"
.. modname .. "_mask_ore.png^[opacity:48)" },
drop_in_place = "nc_terrain:cobble",
strata = stratstone
})
stratstone[1] = stone
local ore = reg("Ore", {
tiles = { "nc_terrain_stone.png^(" .. modname .. "_ore.png^[mask:"
.. modname .. "_mask_ore.png)" },
drop_in_place = modname .. ":cobble",
strata = stratore
})
stratore[1] = ore
for i = 1, nodecore.hard_stone_strata do
local hst = nodecore.hard_stone_tile(i)
stratstone[i + 1] = reg("Stone_" .. i, {
tiles = { hst .. "^(" .. modname .. "_ore.png^[mask:"
.. modname .. "_mask_ore.png^[opacity:48)" },
drop_in_place = "nc_terrain:cobble",
strata = stratstone,
groups = {cracky = i + 2}
})
stratore[i + 1] = reg("Ore_" .. i, {
tiles = { hst .. "^(" .. modname .. "_ore.png^[mask:"
.. modname .. "_mask_ore.png)" },
drop_in_place = modname .. ":cobble",
strata = stratore,
groups = {cracky = i + 2}
})
end
reg("Cobble", {
tiles = { modname .. "_ore.png^nc_terrain_cobble.png" },
alternate_loose = {
repack_level = 2,
groups = {
cracky = 0,
crumbly = 2,
falling_repose = 3
}
}
})
local function regore(name, def)
return minetest.register_ore(nodecore.underride(def, {
name = name,
ore_type = "scatter",
ore = name,
wherein = "nc_terrain:stone",
random_factor = 0,
noise_params = {
offset = 0,
scale = 4,
spread = {x=40, y=5, z=40},
seed = 12497,
octaves = 3,
persist = 0.5,
flags = "eased",
},
noise_threshold = 1.3
}, def))
end
regore(ore, {
clust_num_ores = 16,
clust_size = 3,
clust_scarcity = 8 * 8 * 8,
})
regore(stone, {
clust_num_ores = 4,
clust_size = 3,
clust_scarcity = 2 * 2 * 2,
})
local c_ore = minetest.get_content_id(ore)
local c_istone = minetest.get_content_id(stone)
local c_stone = minetest.get_content_id("nc_terrain:stone")
nodecore.register_mapgen_shared(function(minp, maxp, area, data, vm, emin, emax)
local function bad(x, y, z)
local c = data[area:index(x, y, z)]
return c ~= c_stone and c ~= c_istone
end
for z = minp.z, maxp.z do
for y = minp.y, maxp.y do
for x = minp.x, maxp.x do
local i = area:index(x, y, z)
if data[i] == c_ore then
if x == minp.x
or x == maxp.x
or y == minp.y
or y == maxp.y
or z == minp.z
or z == maxp.z
or bad(x + 1, y, z)
or bad(x - 1, y, z)
or bad(x, y + 1, z)
or bad(x, y - 1, z)
or bad(x, y, z + 1)
or bad(x, y, z - 1)
then data[i] = c_istone
end
end
end
end
end
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

89
mods/nc_lode/tools.lua Normal file
View File

@ -0,0 +1,89 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs, type
= minetest, nodecore, pairs, type
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local function toolhead(name, group)
local n = name:lower()
nodecore.register_lode("toolhead_" .. n, {
type = "craft",
description = "## Lode " .. name .. " Head",
inventory_image = modname .. "_#.png^[mask:" ..
modname .. "_toolhead_" .. n .. ".png",
stack_max = 1
})
nodecore.register_lode("tool_" .. n, {
type = "tool",
description = "## Lode " .. name,
inventory_image = modname .. "_tool_handle.png^(" ..
modname .. "_#.png^[mask:" ..
modname .. "_tool_" .. n .. ".png)",
stack_max = 1,
tool_capabilities = nodecore.toolcaps({
[group] = 4
}),
bytemper = function(t, d)
if t == "Tempered" then
d.tool_capabilities = nodecore.toolcaps({
[group] = 5
})
end
end,
metal_alt_hot = modname .. ":toolhead_" .. n .. "_hot",
tool_wears_to = modname .. ":prill_# 3",
})
for _, t in pairs({"annealed", "tempered"}) do
nodecore.register_craft({
label = "assemble lode " .. n,
normal = {y = 1},
nodes = {
{match = modname .. ":toolhead_" .. n .. "_" .. t,
replace = "air"},
{y = -1, match = "nc_woodwork:staff", replace = "air"},
},
items = {
{y = -1, name = modname .. ":tool_" .. n .. "_" .. t},
}
})
end
end
toolhead("Mallet", "thumpy")
toolhead("Spade", "crumbly")
toolhead("Hatchet", "choppy")
toolhead("Pick", "cracky")
local function forge(from, fromqty, to, prills)
return nodecore.register_craft({
label = "anvil making lode " .. (to or "prills"),
action = "pummel",
toolgroups = {thumpy = 3},
nodes = {
{
match = {name = modname .. ":" .. from .. "_annealed",
count = fromqty},
replace = "air"
},
{
y = -1,
match = modname .. ":block_tempered"
}
},
items = {
to and (modname .. ":" .. to .. "_annealed") or nil,
prills and {name = modname .. ":prill_annealed", count = prills,
scatter = 5} or nil
}
})
end
forge("prill", 3, "toolhead_mallet")
forge("toolhead_mallet", nil, "toolhead_spade", 1)
forge("toolhead_spade", nil, "toolhead_hatchet")
forge("toolhead_hatchet", nil, "toolhead_pick", 1)
forge("toolhead_pick", nil, nil, 1)

View File

@ -0,0 +1 @@
nc_api

225
mods/nc_namehuds/init.lua Normal file
View File

@ -0,0 +1,225 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, nodecore, pairs, string, tonumber
= math, minetest, nodecore, pairs, string, tonumber
local math_sqrt, string_format
= math.sqrt, string.format
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
-- Maximum distance at which custom nametags are visible.
local distance = tonumber(minetest.setting_get(modname .. "_distance")) or 8
-- Precision (number of steps) for line-of-sight check for displaying nametags
local precision = tonumber(minetest.setting_get(modname .. "_precision")) or 50
-- Keep track of active player HUDs.
local huds = {}
------------------------------------------------------------------------
-- PLAYER JOIN/LEAVE
-- On player joining, disable the built-in nametag by setting its
-- text to whitespace and color to transparent.
minetest.register_on_joinplayer(function(player)
player:set_nametag_attributes({
text = " ",
color = {a = 0, r = 0, g = 0, b = 0}
})
end)
-- On player leaving, clean up any associated HUDs.
minetest.register_on_leaveplayer(function(player)
-- Garbage-collect player's own HUDs.
local pn = player:get_player_name()
huds[pn] = nil
-- Remove HUDs for this player's name
-- from other players
for k, v in pairs(huds) do
local i = v[pn]
if i then
i.o:hud_remove(i.i)
v[pn] = nil
end
end
end)
------------------------------------------------------------------------
-- GLOBAL TICK HUD MANAGEMENT
-- Vague health descriptions
local health = {
"critically injured",
"critically injured",
"heavily injured",
"heavily injured",
"heavily injured",
"heavily injured",
"injured",
"injured",
"injured",
"injured",
"injured",
"injured",
"slightly injured",
"slightly injured",
"slightly injured",
"slightly injured",
"barely scratched",
"barely scratched",
"barely scratched",
"uninjured"
}
-- Get custom text for a visible HUD.
local function gettext(p2, n2)
-- First line: distance units, player HP.
local t = "m " .. (health[p2:get_hp()] or "?")
-- Check for a wielded item, and add its description
-- to a line below if available.
local w = p2:get_wielded_item()
if w then
w = w:get_name()
local r = minetest.registered_items[w]
t = t .. "\n" .. (r and r.description or w)
end
if not nodecore.interact(n2) then
t = t .. "\nSPECTATOR"
end
return t
end
-- Determine if two players can see one another, using a
-- shared cache for commutitivity.
local function cansee(p1, n1, p2, n2, los)
-- Sight is communitive: if p1 can see p2, p2 can see p1.
-- Compute a single shared cache key for both players that's
-- independent of order, and check for a cached result for
-- this player pair.
local loskey = (n1 < n2)
and (string_format("%q", n1) .. "|" .. string_format("%q", n2))
or (string_format("%q", n2) .. "|" .. string_format("%q", n1))
local l = los[loskey]
if l ~= nil then return l end
-- Dead players neither see, nor are recognizable.
if p1:get_hp() < 1 or p2:get_hp() < 1 then
los[loskey] = false
return
end
-- Players must be within max distance of one another.
local o1 = p1:getpos()
local o2 = p2:getpos()
local dx = o1.x - o2.x
local dy = o1.y - o2.y
local dz = o1.z - o2.z
if (dx * dx + dy * dy + dz * dz) > (distance * distance) then
los[loskey] = false
return
end
-- Check for line of sight from approximage eye level
-- of one player to the other.
o1.y = o1.y + 1.5
o2.y = o2.y + 1.5
l = minetest.line_of_sight(o1, o2, distance / precision) or false
-- Cache result (for checking opposite direction).
los[loskey] = l
return l
end
-- Determine if player 1 can see player 2's face, including
-- checks for distance, line-of-sight, and facing direction.
local function canseeface(p1, n1, p2, n2, los)
-- Checks for reciprocal line-of-sight.
if not cansee(p1, n1, p2, n2, los) then return end
-- Players must be facing each other; cannot identify another
-- player's face when their back is turned. Note that
-- minetest models don't show pitch, so ignore the y component.
-- Compute normalized 2d vector from one player to another.
local o1 = p1:getpos()
local o2 = p2:getpos()
local ll = minetest.get_node_light({x = o2.x, y = o2.y + 1.6, z = o2.z})
if ll < 5 then return end
local dx = o1.x - o2.x
local dz = o1.z - o2.z
local d = dx * dx + dz * dz
if d == 0 then return end
d = math_sqrt(d)
dx = dx / d
dz = dz / d
-- Compute normalized 2d facing direction vector for target player.
local l2 = p2:get_look_dir()
d = l2.x * l2.x + l2.z * l2.z
if d == 0 then return end
d = math_sqrt(d)
l2.x = l2.x / d
l2.z = l2.z / d
-- Compare directions via dot product.
if (dx * l2.x + dz * l2.z) <= 0.5 then return end
return true
end
-- On each global step, check all player visibility, and create/remove/update
-- each player's HUDs accordingly.
minetest.register_globalstep(function()
local los = {}
local conn = minetest.get_connected_players()
for _, p1 in pairs(conn) do
local n1 = p1:get_player_name()
local h = huds[n1]
if not h then
h = {}
huds[n1] = h
end
for _, p2 in pairs(conn) do
if p2 ~= p1 then
local n2 = p2:get_player_name()
local i = h[n2]
if canseeface(p1, n1, p2, n2, los) then
local p = p2:getpos()
p.y = p.y + 1.25
local t = gettext(p2, n2)
-- Create a new HUD if not present.
if not i then
i = {o = p1, t = t, p = p}
i.i = p1:hud_add({
hud_elem_type = "waypoint",
world_pos = p,
name = n2,
text = t,
number = 0xffffff
})
h[n2] = i
end
-- Update HUD if outdated.
if p.x ~= i.p.x or p.y ~= i.p.y or p.z ~= i.p.z then
p1:hud_change(i.i, "world_pos", p)
i.p = p
end
if i.t ~= t then
p1:hud_change(i.i, "text", t)
i.t = t
end
elseif i then
-- Remove HUD if visibility lost.
p1:hud_remove(i.i)
h[n2] = nil
end
end
end
end
end)

View File

@ -0,0 +1,48 @@
-- LUALOCALS < ---------------------------------------------------------
local math, minetest, pairs, vector
= math, minetest, pairs, vector
local math_floor
= math.floor
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local fallname = "__builtin:falling_node"
local fallnode = minetest.registered_entities[fallname]
local dmg = {}
local function dmggc()
dmg = {}
minetest.after(10, dmggc)
end
dmggc()
local oldtick = fallnode.on_step
fallnode.on_step = function(self, dtime, ...)
if not self.crush_damage then
local def = minetest.registered_items[self.node.name]
self.crush_damage = def and def.crush_damage or 0
end
if self.crush_damage <= 0 then
return oldtick(self, dtime, ...)
end
local pos = self.object:getpos()
local vel = self.object:getvelocity()
local q = dmg[self] or 0
local v = vector.length(vel)
q = q + v * v * dtime * self.crush_damage
if q > 1 then
local n = math_floor(q)
for k, v in pairs(minetest.get_objects_inside_radius(pos, 1)) do
v:set_hp(v:get_hp() - n)
end
q = q - n
end
dmg[self] = q
return oldtick(self, dtime, ...)
end
minetest.register_entity(":" .. fallname, fallnode)

Some files were not shown because too many files have changed in this diff Show More