diff --git a/mods/ctf/ctf_classes/api.lua b/mods/ctf/ctf_classes/api.lua index 4851b62..e8fe5f3 100644 --- a/mods/ctf/ctf_classes/api.lua +++ b/mods/ctf/ctf_classes/api.lua @@ -91,14 +91,11 @@ end local function set_max_hp(player, max_hp) local cur_hp = player:get_hp() local old_max = player:get_properties().hp_max - - if old_max == 0 then - minetest.log("error", "[ctf_classes] Reviving dead player " .. player:get_player_name()) - end - - player:set_properties({hp_max = max_hp}) - local new_hp = cur_hp + max_hp - old_max + player:set_properties({ + hp_max = max_hp + }) + if new_hp > max_hp then minetest.log("error", string.format("New hp %d is larger than new max %d, old max is %d", new_hp, max_hp, old_max)) new_hp = max_hp diff --git a/mods/ctf/ctf_inventory/init.lua b/mods/ctf/ctf_inventory/init.lua index 841e935..785d269 100644 --- a/mods/ctf/ctf_inventory/init.lua +++ b/mods/ctf/ctf_inventory/init.lua @@ -10,10 +10,8 @@ local items = { "* Use medkits to replenish health gradually.", "* Gain more score by killing more than you die, or by capturing the flag.", "* Players are immune for 5 seconds after they respawn.", - "* Access the pro section of the chest by achieving 10k+ score and either", - " killing 3 people for every 2 deaths and capturing the flag at least 10 times", - " or killing as many people as you die, capturing the flag on every 3rd attempt", - " and at least 30 times.", + "* Access the pro section of the chest by achieving 2k+ score,", + " killing 3 people for every 2 deaths, and capturing the flag at least 10 times", "", color .. "Team Co-op", @@ -32,12 +30,12 @@ local items = { color .. "Contact Moderators", "", - "* Report people using /report.", + "* Report people using /report or the #reports channel in Discord", "", color .. "Other", "", - "* Capture The Flag Discord (not related to this server): https://discord.gg/vcZTRPX", + "* Capture The Flag Discord: https://discord.gg/vcZTRPX", } for i = 1, #items do items[i] = minetest.formspec_escape(items[i]) diff --git a/mods/ctf/ctf_map/map_maker/README.md b/mods/ctf/ctf_map/map_maker/README.md index c26c604..12b0b64 100644 --- a/mods/ctf/ctf_map/map_maker/README.md +++ b/mods/ctf/ctf_map/map_maker/README.md @@ -1,84 +1,88 @@ -# CTF map-maker mod +# CTF Map - Map maker -## Making a new map +## Creating a new map -### Youtube Tutorial +### Youtube tutorial https://youtu.be/orBsC9wViUw -### Dependencies -- Minetest 5.0.0 or later (https://minetest.net/) -- Minetest Game (https://github.com/minetest/minetest_game/) (CTF supports most MTG nodes) -- `ctf_map` modpack (copy this folder to `minetest/mods`) -- `worldedit` modpack (WE) (https://content.minetest.net/packages/sfan5/worldedit/) -### Find an area +### 1. Dependencies -- The area can be maximum 230x230 blocks in surface area, but it can be lesser. -- Modify the area to *your* unique ctf_map - - you could add - - buildings - - lakes - - hills - - etc. -- If you haven't modified the map at all, do the following to speed up barrier placement: +* Minetest 5.0.0 or later. +* `ctf_map` modpack (by copying the folder from this game to `minetest/mods`) +* `worldedit` and `worldedit_commands`. - - Stop Minetest. - - Open up the world's world.mt - - Set backend to "dummy". - - Save. +### 2. Find an area -### The `gui`window +* Can use Minetest Game and any mapgen. +* It must be a cube, and the barrier will be in the exact center. +* It should be around 230x230 in surface area, but this can be lesser. +* Feel free to modify the area to your needs. - ![gui-window](./gui.png) +### 3. Select the area -There are many ways of placing the barrier: +There are multiple ways do this, this is the simplest in most cases. -- Go to the center of the map and click on `Player Pos` and then on `To WE` - - set a radius and a height for the map -- **Or** select the area of the map via WE - - Go to one corner of the map and type `//pos 1` in the chat - - Then go to the opposite corner of the cube and type `//pos 2` in the chat - - Click on `From WE` to import the positions - - **If `h` is negative change it to the positive number** (`-130 -> 130`) -- **Both radii must be the same!** -- The rotation of the map has to be `z=0` (currently x=0 creates bugs and errors) -- Click on `Place Barriers` (Note that this has no undo) -- After the barriers are placed, click on `Givme Flags` to get 2 flags and place them at the bases. +* If you haven't modified the map at all, do the following to speed up barrier placement: + * Stop Minetest. + * Open up the world's world.mt + * Set backend to "dummy". + * Save. +* Using worldedit, select the area. +* Type `/gui`, and click `Player pos` then `From WE` and then `To WE`. +* Check that the center location is the right place for the barrier to go. +* Check that the bounds extend far enough. -### Meta Data +### 4. Place barriers -The `gui`window only shows the most important things. You have to add the missing in the `map.conf` later. +* The barrier is a plane defined by co-ordinate (=0). +* If you choose `X=0` the barrier will be placed having the X co-ordinate as 0. But from a few months, the `X=0` co-ordinate creates bugs and errors. It's better if you choose `Z=0` for creating your map. +* If you choose `Z=0` The barrier will be placed having the Z co-ordinate as 0. +* Click "place barrier". Note that this command does not have an undo. +* After placing barriers you should place 2 flags where you want bases to be. You get flags in `/gui` --> `Giveme flags` -### Exporting +### 5. Meta data -- Click on `Export` to export the map-files. This may takes some time +* Set the meta data -## Map Meta +### 6. Export -The metadata of each map are stored in the `map.conf` file and includes all important information about them: -- `name`: Name of the map. -- `author`: Author of the map. -- `hint` [Optional]: A helpful tip for players to understand unique maps. -- `roation`: The rotation of the map. [x|y] -- `r`: Radius of the map. -- `h`: Heigt of the map (**If it's an odd numer, make h=h+1 `107->108`**). -- `team.i`: Name of the team. -- `team.i.color`: Color of the team. -- `team.i.pos`: Position of team `i`'s flag, relative ot the center of schem. **The y-positions of the flags must be an integer!** `30,-32.5,60 -> 30,-33,60` -- `chest.i.from` and `chests.i.to` [Optional]: Positions of diagonal corners of custom chest zone `i`, relative to the center of the schem. -- `chests.i.n` [Optional]: Number if chests in zone `i` -- `license`: Name of license of the map. -- `other` [Optional]: Additional information about the map. This is displayed in the maps catalog. -- `base_node` [Optional]: String of the node around the flags. -- `initial_stuff` [Optional]: Comma-separated list of itemstacks to be given to the player on join and on respawn. -- `treasures` [Optional]: List of treasures to be registered for the map, in a serialized format. Refer to the `treasures` sub-section for more details. -- `start_time` [Optional]: Time of day when the match starts. Default to `0.4` [`0 - 1`]. -- `time_speed` [Optional]: Time speed multiplier. Accepts any valid number. Defaults to 1. -- `phys_speed` [Optional]: Player speed multiplier. Accepts any valid number. Defaults to 1. -- `phys_jump` [Optional]: Player jump multiplier. Accepts any valid number. Defaults to 1. -- `phys_gravity` [Optional]: Player gravity multiplier. Accepts any valid number. Defaults to 1. +* Click export, and wait until completion. +* Copy the resultant folder from `worlddir/schems/` into `games/capturetheflag/mods/ctf/ctf_map/ctf_map_core/maps/`. +* Profit! +## Documentation + +### Map meta + +Each map's metadata is stored in an accompanying `map.conf` file containing the following data: + +* `name`: Name of map. +* `author`: Author of the map. +* `hint`: [Optional] Helpful hint or tip for unique maps, to help players understand the map. +* `rotation`: Rotation of the schem. [`x`|`z`] +* `r`: Radius of the map. +* `h`: Height of the map. +* `team.i`: Name of team `i`. +* `team.i.color`: Color of team `i`. +* `team.i.pos`: Position of team `i`'s flag, relative to center of schem. +* `chests.i.from`, `chests.i.to`: [Optional] Positions of diagonal corners of custom chest +zone `i`, relative to the center of the schem. +* `chests.i.n`: [Optional] Number of chests to place in custom chest zone `i`. +* `license`: Name of the license of the map. +* `other`: [Optional] Misc. information about the map. This is displayed in the maps catalog. +* `base_node`: [Optional] Technical name of node to be used for the team base. +* `initial_stuff`: [Optional] Comma-separated list of itemstacks to be given to the player + on join and on respawn. +* `treasures`: [Optional] List of treasures to be registered for the map, in a serialized +format. Refer to the `treasures` sub-section for more details. +* `start_time`: [Optional] Time at start of match. Defaults to `0.4` [`0` - `1`]. +* `time_speed`: [Optional] Time speed multiplier. Accepts any valid number. Defaults to 1. +* `phys_speed`: [Optional] Player speed multiplier. Accepts any valid number. Defaults to 1. +* `phys_jump`: [Optional] Player jump multiplier. Accepts any valid number. Defaults to 1. +* `phys_gravity`: [Optional] Player gravity multiplier. Accepts any valid number. Defaults to 1. + #### `license` * Every map must have its own license. Once you've chosen your license, simply add the following line to the `map.conf` file: diff --git a/mods/ctf/ctf_map/map_maker/gui.png b/mods/ctf/ctf_map/map_maker/gui.png deleted file mode 100644 index f950473..0000000 Binary files a/mods/ctf/ctf_map/map_maker/gui.png and /dev/null differ diff --git a/mods/ctf/ctf_respawn_delay/init.lua b/mods/ctf/ctf_respawn_delay/init.lua index b12edb0..ab3b481 100644 --- a/mods/ctf/ctf_respawn_delay/init.lua +++ b/mods/ctf/ctf_respawn_delay/init.lua @@ -37,18 +37,13 @@ minetest.register_on_mods_loaded(function() table.insert(minetest.registered_on_respawnplayers, 1, function(player) local pname = player:get_player_name() - if ctf_respawn_delay.players[pname] then - -- Since the player is still dead the client can send respawn actions - -- https://github.com/minetest/minetest/blob/4152227f17315a9cf9038266d9f9bb06e21e3424/src/network/serverpackethandler.cpp#L895 - -- We should ignore those - if ctf_respawn_delay.players[pname].timeleft == "waiting" then - ctf_respawn_delay.players[pname].timeleft = RESPAWN_DELAY - local pos = player:get_pos() - pos.y = ctf_map.map.h/2 + 10 + if ctf_respawn_delay.players[pname] and ctf_respawn_delay.players[pname].timeleft == "waiting" then + ctf_respawn_delay.players[pname].timeleft = RESPAWN_DELAY + local pos = player:get_pos() + pos.y = ctf_map.map.h/2 + 10 - player:set_pos(pos) -- Player will be stuck there because CTF 'air' is walkable - minetest.after(RESPAWN_INTERVAL, respawnfunc, pname) - end + player:set_pos(pos) -- Player will be stuck there because CTF 'air' is walkable + minetest.after(RESPAWN_INTERVAL, respawnfunc, pname) return true end @@ -61,10 +56,15 @@ minetest.register_on_mods_loaded(function() end) end) -function respawnplayer(player, pname) - player:hud_remove(ctf_respawn_delay.players[pname].hudid) - player:set_properties({hp_max = ctf_respawn_delay.players[pname].old_max}) - player:set_hp(ctf_respawn_delay.players[pname].old_max) +function ctf_respawn_delay.respawnplayer(name) + local player = minetest.get_player_by_name(name) + + if not player then return end + + player:hud_remove(ctf_respawn_delay.players[name].hudid) + player:set_properties({hp_max = ctf_respawn_delay.players[name].old_max}) + player:set_hp(ctf_respawn_delay.players[name].old_max) + ctf_respawn_delay.players[name] = nil for k, func in ipairs(ctf_respawn_delay.registered_on_respawnplayers) do func(player) @@ -72,13 +72,16 @@ function respawnplayer(player, pname) end function respawnfunc(pname) - if not ctf_respawn_delay.players[pname] then + local player = minetest.get_player_by_name(pname) + + if not player or not ctf_respawn_delay.players[pname] then + ctf_respawn_delay.players[pname] = nil return end - local player = minetest.get_player_by_name(pname) - if not player then - ctf_respawn_delay.players[pname] = nil + if type(ctf_respawn_delay.players[pname].timeleft) == "string" then + minetest.after(RESPAWN_INTERVAL, respawnfunc, pname) + return end @@ -90,26 +93,12 @@ function respawnfunc(pname) minetest.after(RESPAWN_INTERVAL, respawnfunc, pname) else - respawnplayer(player, pname) - ctf_respawn_delay.players[pname] = nil + ctf_respawn_delay.respawnplayer(pname) end end ctf_match.register_on_new_match(function() - for pname in pairs(ctf_respawn_delay.players) do - local player = minetest.get_player_by_name(pname) - if player then - respawnplayer(player, pname) - end - end - - ctf_respawn_delay.players = {} -end) - -minetest.register_on_leaveplayer(function(player) - local pname = player:get_player_name() - if ctf_respawn_delay.players[pname] then - player:set_properties({hp_max = ctf_respawn_delay.players[pname].old_max}) - ctf_respawn_delay.players[pname] = nil + for name in pairs(ctf_respawn_delay.players) do + ctf_respawn_delay.respawnplayer(name) end end) diff --git a/mods/ctf/ctf_stats/chat.lua b/mods/ctf/ctf_stats/chat.lua index 44dd715..d37942a 100644 --- a/mods/ctf/ctf_stats/chat.lua +++ b/mods/ctf/ctf_stats/chat.lua @@ -259,48 +259,3 @@ minetest.register_chatcommand("makepro", { end end }) - -minetest.register_chatcommand("makecapturepro", { - params = "[player_name]", - description = "Make player a 'capture pro'", - privs = {ctf_admin = true}, - func = function(name, param) - -- Check if param is specified, else target the caller - param = param:trim() - if param == "" then - param = name - end - - local modified = false - local stats = ctf_stats.player(param) - - local deaths = math.max(stats.deaths, 1) - if stats.kills < 1.0 * deaths then - stats.kills = math.ceil(1.01 * deaths) - modified = true - end - - if stats.score < 10000 then - stats.score = 10000 - modified = true - end - - if stats.captures < 30 then - stats.captures = 30 - modified = true - end - - local attempts = math.max(stats.attempts, 1) - if stats.captures < 0.33 * attempts then - stats.captures = math.ceil(0.34 * attempts) - modified = true - end - - if modified then - ctf_stats.request_save() - return true, "Made " .. param .. " a pro!" - else - return false, param .. " is already a pro!" - end - end -}) diff --git a/mods/mtg/default/nodes.lua b/mods/mtg/default/nodes.lua index 3dc290c..e2aa4ad 100644 --- a/mods/mtg/default/nodes.lua +++ b/mods/mtg/default/nodes.lua @@ -578,6 +578,7 @@ minetest.register_node("default:clay", { description = "Clay", tiles = {"default_clay.png"}, groups = {crumbly = 3}, + drop = 'default:clay_lump 4', sounds = default.node_sound_dirt_defaults(), })