Add class items

This commit is contained in:
rubenwardy 2020-03-13 21:58:42 +00:00
parent f610722b83
commit 02d527eaf5
18 changed files with 384 additions and 211 deletions

View file

@ -3,7 +3,7 @@
local healing_limit = 15
minetest.register_craftitem("ctf_bandages:bandage", {
description = "Bandage, heals teammates for 3-4 HP until HP is equal to "..healing_limit,
description = "Bandage\n\nHeals teammates for 3-4 HP until HP is equal to "..healing_limit,
inventory_image = "ctf_bandages_bandage.png",
on_use = function(itemstack, player, pointed_thing)
if pointed_thing.type ~= "object" then

View file

@ -15,6 +15,11 @@ function ctf_classes.register(cname, def)
def.properties.max_hp = def.properties.max_hp or 20
end
local registered_on_changed = {}
function ctf_classes.register_on_changed(func)
table.insert(registered_on_changed, func)
end
function ctf_classes.set_skin(player, color, class)
player:set_properties({
textures = {"ctf_classes_skin_" .. class.name .. "_" .. (color or "blue") .. ".png"}
@ -30,20 +35,22 @@ function ctf_classes.get(player)
return ctf_classes.__classes[cname]
end
function ctf_classes.set(player, cname)
assert(type(cname) == "string")
local class = ctf_classes.__classes[cname]
assert(class)
function ctf_classes.set(player, new_name)
assert(type(new_name) == "string")
local new = ctf_classes.__classes[new_name]
assert(new)
local meta = player:get_meta()
local old = meta:get("ctf_classes:class")
meta:set_string("ctf_classes:class", cname)
local old_name = meta:get("ctf_classes:class")
meta:set_string("ctf_classes:class", new_name)
ctf_classes.update(player)
if old ~= nil and old ~= cname then
local pname = player:get_player_name()
ctf.chat_send_team(ctf.player(pname).team,
minetest.colorize("#ABCDEF", pname .. " is now a " .. class.description))
if old_name == nil or old_name ~= new_name then
local old = old_name and ctf_classes.__classes[old_name]
for i=1, #registered_on_changed do
registered_on_changed[i](player, old, new)
end
end
end
@ -68,13 +75,21 @@ local function set_max_hp(player, max_hp)
end
function ctf_classes.update(player)
local name = player:get_player_name()
local class = ctf_classes.get(player)
local color = ctf_colors.get_color(ctf.player(player:get_player_name())).text
local color = ctf_colors.get_color(ctf.player(name)).text
set_max_hp(player, class.properties.max_hp)
ctf_classes.set_skin(player, color, class)
local speed = class.properties.speed
if ctf_flag.has_flag(name) and speed > 0.9 then
speed = 0.9
end
physics.set(player:get_player_name(), "ctf_classes:speed", {
speed = class.properties.speed,
speed = speed,
})
end

View file

@ -41,6 +41,24 @@ function ctf_classes.show_gui(name, player)
fs[#fs + 1] = ",#fcc," .. minetest.formspec_escape(item)
end
fs[#fs + 1] = "]"
for i, item in pairs(class.properties.items or {}) do
fs[#fs + 1] = "item_image["
fs[#fs + 1] = tostring(i * 0.5 - 0.4)
fs[#fs + 1] = ",2.15;0.5,0.5;"
fs[#fs + 1] = minetest.formspec_escape(ItemStack(item):get_name())
fs[#fs + 1] = "]"
local desc = ItemStack(item):get_description():split("\n")[1]
fs[#fs + 1] = "tooltip["
fs[#fs + 1] = tostring(i * 0.5 - 0.4)
fs[#fs + 1] = ",2.15;0.5,0.5;"
fs[#fs + 1] = minetest.formspec_escape(desc)
fs[#fs + 1] = "]"
end
fs[#fs + 1] = "button_exit[0.5,2.7;2,1;select_"
fs[#fs + 1] = class.name
fs[#fs + 1] = ";Select]"

View file

@ -7,6 +7,7 @@ dofile(minetest.get_modpath("ctf_classes") .. "/api.lua")
dofile(minetest.get_modpath("ctf_classes") .. "/gui.lua")
dofile(minetest.get_modpath("ctf_classes") .. "/regen.lua")
dofile(minetest.get_modpath("ctf_classes") .. "/ranged.lua")
dofile(minetest.get_modpath("ctf_classes") .. "/items.lua")
ctf_classes.register("knight", {
description = "Knight",
@ -16,16 +17,23 @@ ctf_classes.register("knight", {
properties = {
max_hp = 30,
speed = 0.90,
items = {
"default:sword_steel",
},
},
})
ctf_classes.register("shooter", {
description = "Shooter",
pros = { "+10% ranged skill", "Rifles and grappling hooks" },
cons = { "Can't capture the flag" },
description = "Sharp Shooter",
pros = { "+10% ranged skill" },
cons = {},
color = "#c60",
properties = {
can_capture = false,
items = {
"shooter:rifle",
"shooter:grapple_gun_loaded",
}
},
})
@ -36,6 +44,10 @@ ctf_classes.register("medic", {
color = "#0af",
properties = {
max_hp = 10,
items = {
"ctf_bandages:bandage 20",
},
},
})
@ -48,6 +60,14 @@ minetest.register_on_joinplayer(function(player)
end
end)
ctf_flag.register_on_pick_up(function(name)
ctf_classes.update(minetest.get_player_by_name(name))
end)
ctf_flag.register_on_drop(function(name)
ctf_classes.update(minetest.get_player_by_name(name))
end)
minetest.register_chatcommand("class", {
func = function(name, params)
local player = minetest.get_player_by_name(name)
@ -114,3 +134,13 @@ for _, flagname in pairs(flags) do
on_rightclick = show,
})
end
ctf_classes.register_on_changed(function(player, old, new)
if not old then
return
end
local pname = player:get_player_name()
ctf.chat_send_team(ctf.player(pname).team,
minetest.colorize("#ABCDEF", pname .. " is now a " .. new.description))
end)

View file

@ -0,0 +1,60 @@
give_initial_stuff.register_stuff_provider(function(player)
local class = ctf_classes.get(player)
return class.properties.items or {}
end, 1)
ctf_classes.register_on_changed(function(player, old, new)
local inv = player:get_inventory()
if old then
local items = old.properties.items or {}
for i = 1, #items do
inv:remove_item("main", ItemStack(items[i]))
end
end
do
assert(new)
local items = new.properties.items or {}
for i = 1, #items do
inv:add_item("main", ItemStack(items[i]))
end
end
end)
local function stack_list_to_map(stacks)
local map = {}
for i = 1, #stacks do
map[ItemStack(stacks[i]):get_name()] = true
end
return map
end
local old_item_drop = minetest.item_drop
minetest.item_drop = function(itemstack, player, pos)
local class = ctf_classes.get(player)
local items = stack_list_to_map(class.properties.items or {})
if items[itemstack:get_name()] then
minetest.chat_send_player(player:get_player_name(),
"You're not allowed to drop class items!")
return itemstack
else
return old_item_drop(itemstack, player, pos)
end
end
local old_is_allowed = ctf_map.is_item_allowed_in_team_chest
ctf_map.is_item_allowed_in_team_chest = function(listname, stack, player)
local class = ctf_classes.get(player)
local items = stack_list_to_map(class.properties.items or {})
if items[stack:get_name()] then
minetest.chat_send_player(player:get_player_name(),
"You're not allowed to put class items in the chest!")
return false
else
return old_is_allowed(listname, stack, player)
end
end

View file

@ -1,3 +1,3 @@
name = ctf_classes
depends = ctf, ctf_flag, ctf_colors, physics, shooter, hpregen
depends = ctf, ctf_flag, ctf_colors, ctf_map_core, physics, shooter, hpregen, give_initial_stuff
description = Adds classes, including knight, shooter, and medic

View file

@ -49,6 +49,13 @@ local function check_grapple(itemname)
return itemstack
end
if ctf_flag.has_flag(user:get_player_name()) then
minetest.chat_send_player(user:get_player_name(),
"You can't use grapples whilst carrying the flag")
return itemstack
end
return old_func(itemstack, user, ...)
end,
})

View file

@ -1,28 +1,33 @@
local full_ores = {
{"diamond", "default:diamond"},
{"mese", "default:mese_crystal"},
{"bronze", "default:bronze_ingot"},
{"steel", "default:steel_ingot"},
{"stone", "default:cobble"},
diamond = "default:diamond",
mese = "default:mese_crystal",
bronze = "default:bronze_ingot",
steel = "default:steel_ingot",
stone = "default:cobble",
}
local upgrades = {
steel = "mese",
mese = "diamond",
}
-- Swords
for _, orex in pairs(full_ores) do
for from, to in pairs(upgrades) do
crafting.register_recipe({
type = "inv",
output = "default:sword_" .. orex[1],
items = { "default:stick", orex[2] .. " 2" },
output = "default:sword_" .. to,
items = { "default:sword_" .. from, full_ores[to] .. " 2" },
always_known = true,
level = 1,
})
end
-- Pickaxes
for _, orex in pairs(full_ores) do
for ore, ore_item in pairs(full_ores) do
crafting.register_recipe({
type = "inv",
output = "default:pick_" .. orex[1],
items = { "default:stick 2", orex[2] .. " 3" },
output = "default:pick_" .. ore,
items = { "default:stick 2", ore_item .. " 3" },
always_known = true,
level = 1,
})
@ -187,22 +192,22 @@ crafting.register_recipe({
})
-- Shovels
for _, orex in pairs(full_ores) do
for ore, ore_item in pairs(full_ores) do
crafting.register_recipe({
type = "inv",
output = "default:shovel_" .. orex[1],
items = { "default:stick 2", orex[2] },
output = "default:shovel_" .. ore,
items = { "default:stick 2", ore_item },
always_known = true,
level = 1,
})
end
-- Axes
for _, orex in pairs(full_ores) do
for ore, ore_item in pairs(full_ores) do
crafting.register_recipe({
type = "inv",
output = "default:axe_" .. orex[1],
items = { "default:stick 2", orex[2] .. " 3" },
output = "default:axe_" .. ore,
items = { "default:stick 2", ore_item .. " 3" },
always_known = true,
level = 1,
})

View file

@ -50,13 +50,14 @@ function ctf_flag.collect_claimed()
return claimed
end
function ctf_flag.get_claimed_by_player(name)
function ctf_flag.has_flag(name)
local claimed = ctf_flag.collect_claimed()
for _, flag in pairs(claimed) do
if flag.claimed.player == name then
return name
return true
end
end
return false
end
function ctf_flag.player_drop_flag(name)

View file

@ -6,9 +6,24 @@ local blacklist = {
"default:aspen_leaves"
}
function ctf_map.is_item_allowed_in_team_chest(listname, stack, player)
if listname == "helper" then
return false
end
for _, itemstring in ipairs(blacklist) do
if stack:get_name() == itemstring then
return false
end
end
return true
end
local colors = {"red", "blue"}
for _, chest_color in pairs(colors) do
minetest.register_node("ctf_map_core:chest_" .. chest_color, {
local def = {
description = "Chest",
tiles = {
"default_chest_top_" .. chest_color .. ".png",
@ -22,15 +37,22 @@ for _, chest_color in pairs(colors) do
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
on_construct = function(pos)
}
function def.on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Chest")
local inv = meta:get_inventory()
inv:set_size("main", 4 * 7)
inv:set_size("pro", 4 * 7)
inv:set_size("helper", 1 * 1)
end,
on_rightclick = function(pos, node, player)
end
function def.can_dig(pos, player)
return false
end
function def.on_rightclick(pos, node, player)
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
minetest.chat_send_player(name, "You're not on team " .. chest_color)
@ -91,9 +113,9 @@ for _, chest_color in pairs(colors) do
"listring[current_player;main]"
minetest.show_formspec(name, "ctf_map_core:chest", formspec)
end,
end
allow_metadata_inventory_move = function(pos, from_list, from_index,
function def.allow_metadata_inventory_move(pos, from_list, from_index,
to_list, to_index, count, player)
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
@ -125,29 +147,24 @@ for _, chest_color in pairs(colors) do
else
return 0
end
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if listname == "helper" then
return 0
end
function def.allow_metadata_inventory_put(pos, listname, index, stack, player)
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
minetest.chat_send_player(name, "You're not on team " .. chest_color)
return 0
end
for _, itemstring in ipairs(blacklist) do
if stack:get_name() == itemstring then
return 0
end
end
local pstat = ctf_stats.player(name)
if not pstat or not pstat.score or pstat.score < 10 then
return 0
end
if not ctf_map.is_item_allowed_in_team_chest(listname, stack, player) then
return 0
end
if listname ~= "pro" or ctf_stats.is_pro(name) then
local chestinv = minetest.get_inventory({type = "node", pos = pos})
if chestinv:room_for_item("pro", stack) then
@ -165,8 +182,9 @@ for _, chest_color in pairs(colors) do
else
return 0
end
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
end
function def.allow_metadata_inventory_take(pos, listname, index, stack, player)
if listname == "helper" then
return 0
end
@ -186,21 +204,21 @@ for _, chest_color in pairs(colors) do
else
return 0
end
end,
can_dig = function(pos, player)
return false
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
end
function def.on_metadata_inventory_put(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" moves " .. (stack:get_name() or "stuff") .. " " ..
(stack:get_count() or 0) .. " to chest at " ..
minetest.pos_to_string(pos))
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
end
function def.on_metadata_inventory_take(pos, listname, index, stack, player)
minetest.log("action", player:get_player_name() ..
" takes " .. (stack:get_name() or "stuff") .. " " ..
(stack:get_count() or 0) .. " from chest at " ..
minetest.pos_to_string(pos))
end
})
minetest.register_node("ctf_map_core:chest_" .. chest_color, def)
end

View file

@ -34,10 +34,17 @@ dofile(modpath .. "/barrier.lua")
if minetest.get_modpath("ctf") then
dofile(modpath .. "/base.lua")
dofile(modpath .. "/chest.lua")
dofile(modpath .. "/give_initial_stuff.lua")
dofile(modpath .. "/meta_helpers.lua")
dofile(modpath .. "/schem_map.lua")
dofile(modpath .. "/maps_catalog.lua")
ctf_match.register_on_build_time_end(ctf_map.remove_middle_barrier)
give_initial_stuff.register_stuff_provider(function(player)
return ctf_map.map and ctf_map.map.initial_stuff or {
"default:pick_stone",
"default:sword_stone",
"default:torch 3",
}
end)
end

View file

@ -98,7 +98,7 @@ function ctf_map.register_treasures(map)
end
else
-- If treasure is a part of map's initial stuff, don't register it
local blacklist = ctf_map.map.initial_stuff or give_initial_stuff.get_stuff()
local blacklist = ctf_map.map.initial_stuff or {}
for _, def in pairs(ctf_treasure.get_default_treasures()) do
local is_valid = true
for _, b_item in pairs(blacklist) do

View file

@ -1,3 +1,3 @@
name = ctf_map_core
depends = default
optional_depends = ctf, ctf_match, ctf_stats, ctf_treasure, stairs, wool, irc, physics
optional_depends = ctf, ctf_match, ctf_stats, ctf_treasure, stairs, wool, irc, physics, give_initial_stuff

View file

@ -10,7 +10,6 @@ function ctf_treasure.get_default_treasures()
{ "ctf_traps:damage_cobble", 0.3, 4, { 10, 20 } },
{ "default:pick_steel", 0.5, 5, { 1, 10 } },
{ "default:sword_steel", 0.4, 5, { 1, 4 } },
{ "default:shovel_stone", 0.6, 5, { 1, 10 } },
{ "default:shovel_steel", 0.3, 5, { 1, 10 } },
{ "default:axe_steel", 0.4, 5, { 1, 10 } },
@ -21,11 +20,10 @@ function ctf_treasure.get_default_treasures()
{ "shooter:machine_gun", 0.02, 2, 1 },
{ "shooter:crossbow", 0.5, 2, { 1, 5 } },
{ "shooter:pistol", 0.4, 2, { 1, 5 } },
{ "shooter:rifle", 0.1, 2, { 1, 2 } },
{ "shooter:ammo", 0.3, 2, { 1, 10 } },
{ "shooter:arrow_white", 0.5, 2, { 2, 18 } },
{ "medkits:medkit", 0.8, 5, 2 },
{ "ctf_bandages:bandage", 0.8, 2, { 2, 4 } }
}
end

View file

@ -12,7 +12,7 @@ setmetatable(give_initial_stuff, {
inv:set_size("craftresult", 0)
inv:set_size("hand", 0)
local items = give_initial_stuff.get_stuff()
local items = give_initial_stuff.get_stuff(player)
for _, item in pairs(items) do
inv:add_item("main", item)
@ -20,12 +20,24 @@ setmetatable(give_initial_stuff, {
end
})
function give_initial_stuff.get_stuff()
return ctf_map.map and ctf_map.map.initial_stuff or {
"default:pick_stone",
"default:sword_stone",
"default:torch 3",
}
local registered_stuff_providers = {}
function give_initial_stuff.register_stuff_provider(func, priority)
table.insert(registered_stuff_providers,
priority or (#registered_stuff_providers + 1),
func)
end
function give_initial_stuff.get_stuff(player)
local stuff = {}
for i=1, #registered_stuff_providers do
local new_stuff = registered_stuff_providers[i](player)
assert(new_stuff)
for j=1, #new_stuff do
stuff[#stuff + 1] = new_stuff[j]
end
end
return stuff
end
minetest.register_on_joinplayer(function(player)

View file

@ -0,0 +1,2 @@
name = give_initial_stuff
description = API to give give_initial_stuff

View file

@ -36,7 +36,7 @@ local function drop_all(player)
pos.y = math.floor(pos.y + 0.5)
local inv = player:get_inventory()
for _, item in pairs(give_initial_stuff.get_stuff()) do
for _, item in pairs(give_initial_stuff.get_stuff(player)) do
inv:remove_item("main", ItemStack(item))
end
drop_list(pos, inv, "main")

View file

@ -1,3 +1,3 @@
name = dropondie
depends = ctf_map_core
depends = give_initial_stuff
description = With this mod, players will drop all their items in their inventory on the ground when they die.