141 lines
5.1 KiB
Lua
141 lines
5.1 KiB
Lua
--[[
|
|
Illarion Server
|
|
|
|
This program is free software: you can redistribute it and/or modify it under
|
|
the terms of the GNU Affero General Public License as published by the Free
|
|
Software Foundation, either version 3 of the License, or (at your option) any
|
|
later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License along
|
|
with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
]]
|
|
|
|
local common = require("base.common")
|
|
local character = require("base.character")
|
|
local M = {}
|
|
|
|
local function HitVictims(Posi,Hitpoints,CenterPos)
|
|
if world:isCharacterOnField(Posi) then
|
|
local explosionVictim = world:getCharacterOnField(Posi)
|
|
|
|
if (explosionVictim:getType() == 2) then --dont touch npcs
|
|
return
|
|
end
|
|
|
|
local Distance = explosionVictim:distanceMetricToPosition(CenterPos)
|
|
local Diffx = CenterPos.x - explosionVictim.pos.x
|
|
local Diffy = CenterPos.y - explosionVictim.pos.y
|
|
if (Distance == 1) then
|
|
Diffx = 4*Diffx
|
|
Diffy = 4*Diffy
|
|
elseif (Distance == 2) then
|
|
Diffx = 2*Diffx
|
|
Diffy = 2*Diffy
|
|
end
|
|
local posX = explosionVictim.pos.x - Diffx
|
|
local posY = explosionVictim.pos.y - Diffy
|
|
|
|
local listOfStuff = world:LoS(explosionVictim.pos, position(posX,posY,explosionVictim.pos.z))
|
|
|
|
if listOfStuff ~= nil then
|
|
local minDistance = explosionVictim:distanceMetricToPosition(position(posX,posY,explosionVictim.pos.z))
|
|
|
|
for _, listEntry in pairs(listOfStuff) do
|
|
local itemPos = listEntry.OBJECT.pos
|
|
local field = world:getField(itemPos)
|
|
local tempX = posX
|
|
local tempY = posY
|
|
-- something not passable is in the way, recalculate position
|
|
if not field:isPassable() then
|
|
|
|
local phi = common.GetPhi(explosionVictim.pos, itemPos)
|
|
if (phi < math.pi / 8) then
|
|
tempX = itemPos.x - 1
|
|
elseif (phi < 3 * math.pi / 8) then
|
|
tempX = itemPos.x - 1
|
|
tempY = itemPos.y - 1
|
|
elseif (phi < 5 * math.pi / 8) then
|
|
tempY = itemPos.y - 1
|
|
elseif (phi < 7 * math.pi / 8) then
|
|
tempX = itemPos.x + 1
|
|
tempY = itemPos.y - 1
|
|
elseif (phi < 9 * math.pi / 8) then
|
|
tempX = itemPos.x + 1
|
|
elseif (phi < 11 * math.pi / 8) then
|
|
tempX = itemPos.x + 1
|
|
tempY = itemPos.y + 1
|
|
elseif (phi < 13 * math.pi / 8) then
|
|
tempY = itemPos.y + 1
|
|
elseif (phi < 15 * math.pi / 8) then
|
|
tempX = itemPos.x - 1
|
|
tempY = itemPos.y + 1
|
|
else
|
|
tempX = itemPos.x - 1
|
|
end
|
|
|
|
local tempDistance = explosionVictim:distanceMetricToPosition(position(tempX,tempY,explosionVictim.pos.z))
|
|
if tempDistance < minDistance then
|
|
minDistance = tempDistance
|
|
posX = tempX
|
|
posY = tempY
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
explosionVictim:warp(position(posX,posY,explosionVictim.pos.z))
|
|
common.InformNLS(explosionVictim,
|
|
"Getroffen von der Detonation wirst du davon geschleudert.",
|
|
"Hit by the detonation, you get thrown away.")
|
|
character.ChangeHP(explosionVictim, -Hitpoints)
|
|
|
|
end
|
|
end
|
|
|
|
local function CreateExplosionCircle(HitPos,gfxid,Damage,CenterPos,setFlames)
|
|
|
|
world:gfx(gfxid,HitPos)
|
|
HitVictims(HitPos,Damage,CenterPos)
|
|
|
|
if setFlames then
|
|
if (math.random(1,5)==1) then
|
|
local field = world:getField(HitPos)
|
|
if field ~= nil and field:isPassable() then
|
|
world:createItemFromId(359,1,HitPos,true,math.random(200,600),nil)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--[[
|
|
CreateExplosion
|
|
Provide an explosion that also throws characters away, in a radios of 3 fields
|
|
@param integer - Center of the explosion
|
|
]]
|
|
function M.CreateExplosion(CenterPos)
|
|
local function CreateOuterCircle(HitPos)
|
|
CreateExplosionCircle(HitPos, 1,250,CenterPos,false)
|
|
return true
|
|
end
|
|
local function CreateMiddleCircle(HitPos)
|
|
CreateExplosionCircle(HitPos,9,750,CenterPos,true)
|
|
return true
|
|
end
|
|
local function CreateInnerCircle(HitPos)
|
|
CreateExplosionCircle(HitPos, 44,1000,CenterPos,true)
|
|
return true
|
|
end
|
|
|
|
common.CreateCircle(CenterPos, 3, CreateOuterCircle)
|
|
common.CreateCircle(CenterPos, 2, CreateMiddleCircle)
|
|
common.CreateCircle(CenterPos, 1, CreateInnerCircle)
|
|
world:gfx(36,CenterPos)
|
|
world:makeSound(5,CenterPos)
|
|
end
|
|
|
|
return M
|