add support for different attack states

add support for mob <-> mob combat
This commit is contained in:
sapier 2013-02-03 12:50:56 +00:00
parent 286207cef6
commit f092801511

View File

@ -115,41 +115,35 @@ end
--! @param entity mob being hit
--! @param player player/object hitting the mob
-------------------------------------------------------------------------------
function fighting.hit(entity,player)
function fighting.hit(entity,attacker)
--execute user defined on_hit_callback
if entity.data.generic.on_hit_callback ~= nil and
entity.data.generic.on_hit_callback(entity,player) == true
entity.data.generic.on_hit_callback(entity,attacker) == true
then
dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name .. " custom on hit handler superseeds generic handling")
return
end
--TODO calculate damage by players weapon
--local damage = 1
--dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name .. " about to take ".. damage .. " damage")
--entity.dynamic_data.generic.health = entity.dynamic_data.generic.health - damage
--entity.object:set_hp(entity.object:get_hp() - damage )
--get some base information
local mob_pos = entity.object:getpos()
local mob_pos = entity.object:getpos()
local mob_basepos = entity.getbasepos(entity)
local playerpos = player:getpos()
local dir = mobf_get_direction(playerpos,mob_basepos)
local targetpos = attacker:getpos()
local dir = mobf_get_direction(targetpos,mob_basepos)
--update mob orientation
--look towards attacker
if entity.mode == "3d" then
entity.object:setyaw(mobf_calc_yaw(dir.x,dir.z)+math.pi)
else
entity.object:setyaw(mobf_calc_yaw(dir.x,dir.z)-math.pi)
end
--play hit sound
if entity.data.sound ~= nil then
sound.play(mob_pos,entity.data.sound.hit);
end
--push mob back
fighting.push_back(entity,dir)
-- make it die
@ -163,23 +157,23 @@ function fighting.hit(entity,player)
--call on kill callback and superseed normal on kill handling
if entity.data.generic.on_kill_callback == nil or
entity.data.generic.on_kill_callback(entity,player) == false
entity.data.generic.on_kill_callback(entity,attacker) == false
then
if entity.data.sound ~= nil then
sound.play(mob_pos,entity.data.sound.die);
end
if player:is_player() then
if attacker:is_player() then
if type(result) == "table" then
for i=1,#result, 1 do
if player:get_inventory():room_for_item("main", result[i]) then
player:get_inventory():add_item("main", result[i])
if attacker:get_inventory():room_for_item("main", result[i]) then
attacker:get_inventory():add_item("main", result[i])
end
end
else
if player:get_inventory():room_for_item("main", result) then
player:get_inventory():add_item("main", result)
if attacker:get_inventory():room_for_item("main", result) then
attacker:get_inventory():add_item("main", result)
end
end
else
@ -202,22 +196,65 @@ function fighting.hit(entity,player)
dbg_mobf.fighting_lvl2("MOBF: mob with chance of fighting back attacked")
--either the mob hasn't been attacked by now or a new player joined fight
local playername = player.get_player_name(player)
if entity.dynamic_data.combat.target ~= playername then
if entity.dynamic_data.combat.target ~= attacker then
dbg_mobf.fighting_lvl2("MOBF: new player started fight")
--calculate chance of mob fighting back
if math.random() < entity.data.combat.angryness then
dbg_mobf.fighting_lvl2("MOBF: fighting back player "..playername)
entity.dynamic_data.combat.target = playername
local attackername = fighting.get_target_name(attacker)
dbg_mobf.fighting_lvl2("MOBF: fighting back player "..attackername)
entity.dynamic_data.combat.target = attacker
fighting.switch_to_combat_state(entity,mobf_get_current_time(),player)
fighting.switch_to_combat_state(entity,mobf_get_current_time(),attacker)
end
end
end
end
-------------------------------------------------------------------------------
-- name: identify_combat_state(entity,target,distance)
--
--! @brief identify combat state to use
--! @memberof fighting
--! @private
--
--! @param entity mob to find state for
--! @param distance distance to target
--
--! @return state tu use
-------------------------------------------------------------------------------
function fighting.identify_combat_state(entity,target,distance)
mobf_assert_backtrace(entity ~= nil)
mobf_assert_backtrace(target ~= nil)
local combat_melee = mob_state.get_state_by_name(entity,"combat_melee")
local combat_distance = mob_state.get_state_by_name(entity,"combat_distance")
local combat_generic = mob_state.get_state_by_name(entity,"combat")
if distance == nil then
local mob_pos = entity.object:getpos()
local targetpos = target:getpos()
distance = mobf_calc_distance(mob_pos,targetpos)
end
if combat_melee ~= nil and
distance < entity.data.combat.melee.range then
return combat_melee
end
if combat_distance and
entity.data.combat.distance ~= nil and
distance < entity.data.combat.distance.range and
(entity.data.combat.distance.min_range == nil or
distance > entity.data.combat.distance.min_range) then
-- distance within mele range
return combat_distance
end
return combat_generic
end
-------------------------------------------------------------------------------
-- name: switch_to_combat_state(entity,now,target)
--
@ -230,13 +267,16 @@ end
--! @param target the target to attack
-------------------------------------------------------------------------------
function fighting.switch_to_combat_state(entity,now,target)
local combat_state = mob_state.get_state_by_name(entity,"combat")
mobf_assert_backtrace(entity ~= nil)
--precheck
if target == nil then
dbg_mobf.fighting_lvl2("MOBF: no target for combat state change specified")
return
end
local combat_state = fighting.identify_combat_state(entity,target)
if combat_state == nil then
dbg_mobf.fighting_lvl2("MOBF: no special combat state")
return
@ -259,7 +299,7 @@ function fighting.switch_to_combat_state(entity,now,target)
end
--save old movement data to use on switching back
entity.dynamic_data.movement.backup = backup
entity.dynamic_data.combat.movement_backup = backup
--set target
entity.dynamic_data.movement.target = target
@ -285,8 +325,9 @@ end
function fighting.restore_previous_state(entity,now)
--check if ther is anything we can restore
if entity.dynamic_data.movement.backup ~= nil then
local backup = entity.dynamic_data.movement.backup
if entity.dynamic_data.combat.movement_backup ~= nil then
local backup = entity.dynamic_data.combat.movement_backup
local newentity = nil
if backup.current_state ~= nil then
@ -305,14 +346,46 @@ function fighting.restore_previous_state(entity,now)
entity.dynamic_data.movement = backup
--make sure all remaining data is deleted
entity.dynamic_data.movement.backup = nil
entity.dynamic_data.movement.current_state = nil
entity.dynamic_data.combat.movement_backup = nil
end
--make sure state is unlocked
mob_state.lock(entity,false)
end
-------------------------------------------------------------------------------
-- name: restore_previous_state(entity,now)
--
--! @brief check if mob is within range of target
--! @memberof fighting
--! @private
--
--! @param entity mob
--! @param distance to target
-------------------------------------------------------------------------------
function fighting.in_range(entity,distance)
if (entity.data.combat.melee == nil or
distance > entity.data.combat.melee.range) and
(entity.data.combat.distance == nil or
distance > entity.data.combat.distance.range) then
if entity.data.combat.melee ~= nil or
entity.data.combat.distance ~= nil then
dbg_mobf.fighting_lvl2("MOBF: distance="..distance)
if entity.data.combat.melee ~= nil then
dbg_mobf.fighting_lvl2("MOBF: melee="..entity.data.combat.melee.range)
end
if entity.data.combat.distance ~= nil then
dbg_mobf.fighting_lvl2("MOBF: distance="..entity.data.combat.distance.range)
end
end
return false
end
return true
end
-------------------------------------------------------------------------------
-- name: combat(entity,now)
--
@ -326,34 +399,39 @@ function fighting.combat(entity,now)
--handle self destruct mobs
if fighting.self_destruct_handler(entity,now) then
return
return false
end
if entity.dynamic_data.combat ~= nil and
entity.dynamic_data.combat.target ~= "" then
dbg_mobf.fighting_lvl1("MOBF: attacking player: "..entity.dynamic_data.combat.target)
local player = minetest.env:get_player_by_name(entity.dynamic_data.combat.target)
entity.dynamic_data.combat.target ~= nil then
--check if target is still valid
if player == nil then
dbg_mobf.fighting_lvl3("MOBF: not a valid player")
if not entity.dynamic_data.combat.target:is_player() and
entity.dynamic_data.combat.target.data == nil then
dbg_mobf.fighting_lvl3("MOBF: not a valid target")
-- switch back to default movement gen
fighting.restore_previous_state(entity,now)
--there is no player by that name, stop attack
entity.dynamic_data.combat.target = ""
return
entity.dynamic_data.combat.target = nil
return true
end
--calculate some basic data
local mob_pos = entity.object:getpos()
local playerpos = player:getpos()
local distance = mobf_calc_distance(mob_pos,playerpos)
local targetname =
fighting.get_target_name(entity.dynamic_data.combat.target)
dbg_mobf.fighting_lvl1("MOBF: attacking player: "
..targetname)
--calculate some basic data
local mob_pos = entity.object:getpos()
local targetpos = entity.dynamic_data.combat.target:getpos()
local distance = mobf_calc_distance(mob_pos,targetpos)
--initiate self destruct
fighting.self_destruct_trigger(entity,distance,now)
--find out if player is next to mob
@ -367,55 +445,57 @@ function fighting.combat(entity,now)
fighting.restore_previous_state(entity,now)
--there is no player by that name, stop attack
entity.dynamic_data.combat.target = ""
return
entity.dynamic_data.combat.target = nil
return true
end
--is mob near enough for any attack attack?
if (entity.data.combat.melee == nil or
distance > entity.data.combat.melee.range) and
(entity.data.combat.distance == nil or
distance > entity.data.combat.distance.range) then
if entity.data.combat.melee ~= nil or
entity.data.combat.distance ~= nil then
dbg_mobf.fighting_lvl2("MOBF: distance="..distance)
if entity.data.combat.melee ~= nil then
dbg_mobf.fighting_lvl2("MOBF: melee="..entity.data.combat.melee.range)
end
if entity.data.combat.distance ~= nil then
dbg_mobf.fighting_lvl2("MOBF: distance="..entity.data.combat.distance.range)
end
if not fighting.in_range(entity,distance) then
return true
end
--check if state needs to be switched
local required_state = fighting.identify_combat_state(entity,
entity.dynamic_data.combat.target,distance)
if required_state ~= nil then
local newentity = mob_state.change_state(entity,required_state)
--if we just changed entity abort this handler
if newentity ~= nil then
return false
end
return
end
if fighting.melee_attack_handler(entity,player,now,distance) == false then
if fighting.distance_attack_handler(entity,playerpos,mob_pos,now,distance) then
--check if melee attack can be done
if fighting.melee_attack_handler(entity,
entity.dynamic_data.combat.target,now,distance) == false then
--check if distance attack can be done
if fighting.distance_attack_handler(entity,
targetpos,mob_pos,now,distance) then
-- mob did an attack so give chance to stop attack
local rand_value = math.random()
local rand_value = math.random()
if rand_value > entity.data.combat.angryness then
dbg_mobf.fighting_lvl2("MOBF: rand=".. rand_value
.. " angryness=" .. entity.data.combat.angryness)
dbg_mobf.fighting_lvl2("MOBF: " .. entity.data.name .. " "
.. now .. " random aborting attack at player "
..entity.dynamic_data.combat.target)
entity.dynamic_data.combat.target = ""
.. now .. " random aborting attack at "
..targetname)
entity.dynamic_data.combat.target = nil
end
end
end
end
--fight against generic enemy "sun"
fighting.sun_damage_handler(entity,now)
if fighting.sun_damage_handler(entity,now) then
return false
end
return true
end
-------------------------------------------------------------------------------
@ -440,7 +520,7 @@ function fighting.get_target(entity)
for i,v in ipairs(objectlist) do
local playername = v.get_player_name(v)
local playername = v.get_player_name(v)
if playername ~= nil and
playername ~= "" then
@ -512,8 +592,7 @@ function fighting.aggression(entity,now)
--mob is specified as self attacking
if entity.data.combat.starts_attack and
(entity.dynamic_data.combat.target == nil or
entity.dynamic_data.combat.target == "") then
entity.dynamic_data.combat.target == nil then
dbg_mobf.fighting_lvl3("MOBF: ".. entity.data.name .. " " .. now
.. " aggressive mob, is it time to attack?")
if entity.dynamic_data.combat.ts_last_aggression_chance + 1 < now then
@ -528,17 +607,20 @@ function fighting.aggression(entity,now)
local target = fighting.get_target(entity)
if target ~= nil then
local targetname = target.get_player_name(target)
if target ~= entity.dynamic_data.combat.target then
if targetname ~= entity.dynamic_data.combat.target then
entity.dynamic_data.combat.target = targetname
entity.dynamic_data.combat.target = target
fighting.switch_to_combat_state(entity,now,target)
fighting.switch_to_combat_state(entity,now,target)
local targetname = fighting.get_target_name(target)
dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name .. " "
.. now .. " starting attack at player: " ..targetname)
minetest.log(LOGLEVEL_INFO,"MOBF: starting attack at player "..targetname)
.. now .. " starting attack at player: "
..targetname)
minetest.log(LOGLEVEL_INFO,
"MOBF: starting attack at player "..targetname)
end
end
end
@ -556,14 +638,13 @@ end
--! @param now current time
-------------------------------------------------------------------------------
function fighting.init_dynamic_data(entity,now)
local targetstring = ""
local data = {
ts_last_sun_damage = now,
ts_last_attack = now,
ts_last_attack = now,
ts_last_aggression_chance = now,
ts_self_destruct_triggered = -1,
ts_self_destruct_triggered = -1,
target = targetstring,
target = nil,
}
entity.dynamic_data.combat = data
@ -582,21 +663,21 @@ end
--! @return true/false if handled or not
-------------------------------------------------------------------------------
function fighting.self_destruct_trigger(entity,distance,now)
if entity.data.combat ~= nil and
entity.data.combat.self_destruct ~= nil then
if entity.data.combat ~= nil and
entity.data.combat.self_destruct ~= nil then
dbg_mobf.fighting_lvl1("MOBF: checking for self destruct trigger " ..
distance .. " " ..
entity.dynamic_data.combat.ts_self_destruct_triggered ..
" " .. now)
dbg_mobf.fighting_lvl1("MOBF: checking for self destruct trigger " ..
distance .. " " ..
entity.dynamic_data.combat.ts_self_destruct_triggered ..
" " .. now)
--trigger self destruct
if distance <= entity.data.combat.self_destruct.range and
entity.dynamic_data.combat.ts_self_destruct_triggered == -1 then
dbg_mobf.fighting_lvl2("MOBF: self destruct triggered")
entity.dynamic_data.combat.ts_self_destruct_triggered = now
end
--trigger self destruct
if distance <= entity.data.combat.self_destruct.range and
entity.dynamic_data.combat.ts_self_destruct_triggered == -1 then
dbg_mobf.fighting_lvl2("MOBF: self destruct triggered")
entity.dynamic_data.combat.ts_self_destruct_triggered = now
end
end
end
-------------------------------------------------------------------------------
-- name: self_destruct_handler(entity)
@ -610,62 +691,62 @@ end
--! @return true/false if handled or not
-------------------------------------------------------------------------------
function fighting.self_destruct_handler(entity,now)
--self destructing mob?
if entity.data.combat ~= nil and
entity.data.combat.self_destruct ~= nil then
--self destructing mob?
if entity.data.combat ~= nil and
entity.data.combat.self_destruct ~= nil then
local pos = entity.object:getpos()
local pos = entity.object:getpos()
dbg_mobf.fighting_lvl1("MOBF: checking for self destruct imminent")
--do self destruct
if entity.dynamic_data.combat.ts_self_destruct_triggered > 0 and
entity.dynamic_data.combat.ts_self_destruct_triggered +
entity.data.combat.self_destruct.delay
<= now then
dbg_mobf.fighting_lvl2("MOBF: executing self destruct")
if entity.data.sound ~= nil then
sound.play(pos,entity.data.sound.self_destruct);
end
mobf_do_area_damage(pos,nil,
entity.data.combat.self_destruct.damage,
entity.data.combat.self_destruct.range)
--TODO determine block removal by damage and remove blocks
mobf_do_node_damage(pos,{},
entity.data.combat.self_destruct.node_damage_range,
1 - 1/entity.data.combat.self_destruct.node_damage_range)
if mobf_rtd.fire_enabled then
--Add fire
for i=pos.x-entity.data.combat.self_destruct.range/2,
pos.x+entity.data.combat.self_destruct.range/2, 1 do
for j=pos.y-entity.data.combat.self_destruct.range/2,
pos.y+entity.data.combat.self_destruct.range/2, 1 do
for k=pos.z-entity.data.combat.self_destruct.range/2,
pos.z+entity.data.combat.self_destruct.range/2, 1 do
local current = minetest.env:get_node({x=i,y=j,z=k})
if (current.name == "air") then
minetest.env:set_node({x=i,y=j,z=k}, {name="fire:basic_flame"})
end
end
end
end
else
minetest.log(LOGLEVEL_NOTICE,"MOBF: self destruct without fire isn't really impressive!")
end
spawning.remove(entity, "self destruct")
return true
dbg_mobf.fighting_lvl1("MOBF: checking for self destruct imminent")
--do self destruct
if entity.dynamic_data.combat.ts_self_destruct_triggered > 0 and
entity.dynamic_data.combat.ts_self_destruct_triggered +
entity.data.combat.self_destruct.delay
<= now then
dbg_mobf.fighting_lvl2("MOBF: executing self destruct")
if entity.data.sound ~= nil then
sound.play(pos,entity.data.sound.self_destruct);
end
mobf_do_area_damage(pos,nil,
entity.data.combat.self_destruct.damage,
entity.data.combat.self_destruct.range)
--TODO determine block removal by damage and remove blocks
mobf_do_node_damage(pos,{},
entity.data.combat.self_destruct.node_damage_range,
1 - 1/entity.data.combat.self_destruct.node_damage_range)
if mobf_rtd.fire_enabled then
--Add fire
for i=pos.x-entity.data.combat.self_destruct.range/2,
pos.x+entity.data.combat.self_destruct.range/2, 1 do
for j=pos.y-entity.data.combat.self_destruct.range/2,
pos.y+entity.data.combat.self_destruct.range/2, 1 do
for k=pos.z-entity.data.combat.self_destruct.range/2,
pos.z+entity.data.combat.self_destruct.range/2, 1 do
local current = minetest.env:get_node({x=i,y=j,z=k})
if (current.name == "air") then
minetest.env:set_node({x=i,y=j,z=k},
{name="fire:basic_flame"})
end
end
end
end
else
minetest.log(LOGLEVEL_NOTICE,
"MOBF: self destruct without fire isn't really impressive!")
end
spawning.remove(entity, "self destruct")
return true
end
return false
end
return false
end
-------------------------------------------------------------------------------
@ -681,47 +762,50 @@ end
--! @param distance distance to player
--! @return true/false if handled or not
-------------------------------------------------------------------------------
function fighting.melee_attack_handler(entity,player,now,distance)
function fighting.melee_attack_handler(entity,target,now,distance)
if entity.data.combat.melee == nil then
dbg_mobf.fighting_lvl2("MOBF: no meele attack specified")
return false
end
local time_of_next_attack_chance = entity.dynamic_data.combat.ts_last_attack
+ entity.data.combat.melee.speed
--check if mob is ready to attack
if now < time_of_next_attack_chance then
dbg_mobf.fighting_lvl1("MOBF: to early for meele attack " ..
now .. " >= " .. time_of_next_attack_chance)
return false
end
if distance <= entity.data.combat.melee.range
then
--save time of attack
entity.dynamic_data.combat.ts_last_attack = now
if entity.data.sound ~= nil then
sound.play(entity.object:getpos(),entity.data.sound.melee);
end
--calculate damage to be done
local damage_done = math.floor(math.random(0,entity.data.combat.melee.maxdamage)) + 1
local player_health = player:get_hp()
--do damage
player:set_hp(player_health -damage_done)
dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name ..
" doing melee attack damage=" .. damage_done)
return true
end
dbg_mobf.fighting_lvl1("MOBF: not within meele range " ..
distance .. " > " .. entity.data.combat.melee.range)
if entity.data.combat.melee == nil then
dbg_mobf.fighting_lvl2("MOBF: no meele attack specified")
return false
end
local time_of_next_attack_chance = entity.dynamic_data.combat.ts_last_attack
+ entity.data.combat.melee.speed
--check if mob is ready to attack
if now < time_of_next_attack_chance then
dbg_mobf.fighting_lvl1("MOBF: to early for meele attack " ..
now .. " >= " .. time_of_next_attack_chance)
return false
end
if distance <= entity.data.combat.melee.range
then
--save time of attack
entity.dynamic_data.combat.ts_last_attack = now
if entity.data.sound ~= nil then
sound.play(entity.object:getpos(),entity.data.sound.melee);
end
--calculate damage to be done
local damage_done =
math.floor(math.random(0,entity.data.combat.melee.maxdamage)) + 1
--TODO call punch instead of manually setting health
local target_health = target:get_hp()
--do damage
target:set_hp(target_health -damage_done)
dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name ..
" doing melee attack damage=" .. damage_done)
return true
end
dbg_mobf.fighting_lvl1("MOBF: not within meele range " ..
distance .. " > " .. entity.data.combat.melee.range)
return false
end
@ -733,13 +817,13 @@ end
--! @private
--
--! @param entity mob to do action
--! @param playerpos position of target
--! @param targetpos position of target
--! @param mob_pos position of mob
--! @param now current time
--! @param distance distance between target and player
--! @return true/false if handled or not
-------------------------------------------------------------------------------
function fighting.distance_attack_handler(entity,playerpos,mob_pos,now,distance)
function fighting.distance_attack_handler(entity,targetpos,mob_pos,now,distance)
if entity.data.combat.distance == nil then
dbg_mobf.fighting_lvl2("MOBF: no distance attack specified")
return false
@ -758,7 +842,8 @@ function fighting.distance_attack_handler(entity,playerpos,mob_pos,now,distance)
if distance <= entity.data.combat.distance.range
then
dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name .. " doing distance attack")
dbg_mobf.fighting_lvl2("MOBF: ".. entity.data.name ..
" doing distance attack")
--save time of attack
entity.dynamic_data.combat.ts_last_attack = now
@ -767,7 +852,7 @@ function fighting.distance_attack_handler(entity,playerpos,mob_pos,now,distance)
y=mob_pos.y+1,
z=mob_pos.z
},
playerpos)
targetpos)
if entity.data.sound ~= nil then
sound.play(mob_pos,entity.data.sound.distance);
@ -791,7 +876,8 @@ function fighting.distance_attack_handler(entity,playerpos,mob_pos,now,distance)
z=dir.z*thrown_entity.velocity
}
dbg_mobf.fighting_lvl2("MOBF: throwing with velocity: " .. printpos(vel_trown))
dbg_mobf.fighting_lvl2("MOBF: throwing with velocity: " ..
printpos(vel_trown))
newobject:setvelocity(vel_trown)
@ -800,12 +886,14 @@ function fighting.distance_attack_handler(entity,playerpos,mob_pos,now,distance)
dbg_mobf.fighting_lvl2("MOBF: distance attack issued")
else
minetest.log(LOGLEVEL_ERROR, "MOBF: unable to find entity for distance attack")
minetest.log(LOGLEVEL_ERROR,
"MOBF: unable to find entity for distance attack")
end
return true
end
dbg_mobf.fighting_lvl1("MOBF: not within distance range " ..
distance .. " > " .. entity.data.combat.distance.range)
distance .. " > " ..
entity.data.combat.distance.range)
return false
end
@ -819,19 +907,22 @@ end
--
--! @param entity mob to do action
--! @param now current time
--
--! @return true/false if killed or not
-------------------------------------------------------------------------------
function fighting.sun_damage_handler(entity,now)
if entity.data.combat ~= nil and
entity.data.combat.sun_sensitive then
local pos = entity.object:getpos()
local current_state = mob_state.get_state_by_name(entity,entity.dynamic_data.state.current)
local current_state = mob_state.get_state_by_name(entity,
entity.dynamic_data.state.current)
local current_light = minetest.env:get_node_light(pos)
if current_light == nil then
minetest.log(LOGLEVEL_ERROR,"MOBF: Bug!!! didn't get a light value for "
.. printpos(pos))
return
return false
end
--check if mob is in sunlight
if ( current_light > LIGHT_MAX) then
@ -862,12 +953,13 @@ function fighting.sun_damage_handler(entity,now)
--if entity.dynamic_data.generic.health <= 0 then
dbg_mobf.fighting_lvl2("Mob ".. entity.data.name .. " died of sun")
spawning.remove(entity,"died by sun")
return
return true
end
entity.dynamic_data.combat.ts_last_sun_damage = now
end
else
--use last sun damage to avoid setting animation over and over even if nothing changed
--use last sun damage to avoid setting animation over and over
--even if nothing changed
if entity.dynamic_data.combat.ts_last_sun_damage ~= -1 and
current_state.animation ~= nil then
graphics.set_animation(entity,current_state.animation)
@ -875,4 +967,24 @@ function fighting.sun_damage_handler(entity,now)
end
end
end
return false
end
function fighting.get_target_name(target)
if target == nil then
return "invalid"
end
if target:is_player() then
return target:get_player_name()
else
if target.data ~= nil and
target.data.name ~= nil then
return "MOB: " .. attacker.data.name
end
end
return "unknown"
end