BETA
116
README.txt
Normal file
@ -0,0 +1,116 @@
|
||||
--Extreme Survival created by maikerumine
|
||||
-- Minetest 0.4.13 mod: "Extreme Survival"
|
||||
-- namespace: es
|
||||
-- (c) 2014-2015 by: maikerumine
|
||||
--https://github.com/maikerumine
|
||||
--WTFPL
|
||||
|
||||
|
||||
|
||||
Minetest 0.2 mod: es ore generation and special crafting
|
||||
=======================
|
||||
|
||||
___________ __ _________ .__ .__
|
||||
\_ _____/__ ____/ |________ ____ _____ ____ / _____/__ ____________ _|__|__ _______ | |
|
||||
| __)_\ \/ /\ __\_ __ \_/ __ \ / \_/ __ \ \_____ \| | \_ __ \ \/ / \ \/ /\__ \ | |
|
||||
| \> < | | | | \/\ ___/| Y Y \ ___/ / \ | /| | \/\ /| |\ / / __ \| |__
|
||||
/_______ /__/\_ \ |__| |__| \___ >__|_| /\___ > /_______ /____/ |__| \_/ |__| \_/ (____ /____/
|
||||
\/ \/ \/ \/ \/ \/ \/
|
||||
|
||||
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2015 maikerumine
|
||||
|
||||
WTFPL
|
||||
|
||||
|
||||
Craft dirt from 9 papyrus..
|
||||
Craft Mese Crystal from 9 Mese Shards... (soft dependancy to mese_crystals mod)
|
||||
Craft 3 Desert Cobble from one brick and two cobble, brick on top of craft...
|
||||
Emeralds: Below -1000
|
||||
Rubys: Below -3000
|
||||
Aikerum: Below -4000
|
||||
Infinium: Below -4300
|
||||
These can craft into very strong tools and weapons. As of current the Infinuim ingots can be made into infinium armour. (soft dependancy to esarmor mod) You can consider finding Infinium winning the game.
|
||||
To craft these tools you will replace the stick with an iron ingot.
|
||||
To craft an Infinium ingot you must craft first a vessel with Infinium goo to get Infinium container and water flowing. then cook the Infinium container in oven to get ingot.
|
||||
|
||||
Water flowing comes from cooking ice in furnace.
|
||||
|
||||
|
||||
es-- Maikerumine's Extreme Survival mod, has extra crafting recipies for tools and ores.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
soft dependancies:
|
||||
|
||||
|
||||
esarmor
|
||||
mese_crystals
|
||||
technic
|
||||
|
||||
These are heavily modded to suit the Extreme Survival game.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The main game for the Minetest game engine [minetest_game]
|
||||
==========================================================
|
||||
|
||||
To use this game with Minetest, insert this repository as
|
||||
/games/minetest_game
|
||||
in the Minetest Engine.
|
||||
|
||||
The Minetest Engine can be found in:
|
||||
https://github.com/minetest/minetest/
|
||||
|
||||
Compatibility
|
||||
--------------
|
||||
The minetest_game github master HEAD is generally compatible with the github
|
||||
master HEAD of minetest.
|
||||
|
||||
Additionally, when the minetest engine is tagged to be a certain version (eg.
|
||||
0.4.10), minetest_game is tagged with the version too.
|
||||
|
||||
When stable releases are made, minetest_game is packaged and made available in
|
||||
http://minetest.net/download
|
||||
and in case the repository has grown too much, it may be reset. In that sense,
|
||||
this is not a "real" git repository. (Package maintainers please note!)
|
||||
|
||||
License of source code
|
||||
----------------------
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
See README.txt in each mod directory for information about other authors.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
See README.txt in each mod directory for information about other authors.
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
License of menu/header.png
|
||||
Copyright (C) 2013 BlockMen CC BY-3.0
|
314
game_api.txt
Normal file
@ -0,0 +1,314 @@
|
||||
minetest_game API
|
||||
======================
|
||||
GitHub Repo: https://github.com/minetest/minetest_game
|
||||
|
||||
Introduction
|
||||
------------
|
||||
The minetest_game gamemode offers multiple new possibilities in addition to Minetest's built-in API, allowing you to
|
||||
add new plants to farming mod, buckets for new liquids, new stairs and custom panes.
|
||||
For information on the Minetest API, visit https://github.com/minetest/minetest/blob/master/doc/lua_api.txt
|
||||
Please note:
|
||||
[XYZ] refers to a section the Minetest API
|
||||
[#ABC] refers to a section in this document
|
||||
^ Explanation for line above
|
||||
|
||||
Bucket API
|
||||
----------
|
||||
The bucket API allows registering new types of buckets for non-default liquids.
|
||||
|
||||
bucket.register_liquid(
|
||||
"default:lava_source", -- Source node name
|
||||
"default:lava_flowing", -- Flowing node name
|
||||
"bucket:bucket_lava", -- Name to be used for bucket
|
||||
"bucket_lava.png", -- Bucket texture (for wielditem and inventory_image)
|
||||
"Lava Bucket" -- Bucket description
|
||||
)
|
||||
|
||||
Doors API
|
||||
---------
|
||||
The doors mod allows modders to register custom doors and trapdoors.
|
||||
|
||||
doors.register_door(name, def)
|
||||
^ name: "Door name"
|
||||
^ def: See [#Door definition]
|
||||
-> Registers new door
|
||||
|
||||
doors.register_trapdoor(name, def)
|
||||
^ name: "Trapdoor name"
|
||||
^ def: See [#Trapdoor definition]
|
||||
-> Registers new trapdoor
|
||||
|
||||
#Door definition
|
||||
----------------
|
||||
{
|
||||
description = "Door description",
|
||||
inventory_image = "mod_door_inv.png",
|
||||
groups = {group = 1},
|
||||
tiles_bottom: [Tile definition],
|
||||
^ the tiles of the bottom part of the door {front, side}
|
||||
tiles_top: [Tile definition],
|
||||
^ the tiles of the bottom part of the door {front, side}
|
||||
node_box_bottom = regular nodebox, see [Node boxes], OPTIONAL,
|
||||
node_box_top = regular nodebox, see [Node boxes], OPTIONAL,
|
||||
selection_box_bottom = regular nodebox, see [Node boxes], OPTIONAL,
|
||||
selection_box_top = regular nodebox, see [Node boxes], OPTIONAL,
|
||||
sound_open_door = sound play for open door, OPTIONAL,
|
||||
sound_close_door = sound play for close door, OPTIONAL,
|
||||
only_placer_can_open = true/false,
|
||||
^ If true, only placer can open the door (locked for others)
|
||||
}
|
||||
|
||||
#Trapdoor definition
|
||||
----------------
|
||||
{
|
||||
tile_front = "doors_trapdoor.png",
|
||||
^ the texture for the front and back of the trapdoor
|
||||
tile_side: "doors_trapdoor_side.png",
|
||||
^ the tiles of the four side parts of the trapdoor
|
||||
sound_open = sound to play when opening the trapdoor, OPTIONAL,
|
||||
sound_close = sound to play when closing the trapdoor, OPTIONAL,
|
||||
-> You can add any other node definition properties for minetest.register_node,
|
||||
such as wield_image, inventory_image, sounds, groups, description, ...
|
||||
Only node_box, selection_box, tiles, drop, drawtype, paramtype, paramtype2, on_rightclick
|
||||
will be overwritten by the trapdoor registration function
|
||||
}
|
||||
|
||||
Farming API
|
||||
-----------
|
||||
The farming API allows you to easily register plants and hoes.
|
||||
|
||||
farming.register_hoe(name, hoe definition)
|
||||
-> Register a new hoe, see [#hoe definition]
|
||||
|
||||
farming.register_plant(name, Plant definition)
|
||||
-> Register a new growing plant, see [#Plant definition]
|
||||
|
||||
#Hoe Definition
|
||||
---------------
|
||||
{
|
||||
description = "", -- Description for tooltip
|
||||
inventory_image = "unknown_item.png", -- Image to be used as wield- and inventory image
|
||||
max_uses = 30, -- Uses until destroyed
|
||||
recipe = { -- Craft recipe
|
||||
{"air", "air", "air"},
|
||||
{"", "group:stick"},
|
||||
{"", "group:stick"},
|
||||
}
|
||||
}
|
||||
|
||||
#Plant definition
|
||||
-----------------
|
||||
{
|
||||
description = "", -- Description of seed item
|
||||
inventory_image = "unknown_item.png", -- Image to be used as seed's wield- and inventory image
|
||||
steps = 8, -- How many steps the plant has to grow, until it can be harvested
|
||||
^ Always provide a plant texture for ech step, format: modname_plantname_i.png (i = stepnumber)
|
||||
minlight = 13, -- Minimum light to grow
|
||||
maxlight = default.LIGHT_MAX -- Maximum light to grow
|
||||
}
|
||||
|
||||
Stairs API
|
||||
----------
|
||||
The stairs API lets you register stairs and slabs and ensures that they are registered the same way as those
|
||||
delivered with minetest_game, to keep them compatible with other mods.
|
||||
|
||||
stairs.register_stair(subname, recipeitem, groups, images, description, sounds)
|
||||
-> Registers a stair.
|
||||
-> subname: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_subname"
|
||||
-> recipeitem: Item used in the craft recipe, e.g. "default:cobble"
|
||||
-> groups: see [Known damage and digging time defining groups]
|
||||
-> images: see [Tile definition]
|
||||
-> description: used for the description field in the stair's definition
|
||||
-> sounds: see [#Default sounds]
|
||||
|
||||
stairs.register_slab(subname, recipeitem, groups, images, description, sounds)
|
||||
-> Registers a slabs
|
||||
-> subname: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_subname"
|
||||
-> recipeitem: Item used in the craft recipe, e.g. "default:cobble"
|
||||
-> groups: see [Known damage and digging time defining groups]
|
||||
-> images: see [Tile definition]
|
||||
-> description: used for the description field in the stair's definition
|
||||
-> sounds: see [#Default sounds]
|
||||
|
||||
stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab, sounds)
|
||||
-> A wrapper for stairs.register_stair and stairs.register_slab
|
||||
-> Uses almost the same arguments as stairs.register_stair
|
||||
-> desc_stair: Description for stair node
|
||||
-> desc_slab: Description for slab node
|
||||
|
||||
Xpanes API
|
||||
----------
|
||||
Creates panes that automatically connect to each other
|
||||
|
||||
xpanes.register_pane(subname, def)
|
||||
-> subname: used for nodename. Result: "xpanes:subname" and "xpanes:subname_{2..15}"
|
||||
-> def: See [#Pane definition]
|
||||
|
||||
#Pane definition
|
||||
----------------
|
||||
{
|
||||
textures = {"texture_Bottom_top", "texture_left_right", "texture_front_back"},
|
||||
^ More tiles aren't supported
|
||||
groups = {group = rating},
|
||||
^ Uses the known node groups, see [Known damage and digging time defining groups]
|
||||
sounds = SoundSpec,
|
||||
^ See [#Default sounds]
|
||||
recipe = {{"","","","","","","","",""}},
|
||||
^ Recipe field only
|
||||
}
|
||||
|
||||
Default sounds
|
||||
--------------
|
||||
Sounds inside the default table can be used within the sounds field of node definitions.
|
||||
|
||||
default.node_sound_defaults()
|
||||
default.node_sound_stone_defaults()
|
||||
default.node_sound_dirt_defaults()
|
||||
default.node_sound_sand_defaults()
|
||||
default.node_sound_wood_defaults()
|
||||
default.node_sound_leaves_defaults()
|
||||
default.node_sound_glass_defaults()
|
||||
|
||||
Default constants
|
||||
-----------------
|
||||
default.LIGHT_MAX
|
||||
^ The maximum light level (see [Node definition] light_source)
|
||||
|
||||
Player API
|
||||
----------
|
||||
The player API can register player models and update the player's appearence
|
||||
|
||||
default.player_register_model(name, def)
|
||||
^ Register a new model to be used by players.
|
||||
-> name: model filename such as "character.x", "foo.b3d", etc.
|
||||
-> def: See [#Model definition]
|
||||
|
||||
default.registered_player_models[name]
|
||||
^ Get a model's definition
|
||||
-> see [#Model definition]
|
||||
|
||||
default.player_set_model(player, model_name)
|
||||
^ Change a player's model
|
||||
-> player: PlayerRef
|
||||
-> model_name: model registered with player_register_model()
|
||||
|
||||
default.player_set_animation(player, anim_name [, speed])
|
||||
^ Applies an animation to a player
|
||||
-> anim_name: name of the animation.
|
||||
-> speed: frames per second. If nil, default from the model is used
|
||||
|
||||
default.player_set_textures(player, textures)
|
||||
^ Sets player textures
|
||||
-> player: PlayerRef
|
||||
-> textures: array of textures
|
||||
^ If <textures> is nil, the default textures from the model def are used
|
||||
|
||||
default.player_get_animation(player)
|
||||
^ Returns a table containing fields "model", "textures" and "animation".
|
||||
^ Any of the fields of the returned table may be nil.
|
||||
-> player: PlayerRef
|
||||
|
||||
Model Definition
|
||||
----------------
|
||||
{
|
||||
animation_speed = 30, -- Default animation speed, in FPS.
|
||||
textures = {"character.png", }, -- Default array of textures.
|
||||
visual_size = {x=1, y=1,}, -- Used to scale the model.
|
||||
animations = {
|
||||
-- <anim_name> = { x=<start_frame>, y=<end_frame>, },
|
||||
foo = { x= 0, y=19, },
|
||||
bar = { x=20, y=39, },
|
||||
-- ...
|
||||
},
|
||||
}
|
||||
|
||||
Leafdecay
|
||||
---------
|
||||
To enable leaf decay for a node, add it to the "leafdecay" group.
|
||||
|
||||
The rating of the group determines how far from a node in the group "tree"
|
||||
the node can be without decaying.
|
||||
|
||||
If param2 of the node is ~= 0, the node will always be preserved. Thus, if
|
||||
the player places a node of that kind, you will want to set param2=1 or so.
|
||||
|
||||
The function default.after_place_leaves can be set as after_place_node of a node
|
||||
to set param2 to 1 if the player places the node (should not be used for nodes
|
||||
that use param2 otherwise (e.g. facedir)).
|
||||
|
||||
If the node is in the leafdecay_drop group then it will always be dropped as an
|
||||
item.
|
||||
|
||||
Dyes
|
||||
----
|
||||
To make recipes that will work with any dye ever made by anybody, define
|
||||
them based on groups. You can select any group of groups, based on your need for
|
||||
amount of colors.
|
||||
|
||||
#Color groups
|
||||
-------------
|
||||
Base color groups:
|
||||
- basecolor_white
|
||||
- basecolor_grey
|
||||
- basecolor_black
|
||||
- basecolor_red
|
||||
- basecolor_yellow
|
||||
- basecolor_green
|
||||
- basecolor_cyan
|
||||
- basecolor_blue
|
||||
- basecolor_magenta
|
||||
|
||||
Extended color groups (* = equal to a base color):
|
||||
* excolor_white
|
||||
- excolor_lightgrey
|
||||
* excolor_grey
|
||||
- excolor_darkgrey
|
||||
* excolor_black
|
||||
* excolor_red
|
||||
- excolor_orange
|
||||
* excolor_yellow
|
||||
- excolor_lime
|
||||
* excolor_green
|
||||
- excolor_aqua
|
||||
* excolor_cyan
|
||||
- excolor_sky_blue
|
||||
* excolor_blue
|
||||
- excolor_violet
|
||||
* excolor_magenta
|
||||
- excolor_red_violet
|
||||
|
||||
The whole unifieddyes palette as groups:
|
||||
- unicolor_<excolor>
|
||||
For the following, no white/grey/black is allowed:
|
||||
- unicolor_medium_<excolor>
|
||||
- unicolor_dark_<excolor>
|
||||
- unicolor_light_<excolor>
|
||||
- unicolor_<excolor>_s50
|
||||
- unicolor_medium_<excolor>_s50
|
||||
- unicolor_dark_<excolor>_s50
|
||||
|
||||
Example of one shapeless recipe using a color group:
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = '<mod>:item_yellow',
|
||||
recipe = {'<mod>:item_no_color', 'group:basecolor_yellow'},
|
||||
})
|
||||
|
||||
#Color lists
|
||||
------------
|
||||
dye.basecolors
|
||||
^ Array containing the names of available base colors
|
||||
|
||||
dye.excolors
|
||||
^ Array containing the names of the available extended colors
|
||||
|
||||
Trees
|
||||
-----
|
||||
default.grow_tree(pos, is_apple_tree)
|
||||
^ Grows a tree or apple tree at pos
|
||||
|
||||
default.grow_jungle_tree(pos)
|
||||
^ Grows a jungletree at pos
|
||||
|
||||
default.grow_pine_tree(pos)
|
||||
^ Grows a pinetree at pos
|
14
license.txt
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
BIN
menu/header.png
Normal file
After Width: | Height: | Size: 260 KiB |
BIN
menu/icon.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
19
mods/3d_armor/README.txt
Normal file
@ -0,0 +1,19 @@
|
||||
[mod] Visible Player Armor [3d_armor]
|
||||
=====================================
|
||||
|
||||
Depends: default
|
||||
|
||||
Recommends: inventory_plus or unified_inventory (use only one)
|
||||
|
||||
Adds craftable armor that is visible to other players. Each armor item worn contributes to
|
||||
a player"s armor group level making them less vulnerable to weapons.
|
||||
|
||||
Armor takes damage when a player is hurt but also offers a percentage chance of healing.
|
||||
Overall level is boosted by 10% when wearing a full matching set.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
Armor can be configured by adding a file called armor.conf in 3d_armor mod directory.
|
||||
see armor.conf.example for all available options.
|
||||
|
37
mods/3d_armor/armor.conf.example
Normal file
@ -0,0 +1,37 @@
|
||||
-- Armor Configuration (defaults)
|
||||
|
||||
-- Increase this if you get initialization glitches when a player first joins.
|
||||
ARMOR_INIT_DELAY = 3
|
||||
|
||||
-- Number of initialization attempts.
|
||||
-- Use in conjunction with ARMOR_INIT_DELAY if initialization problems persist.
|
||||
ARMOR_INIT_TIMES = 2
|
||||
|
||||
-- Increase this if armor is not getting into bones due to server lag.
|
||||
ARMOR_BONES_DELAY = 2
|
||||
|
||||
-- How often player armor/wield items are updated.
|
||||
ARMOR_UPDATE_TIME = 1
|
||||
|
||||
-- Drop armor when a player dies.
|
||||
-- Uses bones mod if present, otherwise items are dropped around the player.
|
||||
ARMOR_DROP = true
|
||||
|
||||
-- Pulverise armor when a player dies, overrides ARMOR_DROP.
|
||||
ARMOR_DESTROY = false
|
||||
|
||||
-- You can use this to increase or decrease overall armor effectiveness,
|
||||
-- eg: ARMOR_LEVEL_MULTIPLIER = 0.5 will reduce armor level by half.
|
||||
ARMOR_LEVEL_MULTIPLIER = 0.5
|
||||
|
||||
-- You can use this to increase or decrease overall armor healing,
|
||||
-- eg: ARMOR_HEAL_MULTIPLIER = 0 will disable healing altogether.
|
||||
ARMOR_HEAL_MULTIPLIER = 0.2
|
||||
|
||||
-- You can also use this file to execute arbitary lua code
|
||||
-- eg: Dumb the armor down if using Simple Mobs
|
||||
if minetest.get_modpath("mobs") then
|
||||
ARMOR_LEVEL_MULTIPLIER = 0.5
|
||||
ARMOR_HEAL_MULTIPLIER = 0
|
||||
end
|
||||
|
460
mods/3d_armor/armor.lua
Normal file
@ -0,0 +1,460 @@
|
||||
ARMOR_INIT_DELAY = 3
|
||||
ARMOR_INIT_TIMES = 2
|
||||
ARMOR_BONES_DELAY = 1
|
||||
ARMOR_UPDATE_TIME = 1
|
||||
ARMOR_DROP = false
|
||||
ARMOR_DESTROY = false
|
||||
ARMOR_LEVEL_MULTIPLIER = 0.5
|
||||
ARMOR_HEAL_MULTIPLIER = 0
|
||||
|
||||
local modpath = minetest.get_modpath(ARMOR_MOD_NAME)
|
||||
local input = io.open(modpath.."/armor.conf", "r")
|
||||
if input then
|
||||
dofile(modpath.."/armor.conf")
|
||||
input:close()
|
||||
input = nil
|
||||
end
|
||||
local time = 0
|
||||
|
||||
gui_slots = "listcolors[#606060AA;#808080;#101010;#202020;#FFF]"
|
||||
|
||||
armor = {
|
||||
player_hp = {},
|
||||
elements = {"head", "torso", "legs", "feet"},
|
||||
physics = {"jump","speed","gravity"},
|
||||
formspec = "size[8,8.5]" .. gui_slots .. "list[detached:player_name_armor;armor;0,1;2,3;]"
|
||||
.. "image[2,0.75;2,4;armor_preview]"
|
||||
.. "list[current_player;main;0,4.25;8,4;]"
|
||||
.. "list[current_player;craft;4,1;3,3;]"
|
||||
.. "list[current_player;craftpreview;7,2;1,1;]"
|
||||
.. default.get_hotbar_bg(0, 4.25)
|
||||
.. default.get_hotbar_bg(0, 5.25),
|
||||
textures = {},
|
||||
default_skin = "character",
|
||||
}
|
||||
|
||||
if inventory_plus then
|
||||
armor.formspec = "size[8,8.5]button[0,0;2,0.5;main;Back]"
|
||||
.."list[detached:player_name_armor;armor;0,1;2,3;]"
|
||||
.."image[2.5,0.75;2,4;armor_preview]"
|
||||
.."label[5,1;Level: armor_level]"
|
||||
.."label[5,1.5;Heal: armor_heal]"
|
||||
.."list[current_player;main;0,4.5;8,4;]"
|
||||
elseif unified_inventory then
|
||||
unified_inventory.register_button("armor", {
|
||||
type = "image",
|
||||
image = "inventory_plus_armor.png",
|
||||
})
|
||||
unified_inventory.register_page("armor", {
|
||||
get_formspec = function(player)
|
||||
local name = player:get_player_name()
|
||||
local formspec = "background[0.06,0.99;7.92,7.52;3d_armor_ui_form.png]"
|
||||
.."label[0,0;Armor]"
|
||||
.."list[detached:"..name.."_armor;armor;0,1;2,3;]"
|
||||
.."image[2.5,0.75;2,4;"..armor.textures[name].preview.."]"
|
||||
.."label[5,1;Level: "..armor.def[name].level.."]"
|
||||
.."label[5,1.5;Heal: "..armor.def[name].heal.."]"
|
||||
return {formspec=formspec}
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
armor.def = {
|
||||
state = 0,
|
||||
count = 0,
|
||||
}
|
||||
|
||||
armor.update_player_visuals = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
if self.textures[name] then
|
||||
default.player_set_textures(player, {
|
||||
self.textures[name].skin,
|
||||
self.textures[name].armor,
|
||||
self.textures[name].wielditem,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
armor.set_player_armor = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local player_inv = player:get_inventory()
|
||||
if not name or not player_inv then
|
||||
return
|
||||
end
|
||||
local armor_texture = "3d_armor_trans.png"
|
||||
local armor_level = 0
|
||||
local armor_heal = 0
|
||||
local state = 0
|
||||
local items = 0
|
||||
local elements = {}
|
||||
local textures = {}
|
||||
local physics_o = {speed= 1,gravity = 1,jump= 1}
|
||||
local material = {type=nil, count= 1}
|
||||
local preview = armor:get_player_skin(name).."_preview.png"
|
||||
for _,v in ipairs(self.elements) do
|
||||
elements[v] = false
|
||||
end
|
||||
for i= 1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
local item = stack:get_name()
|
||||
if stack:get_count() == 1 then
|
||||
local def = stack:get_definition()
|
||||
for k, v in pairs(elements) do
|
||||
if v == false then
|
||||
local level = def.groups["armor_"..k]
|
||||
if level then
|
||||
local texture = item:gsub("%:", "_")
|
||||
table.insert(textures, texture..".png")
|
||||
preview = preview.."^"..texture.."_preview.png"
|
||||
armor_level = armor_level + level
|
||||
state = state + stack:get_wear()
|
||||
items = items + 1
|
||||
local heal = def.groups["armor_heal"] or 0
|
||||
armor_heal = armor_heal + heal
|
||||
for kk,vv in ipairs(self.physics) do
|
||||
local o_value = def.groups["physics_"..vv]
|
||||
if o_value then
|
||||
physics_o[vv] = physics_o[vv] + o_value
|
||||
end
|
||||
end
|
||||
local mat = string.match(item, "%:.+_(.+)$")
|
||||
if material.type then
|
||||
if material.type == mat then
|
||||
material.count = material.count + 1
|
||||
end
|
||||
else
|
||||
material.type = mat
|
||||
end
|
||||
elements[k] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if minetest.get_modpath("shields") then
|
||||
armor_level = armor_level * 0.9
|
||||
end
|
||||
if material.type and material.count == #self.elements then
|
||||
armor_level = armor_level * 1.1
|
||||
end
|
||||
armor_level = armor_level * ARMOR_LEVEL_MULTIPLIER
|
||||
armor_heal = armor_heal * ARMOR_HEAL_MULTIPLIER
|
||||
if #textures > 0 then
|
||||
armor_texture = table.concat(textures, "^")
|
||||
end
|
||||
local armor_groups = {fleshy = 100}
|
||||
if armor_level > 0 then
|
||||
armor_groups.level = math.floor(armor_level / 20)
|
||||
armor_groups.fleshy = 100 - armor_level
|
||||
end
|
||||
player:set_armor_groups(armor_groups)
|
||||
player:set_physics_override(physics_o)
|
||||
self.textures[name].armor = armor_texture
|
||||
self.textures[name].preview = preview
|
||||
self.def[name].state = state
|
||||
self.def[name].count = items
|
||||
self.def[name].level = armor_level
|
||||
self.def[name].heal = armor_heal
|
||||
self:update_player_visuals(player)
|
||||
end
|
||||
|
||||
armor.update_armor = function(self, player)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local hp = player:get_hp() or 0
|
||||
if hp == 0 or hp == self.player_hp[name] then
|
||||
return
|
||||
end
|
||||
if self.player_hp[name] > hp then
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
if not armor_inv then
|
||||
return
|
||||
end
|
||||
local heal_max = 0
|
||||
local state = 0
|
||||
local items = 0
|
||||
for i= 1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
if stack:get_count() > 0 then
|
||||
local use = stack:get_definition().groups["armor_use"] or 0
|
||||
local heal = stack:get_definition().groups["armor_heal"] or 0
|
||||
local item = stack:get_name()
|
||||
stack:add_wear(use)
|
||||
armor_inv:set_stack("armor", i, stack)
|
||||
player_inv:set_stack("armor", i, stack)
|
||||
state = state + stack:get_wear()
|
||||
items = items + 1
|
||||
if stack:get_count() == 0 then
|
||||
local desc = minetest.registered_items[item].description
|
||||
if desc then
|
||||
minetest.chat_send_player(name, "Your "..desc.." got destroyed!")
|
||||
end
|
||||
self:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
end
|
||||
heal_max = heal_max + heal
|
||||
end
|
||||
end
|
||||
self.def[name].state = state
|
||||
self.def[name].count = items
|
||||
heal_max = heal_max * ARMOR_HEAL_MULTIPLIER
|
||||
if heal_max > math.random(100) then
|
||||
player:set_hp(self.player_hp[name])
|
||||
return
|
||||
end
|
||||
end
|
||||
self.player_hp[name] = hp
|
||||
end
|
||||
|
||||
armor.get_player_skin = function(self, name)
|
||||
local skin = nil
|
||||
if skins then
|
||||
skin = skins.skins[name]
|
||||
elseif u_skins then
|
||||
skin = u_skins.u_skins[name]
|
||||
end
|
||||
return skin or armor.default_skin
|
||||
end
|
||||
|
||||
armor.get_armor_formspec = function(self, name)
|
||||
local formspec = armor.formspec:gsub("player_name", name)
|
||||
formspec = formspec:gsub("armor_preview", armor.textures[name].preview)
|
||||
formspec = formspec:gsub("armor_level", armor.def[name].level)
|
||||
return formspec:gsub("armor_heal", armor.def[name].heal)
|
||||
end
|
||||
|
||||
armor.update_inventory = function(self, player)
|
||||
local name = player:get_player_name()
|
||||
if unified_inventory then
|
||||
if unified_inventory.current_page[name] == "armor" then
|
||||
unified_inventory.set_inventory_formspec(player, "armor")
|
||||
end
|
||||
else
|
||||
local formspec = armor:get_armor_formspec(name)
|
||||
if inventory_plus then
|
||||
local page = player:get_inventory_formspec()
|
||||
if page:find("detached:"..name.."_armor") then
|
||||
inventory_plus.set_inventory_formspec(player, formspec)
|
||||
end
|
||||
else
|
||||
player:set_inventory_formspec(formspec)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Register Player Model
|
||||
|
||||
default.player_register_model("3d_armor_character.x", {
|
||||
animation_speed = 35,
|
||||
textures = {
|
||||
armor.default_skin..".png",
|
||||
"3d_armor_trans.png",
|
||||
"3d_armor_trans.png",
|
||||
},
|
||||
animations = {
|
||||
stand = {x = 0, y = 40},
|
||||
lay = {x = 162, y = 166},
|
||||
walk = {x = 168, y = 187},
|
||||
mine = {x = 189, y = 198},
|
||||
walk_mine = {x = 200, y = 219},
|
||||
sit = {x = 81, y = 160},
|
||||
},
|
||||
})
|
||||
|
||||
-- Register Callbacks
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local name = player:get_player_name()
|
||||
if inventory_plus and fields.armor then
|
||||
local formspec = armor:get_armor_formspec(name)
|
||||
inventory_plus.set_inventory_formspec(player, formspec)
|
||||
return
|
||||
end
|
||||
for field, _ in pairs(fields) do
|
||||
if string.find(field, "skins_set_") then
|
||||
minetest.after(0, function(player)
|
||||
local skin = armor:get_player_skin(name)
|
||||
armor.textures[name].skin = skin..".png"
|
||||
armor:set_player_armor(player)
|
||||
end, player)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
default.player_set_model(player, "3d_armor_character.x")
|
||||
local name = player:get_player_name()
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_inv = minetest.create_detached_inventory(name.."_armor",{
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
player:get_inventory():set_stack(listname, index, stack)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
end,
|
||||
on_take = function(inv, listname, index, stack, player)
|
||||
player:get_inventory():set_stack(listname, index, nil)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
end,
|
||||
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
local plaver_inv = player:get_inventory()
|
||||
local stack = inv:get_stack(to_list, to_index)
|
||||
player_inv:set_stack(to_list, to_index, stack)
|
||||
player_inv:set_stack(from_list, from_index, nil)
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
end,
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
return 1
|
||||
end,
|
||||
allow_take = function(inv, listname, index, stack, player)
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return count
|
||||
end,
|
||||
})
|
||||
if inventory_plus then
|
||||
inventory_plus.register_button(player,"armor", "Armor")
|
||||
end
|
||||
armor_inv:set_size("armor", 6)
|
||||
player_inv:set_size("armor", 6)
|
||||
for i= 1, 6 do
|
||||
local stack = player_inv:get_stack("armor", i)
|
||||
armor_inv:set_stack("armor", i, stack)
|
||||
end
|
||||
|
||||
-- Legacy support, import player"s armor from old inventory format
|
||||
--[[
|
||||
for _,v in pairs(armor.elements) do
|
||||
local list = "armor_"..v
|
||||
armor_inv:add_item("armor", player_inv:get_stack(list, 1))
|
||||
player_inv:set_stack(list, 1, nil)
|
||||
end
|
||||
--]]
|
||||
|
||||
armor.player_hp[name] = 0
|
||||
armor.def[name] = {
|
||||
state = 0,
|
||||
count = 0,
|
||||
level = 0,
|
||||
heal = 0,
|
||||
}
|
||||
armor.textures[name] = {
|
||||
skin = armor.default_skin..".png",
|
||||
armor = "3d_armor_trans.png",
|
||||
wielditem = "3d_armor_trans.png",
|
||||
preview = armor.default_skin.."_preview.png",
|
||||
}
|
||||
if minetest.get_modpath("skins") then
|
||||
local skin = skins.skins[name]
|
||||
if skin and skins.get_type(skin) == skins.type.MODEL then
|
||||
armor.textures[name].skin = skin..".png"
|
||||
end
|
||||
elseif minetest.get_modpath("u_skins") then
|
||||
local skin = u_skins.u_skins[name]
|
||||
if skin and u_skins.get_type(skin) == u_skins.type.MODEL then
|
||||
armor.textures[name].skin = skin..".png"
|
||||
end
|
||||
end
|
||||
if minetest.get_modpath("player_textures") then
|
||||
local filename = minetest.get_modpath("player_textures").."/textures/player_"..name
|
||||
local f = io.open(filename..".png")
|
||||
if f then
|
||||
f:close()
|
||||
armor.textures[name].skin = "player_"..name..".png"
|
||||
end
|
||||
end
|
||||
for i= 1, ARMOR_INIT_TIMES do
|
||||
minetest.after(ARMOR_INIT_DELAY * i, function(player)
|
||||
armor:set_player_armor(player)
|
||||
if inventory_plus == nil and unified_inventory == nil then
|
||||
armor:update_inventory(player)
|
||||
end
|
||||
end, player)
|
||||
end
|
||||
end)
|
||||
|
||||
if ARMOR_DROP == true or ARMOR_DESTROY == true then
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
local pos = player:getpos()
|
||||
if name and pos then
|
||||
local drop = {}
|
||||
local player_inv = player:get_inventory()
|
||||
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
|
||||
for i= 1, player_inv:get_size("armor") do
|
||||
local stack = armor_inv:get_stack("armor", i)
|
||||
if stack:get_count() > 0 then
|
||||
table.insert(drop, stack)
|
||||
armor_inv:set_stack("armor", i, nil)
|
||||
player_inv:set_stack("armor", i, nil)
|
||||
end
|
||||
end
|
||||
armor:set_player_armor(player)
|
||||
if unified_inventory then
|
||||
unified_inventory.set_inventory_formspec(player, "craft")
|
||||
elseif inventory_plus then
|
||||
local formspec = inventory_plus.get_formspec(player,"main")
|
||||
inventory_plus.set_inventory_formspec(player, formspec)
|
||||
else
|
||||
armor:update_inventory(player)
|
||||
end
|
||||
if ARMOR_DESTROY == false then
|
||||
if minetest.get_modpath("bones") then
|
||||
minetest.after(ARMOR_BONES_DELAY, function()
|
||||
pos = vector.round(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == "bones:bones" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
local inv = meta:get_inventory()
|
||||
if name == owner then
|
||||
for _,stack in ipairs(drop) do
|
||||
if inv:room_for_item("main", stack) then
|
||||
inv:add_item("main", stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
else
|
||||
for _,stack in ipairs(drop) do
|
||||
local obj = minetest.add_item(pos, stack)
|
||||
if obj then
|
||||
local x = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
x = -x
|
||||
end
|
||||
local z = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
z = -z
|
||||
end
|
||||
obj:setvelocity({x = 1/x, y =obj:getvelocity().y, z = 1/z})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
time = time + dtime
|
||||
if time > ARMOR_UPDATE_TIME then
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
armor:update_armor(player)
|
||||
end
|
||||
time = 0
|
||||
end
|
||||
end)
|
||||
|
67
mods/3d_armor/crafting_guide.txt
Normal file
@ -0,0 +1,67 @@
|
||||
3d_armor -- Crafting Guide
|
||||
--------------------------
|
||||
|
||||
Helmets:
|
||||
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| | | |
|
||||
+---+---+---+
|
||||
|
||||
--[3d_armor:helmet_wood] X = [default:wood]
|
||||
[3d_armor:helmet_steel] X = [default:steel_ingot]
|
||||
--[3d_armor:helmet_bronze] X = [default:bronze_ingot]
|
||||
--[3d_armor:helmet_diamond] X = [default:diamond]
|
||||
--[3d_armor:helmet_mithril] X = [moreores:mithril_ingot] *
|
||||
|
||||
Chestplates:
|
||||
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
|
||||
--[3d_armor:chestplate_wood] X = [default:wood]
|
||||
[3d_armor:chestplate_steel] X = [default:steel_ingot]
|
||||
--[3d_armor:chestplate_bronze] X = [default:bronze_ingot]
|
||||
--[3d_armor:chestplate_diamond] X = [default:diamond]
|
||||
--[3d_armor:chestplate_mithril] X = [moreores:mithril_ingot] *
|
||||
|
||||
Leggings:
|
||||
|
||||
+---+---+---+
|
||||
| X | X | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
|
||||
--[3d_armor:leggings_wood] X = [default:wood]
|
||||
[3d_armor:leggings_steel] X = [default:steel_ingot]
|
||||
--[3d_armor:leggings_bronze] X = [default:bronze_ingot]
|
||||
--[3d_armor:leggings_diamond] X = [default:diamond]
|
||||
--[3d_armor:leggings_mithril] X = [moreores:mithril_ingot] *
|
||||
|
||||
Boots:
|
||||
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
| X | | X |
|
||||
+---+---+---+
|
||||
|
||||
--[3d_armor:boots_wood] X = [default:wood]
|
||||
[3d_armor:boots_steel] X = [default:steel_ingot]
|
||||
--[3d_armor:boots_bronze] X = [default:bronze_ingot
|
||||
--[3d_armor:boots_diamond] X = [default:diamond]
|
||||
--[3d_armor:boots_mithril] X = [moreores:mithril_ingot] *
|
||||
|
||||
* Requires moreores mod by Calinou - https://forum.minetest.net/viewtopic.php?id=549
|
||||
|
5
mods/3d_armor/depends.txt
Normal file
@ -0,0 +1,5 @@
|
||||
default
|
||||
inventory_plus?
|
||||
unified_inventory?
|
||||
es?
|
||||
|
161
mods/3d_armor/init.lua
Normal file
@ -0,0 +1,161 @@
|
||||
ARMOR_MOD_NAME = minetest.get_current_modname()
|
||||
dofile(minetest.get_modpath(ARMOR_MOD_NAME).."/armor.lua")
|
||||
local use_moreores = minetest.get_modpath("moreores")
|
||||
|
||||
|
||||
|
||||
-- Register helmets:
|
||||
minetest.register_tool("3d_armor:helmet_steel", {
|
||||
description = "Steel Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_steel.png",
|
||||
groups = {armor_head = 10, armor_heal = 0, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:helmet_diamond", {
|
||||
description = "Diamond Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_diamond.png",
|
||||
groups = {armor_head = 15, armor_heal = 12, armor_use = 100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
|
||||
if use_moreores then
|
||||
minetest.register_tool("3d_armor:helmet_mithril", {
|
||||
description = "Mithril Helmet",
|
||||
inventory_image = "3d_armor_inv_helmet_mithril.png",
|
||||
groups = {armor_head = 15, armor_heal = 12, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register chestplates:
|
||||
minetest.register_tool("3d_armor:chestplate_steel", {
|
||||
description = "Steel Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_steel.png",
|
||||
groups = {armor_torso = 15, armor_heal = 0, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:chestplate_diamond", {
|
||||
description = "Diamond Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_diamond.png",
|
||||
groups = {armor_torso = 20, armor_heal = 12, armor_use = 100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
|
||||
if use_moreores then
|
||||
minetest.register_tool("3d_armor:chestplate_mithril", {
|
||||
description = "Mithril Chestplate",
|
||||
inventory_image = "3d_armor_inv_chestplate_mithril.png",
|
||||
groups = {armor_torso = 20, armor_heal = 12, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register leggings:
|
||||
minetest.register_tool("3d_armor:leggings_steel", {
|
||||
description = "Steel Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_steel.png",
|
||||
groups = {armor_legs = 15, armor_heal = 0, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:leggings_diamond", {
|
||||
description = "Diamond Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_diamond.png",
|
||||
groups = {armor_legs = 20, armor_heal = 12, armor_use = 100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
|
||||
if use_moreores then
|
||||
minetest.register_tool("3d_armor:leggings_mithril", {
|
||||
description = "Mithril Leggings",
|
||||
inventory_image = "3d_armor_inv_leggings_mithril.png",
|
||||
groups = {armor_legs = 20, armor_heal = 12, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register boots:
|
||||
minetest.register_tool("3d_armor:boots_steel", {
|
||||
description = "Steel Boots",
|
||||
inventory_image = "3d_armor_inv_boots_steel.png",
|
||||
groups = {armor_feet = 10, armor_heal = 0, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
minetest.register_tool("3d_armor:boots_diamond", {
|
||||
description = "Diamond Boots",
|
||||
inventory_image = "3d_armor_inv_boots_diamond.png",
|
||||
groups = {armor_feet = 15, armor_heal = 12, armor_use = 100},
|
||||
wear = 0,
|
||||
})
|
||||
|
||||
|
||||
|
||||
if use_moreores then
|
||||
minetest.register_tool("3d_armor:boots_mithril", {
|
||||
description = "Mithril Boots",
|
||||
inventory_image = "3d_armor_inv_boots_mithril.png",
|
||||
groups = {armor_feet = 15, armor_heal = 12, armor_use = 50},
|
||||
wear = 0,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register crafting recipes:
|
||||
|
||||
local craft_ingreds = {
|
||||
--wood = "default:wood",
|
||||
steel = "default:steel_ingot",
|
||||
--bronze = "default:bronze_ingot",
|
||||
diamond = "default:diamond",
|
||||
--gold = "default:gold_ingot",
|
||||
}
|
||||
|
||||
if use_moreores then
|
||||
craft_ingreds.mithril = "moreores:mithril_ingot"
|
||||
end
|
||||
|
||||
for k, v in pairs(craft_ingreds) do
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:helmet_"..k,
|
||||
recipe = {
|
||||
{v, v, v},
|
||||
{v, "", v},
|
||||
{"", "", ""},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:chestplate_"..k,
|
||||
recipe = {
|
||||
{v, "", v},
|
||||
{v, v, v},
|
||||
{v, v, v},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:leggings_"..k,
|
||||
recipe = {
|
||||
{v, v, v},
|
||||
{v, "", v},
|
||||
{v, "", v},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "3d_armor:boots_"..k,
|
||||
recipe = {
|
||||
{v, "", v},
|
||||
{v, "", v},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if minetest.setting_getbool("log_mods") then
|
||||
minetest.log("action", "Carbone: [3d_armor] loaded.")
|
||||
end
|
BIN
mods/3d_armor/models/3d_armor_character.blend
Normal file
9156
mods/3d_armor/models/3d_armor_character.x
Normal file
BIN
mods/3d_armor/textures/3d_armor_boots_bronze.png
Normal file
After Width: | Height: | Size: 321 B |
BIN
mods/3d_armor/textures/3d_armor_boots_bronze_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_boots_diamond.png
Normal file
After Width: | Height: | Size: 295 B |
BIN
mods/3d_armor/textures/3d_armor_boots_diamond_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_boots_gold.png
Normal file
After Width: | Height: | Size: 287 B |
BIN
mods/3d_armor/textures/3d_armor_boots_gold_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_boots_mithril.png
Normal file
After Width: | Height: | Size: 216 B |
BIN
mods/3d_armor/textures/3d_armor_boots_mithril_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_boots_steel.png
Normal file
After Width: | Height: | Size: 316 B |
BIN
mods/3d_armor/textures/3d_armor_boots_steel_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_boots_wood.png
Normal file
After Width: | Height: | Size: 274 B |
BIN
mods/3d_armor/textures/3d_armor_boots_wood_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_chestplate_bronze.png
Normal file
After Width: | Height: | Size: 556 B |
BIN
mods/3d_armor/textures/3d_armor_chestplate_bronze_preview.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mods/3d_armor/textures/3d_armor_chestplate_diamond.png
Normal file
After Width: | Height: | Size: 475 B |
BIN
mods/3d_armor/textures/3d_armor_chestplate_diamond_preview.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
mods/3d_armor/textures/3d_armor_chestplate_gold.png
Normal file
After Width: | Height: | Size: 430 B |
BIN
mods/3d_armor/textures/3d_armor_chestplate_gold_preview.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
mods/3d_armor/textures/3d_armor_chestplate_mithril.png
Normal file
After Width: | Height: | Size: 669 B |
BIN
mods/3d_armor/textures/3d_armor_chestplate_mithril_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_chestplate_steel.png
Normal file
After Width: | Height: | Size: 537 B |
BIN
mods/3d_armor/textures/3d_armor_chestplate_steel_preview.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mods/3d_armor/textures/3d_armor_chestplate_wood.png
Normal file
After Width: | Height: | Size: 453 B |
BIN
mods/3d_armor/textures/3d_armor_chestplate_wood_preview.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
mods/3d_armor/textures/3d_armor_helmet_bronze.png
Normal file
After Width: | Height: | Size: 602 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_bronze_preview.png
Normal file
After Width: | Height: | Size: 891 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_diamond.png
Normal file
After Width: | Height: | Size: 524 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_diamond_preview.png
Normal file
After Width: | Height: | Size: 902 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_gold.png
Normal file
After Width: | Height: | Size: 489 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_gold_preview.png
Normal file
After Width: | Height: | Size: 893 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_mithril.png
Normal file
After Width: | Height: | Size: 798 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_mithril_preview.png
Normal file
After Width: | Height: | Size: 853 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_steel.png
Normal file
After Width: | Height: | Size: 556 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_steel_preview.png
Normal file
After Width: | Height: | Size: 887 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_wood.png
Normal file
After Width: | Height: | Size: 485 B |
BIN
mods/3d_armor/textures/3d_armor_helmet_wood_preview.png
Normal file
After Width: | Height: | Size: 878 B |
BIN
mods/3d_armor/textures/3d_armor_inv_boots_bronze.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
mods/3d_armor/textures/3d_armor_inv_boots_diamond.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
mods/3d_armor/textures/3d_armor_inv_boots_gold.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
mods/3d_armor/textures/3d_armor_inv_boots_mithril.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
mods/3d_armor/textures/3d_armor_inv_boots_steel.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
mods/3d_armor/textures/3d_armor_inv_boots_wood.png
Normal file
After Width: | Height: | Size: 129 B |
BIN
mods/3d_armor/textures/3d_armor_inv_chestplate_bronze.png
Normal file
After Width: | Height: | Size: 142 B |
BIN
mods/3d_armor/textures/3d_armor_inv_chestplate_diamond.png
Normal file
After Width: | Height: | Size: 142 B |
BIN
mods/3d_armor/textures/3d_armor_inv_chestplate_gold.png
Normal file
After Width: | Height: | Size: 142 B |
BIN
mods/3d_armor/textures/3d_armor_inv_chestplate_mithril.png
Normal file
After Width: | Height: | Size: 142 B |
BIN
mods/3d_armor/textures/3d_armor_inv_chestplate_steel.png
Normal file
After Width: | Height: | Size: 142 B |
BIN
mods/3d_armor/textures/3d_armor_inv_chestplate_wood.png
Normal file
After Width: | Height: | Size: 142 B |
BIN
mods/3d_armor/textures/3d_armor_inv_helmet_bronze.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mods/3d_armor/textures/3d_armor_inv_helmet_diamond.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mods/3d_armor/textures/3d_armor_inv_helmet_gold.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mods/3d_armor/textures/3d_armor_inv_helmet_mithril.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mods/3d_armor/textures/3d_armor_inv_helmet_steel.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mods/3d_armor/textures/3d_armor_inv_helmet_wood.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
mods/3d_armor/textures/3d_armor_inv_leggings_bronze.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
mods/3d_armor/textures/3d_armor_inv_leggings_diamond.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
mods/3d_armor/textures/3d_armor_inv_leggings_gold.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
mods/3d_armor/textures/3d_armor_inv_leggings_mithril.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
mods/3d_armor/textures/3d_armor_inv_leggings_steel.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
mods/3d_armor/textures/3d_armor_inv_leggings_wood.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_bronze.png
Normal file
After Width: | Height: | Size: 335 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_bronze_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_leggings_diamond.png
Normal file
After Width: | Height: | Size: 306 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_diamond_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_leggings_gold.png
Normal file
After Width: | Height: | Size: 298 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_gold_preview.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mods/3d_armor/textures/3d_armor_leggings_mithril.png
Normal file
After Width: | Height: | Size: 497 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_mithril_preview.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
mods/3d_armor/textures/3d_armor_leggings_steel.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_steel_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_leggings_wood.png
Normal file
After Width: | Height: | Size: 285 B |
BIN
mods/3d_armor/textures/3d_armor_leggings_wood_preview.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
mods/3d_armor/textures/3d_armor_trans.png
Normal file
After Width: | Height: | Size: 75 B |
BIN
mods/3d_armor/textures/3d_armor_ui_form.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
mods/3d_armor/textures/character_preview.png
Normal file
After Width: | Height: | Size: 256 B |
BIN
mods/3d_armor/textures/inventory_plus_armor.png
Normal file
After Width: | Height: | Size: 544 B |
51
mods/anticheat/init.lua
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
-- rnd: anti noclip cheat
|
||||
local clip_nodes = {["default:stone"]=1,["default:cobble"]=1,["default:stonebrick"]=1,["default:dirt"]=1,["default:glass"]=1,["default:dirt"]=1,["default:steelblock"]=1}
|
||||
local time =0;
|
||||
local ANTI_CHEAT_UPDATE_TIME = 5;
|
||||
local anti_cheat = {};
|
||||
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
time = time + dtime
|
||||
if time < ANTI_CHEAT_UPDATE_TIME then return end
|
||||
time = 0;
|
||||
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
local p = player:getpos()
|
||||
local name = player:get_player_name();
|
||||
local node1 = minetest.get_node(p).name;
|
||||
p.y=p.y+1;
|
||||
local node2 = minetest.get_node(p).name;
|
||||
--minetest.chat_send_all(name .. " : " .. (clip_nodes[node1] or 0) .. " " .. (clip_nodes[node2] or 0));
|
||||
local privs = minetest.get_player_privs(name);
|
||||
if not privs.noclip then
|
||||
if clip_nodes[node1]==1 and clip_nodes[node2]==1 then
|
||||
if player:get_hp() > 0 then -- if alive
|
||||
local p0 = anti_cheat[name] or {x=p.x,y=p.y,z=p.z}; -- read previous player position from 5 secs ago
|
||||
local check = true;
|
||||
if clip_nodes[minetest.get_node(p0).name]~=1 then check = false end -- previous position was not inside clip
|
||||
p0={x=p.x-p0.x,y=p.y-p0.y,z=p.z-p0.z}; -- movement direction
|
||||
local dist = math.sqrt(p0.x*p0.x+p0.y*p0.y+p0.z*p0.z);
|
||||
if dist == 0 then check = false -- player not moving
|
||||
else
|
||||
p0.x=p0.x/dist;p0.y=p0.y/dist;p0.z=p0.z/dist;
|
||||
for i=1,16 do -- look into direction of movement backwards for any nonclip blocks
|
||||
local node = minetest.get_node({x=p.x-p0.x*i,y=p.y-p0.y*i,z=p.z-p0.z*i}).name;
|
||||
if clip_nodes[node]~=1 then check = false break end
|
||||
end
|
||||
|
||||
end
|
||||
if check then
|
||||
player:set_hp(1); -- kill player
|
||||
minetest.chat_send_all(name.. " was caught walking inside walls at " .. p.x .. " " .. p.y .. " " .. p.z)
|
||||
minetest.log("action", name.. " was caught walking inside walls at " .. p.x .. " " .. p.y .. " " .. p.z)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
anti_cheat[name]=p; -- remember previous position
|
||||
end
|
||||
end
|
||||
)
|
492
mods/awards/api.lua
Normal file
@ -0,0 +1,492 @@
|
||||
-- AWARDS
|
||||
-- by Rubenwardy
|
||||
-------------------------------------------------------
|
||||
-- this is api function file
|
||||
-------------------------------------------------------
|
||||
|
||||
-- The global award namespace
|
||||
awards = {
|
||||
show_mode = "hud"
|
||||
}
|
||||
|
||||
-- Table Save Load Functions
|
||||
function awards.save()
|
||||
local file = io.open(minetest.get_worldpath().."/awards.txt", "w")
|
||||
if file then
|
||||
file:write(minetest.serialize(awards.players))
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
function awards.load()
|
||||
local file = io.open(minetest.get_worldpath().."/awards.txt", "r")
|
||||
if file then
|
||||
local table = minetest.deserialize(file:read("*all"))
|
||||
if type(table) == "table" then
|
||||
return table
|
||||
end
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
awards.players = awards.load()
|
||||
function awards.player(name)
|
||||
return awards.players[name]
|
||||
end
|
||||
|
||||
-- A table of award definitions
|
||||
awards.def = {}
|
||||
|
||||
function awards.tbv(tb,value,default)
|
||||
if not default then
|
||||
default = {}
|
||||
end
|
||||
if not tb or type(tb) ~= "table" then
|
||||
if not value then
|
||||
value = "[NULL]"
|
||||
end
|
||||
minetest.log("error", "awards.tbv - table "..dump(value).." is null, or not a table! Dump: "..dump(tb))
|
||||
return
|
||||
end
|
||||
if not value then
|
||||
error("[ERROR] awards.tbv was not used correctly!\n"..
|
||||
"Value: '"..dump(value).."'\n"..
|
||||
"Dump:"..dump(tb))
|
||||
return
|
||||
end
|
||||
if not tb[value] then
|
||||
tb[value] = default
|
||||
end
|
||||
end
|
||||
|
||||
function awards.assertPlayer(playern)
|
||||
awards.tbv(awards.players, playern)
|
||||
awards.tbv(awards.players[playern], "name", playern)
|
||||
awards.tbv(awards.players[playern], "unlocked")
|
||||
awards.tbv(awards.players[playern], "place")
|
||||
awards.tbv(awards.players[playern], "count")
|
||||
awards.tbv(awards.players[playern], "deaths", 0)
|
||||
awards.tbv(awards.players[playern], "joins", 0)
|
||||
awards.tbv(awards.players[playern], "chats", 0)
|
||||
end
|
||||
|
||||
-- Load files
|
||||
dofile(minetest.get_modpath("awards").."/triggers.lua")
|
||||
|
||||
-- API Functions
|
||||
function awards._additional_triggers(name, data_table)
|
||||
-- To add triggers in another mod, you should override this function
|
||||
-- If the code can't handle the trigger passed, then call the last value of _additional_triggers
|
||||
--[[
|
||||
local add_trig = awards._additional_triggers
|
||||
awards._additional_triggers = function(name, data_table)
|
||||
if data_table.trigger.type == "trigger" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onTrigger,tmp)
|
||||
elseif data_table.trigger.type == "trigger2" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onTrigger2,tmp)
|
||||
else
|
||||
add_trig(name, data_table)
|
||||
end
|
||||
end
|
||||
]]--
|
||||
end
|
||||
function awards.register_achievement(name,data_table)
|
||||
-- see if a trigger is defined in the achievement definition
|
||||
if data_table.trigger and data_table.trigger.type then
|
||||
if data_table.trigger.type == "dig" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onDig,tmp)
|
||||
elseif data_table.trigger.type == "place" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
node = data_table.trigger.node,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onPlace,tmp)
|
||||
elseif data_table.trigger.type == "death" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onDeath,tmp)
|
||||
elseif data_table.trigger.type == "chat" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onChat,tmp)
|
||||
elseif data_table.trigger.type == "join" then
|
||||
local tmp = {
|
||||
award = name,
|
||||
target = data_table.trigger.target,
|
||||
}
|
||||
table.insert(awards.onJoin,tmp)
|
||||
else
|
||||
awards._additional_triggers(name, data_table)
|
||||
end
|
||||
end
|
||||
|
||||
-- check icon, background and custom_announce data
|
||||
if data_table.icon == nil or data_table.icon == "" then
|
||||
data_table.icon = "unknown.png"
|
||||
end
|
||||
if data_table.background == nil or data_table.background == "" then
|
||||
data_table.background = "bg_default.png"
|
||||
end
|
||||
if data_table.custom_announce == nil or data_table.custom_announce == "" then
|
||||
data_table.custom_announce = "Achievement Unlocked:"
|
||||
end
|
||||
|
||||
-- add the achievement to the definition table
|
||||
data_table.name = name
|
||||
awards.def[name] = data_table
|
||||
end
|
||||
|
||||
-- run a function when a node is dug
|
||||
function awards.register_onDig(func)
|
||||
table.insert(awards.onDig,func)
|
||||
end
|
||||
|
||||
-- run a function when a node is placed
|
||||
function awards.register_onPlace(func)
|
||||
table.insert(awards.onPlace,func)
|
||||
end
|
||||
|
||||
-- run a function when a player dies
|
||||
function awards.register_onDeath(func)
|
||||
table.insert(awards.onDeath,func)
|
||||
end
|
||||
|
||||
-- run a function when a player chats
|
||||
function awards.register_onChat(func)
|
||||
table.insert(awards.onChat,func)
|
||||
end
|
||||
|
||||
-- run a function when a player joins
|
||||
function awards.register_onJoin(func)
|
||||
table.insert(awards.onJoin,func)
|
||||
end
|
||||
|
||||
-- This function is called whenever a target condition is met.
|
||||
-- It checks if a player already has that achievement, and if they do not,
|
||||
-- it gives it to them
|
||||
----------------------------------------------
|
||||
--awards.give_achievement(name,award)
|
||||
-- name - the name of the player
|
||||
-- award - the name of the award to give
|
||||
function awards.give_achievement(name, award)
|
||||
-- Access Player Data
|
||||
local data = awards.players[name]
|
||||
|
||||
-- Perform checks
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
if not awards.def[award] then
|
||||
return
|
||||
end
|
||||
awards.tbv(data,"unlocked")
|
||||
|
||||
-- check to see if the player does not already have that achievement
|
||||
if not data.unlocked[award] or data.unlocked[award]~=award then
|
||||
-- Set award flag
|
||||
data.unlocked[award]=award
|
||||
|
||||
-- Give Prizes
|
||||
if awards.def[award] and awards.def[award].prizes then
|
||||
for i = 1, #awards.def[award].prizes do
|
||||
local itemstack = ItemStack(awards.def[award].prizes[i])
|
||||
if itemstack:is_empty() or not itemstack:is_known() then
|
||||
return
|
||||
end
|
||||
local receiverref = core.get_player_by_name(name)
|
||||
if receiverref == nil then
|
||||
return
|
||||
end
|
||||
receiverref:get_inventory():add_item("main", itemstack)
|
||||
end
|
||||
end
|
||||
|
||||
-- Get data from definition tables
|
||||
local title = award
|
||||
local desc = ""
|
||||
local background = ""
|
||||
local icon = ""
|
||||
local custom_announce = ""
|
||||
if awards.def[award].title then
|
||||
title = awards.def[award].title
|
||||
end
|
||||
if awards.def[award].custom_announce then
|
||||
custom_announce = awards.def[award].custom_announce
|
||||
end
|
||||
if awards.def[award].background then
|
||||
background = awards.def[award].background
|
||||
end
|
||||
if awards.def[award].icon then
|
||||
icon = awards.def[award].icon
|
||||
end
|
||||
if awards.def[award] and awards.def[award].description then
|
||||
desc = awards.def[award].description
|
||||
end
|
||||
|
||||
-- send the won award message to the player
|
||||
if awards.show_mode == "formspec" then
|
||||
-- use a formspec to send it
|
||||
minetest.show_formspec(name, "achievements:unlocked", "size[4,2]"..
|
||||
"image_button_exit[0,0;4,2;"..background..";close1; ]"..
|
||||
"image_button_exit[0.2,0.8;1,1;"..icon..";close2; ]"..
|
||||
"label[1.1,1;"..title.."]"..
|
||||
"label[0.3,0.1;"..custom_announce.."]")
|
||||
elseif awards.show_mode == "chat" then
|
||||
-- use the chat console to send it
|
||||
minetest.chat_send_player(name, "Achievement Unlocked: "..title)
|
||||
if desc~="" then
|
||||
minetest.chat_send_player(name, desc)
|
||||
end
|
||||
else
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local one = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
name = "award_bg",
|
||||
scale = {x = 1, y = 1},
|
||||
text = background,
|
||||
position = {x = 0.5, y = 0},
|
||||
offset = {x = 0, y = 138},
|
||||
alignment = {x = 0, y = -1}
|
||||
})
|
||||
local two = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
name = "award_au",
|
||||
number = 0xFFFFFF,
|
||||
scale = {x = 100, y = 20},
|
||||
text = "Achievement Unlocked!",
|
||||
position = {x = 0.5, y = 0},
|
||||
offset = {x = 0, y = 40},
|
||||
alignment = {x = 0, y = -1}
|
||||
})
|
||||
local three = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
name = "award_title",
|
||||
number = 0xFFFFFF,
|
||||
scale = {x = 100, y = 20},
|
||||
text = title,
|
||||
position = {x = 0.5, y = 0},
|
||||
offset = {x = 30, y = 100},
|
||||
alignment = {x = 0, y = -1}
|
||||
})
|
||||
local four = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
name = "award_icon",
|
||||
scale = {x = 4, y = 4},
|
||||
text = icon,
|
||||
position = {x = 0.5, y = 0},
|
||||
offset = {x = -81.5, y = 126},
|
||||
alignment = {x = 0, y = -1}
|
||||
})
|
||||
minetest.after(3, function()
|
||||
player:hud_remove(one)
|
||||
player:hud_remove(two)
|
||||
player:hud_remove(three)
|
||||
player:hud_remove(four)
|
||||
end)
|
||||
end
|
||||
|
||||
-- record this in the log
|
||||
minetest.log("action", name.." has unlocked award "..title)
|
||||
|
||||
-- save playertable
|
||||
awards.save()
|
||||
end
|
||||
end
|
||||
|
||||
-- List a player's achievements
|
||||
minetest.register_chatcommand("list_awards", {
|
||||
params = "obsolete",
|
||||
description = "list_awards: obsolete. Use /awards",
|
||||
func = function(name, param)
|
||||
minetest.chat_send_player(name, "This command has been made obsolete. Use /awards instead.")
|
||||
awards.showto(name, name, nil, false)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("awards", {
|
||||
params = "",
|
||||
description = "awards: list awards",
|
||||
func = function(name, param)
|
||||
awards.showto(name, name, nil, false)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("cawards", {
|
||||
params = "",
|
||||
description = "awards: list awards in chat",
|
||||
func = function(name, param)
|
||||
awards.showto(name, name, nil, true)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("awd", {
|
||||
params = "award name",
|
||||
description = "awd: Details of awd gotten",
|
||||
func = function(name, param)
|
||||
local def = awards.def[param]
|
||||
if def then
|
||||
minetest.chat_send_player(name,def.title..": "..def.description)
|
||||
else
|
||||
minetest.chat_send_player(name,"Award not found.")
|
||||
end
|
||||
end
|
||||
})
|
||||
--[[minetest.register_chatcommand("gawd", {
|
||||
params = "award name",
|
||||
description = "gawd: give award to self",
|
||||
func = function(name, param)
|
||||
awards.give_achievement(name,param)
|
||||
end
|
||||
})]]--
|
||||
|
||||
function awards._order_awards(name)
|
||||
local done = {}
|
||||
local retval = {}
|
||||
local player = awards.player(name)
|
||||
if player and player.unlocked then
|
||||
for _,got in pairs(player.unlocked) do
|
||||
if awards.def[got] then
|
||||
done[got] = true
|
||||
table.insert(retval,{name=got,got=true})
|
||||
end
|
||||
end
|
||||
end
|
||||
for _,def in pairs(awards.def) do
|
||||
if not done[def.name] then
|
||||
table.insert(retval,{name=def.name,got=false})
|
||||
end
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
function awards.showto(name, to, sid, text)
|
||||
if name == "" or name == nil then
|
||||
name = to
|
||||
end
|
||||
if text then
|
||||
if not awards.players[name] or not awards.players[name].unlocked then
|
||||
minetest.chat_send_player(to, "You have not unlocked any awards")
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(to, name.."'s awards:")
|
||||
|
||||
for _, str in pairs(awards.players[name].unlocked) do
|
||||
local def = awards.def[str]
|
||||
if def then
|
||||
if def.title then
|
||||
if def.description then
|
||||
minetest.chat_send_player(to, def.title..": "..def.description)
|
||||
else
|
||||
minetest.chat_send_player(to, def.title)
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(to, str)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if sid == nil or sid < 1 then
|
||||
sid = 1
|
||||
end
|
||||
local formspec = "size[11,5]"
|
||||
local listofawards = awards._order_awards(name)
|
||||
|
||||
-- Sidebar
|
||||
if sid then
|
||||
local item = listofawards[sid+0]
|
||||
local def = awards.def[item.name]
|
||||
if def and def.secret and not item.got then
|
||||
formspec = formspec .. "label[1,2.75;Secret Award]"..
|
||||
"image[1,0;3,3;unknown.png]"
|
||||
if def and def.description then
|
||||
formspec = formspec .. "label[0,3.25;Unlock this award to find out what it is]"
|
||||
end
|
||||
else
|
||||
local title = item.name
|
||||
if def and def.title then
|
||||
title = def.title
|
||||
end
|
||||
local status = ""
|
||||
if item.got then
|
||||
status = " (got)"
|
||||
end
|
||||
local icon = ""
|
||||
if def and def.icon then
|
||||
icon = def.icon
|
||||
end
|
||||
formspec = formspec .. "label[1,2.75;"..title..status.."]"..
|
||||
"image[1,0;3,3;"..icon.."]"
|
||||
if def and def.description then
|
||||
formspec = formspec .. "label[0,3.25;"..def.description.."]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Create list box
|
||||
formspec = formspec .. "textlist[4.75,0;6,5;awards;"
|
||||
local first = true
|
||||
for _,award in pairs(listofawards) do
|
||||
local def = awards.def[award.name]
|
||||
if def then
|
||||
if not first then
|
||||
formspec = formspec .. ","
|
||||
end
|
||||
first = false
|
||||
|
||||
if def.secret and not award.got then
|
||||
formspec = formspec .. "#ACACACSecret Award"
|
||||
else
|
||||
local title = award.name
|
||||
if def and def.title then
|
||||
title = def.title
|
||||
end
|
||||
if award.got then
|
||||
formspec = formspec .. minetest.formspec_escape(title)
|
||||
else
|
||||
formspec = formspec .. "#ACACAC".. minetest.formspec_escape(title)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
formspec = formspec .. ";"..sid.."]"
|
||||
|
||||
-- Show formspec to user
|
||||
minetest.show_formspec(to,"awards:awards",formspec)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname~="awards:awards" then
|
||||
return false
|
||||
end
|
||||
if fields.quit then
|
||||
return true
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
if fields.awards then
|
||||
local event = minetest.explode_textlist_event(fields.awards)
|
||||
if event.type == "CHG" then
|
||||
awards.showto(name,name,event.index,false)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
373
mods/awards/init.lua
Normal file
@ -0,0 +1,373 @@
|
||||
-- AWARDS
|
||||
-- by Rubenwardy
|
||||
-------------------------------------------------------
|
||||
-- this is the init file for the award mod
|
||||
-------------------------------------------------------
|
||||
|
||||
local S
|
||||
if (intllib) then
|
||||
dofile(minetest.get_modpath("intllib").."/intllib.lua")
|
||||
S = intllib.Getter(minetest.get_current_modname())
|
||||
else
|
||||
S = function ( s ) return s end
|
||||
end
|
||||
|
||||
dofile(minetest.get_modpath("awards").."/api.lua")
|
||||
|
||||
-- Light it up
|
||||
awards.register_achievement("award_lightitup",{
|
||||
title = S("Light It Up"),
|
||||
description = S("Place 100 torches."),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "default:torch",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Light ALL the things!
|
||||
awards.register_achievement("award_light_all_the_things",{
|
||||
title = S("Light ALL The Things!"),
|
||||
description = S("Place 1,000 torches."),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "default:torch",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- Saint-Maclou
|
||||
if minetest.get_modpath("moreblocks") then
|
||||
awards.register_achievement("award_saint_maclou",{
|
||||
title = S("Saint-Maclou"),
|
||||
description = S("Place 20 coal checkers."),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "moreblocks:coal_checker",
|
||||
target = 20
|
||||
}
|
||||
})
|
||||
|
||||
-- Castorama
|
||||
awards.register_achievement("award_castorama",{
|
||||
title = S("Castorama"),
|
||||
description = S("Place 20 iron checkers."),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "moreblocks:iron_checker",
|
||||
target = 20
|
||||
}
|
||||
})
|
||||
|
||||
-- Sam the Trapper
|
||||
awards.register_achievement("award_sam_the_trapper",{
|
||||
title = S("Sam the Trapper"),
|
||||
description = S("Place 2 trap stones."),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "moreblocks:trap_stone",
|
||||
target = 2
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
-- Obsessed with Obsidian
|
||||
awards.register_achievement("award_obsessed_with_obsidian",{
|
||||
title = S("Obsessed with Obsidian"),
|
||||
description = S("Mine 50 obsidian."),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:obsidian",
|
||||
target = 50
|
||||
}
|
||||
})
|
||||
|
||||
-- On the way
|
||||
awards.register_achievement("award_on_the_way",{
|
||||
title = S("On The Way"),
|
||||
description = S("Place 100 rails."),
|
||||
icon = "novicebuilder.png",
|
||||
trigger = {
|
||||
type = "place",
|
||||
node = "default:rail",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Lumberjack
|
||||
awards.register_achievement("award_lumberjack",{
|
||||
title = S("Lumberjack"),
|
||||
description = S("Dig 100 tree blocks."),
|
||||
icon = "default_tree.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:tree",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Semi-pro Lumberjack
|
||||
awards.register_achievement("award_lumberjack_semipro",{
|
||||
title = S("Semi-pro Lumberjack"),
|
||||
description = S("Dig 1,000 tree blocks."),
|
||||
icon = "default_tree.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:tree",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
-- Professional Lumberjack
|
||||
awards.register_achievement("award_lumberjack_professional",{
|
||||
title = S("Professional Lumberjack"),
|
||||
description = S("Dig 10,000 tree blocks."),
|
||||
icon = "default_tree.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:tree",
|
||||
target = 10000
|
||||
}
|
||||
})
|
||||
|
||||
-- L33T Lumberjack
|
||||
awards.register_achievement("award_lumberjack_leet",{
|
||||
title = S("L33T Lumberjack"),
|
||||
description = S("Dig 100,000 tree blocks."),
|
||||
icon = "default_tree.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:tree",
|
||||
target = 100000
|
||||
}
|
||||
})
|
||||
|
||||
-- Junglebaby
|
||||
awards.register_achievement("award_junglebaby",{
|
||||
title = S("Junglebaby"),
|
||||
description = S("Dig 100 jungle tree blocks."),
|
||||
icon = "default_jungletree.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:jungletree",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Jungleman
|
||||
awards.register_achievement("award_jungleman",{
|
||||
title = S("Jungleman"),
|
||||
description = S("Dig 1,000 jungle tree blocks."),
|
||||
icon = "default_jungletree.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:jungletree",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
-- Found some Mese!
|
||||
awards.register_achievement("award_mesefind",{
|
||||
title = S("First Mese Find"),
|
||||
description = S("Find some Mese."),
|
||||
icon = "default_mese_block.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone_with_mese",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
-- You're a copper
|
||||
awards.register_achievement("award_youre_a_copper",{
|
||||
title = S("You're a copper"),
|
||||
description = S("Dig 1,000 copper ores."),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone_with_copper",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
-- You're winner
|
||||
awards.register_achievement("award_youre_winner",{
|
||||
title = S("YOU'RE A WINNER!"),
|
||||
description = S("Dig 1 mossy cobblestone."),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:mossycobble",
|
||||
target = 1
|
||||
},
|
||||
secret = true,
|
||||
})
|
||||
|
||||
-- Found a Nyan cat!
|
||||
awards.register_achievement("award_nyanfind",{
|
||||
title = S("OMG, Nyan Cat!"),
|
||||
description = S("Find a nyan cat."),
|
||||
icon = "default_nc_rb.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:nyancat",
|
||||
target = 1
|
||||
}
|
||||
})
|
||||
|
||||
-- Mini Miner
|
||||
awards.register_achievement("award_mine2",{
|
||||
title = S("Mini Miner"),
|
||||
description = S("Dig 100 stone blocks."),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 100
|
||||
}
|
||||
})
|
||||
|
||||
-- Hardened Miner
|
||||
awards.register_achievement("award_mine3",{
|
||||
title = S("Hardened Miner"),
|
||||
description = S("Dig 1,000 stone blocks"),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
-- Master Miner
|
||||
awards.register_achievement("award_mine4",{
|
||||
title = S("Master Miner"),
|
||||
description = S("Dig 10,000 stone blocks."),
|
||||
icon = "miniminer.png",
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:stone",
|
||||
target = 10000
|
||||
}
|
||||
})
|
||||
|
||||
-- Marchand de sable
|
||||
awards.register_achievement("award_marchand_de_sable",{
|
||||
title = S("Marchand De Sable"),
|
||||
description = S("Dig 1,000 sand."),
|
||||
background = "bg_mining.png",
|
||||
trigger = {
|
||||
type = "dig",
|
||||
node = "default:sand",
|
||||
target = 1000
|
||||
}
|
||||
})
|
||||
|
||||
-- Join
|
||||
awards.register_achievement("award_join2",{
|
||||
title = S("Frequent Visitor"),
|
||||
description = S("Connect to the server 50 times."),
|
||||
trigger = {
|
||||
type = "join",
|
||||
target = 50
|
||||
},
|
||||
secret = true
|
||||
})
|
||||
|
||||
-- Dying Spree
|
||||
awards.register_achievement("award_dying_spree",{
|
||||
title = S("Dying Spree"),
|
||||
description = S("Die 5 times."),
|
||||
trigger = {
|
||||
type = "death",
|
||||
target = 5
|
||||
}
|
||||
})
|
||||
|
||||
-- Bot-like
|
||||
awards.register_achievement("award_bot_like",{
|
||||
title = S("Bot-like"),
|
||||
description = S("Die 10 times."),
|
||||
trigger = {
|
||||
type = "death",
|
||||
target = 10
|
||||
}
|
||||
})
|
||||
|
||||
-- You Suck!
|
||||
awards.register_achievement("award_you_suck",{
|
||||
title = S("You Suck!"),
|
||||
description = S("Die 100 times."),
|
||||
trigger = {
|
||||
type = "death",
|
||||
target = 100
|
||||
},
|
||||
secret = true
|
||||
})
|
||||
|
||||
-- Burned to death
|
||||
awards.register_achievement("award_burn",{
|
||||
title = S("You're a witch!"),
|
||||
description = S("Burn to death in a fire.")
|
||||
})
|
||||
awards.register_onDeath(function(player,data)
|
||||
local pos = player:getpos()
|
||||
if pos and minetest.find_node_near(pos, 2, "fire:basic_flame") ~= nil then
|
||||
return "award_burn"
|
||||
end
|
||||
return nil
|
||||
end)
|
||||
|
||||
-- Died in flowing lava
|
||||
awards.register_achievement("award_in_the_flow",{
|
||||
title = S("In the Flow"),
|
||||
description = S("Die in flowing lava.")
|
||||
})
|
||||
awards.register_onDeath(function(player,data)
|
||||
local pos = player:getpos()
|
||||
if pos and minetest.find_node_near(pos, 2, "default:lava_flowing") ~= nil then
|
||||
return "award_in_the_flow"
|
||||
end
|
||||
return nil
|
||||
end)
|
||||
|
||||
-- Die near diamond ore
|
||||
awards.register_achievement("award_this_is_sad",{
|
||||
title = S("This is Sad"),
|
||||
description = S("Die near diamond ore.")
|
||||
})
|
||||
awards.register_onDeath(function(player,data)
|
||||
local pos = player:getpos()
|
||||
if pos and minetest.find_node_near(pos, 5, "default:stone_with_diamond") ~= nil then
|
||||
return "award_this_is_sad"
|
||||
end
|
||||
return nil
|
||||
end)
|
||||
|
||||
-- Die near diamond ore
|
||||
awards.register_achievement("award_the_stack",{
|
||||
title = S("The Stack"),
|
||||
description = S("Die near bones.")
|
||||
})
|
||||
awards.register_onDeath(function(player,data)
|
||||
local pos = player:getpos()
|
||||
if pos and minetest.find_node_near(pos, 5, "bones:bones") ~= nil then
|
||||
return "award_the_stack"
|
||||
end
|
||||
return nil
|
||||
end)
|
||||
|
55
mods/awards/readme.md
Normal file
@ -0,0 +1,55 @@
|
||||
Awards
|
||||
------
|
||||
|
||||
by Andrew "Rubenwardy" Ward, GPL 3.0 or later.
|
||||
|
||||
This mod adds achievements to Minetest.
|
||||
|
||||
Majority of awards are back ported from Calinou's
|
||||
old fork in Carbone, under same license.
|
||||
|
||||
|
||||
Code Reference
|
||||
--------------
|
||||
|
||||
The API
|
||||
=======
|
||||
* awards.register_achievement(name,data_table)
|
||||
* name
|
||||
* desciption
|
||||
* sound [optional]
|
||||
* image [optional]
|
||||
* trigger [optional] [table]
|
||||
* type - "dig", "place", "death", "chat" or "join"
|
||||
* (for dig/place type) node - the nodes name
|
||||
* (for all types) target - how many to dig / place
|
||||
* secret [optional] - if true, then player needs to unlock to find out what it is.
|
||||
* awards.give_achievement(name,award)
|
||||
* -- gives an award to a player
|
||||
* awards.register_onDig(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onPlace(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onDeath(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onChat(func(player,data))
|
||||
* -- return award name or null
|
||||
* awards.register_onJoin(func(player,data))
|
||||
* -- return award name or null
|
||||
|
||||
|
||||
Player Data
|
||||
===========
|
||||
|
||||
A list of data referenced/hashed by the player's name.
|
||||
* player name
|
||||
* name [string]
|
||||
* count [table] - dig counter
|
||||
* modname [table]
|
||||
* itemname [int]
|
||||
* place [table] - place counter
|
||||
* modname [table]
|
||||
* itemname [int]
|
||||
* deaths
|
||||
* chats
|
||||
* joins
|
BIN
mods/awards/textures/bg_default.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
mods/awards/textures/bg_mining.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
mods/awards/textures/mese.png
Normal file
After Width: | Height: | Size: 564 B |
BIN
mods/awards/textures/miniminer.png
Normal file
After Width: | Height: | Size: 455 B |
BIN
mods/awards/textures/novicebuilder.png
Normal file
After Width: | Height: | Size: 374 B |
BIN
mods/awards/textures/template.png
Normal file
After Width: | Height: | Size: 322 B |