Death Invincibility During the Round

Discussion in 'Deathrun Suggestions' started by veri, Nov 8, 2015.

  1. veri

    veri Creating Order VIP Silver

    Deaths should have invincibility until a runner completes the map. There are areas on some of the maps where it is possible for the death to become injured or even killed before the map is completed, leaving them at a disadvantage. Having this would also prevent the deaths from killing themselves to avoid their role.
     
    • Agree Agree x 1
  2. Steven

    Steven VIP Silver

    I agree, I noticed this yesterday when a death crowbarred me through a fence and I attempted to crowbar him back to which I was successful and killed him.
     
  3. ryan4win

    ryan4win I was supposed to do great things Banned VIP+ Silver

    I don't think this is possible, but if it is sure.
     
    • Optimistic Optimistic x 1
    • Creative Creative x 1
  4. Patrick

    Patrick Ex-Deathrun Administrator VIP Silver

    It's possible on maps like Spy vs Spy, as an example to steven. Also on maps like texture, if you fall down the ladder you can die.
    +1
     
    • Optimistic Optimistic x 1
  5. Paradox

    Paradox The One Eyed Ghoul Banned Elite

    Not much of a dr player but +1
     
  6. Tinbuster00

    Tinbuster00 See you on the forums! VIP Silver Emerald

    A deathrun server I used to play on before it shut down kept track of when runners finished the map just like how it's done on bhop servers. The death was invincible until someone got to the end of the map.

    A side effect of this was the server was also able to keep track of who finished first, their time, or if they finished at all. It awarded a small number of points based if you were first or second, and then less if you came later.

    Cool system but they had to figure out where to put the ending when they added maps or else the death was always invincible. Quick to do though.

    I think Highwon has been busy recently so not sure if he has the free time to implement something like this, but it was a cool system that would work well on this server +1
     
    • Agree Agree x 1
    • Useful Useful x 1
  7. Doodle Bop

    Doodle Bop Things always look impossible until they're done. VIP

    +1 because on that steam works map with the barrel part if the death is by the wall you can run into the barrel on purpose and kill the death through the wall.
     
  8. veri

    veri Creating Order VIP Silver

    It's possible to define an area as the "end of the map" and just give deaths invincibility until a runner reaches the end of the map. The downside is that new maps will have a small amount of configuring before they can be added to the rotation, and all current maps must be configured this way as well.

    I made a prototype addon today to accomplish this.

    Server Side
    Code:
    
    util.AddNetworkString("deathinv_areacreator")
    util.AddNetworkString("deathinv_receivearea")
    
    dinv = {}
    
    dinv.endArea = {}
    dinv.mapWon = false
    dinv.areaLoaded = false
    
    function dinv.LoadMap(map)
    	if file.Exists("dinv/" .. map .. ".txt", "DATA") then
    		MsgC(Color(0, 255, 0), "Loading endzone for " .. map .. "\n")
    
    		local dat = file.Read("dinv/" .. map .. ".txt", "DATA")
    
    		dat = util.Decompress(dat)
    
    		dinv.endArea = util.JSONToTable(dat)
    
    		dinv.areaLoaded = true
    	end
    end
    
    function dinv.SaveMap(map)
    	if not file.Exists("dinv", "DATA") then
    		file.CreateDir("dinv", "DATA")
    	end
    	local dat = util.TableToJSON(dinv.endArea)
    	dat = util.Compress(dat)
    	file.Write("dinv/" .. map .. ".txt", dat)
    end
    
    function dinv.NewRound()
    	dinv.mapWon = false
    	-- Disable god for everybody, just in case somebody still has it.
    	for k, v in pairs(player.GetAll()) do
    		v:GodDisable()
    	end
    
    	-- Get all deaths
    	local deaths = team.GetPlayers(TEAM_DEATH)
    
    	for k, v in pairs(deaths) do
    		v:GodEnable()
    	end
    end
    
    function dinv.EndRound()
    	for k, v in pairs(player.GetAll()) do
    		v:GodDisable()
    	end
    end
    
    function dinv.CheckEnd()
    	if not dinv.mapWon then
    		for k, v in pairs(team.GetPlayers(TEAM_RUNNER)) do
    			if IsValid(v) and v:Alive() then
    				if v:GetPos():WithinAABox(dinv.endArea.min, dinv.endArea.max) then
    					dinv.mapWon = true
    					PrintMessage(HUD_PRINTTALK, v:Nick() .. " has finished the map.")
    					dinv.EndRound()
    				end
    			end
    		end
    	end
    end
    
    -- Copy/paste function from an old project of mine. There's probably a way better method of doing this.
    -- "fixes" the areas so that low and high are actually the lowest and highest points.
    function dinv.FixArea(low, high)
    	local newLow, newHigh = {}, {}
    
    	if low[1] < high[1] then
    		newLow[1] = low[1]
    		newHigh[1] = high[1]
    	else
    		newLow[1] = high[1]
    		newHigh[1] = low[1]
    	end
    
    	if low[2] < high[2] then
    		newLow[2] = low[2]
    		newHigh[2] = high[2]
    	else
    		newLow[2] = high[2]
    		newHigh[2] = low[2]
    	end
    
    	if low[3] < high[3] then
    		newLow[3] = low[3]
    		newHigh[3] = high[3]
    	else
    		newLow[3] = high[3]
    		newHigh[3] = low[3]
    	end
    
    	return newLow, newHigh
    end
    
    hook.Add("OnRoundSet", "dinv.newround", function(round)
    	if round == ROUND_ACTIVE then
    		dinv.NewRound()
    	end
    end)
    
    hook.Add("Tick", "dinv.checkending", function()
    	if dinv.areaLoaded then
    		dinv.CheckEnd()
    	end
    end)
    
    dinv.LoadMap(game.GetMap())
    
    concommand.Add("endset", function(ply)
    	if not ply:IsSuperAdmin() then return end
    
    	net.Start("deathinv_areacreator")
    	net.Send(ply)
    end)
    
    concommand.Add("saveend", function(ply)
    	if not ply:IsSuperAdmin() then return end
    
    	if not dinv.endArea.min or not dinv.endArea.max then
    		ply:PrintMessage(HUD_PRINTTALK, "You must select the bounds of the area before saving it!")
    		ply:PrintMessage(HUD_PRINTTALK, "Use console command 'endset' to open the editor.")
    		return
    	end
    
    	ply:PrintMessage(HUD_PRINTTALK, "Fixing selection...")
    	local low, high = dinv.FixArea(dinv.endArea.min, dinv.endArea.max)
    	dinv.endArea.min = Vector(low[1], low[2], low[3])
    	dinv.endArea.max = Vector(high[1], high[2], high[3])
    
    	ply:PrintMessage(HUD_PRINTTALK, "Saving map...")
    	dinv.SaveMap(game.GetMap())
    
    	ply:PrintMessage(HUD_PRINTTALK, "Done!")
    end)
    
    net.Receive("deathinv_receivearea", function(len, ply)
    	if not ply:IsSuperAdmin() then return end
    
    	local minmax = net.ReadBool()
    	local vect = net.ReadVector()
    
    	if not vect then return end
    
    	if minmax then
    		dinv.endArea.min = vect
    	else
    		dinv.endArea.max = vect
    	end
    
    	ply:PrintMessage(HUD_PRINTTALK, "Set point " .. (minmax and "1" or "2") .. " @ " .. tostring(vect))
    end)
    

    Client Side

    Code:
    dinv = {}
    dinv.active = false
    
    function dinv.EnableAreaCreator()
    	dinv.active = true
    	hook.Add("HUDPaint", "dinv_ac_hud", function()
    		draw.RoundedBox( 0, 10, 50, 350, 300, Color( 0, 0, 0, 128 ) )
    		draw.RoundedBox(0, ScrW() / 2 - 20, ScrH() / 2, 40, 1, Color(255, 0, 0, 255))
    		draw.RoundedBox(0, ScrW() / 2, ScrH() / 2 - 20, 1, 40, Color(255, 0, 0, 255))
    
    		local txt = ""
    
    		local trace = LocalPlayer():GetEyeTrace()
    
    		for k, v in pairs(trace) do
    			txt = txt .. k .. ": " .. tostring(v) .. "\n"
    		end
    
    		draw.DrawText(txt, "DebugFixed", 17, 80, Color(255, 255, 255, 255))
    
    		draw.DrawText("Area Editor", "DebugFixed", 17, 57, Color(255, 255, 255, 255))
    	end)
    
    	hook.Add("PlayerBindPress", "dinv_ac_bp", function(ply, bind, pressed)
    		if bind == "+attack" then
    			dinv.SendArea(true, LocalPlayer():GetEyeTrace().HitPos)
    		end
    
    		if bind == "+attack2" then
    			dinv.SendArea(false, LocalPlayer():GetEyeTrace().HitPos)
    		end
    	end)
    end
    
    function dinv.SendArea(minmax, vect)
    	net.Start("deathinv_receivearea")
    		net.WriteBool(minmax)
    		net.WriteVector(vect)
    	net.SendToServer()
    end
    
    function dinv.DisableAreaCreator()
    	dinv.active = false
    end
    
    net.Receive("deathinv_areacreator", function()
    
    	if not dinv.active then dinv.EnableAreaCreator() else dinv.DisableAreaCreator() end
    end)

    This can be further written into a time tracker and "record time" keeper, since those would most likely use a similar region system.
     
    • Like Like x 3
  9. Viral☣

    Viral☣ I'm the hero that Deathrun deserves! VIP Silver

    I would like to see this implemented because I am now seeing a big amount of people death avoiding because we do not have this on our server.