Polishing: TNT particles, countdown sounds, tag sounds, HUD fixes, improved messages

This commit is contained in:
Wuzzy 2023-08-01 23:22:44 +00:00 committed by Zughy
parent 6b694665d1
commit 6d936ca8dd
21 changed files with 319 additions and 41 deletions

View File

@ -1,28 +1,63 @@
# TNTTAG
## Create an own arena
## Gameplay
At the start of the game, one or more players are chosen
at random. These players are forced to carry TNT which
will explode soon! Players carrying TNT are called "taggers".
As a tagger, you have to chase any other player and
punch them so they have to carry the TNT instead.
When the TNT timer reaches 0, it will explode together with
the tagger holding. The tagger is eliminated.
Once the TNT has gone boom, there's a short pause, then
the next "wave" begins with new player(s) being chosen
at random to become taggers.
Players will explode that way, one after another, until only
one is left. The last player standing wins the game.
## HUD indicators
On the top of the screen, there are several indicators in the
Heads-Up Display (HUD) showing info about the game.
From left to right:
1. Status: Shows whether there is an active TNT in the game
("play" icon) or if it's in pause mode ("pause" icon).
2. Player count: Shows the number of remaining and total players
3. TNT timer: How many seconds remain on the TNT timer.
Shows "-" during a pause.
4. Wave: Shows the current and final wave (i.e. round)
## Setting up
### Create an own arena
Use this chat command:
`/tnttag create <arena> <minplayers:int> <maxplayers:int>`
## Edit own arena
### Schematics for your arenas
### Warnings
Find nice arenas here: <https://codeberg.org/debiankaios/tnttag_arenas>
#### Timers
### Edit your own arena
Don't set timer-time it won't change anything. Set the lap_time in settings.
#### Warning about timers
## Licensing
Don't set the arena timer. It won't change anything. Set the `wavetime` in
the arena settings instead for the time of each wave.
Main-License: LICENSE.txt
Media License: LICENSE_MEDIA.txt textures/license.txt
## Licensing / Credits
## Schems for you arenas
Main license: See `LICENSE.txt`
Media license: See `LICENSE_MEDIA.txt`, `textures/license.txt` and `sounds/LICENSE.txt`
Find nice arenas on: https://codeberg.org/debiankaios/tnttag_arenas
### Chatcommandbuilder
## Chatcommandbuilder
Thankyou to rubenwardy for chatcommandbuilder.lua.
Thanks to rubenwardy for chatcommandbuilder.lua.
Here links to original:
https://github.com/rubenwardy/ChatCmdBuilder
https://gitlab.com/rubenwardy/ChatCmdBuilder
https://gitlab.com/rubenwardy/ChatCmdBuilder

143
api.lua
View File

@ -1,5 +1,113 @@
local S = minetest.get_translator("tnttag")
-- TNT break particles (for TNT above player head)
local function tnt_particles(pos)
minetest.add_particlespawner({
amount = 16,
time = 0.01,
pos = {
min = vector.add(pos, vector.new(-0.2, -0.2, -0.2)),
max = vector.add(pos, vector.new(0.2, 0.2, 0.2)),
},
vel = {
min = vector.new(-1, -0.2, -1),
max = vector.new(1, 0.2, 1),
},
acc = vector.new(0, -1, 0),
exptime = { min = 0.2, max = 0.7 },
size = { min = 0.25, max = 0.5 },
collisiondetection = false,
vertical = false,
node = {name="tnttag:tnt"},
})
end
-- Spawns explosion particles at pos
local function explosion_particles(pos)
local radius = 3
minetest.add_particlespawner({
amount = 128,
time = 0.6,
pos = {
min = vector.subtract(pos, radius / 2),
max = vector.add(pos, radius / 2),
},
vel = {
min = vector.new(-20, -20, -20),
max = vector.new(20, 20, 20),
},
acc = vector.zero(),
exptime = { min = 0.2, max = 1.0 },
size = { min = 16, max = 24 },
drag = vector.new(1,1,1),
texture = {
name = "tnttag_smoke_anim_1.png", animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = -1 },
name = "tnttag_smoke_anim_2.png", animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = -1 },
name = "tnttag_smoke_anim_1.png^[transformFX", animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = -1 },
name = "tnttag_smoke_anim_2.png^[transformFX", animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = -1 },
},
})
minetest.add_particlespawner({
amount = 1,
time = 0.01,
pos = pos,
vel = vector.zero(),
acc = vector.zero(),
exptime = 1,
size = radius*10,
texture = "tnttag_smoke_ball_big.png",
animation = { type = "vertical_frames", aspect_w = 32, aspect_h = 32, length = -1, },
})
minetest.add_particlespawner({
amount = 4,
time = 0.25,
pos = pos,
vel = vector.zero(),
acc = vector.zero(),
exptime = { min = 0.6, max = 0.9 },
size = { min = 8, max = 12 },
radius = { min = 0.5, max = math.max(0.6, radius*0.75) },
texture = "tnttag_smoke_ball_medium.png",
animation = { type = "vertical_frames", aspect_w = 32, aspect_h = 32, length = -1, },
})
minetest.add_particlespawner({
amount = 28,
time = 0.5,
pos = pos,
vel = vector.zero(),
acc = vector.zero(),
exptime = { min = 0.5, max = 0.8 },
size = { min = 6, max = 8 },
radius = { min = 1, max = math.max(1.1, radius+1) },
texture = "tnttag_smoke_ball_small.png",
animation = { type = "vertical_frames", aspect_w = 32, aspect_h = 32, length = -1, },
})
end
-- Spawn black particles to make it look like as if
-- a player was scorched.
-- pos is the player position.
local function scorched_player_particles(pos)
minetest.add_particlespawner({
amount = 100,
time = 0.1,
pos = {
min = vector.subtract(pos, vector.new(0.3, 0, 0.3)),
max = vector.add(pos, vector.new(0.3, 1.78, 0.3)),
},
vel = {
min = vector.new(-0.2, 0.1, -0.2),
max = vector.new(0.2, 0.1, 0.2),
},
collisiondetection = true,
acc = vector.new(0, -0.5, 0),
exptime = { min = 4.5, max = 5.5 },
size = { min = 0.5, max = 1 },
drag = vector.new(1,0,1),
texture = "tnttag_scorch.png",
})
end
-- gives a player the tagging item
function tnttag.add_tager(player)
player:get_inventory():set_stack("main", 1, tnttag.tagitem)
@ -106,15 +214,25 @@ end
function tnttag.explode_player(p_name, arena)
minetest.sound_play("tnt_explode", {object = minetest.get_player_by_name(p_name), gain = 1.0, max_hear_distance = 128, loop = false,}, true)
arena_lib.HUD_send_msg("title", p_name, S("You exploded!"),1, nil--[[sound↑]], 0xFF3300)
local player = minetest.get_player_by_name(p_name)
minetest.sound_play("tnt_explode", {object = player, gain = 1.0, max_hear_distance = 128, loop = false,}, true)
-- explosion particles
local ppos = player:get_pos()
-- center explosion above player head (roughly at the TNT entity is)
local epos = vector.add(ppos, {x=0, y=2.2, z=0})
tnt_particles(epos)
scorched_player_particles(ppos)
explosion_particles(epos)
arena_lib.remove_player_from_arena(p_name, 1)
arena_lib.HUD_send_msg("title", p_name, S("You exploded!"),1, nil--[[sound↑]], 0xFF3300)
for pl_name,_ in pairs(arena.players) do
minetest.chat_send_player(pl_name,p_name.." "..S("exploded!"))
end
end
function tnttag.newwave(arena)
local player
local new_tagger
@ -139,17 +257,26 @@ function tnttag.newwave(arena)
end
end
for p_name in pairs(arena.players_and_spectators) do
local message = S("The new tagger is").." "
if #real_new_tagger > 1 then
message = S("The new taggers are").." "
end
local message = S("The new tagger is").." "
if #real_new_tagger > 1 then
message = S("The new taggers are").." "
end
minetest.chat_send_player(p_name, message .. table.concat(real_new_tagger,", ").."!")
minetest.sound_play("new_round", {to_player = p_name, gain = 1.0, loop = false,}, true)
if #real_new_tagger == 1 then
message = S("You're the tagger!")
else
message = S("You're a tagger!")
end
for i=1, #real_new_tagger do
arena_lib.HUD_send_msg("title", real_new_tagger[i], message, 1, nil, 0xFF3300)
end
end
for p_name in pairs(arena.players) do
player = minetest.get_player_by_name(p_name)
player:set_pos(arena_lib.get_random_spawner(arena, arena.players[p_name]))--WARNING: Tagged and Untagged player on same spawn-point
end
end
arena.pause = false
tnttag.update_pause_hud(arena)
tnttag.update_wave_timer_hud(arena, true)
end

View File

@ -1,3 +1,7 @@
-- How many seconds need to be left on the TNT clock
-- to play a countdown beep each second for the tagger(s)
local COUNTDOWN_SECONDS = 10
arena_lib.on_load("tnttag", function(arena)
arena.original_player_amount = arena.players_amount
if arena.autochoosewaves then arena.waves = math.ceil((arena.players_amount - 1)/arena.max_players_in_autochoose) end
@ -17,18 +21,21 @@ arena_lib.on_join("tnttag", function(p_name, arena, as_spectator)
if as_spectator then
tnttag.generate_HUD(arena, p_name)
tnttag.update_pause_hud(arena)
tnttag.update_wave_timer_hud(arena)
end
end)
arena_lib.on_quit("tnttag", function(arena, p_name, is_spectator, reason)
if not is_spectator then
tnttag.remove_tnthead(p_name)
tnttag.update_player_count_hud(arena)
end
tnttag.remove_HUD(arena, p_name)
end)
arena_lib.on_eliminate("tnttag", function(arena, p_name)
tnttag.remove_tnthead(p_name)
tnttag.update_player_count_hud(arena)
end)
arena_lib.on_celebration("tnttag", function(arena, winner)
@ -36,6 +43,10 @@ arena_lib.on_celebration("tnttag", function(arena, winner)
for p_name in pairs(arena.players) do
tnttag.remove_tnthead(p_name)
end
-- Celebration counts as "pause"
arena.pause = true
tnttag.update_pause_hud(arena)
tnttag.update_wave_timer_hud(arena)
end)
arena_lib.on_end("tnttag", function(arena, players, winners, spectators)
@ -48,9 +59,11 @@ arena_lib.on_end("tnttag", function(arena, players, winners, spectators)
end)
arena_lib.on_time_tick("tnttag", function(arena)
local newwave = false
if arena.pause then
if arena.current_time%arena.wavetime == 0 then
tnttag.newwave(arena)
newwave = true
end
else
local taggersnum = 0
@ -60,31 +73,44 @@ arena_lib.on_time_tick("tnttag", function(arena)
if taggersnum == 0 then
arena.current_time=(arena.current_time-arena.current_time%arena.wavetime)-1
tnttag.newwave(arena)
newwave = true
end
if arena.current_time%arena.wavetime == 0 then
local wavetimeleft = arena.current_time%arena.wavetime
if wavetimeleft == 0 then
for p_name in pairs(arena.players) do
if arena.players[p_name].tagged then
if arena.players[p_name].tagged then
tnttag.explode_player(p_name, arena)
end
end
end
arena.current_time = arena.current_time + arena.pause_length
if arena.pause_length == 0 then
tnttag.newwave(arena)
newwave = true
else
arena.pause = true
tnttag.update_pause_hud(arena)
end
-- Play warning sound each second to tagger(s) when time is running out
elseif wavetimeleft <= COUNTDOWN_SECONDS then
for p_name in pairs(arena.players) do
if arena.players[p_name].tagged then
minetest.sound_play({name="tnttag_timer", gain=0.7}, {to_player=p_name}, true)
end
end
end
end
tnttag.update_wave_timer_hud(arena)
if not newwave then
tnttag.update_wave_timer_hud(arena)
end
tnttag.update_player_count_hud(arena)
end)
arena_lib.on_timeout("tnttag", function(arena)
winners = {}
local winners = {}
for p_name in pairs(arena.players) do
if arena.players[p_name].tagged then
tnttag.explode_player(p_name, arena)
tnttag.update_player_count_hud(arena)
else
table.insert(winners, p_name)
end
@ -92,4 +118,5 @@ arena_lib.on_timeout("tnttag", function(arena)
if (#winners > 1) then
arena_lib.load_celebration("tnttag", arena, table.concat(winners,", "))
end
tnttag.update_wave_timer_hud(arena)
end)

12
hud.lua
View File

@ -5,7 +5,9 @@ function tnttag.generate_HUD(arena, p_name)
local background_timer_
local timer_
local background_wave_counter_
local background_wave_timer_
local wave_counter_
local wave_timer_
local hud_pause_
local pos_x = 0.48
local pos_y = 0
@ -111,10 +113,16 @@ function tnttag.update_player_count_hud(arena)
end
end
function tnttag.update_wave_timer_hud(arena)
function tnttag.update_wave_timer_hud(arena, just_started)
local wave_timer
if just_started then
wave_timer = tostring(arena.wavetime)
else
wave_timer = tostring(arena.current_time % arena.wavetime)
end
for p_name in pairs(arena.players_and_spectators) do
local player = minetest.get_player_by_name(p_name)
player:hud_change(tnttag.saved_huds[p_name].wave_timer, "text", arena.current_time%arena.wavetime)
player:hud_change(tnttag.saved_huds[p_name].wave_timer, "text", wave_timer)
end
end

View File

@ -25,8 +25,8 @@ arena_lib.register_minigame("tnttag", {
pause = true,
},
player_properties = {
tagged = false,
tnt_if_tagged,
tagged = false,
tnt_if_tagged = nil,
},
in_game_physics = {
speed = tnttag.player_speed,

View File

@ -1,8 +1,13 @@
local S = minetest.get_translator("tnttag")
-- The item used to tag other players with TNT.
-- Note: This MUST be registered as a node, the particles depend on it.
minetest.register_node("tnttag:tnt", {
description = S("TNTTagger - Tag other players"),
tiles = {"tnttag_tnt_top_burning.png", "tnttag_tnt_bottom.png", "tnttag_tnt_side.png"},
-- Allow it to be dug
groups = { choppy = 1, not_in_creative_inventory = 1 },
node_placement_prediction = "",
on_place = function(itemstack, placer, pointed_thing)
local placer_name = placer:get_player_name()
if arena_lib.is_player_in_arena(placer_name, "tnttag") then
@ -35,8 +40,8 @@ minetest.register_node("tnttag:tnt", {
for pl_name, _ in pairs(arena.players) do
minetest.chat_send_player(pl_name, S("@1 tagged @2", user_name, p_name))
end
arena_lib.HUD_send_msg("title", p_name, S("You have been tagged by @1!", user_name),1, nil--[[sound?]], 0xFF3300)
arena_lib.HUD_send_msg("title", user_name, S("You tagged @1!", p_name),1, nil--[[sound?]], 0xFF3300)
arena_lib.HUD_send_msg("title", p_name, S("You have been tagged by @1!", user_name),1, {name="tnttag_tag_gotten", gain=1}, 0xFF3300)
arena_lib.HUD_send_msg("title", user_name, S("You tagged @1!", p_name),1, {name="tnttag_tag_given", gain=1}, 0x33FF33)
end
end
end

View File

@ -3,6 +3,8 @@ You exploded!=
exploded!=
The new tagger is=
The new taggers are=
You're the tagger!=
You're a tagger!=
Needed for tnttag=
TNTTagger - Tag other players=
@1 tagged @2=

View File

@ -1,10 +1,12 @@
# textdomain: tnttag
You exploded!=Sie sind explodiert!
exploded!=ist explodiert!
The new tagger is=Der neue Tagger ist
The new taggers are=Die neuen Tagger sind
The new tagger is=Der neue Fänger ist
The new taggers are=Die neuen Fänger sind
You're the tagger!=Sie sind der Fänger!
You're a tagger!=Sie sind ein Fänger!
Needed for tnttag=Benötigt für tnttag
TNTTagger - Tag other players=TNTTagger Taggen Sie andere Spieler
@1 tagged @2=@1 taggte @2
You have been tagged by @1!=Sie wurden von @1 getaggt
You tagged @1!=Sie haben @1 getaggt!
TNTTagger - Tag other players=TNTTagger Fangen Sie andere Spieler
@1 tagged @2=@1 hat @2 gefangen
You have been tagged by @1!=Sie wurden von @1 gefangen
You tagged @1!=Sie haben @1 gefangen!

View File

@ -3,8 +3,10 @@ You exploded!=Felrobbantál!
exploded!=Felrobbant!
The new tagger is=Az új célpont
The new taggers are=Az új célpontok
You're the tagger!=
You're a tagger!=
Needed for tnttag=Sükséges a tnttag-hez
TNTTagger - Tag other players=TNTTagger Jelölj meg más játékosokat
@1 tagged @2=@1 megjelölte @2
You have been tagged by @1!=Megjelölt @1!
You tagged @1!=megjelölted @1-et!
You tagged @1!=megjelölted @1-et!

View File

@ -1,9 +1,36 @@
Black Vortex Kevin MacLeod (incompetech.com)(./Black_Vortex.ogg)
Licensed under Creative Commons: By Attribution 3.0 License
http://creativecommons.org/licenses/by/3.0/
---------------------
TumeniNodes (CC0 1.0)
tnt_explode.ogg
renamed, edited, and converted to .ogg from Explosion2.wav
by steveygos93 (CC0 1.0)
<https://freesound.org/s/80401/>
<https://freesound.org/s/80401/>
---------------------
tnttag_tag_given.ogg
CC0 1.0
based on a sound by Kenney Vleugels (www.kenney.nl)
edited by Wuzzy
---------------------
tnttag_tag_gotten.ogg
CC0 1.0
based on 'Ani Big Pipe Hit'
by ani_music
edited by Wuzzy
<https://freesound.org/people/ani_music/sounds/244983/>
---------------------
tnttag_timer.ogg
CC0 1.0
based on 'Beep warning'
by SamsterBirdies
edited by Wuzzy
<https://freesound.org/people/SamsterBirdies/sounds/467882/>

BIN
sounds/tnttag_tag_given.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
sounds/tnttag_timer.ogg Normal file

Binary file not shown.

43
textures/license.txt Normal file
View File

@ -0,0 +1,43 @@
tnt textures from minetest game:
---------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
Copyright (C) 2014-2016 BlockMen
Copyright (C) 2014-2016 ShadowNinja
Copyright (C) 2015-2016 Wuzzy
Copyright (C) 2016 sofar (sofar@foo-projects.org)
Copyright (C) 2018 paramat
You are free to:
Share — copy and redistribute the material in any medium or format.
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in any way
that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that
legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in the public
domain or where your use is permitted by an applicable exception or limitation.
No warranties are given. The license may not give you all of the permissions necessary
for your intended use. For example, other rights such as publicity, privacy, or moral
rights may limit how you use the material.
For more details:
http://creativecommons.org/licenses/by-sa/3.0/
-------------
Media:
tnt_bottom.png
tnt_side.png
tnt_top_burning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

BIN
textures/tnttag_scorch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B