1+ -- local bc = better_commands
2+
3+ --- Deals damage; copied from Mineclonia's mcl_util.deal_damage
4+ --- @param target minetest.ObjectRef
5+ --- @param damage integer
6+ --- @param reason table ?
7+ --- @param damage_immortal ? boolean
8+ function better_commands .deal_damage (target , damage , reason , damage_immortal )
9+ local luaentity = target :get_luaentity ()
10+
11+ if luaentity then
12+ if luaentity .deal_damage then -- Mobs Redo/Mobs MC
13+ luaentity :deal_damage (damage , reason or {type = " generic" })
14+ minetest .log (" deal_damage" )
15+ return
16+ elseif luaentity .hurt then -- Animalia
17+ luaentity :hurt (damage )
18+ minetest .log (" hurt" )
19+ luaentity :indicate_damage ()
20+ return
21+ elseif luaentity .health then -- Mobs Redo/Mobs MC/NSSM
22+ -- local puncher = mcl_reason and mcl_reason.direct or target
23+ -- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage)
24+ if luaentity .health > 0 then
25+ minetest .log (" luaentity.health" )
26+ luaentity .health = luaentity .health - damage
27+ end
28+ return
29+ end
30+ end
31+
32+ local hp = target :get_hp ()
33+ local armorgroups = target :get_armor_groups ()
34+
35+ if hp > 0 and armorgroups and (damage_immortal or not armorgroups .immortal ) then
36+ minetest .log (" set_hp" )
37+ target :set_hp (hp - damage , reason )
38+ end
39+ end
40+
41+ minetest .register_on_dieplayer (function (player , reason )
42+ local player_name = player :get_player_name ()
43+ for _ , def in pairs (better_commands .scoreboard .objectives ) do
44+ if def .criterion == " deathCount" then
45+ if def .scores [player_name ] then
46+ def .scores [player_name ].score = def .scores [player_name ].score + 1
47+ end
48+ end
49+ end
50+ local killer
51+ if reason ._mcl_reason then
52+ killer = reason ._mcl_reason .source
53+ else
54+ killer = reason .object
55+ end
56+ if killer and killer :is_player () then
57+ local player_name = player :get_player_name ()
58+ local killer_name = killer :get_player_name ()
59+ local player_team = better_commands .teams .players [player_name ]
60+ local killer_team = better_commands .teams .players [killer_name ]
61+ for _ , def in pairs (better_commands .scoreboard .objectives ) do
62+ if def .criterion == " playerKillCount" or (player_team and def .criterion == " teamkill." .. player_team ) then
63+ if def .scores [killer_name ] then
64+ def .scores [killer_name ].score = def .scores [killer_name ].score + 1
65+ end
66+ elseif killer_team and def .criterion == " killedByTeam." .. killer_team then
67+ if def .scores [player_name ] then
68+ def .scores [player_name ].score = def .scores [player_name ].score + 1
69+ end
70+ elseif def .criterion == " killed_by.player" then
71+ if def .scores [player_name ] then
72+ def .scores [player_name ].score = def .scores [player_name ].score + 1
73+ end
74+ end
75+ end
76+ elseif killer then
77+ local killer_type = killer :get_luaentity ().name
78+ for _ , def in pairs (better_commands .scoreboard .objectives ) do
79+ local killed_by = def .criterion :match (" ^killed_by%.(.*)$" )
80+ if killed_by and (killer_type == killed_by or
81+ (better_commands .entity_aliases [killer_type ] and better_commands .entity_aliases [killer_type ][killed_by ])) then
82+ if def .scores [player_name ] then
83+ def .scores [player_name ].score = def .scores [player_name ].score + 1
84+ end
85+ end
86+ end
87+ end
88+ end )
89+
90+ -- Make sure players always die when /killed, also track hp
91+ minetest .register_on_player_hpchange (function (player , hp_change , reason )
92+ if reason .better_commands == " kill" then
93+ return - player :get_properties ().hp_max , true
94+ end
95+ local player_name = player :get_player_name ()
96+ for _ , def in pairs (better_commands .scoreboard .objectives ) do
97+ if def .criterion == " health" then
98+ if def .scores [player_name ] then
99+ minetest .after (0 , function () def .scores [player_name ].score = player :get_hp () end )
100+ end
101+ end
102+ end
103+ if hp_change < 0 then
104+ local attacker
105+ if reason ._mcl_reason then
106+ attacker = reason ._mcl_reason .source
107+ else
108+ attacker = reason .object
109+ end
110+ if attacker and attacker :is_player () then
111+ local player_name = player :get_player_name ()
112+ local attacker_name = attacker :get_player_name ()
113+ local player_team = better_commands .teams .players [player_name ]
114+ local attacker_team = better_commands .teams .players [attacker_name ]
115+ if player_team == attacker_team then
116+ if better_commands .teams .teams [player_team ].pvp == false then
117+ return 0 , true
118+ end
119+ end
120+ end
121+ end
122+ return hp_change
123+ end , true )
0 commit comments