Merge development branch (#4)

merge development code in to master
master
shivajiva101 2020-08-12 17:08:29 +01:00 committed by GitHub
parent cc6ebe96ad
commit 5d639dbcc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 6067 additions and 498 deletions

100
API.md Normal file
View File

@ -0,0 +1,100 @@
## Eggwars API
Welcome to the API documentation
The structure of the mod hinges around the arena definitions registered to the mod.
There is a default arena definition which you can use as a template for your own arenas.
It's structure is a table of key pairs holding all the information required to insert
an arena at any location on the map, position vectors used in the definition MUST
be relative to x=0, y=0, z=0 of the arena unless stated otherwise.
### Arena Definition Structure
{
blocked_recipes = {
{input or output recipe},
...
}
colour = {
{ rgb table },
...
},
cs = {
{'colour', 'hex string', 'formatted'},
...
}
description = "short description",
egg_offset = { -- island relative
{vector},
...
}
exempt_nodes = {
['full or partial node name'] = true,
...
}
hub = {
insert_offset = {vector},
schem = 'filename'
},
island = {
{vector},
...,
insert_offset = {vector},
schem = 'filename'
},
name = 'arena name',
region = {
p1 = {vector},
p2 = {vector}
},
satellite = {
offset = {vector},
pos = {
{vector},
...
}
},
spawners = {
diamond = {
{vector},
...,
rate = number of seconds
},
gold = { -- island relative
{vector},
...,
rate = number of seconds
},
ruby = {
{vector},
...,
rate = number of seconds
}
bot = { -- island relative
offset = {
{vector},
...,
yaw = {degrees, ...}
}
}
}
timer = {
max_time = number of seconds,
suddendeath = number of seconds
},
trader = {
names = {
"name",
...,
},
offset = { -- island relative
{vector},
...,
},
yaw = {degrees, ...}
}
}
### Functions
eggwars.register_arena(arena_def)
Registers an arena definition to eggwars.

0
LICENSE Normal file → Executable file
View File

44
README.md Normal file → Executable file
View File

@ -3,23 +3,51 @@
## What this is
This mod is inspired by the Minecraft mod of the same name and has similar features.
Each player's goal is to defend their egg and be the last person standing. If a player dies - either from being killed by another player or falling off - they will respawn if their egg is intact. If it is not intact, they will be put into spectator mode.
Each player's goal is to defend their egg and be the last person standing. If a player dies - either from being killed by another player or falling off - they will re-spawn whilst their egg is intact. If it is not intact, they experience match death and enter into spectator mode.
When there is one player left standing, they are declared the winner.
When there is one player left standing in a match, they are declared the winner.
## Features
* Lobby
* Multiple match instances
* Island NPC Trader shops
* Island NPC Spawner Upgrades
* Coloured match chat
* API for adding content
## Install
Extract the zip file to mods/ **or** use `git clone https://github.com/shivajiva101/eggwars` from within the mods directory.
* Do **NOT** use an existing world - this will overwrite the mapgen and cause destruction.
* Do not use a different mapgen mod. This will also cause issues
* Make and use a copy of games/minetest_game called games/eggwars and delete the mods you don't need like beds, boats, bucket, butterflies, carts, dungeon_loot, fireflies, give_initial_stuff, sethome, spawn, vessels, weather
## Using custom structures
The structures are stored in the schems/ folder. The centre and island files are the centre island and player islands respectively. They are stored using Minetest's MTS files. These do not save metadata, so you cannot prefill chests. If you modify these, please update the offsets for the islands:
* Centre island: Lines `96-98`
* Player island: Lines `109-111`
###### Additionally it is highly recommended that you add these mods:
* 3D armor [ https://github.com/minetest-mods/3d_armor ]
* Bows [ https://notabug.org/TenPlus1/bows ]
## Adding your own arena
Adding your own arena is easy via the API function ``eggwars.register_arena(def) ``
the default definition can be found in ``register_arena.lua `` and should be used as the reference template for creating your own arenas, it's a keypair table proliferated with comments to help understand what data each key requires. This design concept allows you to use your own schematics for islands, arena hubs and spawner satellites, controlling the positions of all current arena elements. See API.md for more details on this mods API functions and how to use them.
## License
This project is licensed under AGPL v3. This is similar to the GPLv3, but requires servers that modify the mod to also make their changes available.
This project is licensed under AGPL v3. This is similar to the GPLv3, but requires any code modifications to be available on request.
## Contributors
This project was originally started by wilkgr, but after years of inactivity handed over to shivajiva.
This project was originally started by wilkgr, but after years of inactivity handed over to shivajiva.
## Credits
###### Sounds:
* eggwars_winner.ogg uses https://freesound.org/s/406371/ by SoundBat (CC0 1.0)
* eggwars_out.ogg uses https://freesound.org/s/350985/ by cabled_mess (CC0 1.0)
* eggwars_game_over.ogg uses https://freesound.org/s/277403/ by landlucky (CC BY 3.0)
* eggwars_time_over.ogg uses https://freesound.org/s/437661/ by dersuperanton (CC BY 3.0)
* eggwars_sudden.ogg uses https://freesound.org/s/476176/ by umdamlar (CC0 1.0)
###### Textures:
* All textures created by shivajiva using Gimp (CC BY-NC 4.0)
* Egg mesh created by shivajiva using Blender (CC BY-NC 4.0)
###### Schematics:
* created in MT by shivajiva (CC BY-NC 4.0)

0
_config.yml Normal file → Executable file
View File

3
depends.txt Normal file → Executable file
View File

@ -1,2 +1,3 @@
default
sfinv
armor?
bows?

516
extender.lua Executable file
View File

@ -0,0 +1,516 @@
----------------------------------------------------------------------
-- Eggwars by wilkgr --
-- with additional code by shivajiva101@hotmail.com --
-- Licensed under the AGPL v3 --
-- You MUST make any changes you make open source --
-- even if you just run it on your server without publishing it --
-- Supports a maximum of 8 players per instance and 8 concurrent --
-- instances for a max of 64 players --
----------------------------------------------------------------------
-- Parts of the code in this file are modified or copied
-- from worldedit by Uberi https://github.com/Uberi/Minetest-WorldEdit
local HEADER = 5 .. ":"
local jit_available = jit ~= nil
--- Copies and modifies positions `pos1` and `pos2` so that each component of
-- `pos1` is less than or equal to the corresponding component of `pos2`.
-- @return the new positions.
local function sort_pos(pos1, pos2)
pos1 = {x=pos1.x, y=pos1.y, z=pos1.z}
pos2 = {x=pos2.x, y=pos2.y, z=pos2.z}
if pos1.x > pos2.x then
pos2.x, pos1.x = pos1.x, pos2.x
end
if pos1.y > pos2.y then
pos2.y, pos1.y = pos1.y, pos2.y
end
if pos1.z > pos2.z then
pos2.z, pos1.z = pos1.z, pos2.z
end
return pos1, pos2
end
--- Keeps a region of map chunks loaded
local function keep_loaded(pos1, pos2)
local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2)
end
--- Reads the header of serialized data.
-- @param value Serialized data.
-- @return The version as a positive natural number, or 0 for unknown versions.
-- @return Extra header fields as a list of strings, or nil if not supported.
-- @return Content (data after header).
local function read_header(value)
if value:find("^[0-9]+[%-:]") then
local header_end = value:find(":", 1, true)
local header = value:sub(1, header_end - 1):split(",")
local version = tonumber(header[1])
table.remove(header, 1)
local content = value:sub(header_end + 1)
return version, header, content
end
return nil
end
--- Loads the schematic in `value` into a node list in the latest format.
-- Contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile)
-- by ChillCode, available under the MIT license.
-- @return A node list in the latest format, or nil on failure.
local function load_schematic(value)
local version, _, content = read_header(value)
local nodes = {}
if version == 5 then -- correct format
if not jit_available then
-- This is broken for larger tables in the current version of LuaJIT
nodes = minetest.deserialize(content)
else
-- XXX: This is a filthy hack that works surprisingly well - in LuaJIT, `minetest.deserialize` will fail due to the register limit
content = content:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data
local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)
local startpos, startpos1, endpos = 1, 1
while true do -- go through each individual node entry (except the last)
startpos, endpos = escaped:find("},%s*{", startpos)
if not startpos then
break
end
local current = content:sub(startpos1, startpos)
local entry = minetest.deserialize("return " .. current)
table.insert(nodes, entry)
startpos, startpos1 = endpos, endpos
end
local entry = minetest.deserialize("return " .. content:sub(startpos1)) -- process the last entry
table.insert(nodes, entry)
end
else
return nil
end
return nodes
end
local function allocate_with_nodes(origin_pos, nodes)
local huge = math.huge
local pos1x, pos1y, pos1z = huge, huge, huge
local pos2x, pos2y, pos2z = -huge, -huge, -huge
local origin_x, origin_y, origin_z = origin_pos.x, origin_pos.y, origin_pos.z
for i, entry in ipairs(nodes) do
local x, y, z = origin_x + entry.x, origin_y + entry.y, origin_z + entry.z
if x < pos1x then pos1x = x end
if y < pos1y then pos1y = y end
if z < pos1z then pos1z = z end
if x > pos2x then pos2x = x end
if y > pos2y then pos2y = y end
if z > pos2z then pos2z = z end
end
local pos1 = {x=pos1x, y=pos1y, z=pos1z}
local pos2 = {x=pos2x, y=pos2y, z=pos2z}
return pos1, pos2, #nodes
end
--- Return volume in nodes of a region
-- @param pos1 - starting point vector table
-- @param pos2 - ending point vector table
-- @return number of nodes as an integer?
local function volume(pos1, pos2)
local p1, p2 = sort_pos(pos1, pos2)
return (p2.x - p1.x + 1) *
(p2.y - p1.y + 1) *
(p2.z - p1.z + 1)
end
--- Slice a region along the midpoint of an axis
-- @param pos1 - vector passed as a table
-- @param pos2 - vector passed as a table
-- @param axis - axis passed as a string
-- @return ipair table containing 2 regions
local function region_slicer(pos1, pos2, axis)
local len = vector.subtract(pos2, pos1)
local mid = vector.new(
pos2.x + (len.x / 2),
pos1.y + (len.y / 2),
pos1.z + (len.z / 2)
)
local r = {}
if axis == 'y' then
r = {
{
p1 = pos1,
p2 = vector.new(pos2.x, mid.y, pos2.z)
},
{
p1 = vector.new(pos1.x, mid.y + 1, pos1.z),
p2 = pos2
}
}
elseif axis == 'x' then
r = {
{
p1 = pos1,
p2 = vector.new(mid.x, pos2.y, pos2.z)
},
{
p1 = vector.new(mid.x - 1, pos1.y, pos1.z),
p2 = pos2
}
}
elseif axis == 'z' then
r = {
{
p1 = pos1,
p2 = vector.new(pos2.x, pos2.y, mid.z)
},
{
p1 = vector.new(pos1.x, pos1.y, mid.z + 1),
p2 = pos2
}
}
end
return r
end
--- Create a table of ignore for the volume of the area
-- @param area pair table
-- @return ipair table
local function get_empty_data(area)
local data = {}
local c_ignore = minetest.get_content_id("ignore")
for i = 1, volume(area.MinEdge, area.MaxEdge) do
data[i] = c_ignore
end
return data
end
--- Create and return a voxel manip and it's area
-- @param pos1 - starting point vector table
-- @param pos2 - ending point vector table
-- @return voxel manip
-- @return area vector table
local function init(pos1, pos2)
local manip = minetest.get_voxel_manip()
local emerged_pos1, emerged_pos2 = manip:read_from_map(pos1, pos2)
local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
return manip, area
end
-- Adds a hollow cube of playerclip double lined with kill
-- designed for games created in the air
-- @param pos: base vector of cube (x=,y=,z=)
-- @param vol: volume (x=,y=,z=)
-- @param remove: replace shield with air (bool)
-- @return number of nodes added
local function shield(pos, vol, remove)
local manip, area = init(pos, vector.add(pos, vol))
local data = get_empty_data(area)
local node_1, node_2, msg
if remove == true then
node_1 = minetest.get_content_id("air")
node_2 = node_1
msg = "Warning: Area unprotected!"
else
node_1 = minetest.get_content_id("eggwars:playerclip")
node_2 = minetest.get_content_id("eggwars:kill")
msg = "Warning: Area now shielded"
end
local stride = {x=1, y=area.ystride, z=area.zstride}
local offset = vector.subtract(pos, area.MinEdge)
local count = 0
-- add the nodes
for z = 0, vol.z-1 do
local index_z = (offset.z + z) * stride.z + 1
for y = 0, vol.y-1 do
local index_y = index_z + (offset.y + y) * stride.y
for x = 0, vol.x-1 do
local is_clip = z == 0 or z == vol.z-1
or y == 0 or y == vol.y-1
or x == 0 or x == vol.x-1
local is_kill = z == 1 or z == vol.z-2 or z == vol.z-3
or y == 1 or y == 2 or y == vol.y-2 or y == vol.y-3
or x == 1 or x == 2 or x == vol.x-2 or x == vol.x-3
if is_clip then
local i = index_y + (offset.x + x)
data[i] = node_1
count = count + 1
elseif is_kill then
local i = index_y + (offset.x + x)
data[i] = node_2
count = count + 1
end
end
end
end
manip:set_data(data)
manip:write_to_map()
return count, msg
end
function eggwars.metasave(pos1, pos2, filename)
local file, err = io.open(filename, "wb")
if err then return 0 end
local data, count = eggwars.serialize_meta(pos1, pos2)
file:write(data)
file:close()
return count
end
function eggwars.metaload(originpos, filename)
filename = minetest.get_worldpath() .. "/schems/" .. filename .. ".ewm"
local file, err = io.open(filename, "wb")
if err then return 0 end
local data = file:read("*a")
file:close()
return eggwars.deserialize_meta(originpos, data)
end
--- Fixes lighting within a region
-- @param pos1 start vector
-- @param pos2 end vector
-- @return nothing
function eggwars.fixlight(pos1, pos2)
local vmanip = minetest.get_voxel_manip(pos1, pos2)
vmanip:write_to_map()
end
--- Clears all objects in a region.
-- @return The number of objects cleared.
function eggwars.clear_objects(pos1, pos2)
pos1, pos2 = sort_pos(pos1, pos2)
keep_loaded(pos1, pos2)
-- Offset positions to include full nodes (positions are in the center of nodes)
local pos1x, pos1y, pos1z = pos1.x - 0.5, pos1.y - 0.5, pos1.z - 0.5
local pos2x, pos2y, pos2z = pos2.x + 0.5, pos2.y + 0.5, pos2.z + 0.5
-- Center of region
local center = {
x = pos1x + ((pos2x - pos1x) / 2),
y = pos1y + ((pos2y - pos1y) / 2),
z = pos1z + ((pos2z - pos1z) / 2)
}
-- Bounding sphere radius
local radius = math.sqrt(
(center.x - pos1x) ^ 2 +
(center.y - pos1y) ^ 2 +
(center.z - pos1z) ^ 2)
local count = 0
for _, obj in pairs(minetest.get_objects_inside_radius(center, radius)) do
-- Avoid players
if not obj:is_player() then
local pos = obj:getpos()
if pos.x >= pos1x and pos.x <= pos2x and
pos.y >= pos1y and pos.y <= pos2y and
pos.z >= pos1z and pos.z <= pos2z then
-- Inside region
obj:remove()
count = count + 1
end
end
end
return count
end
--- Clears specific nodes in a region.
-- @return The number of nodes cleared.
function eggwars.clear_nodes(pos1, pos2)
pos1, pos2 = sort_pos(pos1, pos2)
keep_loaded(pos1, pos2)
-- Offset positions to include full nodes (positions are in the center of nodes)
local p1 = vector.new(pos1.x - 0.5, pos1.y - 0.5, pos1.z - 0.5)
local p2 = vector.new(pos2.x + 0.5, pos2.y + 0.5, pos2.z + 0.5)
local nodenames = {
"group:choppy",
"group:cracky",
"group:crumbly",
"group:oddly_breakable_by_hand"
}
local slices = region_slicer(pos1, pos2, 'y')
local n = 0
for _, slice in ipairs(slices) do
local found = minetest.find_nodes_in_area(slice.p1, slice.p2, nodenames)
for _,v in ipairs(found) do
minetest.set_node(v, {name="air"})
end
n = n + #found
end
return n
end
--- Sets a region to `air`.
-- @param pos1
-- @param pos2
-- @return The number of nodes set.
function eggwars.delete_area(pos1, pos2)
pos1, pos2 = sort_pos(pos1, pos2)
local manip, area = init(pos1, pos2)
local data = get_empty_data(area)
local node_id = minetest.get_content_id('air')
-- Fill area with node
for i in area:iterp(pos1, pos2) do
data[i] = node_id
end
manip:set_data(data)
manip:write_to_map()
return volume(pos1, pos2)
end
--- Loads the nodes represented by string `value` at position `origin_pos`.
-- @return The number of nodes deserialized.
function eggwars.deserialize_meta(origin_pos, value)
local nodes = load_schematic(value)
if not nodes then return nil end
local pos1, pos2 = allocate_with_nodes(origin_pos, nodes)
keep_loaded(pos1, pos2)
local origin_x, origin_y, origin_z = origin_pos.x, origin_pos.y, origin_pos.z
local add_node, get_meta = minetest.add_node, minetest.get_meta
for i, entry in ipairs(nodes) do
entry.x, entry.y, entry.z = origin_x + entry.x, origin_y + entry.y, origin_z + entry.z
-- Entry acts as both position and node
add_node(entry, entry)
if entry.meta then
get_meta(entry):from_table(entry.meta)
end
end
return #nodes
end
-- Serialise any meta nodes within a volume
-- @param pos1: first vector
-- @param pos2: second vector
-- @return serialised string, node count
function eggwars.serialize_meta(pos1, pos2)
pos1, pos2 = sort_pos(pos1, pos2)
keep_loaded(pos1, pos2)
local pos = {x=pos1.x, y=0, z=0}
local count = 0
local result = {}
local get_node, get_meta = minetest.get_node, minetest.get_meta
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
local node = get_node(pos)
if node.name ~= "air" and node.name ~= "ignore" then
local meta = get_meta(pos):to_table()
local meta_content
-- Convert metadata item stacks to item strings
for name, inventory in pairs(meta.inventory) do
for index, stack in ipairs(inventory) do
meta_content = true
inventory[index] = stack.to_string and stack:to_string() or stack
end
end
for name, field in pairs(meta.fields) do
meta_content = true
end
for k in pairs(meta) do
if k ~= "inventory" and k ~= "fields" then
meta_content = true
break
end
end
if meta_content then
count = count + 1
result[count] = {
x = pos.x - pos1.x,
y = pos.y - pos1.y,
z = pos.z - pos1.z,
name = node.name,
param1 = node.param1 ~= 0 and node.param1 or nil,
param2 = node.param2 ~= 0 and node.param2 or nil,
meta = meta_content and meta or nil,
}
end
end
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
-- Serialise entries
return HEADER .. minetest.serialize(result), count
end
-- Adds a protective shield to a volume
-- @param vol: position vectors
-- @param remover: replace shield with air (bool)
-- @return number of nodes added
eggwars.protect = function(pos1, pos2, remove)
local p1, p2, dims
-- using vectors
p1 = pos1
p2 = pos2
-- sort if reqd
if p1.y > p2.y then
p2, p1 = p1, p2
end
-- volume vect
dims = {
x = p2.x - p1.x,
y = p2.y - p1.y,
z = p2.z - p1.z
}
-- unsign if reqd
for k,v in pairs(dims) do
if v < 0 then
dims[k] = (v*v)^0.5
end
end
-- execute, returning node count
return shield(p1, dims, remove)
end
-- Clear a players inventory
-- @param player; minetest player object
-- @return nothing
eggwars.clear_inventory = function(player)
local player_inv = player:get_inventory()
player_inv:set_list("main", {}) -- clear
player_inv:set_list("craft", {}) -- clear
end
if eggwars.armor then
-- Clear a players armour
-- @param player; minetest player object
-- @return nothing
eggwars.clear_armor = function(player)
local player_inv = player:get_inventory()
player_inv:set_list("armor", {}) -- clear
armor:set_player_armor(player) -- luacheck: ignore
end
end

1470
init.lua Normal file → Executable file

File diff suppressed because it is too large Load Diff

Binary file not shown.

3397
models/eggwars_egg.obj Executable file

File diff suppressed because it is too large Load Diff

202
register_arena.lua Normal file
View File

@ -0,0 +1,202 @@
----------------------------------------------------------------------
-- Eggwars by wilkgr --
-- with additional code by shivajiva101@hotmail.com --
-- Licensed under the AGPL v3 --
-- You MUST make any changes you make open source --
-- even if you just run it on your server without publishing it --
-- Supports a maximum of 8 players per instance and 8 concurrent --
-- instances for a max of 64 players --
----------------------------------------------------------------------
-- default arena definition template, all fields reqd
local default_arena = {
blocked_recipes = {
-- Recipes removed from world for gameplay so player MUST purchase items
{output = 'default:stick'}, -- tools
{output = '3d_armor:boots_wood'},
{output = '3d_armor:helmet_wood'},
{output = '3d_armor:leggings_wood'},
{output = '3d_armor:chestplate_wood'},
{output = '3d_armor:boots_diamond'},
{output = '3d_armor:helmet_diamond'},
{output = '3d_armor:leggings_diamond'},
{output = '3d_armor:chestplate_diamond'},
},
bot = {
-- spawner upgrade bot
offset = {
{x=-2, y=0, z=-4}, -- relative to island origin
{x=2, y=0, z=4},
{x=-2, y=0, z=-4},
{x=2, y=0, z=4},
{x=-4, y=0, z=2},
{x=-4, y=0, z=2},
{x=4, y=0, z=-2},
{x=4, y=0, z=-2}
},
yaw = {90,270,90,270,0,0,180,180} -- facing
},
colour = {
-- rgb colour tables
{r = 0, g = 0, b = 255}, -- Blue
{r = 0, g = 255, b = 0}, -- Green
{r = 255, g = 0, b = 0}, -- Red
{r = 108, g = 0, b = 255}, -- Purple
{r = 255, g = 255, b = 0}, -- Yellow
{r = 0, g = 255, b = 255}, -- Cyan
{r = 255, g = 150, b = 0}, -- Orange
{r = 255, g = 0, b = 255} -- Pink
},
cs = {
-- colour strings used by mod
{"Blue", "#0000FFBF", "blue", "0x0000FF"},
{"Green", "#00FF00BF", "green", "0x00FF00"},
{"Red", "#FF0000BF", "red", "0xFF0000"},
{"Violet", "#7800FFBF", "violet", "0x7800FF"},
{"Yellow", "#FFFF00BF", "yellow", "0xFFFF00"},
{"Cyan", "#00FFFFBF", "cyan", "0x00FFFF"},
{"Orange", "#FF9600BF", "orange", "0xFF9600"},
{"Pink", "#FF00FFBF", "pink", "0xFF00FF"}
},
description = 'default arena by shivajiva',
egg_offset = {
{x=-5, y=0, z=0}, -- relative to island origin
{x=5, y=0, z=0},
{x=-5, y=0, z=0},
{x=-5, y=0, z=0},
{x=-5, y=0, z=0},
{x=-5, y=0, z=0},
{x=-5, y=0, z=0},
{x=-5, y=0, z=0}
},
exempt_nodes = {
-- exempt nodes you want breakable within the world
-- partial strings allowed
'eggwars:',
'wool:', -- bridging block
'default:obsidian_block' -- requires pick
},
hub = {
-- arena hub def
offset = {x=-30, y=-18, z=-30}, -- pos1 for place
schem = 'hub_1.mts'
},
island = {
-- Confined to 90 degree rotations the current schema
-- places 2 islands per side of a square, giving us 8
-- islands max per instance. Each island is displaced
-- equally from the arena centre position using the
-- island vector table
{x=85, y=0, z=-40}, -- BL
{x=-85, y=0, z=-40}, -- TL
{x=85, y=0, z=40}, -- BR
{x=-85, y=0, z=40}, -- TR
{x=40, y=0, z=-85}, -- LB
{x=-40, y=0, z=-85}, -- LT
{x=40, y=0, z=85}, -- RB
{x=-40, y=0, z=85}, -- RT
offset = {x=-11, y=-20, z=-10},
rotate = {"0", "180", "0", "180", "90", "90", "270", "270"},
schem = 'island_1.mts'
},
name = 'default', -- arena name
region = {
-- arena region relative to origin
p1 = {x=-120, y=-30, z=-120},
p2 = {x=120, y=100, z=120}
},
register_nodes = {
-- add any arena specific custom nodes here, generally
-- these are the nodes the player can use in the arenas
-- and should contain nodes not previously registered by
-- other arenas.
-- name = {normal node def}
['log'] = {
description = "Log",
tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
paramtype2 = "facedir",
is_ground_content = false,
groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2},
sounds = default.node_sound_wood_defaults(),
on_place = minetest.rotate_node
},
},
satellite = {
-- satellite ruby spawner island positions relative to origin
offset = {x=-5, y=-13, z=-5},
pos = {
{x=-65, y=0, z=0}, -- N
{x=0, y=0, z=65}, -- E
{x=65, y=0, z=0}, -- S
{x=0, y=0, z=-65} -- W
},
schem = 'island_small_1.mts'
},
spawners = {
-- centre
diamond = {
{x=9, y=4, z=-9}, -- relative to arena origin
{x=-9, y=4, z=9},
{x=-9, y=4, z=-9},
{x=9, y=4, z=9},
rate = 30
},
-- player island
gold = {
{x=-3, y=-1, z=-4}, -- relative to island origin
{x=3, y=-1, z=4},
{x=-3, y=-1, z=-4},
{x=3, y=-1, z=4},
{x=-4, y=-1, z=3},
{x=-4, y=-1, z=3},
{x=4, y=-1, z=-3},
{x=4, y=-1, z=-3},
rate = 5 -- starting rate in seconds
},
-- satellites
ruby = {
{x=65, y=0.5, z=0}, -- relative to arena origin
{x=0, y=0, z=65},
{x=-65, y=0, z=0},
{x=0, y=0, z=-65},
rate = 15
},
},
timer = {
max_time = 1800, -- seconds
suddendeath = 1200 -- seconds
},
trader = {
names = {
"Johann",
"Celery55",
"Moldy Coder",
"Wilkgr",
"Rick O Shae",
"Bernie Towndown",
"Warden Ruby",
"Bom Shiva"
},
offset = {
{x=2, y=0.5, z=0}, -- relative to island origin
{x=-2, y=0.5, z=0},
{x=2, y=0.5, z=0},
{x=-2, y=0.5, z=0},
{x=0, y=0.5, z=2},
{x=0, y=0.5, z=2},
{x=0, y=0.5, z=-2},
{x=0, y=0.5, z=-2}
},
yaw = {90,270,90,270,0,0,180,180} -- facing
},
}
eggwars.register_arena = function(def)
table.insert(eggwars.arena, def)
for k,v in pairs(def.register_nodes) do
minetest.register_node('eggwars:' .. k, v)
end
end
-- Register the sample default arena
eggwars.register_arena(default_arena)

335
register_nodes.lua Normal file → Executable file
View File

@ -1,220 +1,137 @@
-- Probably find a use for this I s'pose... May not.
minetest.register_node("eggwars:pedestal", {
tiles = {
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png"
},
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
{-0.375, -0.4375, -0.375, 0.375, -0.3125, 0.375}, -- NodeBox2
{-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}, -- NodeBox3
{-0.4375, -0.5, -0.4375, 0.4375, -0.375, 0.4375}, -- NodeBox4
{-0.1875, -0.5, -0.1875, 0.1875, 0.5, 0.1875}, -- NodeBox5
{-0.5, 0.4375, -0.5, 0.5, 0.5, 0.5}, -- NodeBox6
{-0.4375, 0.375, -0.4375, 0.4375, 0.5, 0.4375}, -- NodeBox7
{-0.5, 0.3125, -0.375, 0.5, 0.5, 0.375}, -- NodeBox8
}
}
})
minetest.register_node("eggwars:egg", {
description = "Egg",
tiles = {
"default_stone.png",
"default_stone.png",
"default_stone.png",
"default_stone.png",
"default_stone.png",
"default_stone.png"
},
groups = {crumbly = 3},
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
{-0.1875, -0.5, -0.1875, 0.1875, 0.5, 0.1875}, -- NodeBox1
{-0.25, -0.4375, -0.25, 0.25, 0.4375, 0.25}, -- NodeBox2
{-0.3125, -0.375, -0.3125, 0.3125, 0.3125, 0.3125}, -- NodeBox3
{-0.375, -0.3125, -0.375, 0.375, 0.1875, 0.375}, -- NodeBox4
{-0.4375, -0.25, -0.4375, 0.4375, 0.0625, 0.4375}, -- NodeBox5
{-0.5, -0.125, -0.5, 0.5, -0.0625, 0.5}, -- NodeBox6
}
}
----------------------------------------------------------------------
-- Eggwars by wilkgr --
-- with additional code by shivajiva101@hotmail.com --
-- Licensed under the AGPL v3 --
-- You MUST make any changes you make open source --
-- even if you just run it on your server without publishing it --
-- Supports a maximum of 8 players per instance and 8 concurrent --
-- instances for a max of 64 players --
----------------------------------------------------------------------
------------------------
-- on_timer functions --
------------------------
local function goldspawner(pos, elapsed)
local sp = vector.new(pos.x, pos.y + 3, pos.z)
minetest.add_item(sp, "default:gold_ingot")
return true
end
local function rubyspawner(pos, elapsed)
local sp = vector.new(pos.x, pos.y + 3, pos.z)
minetest.add_item(sp, "eggwars:ruby")
return true
end
local function diamondspawner(pos, elapsed)
local sp = vector.new(pos.x, pos.y + 3, pos.z)
minetest.add_item(sp, "default:diamond")
return true
end
-----------------
-- craft items --
-----------------
minetest.register_craftitem("eggwars:ruby", {
description = "Ruby",
inventory_image = "eggwars_ruby.png",
})
minetest.register_node("eggwars:dirt", {
description = "Unbreakable Dirt",
range = 12,
stack_max = 99,
tiles = {"default_dirt.png"},
drop = "",
groups = {unbreakable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_dirt_defaults(),
------------------------
-- node registrations --
------------------------
-- Arena eggs
for i,v in ipairs(eggwars.arena[1].cs) do
minetest.register_node("eggwars:egg" .. i, {
description = eggwars.arena[1].cs[i][1] .. " egg",
tiles = {"eggwars_shell.png^[colorize:" .. eggwars.arena[1].cs[i][2]},
drawtype = "mesh",
mesh = "eggwars_egg.obj",
groups = {crumbly = 3, not_in_creative_inventory = 1},
paramtype = "light",
--light_source = 14,
selection_box = {
type = "fixed",
fixed = {-0.35, -0.5, -0.35, 0.35, 0.45, 0.35} -- right, bottom, back, left, top, front
},
collision_box = {
type = "fixed",
fixed = {-0.35, -0.5, -0.35, 0.35, 0.45, 0.35}
},
drop = {},
on_drop = eggwars.drop_msg,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local victim, attacker, msg, key, match, eggs
victim = oldmetadata.fields.owner
attacker = digger:get_player_name()
if not victim then return end -- dev ONLY!
key = eggwars.player[victim]
match = eggwars.match[key]
match.player[victim].egg = false
eggs = match.player[attacker].eggs + 1
match.player[attacker].eggs = eggs
msg = victim .. "'s egg was destroyed by " .. attacker
eggwars.chat_send_match(eggwars.player[victim].match, msg)
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local name = meta:get_string("owner")
if name == "" or not name == player:get_player_name() then
return true
end
end
})
end
-- Spawners
minetest.register_node("eggwars:gold_spawner", {
description = "Gold ingot spawner",
tiles = {"default_stone.png^default_mineral_gold.png"},
on_timer = goldspawner
})
minetest.register_node("eggwars:grass", {
description = "Unbreakable Dirt With Grass",
minetest.register_node("eggwars:ruby_spawner", {
description = "Ruby gemstone spawner",
tiles = {"default_stone.png^eggwars_mineral_ruby.png"},
on_timer = rubyspawner
})
minetest.register_node("eggwars:diamond_spawner", {
description = "Diamond gemstone spawner",
tiles = {"default_stone.png^default_mineral_diamond.png"},
on_timer = diamondspawner
})
-- Misc
minetest.register_node("eggwars:kill", {
description = "Kill Block",
range = 12,
stack_max = 10000,
tiles = {"default_grass.png", "default_dirt.png", "default_dirt.png^default_grass_side.png"},
paramtype2 = "facedir",
drop = "",
groups = {unbreakable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_grass_footstep", gain = 0.4},
}),
})
minetest.register_node("eggwars:stone_block", {
description = "Unbreakable Stone Block",
range = 12,
tiles = {"default_stone_block.png"},
is_ground_content = false,
drop = "",
groups = {unbreakable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("eggwars:aspen_wood", {
description = "Unbreakable Aspen Planks",
range = 12,
paramtype2 = "facedir",
place_param2 = 0,
tiles = {"default_aspen_wood.png"},
drop = "",
is_ground_content = false,
groups = {unbreakable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node("eggwars:acacia_wood", {
description = "Acacia Wood Planks",
range = 12,
paramtype2 = "facedir",
place_param2 = 0,
tiles = {"default_acacia_wood.png"},
drop = "",
is_ground_content = false,
groups = {unbreakable = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node("eggwars:ladder_wood", {
description = "Wooden Ladder",
drawtype = "signlike",
tiles = {"default_ladder_wood.png"},
inventory_image = "default_ladder_wood.png",
wield_image = "default_ladder_wood.png",
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
inventory_image = "default_steel_block.png^dye_black.png",
drawtype = "airlike",
walkable = false,
climbable = true,
is_ground_content = false,
selection_box = {
type = "wallmounted",
},
drop = "",
pointable = false,
damage_per_second = 20,
paramtype = "light",
sunlight_propagates = true,
drop = "",
groups = {unbreakable = 1, not_in_creative_inventory = 1},
legacy_wallmounted = true,
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node("eggwars:goldspawn1", {
tiles = {"default_gold_block.png"}
minetest.register_node("eggwars:playerclip", {
description = "Player Clip",
range = 12,
stack_max = 10000,
inventory_image = "default_steel_block.png^dye_green.png",
drawtype = "airlike",
paramtype = "light",
pointable = false,
sunlight_propagates = true,
drop = "",
groups = {unbreakable = 1, not_in_creative_inventory = 1},
})
minetest.register_node("eggwars:stickspawn", {
tiles = {"default_aspen_wood.png"}
})
minetest.register_node("eggwars:diamondspawn", {
tiles = {"default_diamond_block.png"}
})
minetest.register_node("eggwars:steelspawn1", { --Slower spawn rate; for player islands
tiles = {"default_steel_block.png"}
})
minetest.register_node("eggwars:steelspawn2", { --Faster spawn rate; for center island(s)
tiles = {"default_diamond_block.png"}
})
minetest.register_node("eggwars:cobblespawn", {
tiles = {"default_cobble.png"}
})
-- Register ABMs
-- Diamond spawn. Only for centre island(s)
minetest.register_abm({
nodenames = {"eggwars:diamondspawn"},
interval = 8,
chance = 1,
action = function(pos)
pos.y = pos.y + 1
minetest.add_item(pos,"default:diamond")
end,
})
-- Cobble is the building material
minetest.register_abm({
nodenames = {"eggwars:cobblespawn"},
interval = 5,
chance = 1,
action = function(pos)
pos.y = pos.y + 1
minetest.add_item(pos,"default:cobble")
end,
})
-- Steelspawn1 is slower, ideal for player islands
minetest.register_abm({
nodenames = {"eggwars:steelspawn1"},
interval = 10,
chance = 1,
action = function(pos)
pos.y = pos.y + 1
minetest.add_item(pos,"default:steel_ingot")
end,
})
-- Steelspawn2 is faster, ideal for centre island
minetest.register_abm({
nodenames = {"eggwars:steelspawn2"},
interval = 5,
chance = 1,
action = function(pos)
pos.y = pos.y + 1
minetest.add_item(pos,"default:steel_ingot")
end,
})
-- Stick spawner, for allowing players to craft tools
minetest.register_abm({
nodenames = {"eggwars:stickspawn"},
interval = 8,
chance = 1,
action = function(pos)
pos.y = pos.y + 1
minetest.add_item(pos,"default:stick")
end,
})
-- Goldspawn1 is slower, ideal for player islands
minetest.register_abm({
nodenames = {"eggwars:goldspawn1"},
interval = 10,
chance = 1,
action = function(pos)
pos.y = pos.y + 1
minetest.add_item(pos,"default:gold_ingot")
end,
})

Binary file not shown.

BIN
schems/hub_1.mts Executable file

Binary file not shown.

BIN
schems/island.mts Normal file → Executable file

Binary file not shown.

BIN
schems/island_1.mts Executable file

Binary file not shown.

BIN
schems/island_small_1.mts Executable file

Binary file not shown.

BIN
schems/lobby.mts Executable file

Binary file not shown.

442
shop.lua Normal file → Executable file
View File

@ -1,28 +1,418 @@
sfinv.register_page("sfinv:shop", {
title = "Shop",
get = function(self, player, context)
-- local name = player:get_player_name()
return sfinv.make_formspec(player, context, "size[8,9] bgcolor[#080808BB;true] background[5,5;1,1;gui_formbg.png;true] button[0.1,0.1;4,1;upgradespeed;Upgrade speed (cost: 20 diamonds)] button[4,0.1;4,1;upgradejump;Upgrade jump (cost: 20 diamonds)]", true)
end
----------------------------------------------------------------------
-- Eggwars by wilkgr --
-- with additional code by shivajiva101@hotmail.com --
-- Licensed under the AGPL v3 --
-- You MUST make any changes you make open source --
-- even if you just run it on your server without publishing it --
-- Supports a maximum of 8 players per instance and 8 concurrent --
-- instances for a max of 64 players --
----------------------------------------------------------------------
local TF = 'eggwars:trade'
local BF = 'eggwars:bot'
eggwars.shop_items = {}
eggwars.register_shop_item = function(def)
def.entry = #eggwars.shop_items + 1
eggwars.shop_items[def.entry] = def
end
local function build_formspec_items(name, items)
local fsi = {}
local y = 0.5
for i, item in ipairs(items) do
local fs = {
'image[0,',
y,
';1,1;',
item.image,
']',
'tooltip[0,',
y,
';1,1;',
item.name.count,
' ',
item.description,
']',
'label[1.1,',
y + 0.7,
';',
item.name.count,
']',
'item_image_button[2.5,',
y,
';1,1;',
item.cost.name,
';btn_',
i,
';]',
'label[3.6,',
y + 0.7,
';',
item.cost.count,
']'
}
table.insert(fsi, table.concat(fs))
y = y + 1.1
end
return table.concat(fsi)
end
local function build_form(name, items)
local frm = {
"formspec_version[3]",
"size[6,5.5]",
"scrollbaroptions[min=0;max=",
(#items * 8) + (#items - 1), -- qty x height + space
";smallstep=44;largestep=44;thumbsize=1;arrows=default]",
"scrollbar[5,0.5;0.5,4.3;vertical;msb;",
context[name].val,
"]",
"container[0.5,",
context[name].y,
"]",
}
-- nasty hack to window the container!
local fse = {
"container_end[]",
'box[0.05,0.0;5.9,0.5;#343434FF]',
'box[0.05,4.9;5.9,0.6;#343434FF]',
}
local fstbl = build_formspec_items(name, items)
return table.concat(frm) .. fstbl .. table.concat(fse)
end
local function trader_form_handler(clicker)
local name = clicker:get_player_name()
local key = eggwars.player[name]
local def = eggwars.match[key].player[name]
context[name] = {y=0, val=0}
minetest.show_formspec(name, TF, build_form(name, def.shop_items))
end
local function bot_form_handler(clicker)
local name = clicker:get_player_name()
local key = eggwars.player[name]
local def = eggwars.match[key]
if def.player[name].rate == 1 then return end
local level = 5 - def.player[name].rate
local cost = (level + 1)
local fs = {}
fs[#fs+1] = 'size[2,2]'
fs[#fs+1] = 'label[0.3,0;Level ' .. level + 1 .. ']'
fs[#fs+1] = 'image_button_exit[0.5,0.6;1.0,1.0;eggwars_ruby.png;btn;]'
fs[#fs+1] = 'label[0.5,1.6;x '.. cost .. ']'
minetest.show_formspec(name, BF, table.concat(fs))
end
context = {}
minetest.register_on_player_receive_fields(function(player, formname, fields)
-- Only handle this mods forms!
if formname ~= TF and formname ~= BF then return end
local name = player:get_player_name()
-- Only match players have access to these forms!
if not eggwars.player[name] then return end
local key = eggwars.player[name]
local def = eggwars.match[key].player[name]
local pinv = player:get_inventory()
-- Trader form
if formname == TF then
-- buttons
for item, _ in pairs(fields) do
if string.find(item, 'btn_') then
local i = tonumber(string.sub(item, 5))
local row, goods, cost
row = def.shop_items[i]
goods = row.name
cost = row.cost
if pinv:contains_item('main', cost) then
if pinv:room_for_item('main', goods) then
pinv:remove_item('main', cost)
pinv:add_item('main', goods)
else
minetest.chat_send_player(name, 'insufficient room in your inventory!')
end
else
minetest.chat_send_player(name, 'insufficient funds in your inventory!')
end
return
end
end
-- scrollbar
if formname == TF and fields.msb then
local res = minetest.explode_scrollbar_event(fields.msb)
if res.type == "CHG" then
local val = res.value
context[name].y = -val/10
context[name].val = val
minetest.show_formspec(name, TF, build_form(name, def.shop_items))
end
end
elseif formname == BF and fields.btn then
if def.rate <= 1 then return end -- limit reached
local qty = (5 - def.rate + 1)
local upd = def.rate - 1
local cost = ItemStack('eggwars:ruby ' .. qty)
if pinv:contains_item('main', cost) then
pinv:remove_item('main', cost)
eggwars.match[key].player[name].rate = upd
minetest.get_node_timer(def.spawner):start(upd)
else
minetest.chat_send_player(name, 'insufficient funds in your inventory!')
end
end
end)
minetest.register_entity("eggwars:trader", {
initial_properties = {
physical = false,
collisionbox = {-0.35,-1.0,-0.35, 0.35,0.8,0.35},
visual = "mesh",
mesh = "eggwars_character.b3d",
textures = {"eggwars_trader7.png"},
is_visible = true,
},
on_activate = function(self, staticdata)
local data = minetest.deserialize(staticdata)
self.owner = data.owner
self.nametag = data.nametag
self.object:set_armor_groups({immortal = 1})
self.object:set_properties({
nametag = self.nametag,
nametag_color = "#FFFF1F",
})
end,
on_rightclick = function(self, clicker)
trader_form_handler(clicker)
end,
on_step = function(self, dtime, ...)
if not eggwars.player[self.owner] then
self.object:remove()
end
end,
get_staticdata = function(self)
return minetest.serialize({
owner = self.owner,
nametag = self.nametag
})
end
})
minetest.register_on_player_receive_fields( function(player, formname, fields)
minetest.chat_send_all("Player "..player:get_player_name().." submitted fields "..dump(fields));
if fields.upgradejump then
local inv = minetest.get_inventory({type="player", name=player:get_player_name()})
if inv:contains_item("main", "default:diamond") then
inv:remove_item("main","default:diamond 20")
local player_physics = player:get_physics_override()
player_physics.jump = player_physics.jump * 1.25
player:set_physics_override(player_physics)
end
elseif fields.upgradespeed then
local inv = minetest.get_inventory({type="player", name=player:get_player_name()})
if inv:contains_item("main", "default:diamond") then
inv:remove_item("main","default:diamond 20")
local player_physics = player:get_physics_override()
player_physics.speed = player_physics.speed * 1.25
player:set_physics_override(player_physics)
end
end
end)
minetest.register_entity("eggwars:bot", {
initial_properties = {
physical = false,
collisionbox = {-0.25,-0.4,-0.25, 0.25,0.5,0.25},
visual = "mesh",
mesh = "eggwars_character.b3d",
textures = {"eggwars_trader1.png"},
is_visible = true,
visual_size = {x=0.5, y=0.5}
},
on_activate = function(self, staticdata)
self.owner = staticdata
self.object:set_armor_groups({immortal = 1})
end,
on_rightclick = function(self, clicker)
bot_form_handler(clicker)
end,
on_step = function(self, dtime, ...)
if not eggwars.player[self.owner] then
self.object:remove()
end
end,
get_staticdata = function(self)
return self.owner
end
})
-- wooden log
eggwars.register_shop_item({
name = {name="eggwars:log", count=20, wear=0, metadata=""},
description = 'Wood Log',
image = 'default_tree.png',
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
-- obsidian block
eggwars.register_shop_item({
name = {name="default:obsidian_block", count=20, wear=0, metadata=""},
description = 'Obsidian Block',
image = 'default_obsidian_block.png',
cost = {name="eggwars:ruby", count=5, wear=0, metadata=""},
})
-- binoculars
eggwars.register_shop_item({
name = {name="binoculars:binoculars", count=1, wear=0, metadata=""},
description = 'Binoculars',
image = 'binoculars_binoculars.png',
cost = {name="default:gold_ingot", count=5, wear=0, metadata=""},
})
-- Steel sword
eggwars.register_shop_item({
name = {name="default:sword_steel", count=1, wear=0, metadata=""},
description = 'Stone Sword',
image = 'default_tool_steelsword.png',
cost = {name="default:gold_ingot", count=15, wear=0, metadata=""},
})
-- Steel axe
eggwars.register_shop_item({
name = {name="default:axe_steel", count=1, wear=0, metadata=""},
description = 'Steel Axe',
image = 'default_tool_steelaxe.png',
cost = {name="default:gold_ingot", count=15, wear=0, metadata=""},
})
-- Diamond sword
eggwars.register_shop_item({
name = {name="default:sword_diamond", count=1, wear=0, metadata=""},
description = 'Diamond Sword',
image = 'default_tool_diamondsword.png',
cost = {name="default:diamond", count=5, wear=0, metadata=""},
})
-- Diamond pick
eggwars.register_shop_item({
name = {name="default:pick_diamond", count=1, wear=0, metadata=""},
description = 'Diamond Pick',
image = 'default_tool_diamondpick.png',
cost = {name="default:diamond", count=10, wear=0, metadata=""},
})
if eggwars.armor then
-- wood
eggwars.register_shop_item({
name = {name="3d_armor:helmet_wood", count=1, wear=0, metadata=""},
description = 'Wooden Helmet',
image = "3d_armor_inv_helmet_wood.png",
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="3d_armor:chestplate_wood", count=1, wear=0, metadata=""},
description = 'Wooden Chestplate',
image = "3d_armor_inv_chestplate_wood.png",
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="3d_armor:leggings_wood", count=1, wear=0, metadata=""},
description = 'Wooden Leggings',
image = "3d_armor_inv_leggings_wood.png",
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="3d_armor:boots_wood", count=1, wear=0, metadata=""},
description = 'Wooden Boots',
image = "3d_armor_inv_boots_wood.png",
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
--diamond
eggwars.register_shop_item({
name = {name="3d_armor:helmet_diamond", count=1, wear=0, metadata=""},
description = 'Diamond Helmet',
image = "3d_armor_inv_helmet_diamond.png",
cost = {name="default:diamond", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="3d_armor:chestplate_diamond", count=1, wear=0, metadata=""},
description = 'Diamond Chestplate',
image = "3d_armor_inv_chestplate_diamond.png",
cost = {name="default:diamond", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="3d_armor:leggings_diamond", count=1, wear=0, metadata=""},
description = 'Diamond Leggings',
image = "3d_armor_inv_leggings_diamond.png",
cost = {name="default:diamond", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="3d_armor:boots_diamond", count=1, wear=0, metadata=""},
description = 'Diamond Boots',
image = "3d_armor_inv_boots_diamond.png",
cost = {name="default:diamond", count=10, wear=0, metadata=""},
})
end
if eggwars.bows then
-- Bows
eggwars.register_shop_item({
name = {name="bows:bow_wood", count=1, wear=0, metadata=""},
description = 'Wooden Bow',
image = 'bows_bow.png',
cost = {name="default:gold_ingot", count=50, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="bows:bow_steel", count=1, wear=0, metadata=""},
description = 'Steel Bow',
image = 'bows_bow_steel.png',
cost = {name="eggwars:ruby", count=25, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="bows:bow_bowie", count=1, wear=0, metadata=""},
description = 'Bowie Bow',
image = 'bows_bow_bowie.png',
cost = {name="default:diamond", count=35, wear=0, metadata=""},
})
bows.register_arrow("arrow_tp",{
description = "Teleport arrow",
texture = "bows_arrow_wood.png^[colorize:#0000FFcc",
damage = 0,
craft_count = 0,
drop_chance = 99,
on_hit_node = function(self, pos, user, arrow_pos)
if arrow_pos.y > 0 then
user:set_pos(arrow_pos)
end
end,
})
-- Arrows
eggwars.register_shop_item({
name = {name="bows:arrow", count=5, wear=0, metadata=""},
description = 'Wooden Arrow',
image = 'bows_arrow_wood.png',
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="bows:arrow_steel", count=10, wear=0, metadata=""},
description = 'Steel Arrow',
image = 'eggwars_arrow_steel.png',
cost = {name="eggwars:ruby", count=20, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="bows:arrow_diamond", count=10, wear=0, metadata=""},
description = 'Diamond Arrow',
image = 'eggwars_arrow_diamond.png',
cost = {name="default:diamond", count=20, wear=0, metadata=""},
})
eggwars.register_shop_item({
name = {name="bows:arrow_tp", count=5, wear=0, metadata=""},
description = 'Teleport Arrow',
image = 'bows_arrow_wood.png',
cost = {name="default:gold_ingot", count=10, wear=0, metadata=""},
})
end

Binary file not shown.

BIN
sounds/eggwars_out.ogg Normal file

Binary file not shown.

BIN
sounds/eggwars_sudden.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
sounds/eggwars_winner.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

BIN
textures/eggwars_blue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

BIN
textures/eggwars_cyan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

BIN
textures/eggwars_green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

BIN
textures/eggwars_orange.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

BIN
textures/eggwars_out.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

BIN
textures/eggwars_pick.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

BIN
textures/eggwars_pil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

BIN
textures/eggwars_pink.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

BIN
textures/eggwars_red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

BIN
textures/eggwars_ruby.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

BIN
textures/eggwars_shell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
textures/eggwars_trader1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
textures/eggwars_trader2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
textures/eggwars_trader3.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

BIN
textures/eggwars_violet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
textures/eggwars_winner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
textures/eggwars_yellow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

31
tools.lua Normal file
View File

@ -0,0 +1,31 @@
----------------------------------------------------------------------
-- Eggwars by wilkgr --
-- with additional code by shivajiva101@hotmail.com --
-- Licensed under the AGPL v3 --
-- You MUST make any changes you make open source --
-- even if you just run it on your server without publishing it --
-- Supports a maximum of 8 players per instance and 8 concurrent --
-- instances for a max of 64 players --
----------------------------------------------------------------------
minetest.register_tool("eggwars:pick_rainbow", {
description = "Rainbow Pickaxe",
range = 20,
inventory_image = "eggwars_rainbowpick.png",
groups = {not_in_creative_inventory = 1},
tool_capabilities = {
full_punch_interval = 0.1,
max_drop_level = 3,
groupcaps = {
unbreakable = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
fleshy = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
choppy = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
bendy = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
cracky = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
crumbly = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
snappy = {times = {[1] = 0, [2] = 0, [3] = 0}, uses = 0, maxlevel = 3},
},
damage_groups = {fleshy = 1000},
},
on_drop = eggwars.drop_msg,
})

View File

@ -1,25 +0,0 @@
-- We don't use chests anymore
chestrefill = function ()
for i=1, #islands do
local items = {"default:diamond","default:wood","default:wood","default:stick","default:wood","default:wood","default:mesecrystal","default:sword_diamond","default:sword_stone","default:sword_stone","default:sword_stone","default:sword_stone"}
minetest.set_node(islands[i],{name = "default:chest"})
math.randomseed(os.clock()*100000000000)
math.random()
local item_no = math.random(1, 4)
local n = 0
while n < item_no do
math.randomseed(os.clock()*100000000000)
math.random()
local item = math.random(1, #items)
local inv = minetest.get_inventory({type="node", pos=islands[i]})
inv:add_item("main",items[item])
n = n + 1;
end
end
end
-- Set nametag colour:
player:set_nametag_attributes({color = {a = 255, r = 0, g = 0, b = 0}}) --Make nametag invisible
-- colourise chat text:
minetest.colorize('colour','text')