Dynamic Fire (Smart Fire)

Could anyone code a system for dealing with Fires similar to that of PERP’s, exluding the excesive smoke effects. If you havent played PERP, the fires spread to the world and I think it checks the materials of props/TheWorld to see if it can spread or something similar to that.

IE: The fire would spread rapidly on wood/grass, and not at all on concrete.

This might be possible with a map built for it, but I don’t think regular brushes have a material type that you could compare to to set them on fire. I think there are a few addons like this for props, but I don’t know about the world. I think Jinto (or one of the Lua Gods from way back when) had a SmartFire addon that is sort of like what you’re lookin for, but I think that project died long ago.

I agree. the code probably would have to specify what kinds of materials can set on fire. Imagine someone setting fire to flatgrass…
but then again, it would probably be set to burn a certain radius of the grass, instead of immedeatley engulfing that face of the brush with fire.

It can be done with Trace.MatType, should be simple to make really.

Would you be willing to code it?

I dont know if different parts of the world return different MatTypes - and the problem with that is recursive traces for spreading the fire can lag your game down pretty fast if you have enough of them (not to mention it would also be a pain to do it that way)

Nah, sorry to lazy atm ;#

The traces is serverside, so how would that lag you down?

If the server is running slow, that will slow you down as well.
Think of it this way, if the server is running slow it cant recieve/send data as fast, so it cant interact with you (the client) as fast

all the fire has to do is see if the textures material is set to wood/grass. you wouldent need to make it go by texture, just material.

Depends if you want it to look good or not.

Would anyone be willing create the script?

Bump

Did anyone make this in the end? Would really be nice on my RP server :smiley:

cl_init.lua
[lua]
///////////////////////////////
// © 2009-2010 Pulsar Effect //
// All rights reserved //
///////////////////////////////
// This material may not be //
// reproduced, displayed, //
// modified or distributed //
// without the express prior //
// written permission of the //
// the copyright holder. //
///////////////////////////////

include(‘shared.lua’)

function ENT:Draw()
end

function ENT:Think ( )
if !LocalPlayer():CanSee(self) and !LocalPlayer():InVehicle() then return false; end
if self.LastEffect + .15 < CurTime() then
self.LastEffect = CurTime();

	local effect = EffectData();
		effect:SetOrigin(self:GetPos());
	util.Effect("fire_ent", effect);
end

if self.LastPlayTime + self.InBetween &lt; CurTime() then
	self.SoundEffect:Stop();
	self.SoundEffect:Play();
	self.LastPlayTime = CurTime();
end

end

function ENT:Initialize ( )
self.LastEffect = CurTime();

self.SoundID = math.random(1, 2);

if self.SoundID == 1 then
	self.SoundEffect = CreateSound(self, Sound('ambient/fire/fire_med_loop1.wav'));
	self.InBetween = 6.5;
elseif self.SoundID == 2 then
	self.SoundEffect = CreateSound(self, Sound('ambient/fire/firebig.wav'));
	self.InBetween = 5;
else
	self.SoundEffect = CreateSound(self, Sound('ambient/fire/fire_big_loop1.wav'));
	self.InBetween = 5;
end

self.LastPlayTime = 0;

end

function ENT:OnRemove ( )
self.SoundEffect:Stop();
end

[/lua]

shared.lua
[lua]
///////////////////////////////
// © 2009-2010 Pulsar Effect //
// All rights reserved //
///////////////////////////////
// This material may not be //
// reproduced, displayed, //
// modified or distributed //
// without the express prior //
// written permission of the //
// the copyright holder. //
///////////////////////////////

ENT.Type = “anim”
ENT.Base = “base_anim”

ENT.PrintName = “”
ENT.Author = “”
ENT.Contact = “”
ENT.Purpose = “”
ENT.Instructions = “”
[/lua]

init.lua
[lua]
///////////////////////////////
// © 2009-2010 Pulsar Effect //
// All rights reserved //
///////////////////////////////
// This material may not be //
// reproduced, displayed, //
// modified or distributed //
// without the express prior //
// written permission of the //
// the copyright holder. //
///////////////////////////////

AddCSLuaFile( “cl_init.lua” )
AddCSLuaFile( “shared.lua” )
include(‘shared.lua’)

local Distance = 75
local MaxFires = 35;
local NumberOfFires = 0;

function ENT:Initialize()
self.Entity:SetModel(“models/props_junk/wood_pallet001a.mdl”);

self.Entity:SetMoveType( MOVETYPE_NONE )
self.Entity:SetSolid( SOLID_NONE )
self.Entity:SetAngles(Angle(0, 0, 0));
self.Entity:SetPos(self:GetPos() + Vector(0, 0, 10));

self.LastSpread = CurTime();
self.SpawnTime = CurTime();

NumberOfFires = NumberOfFires + 1;

self.LastDamage = CurTime();
self.ExtinguisherLeft = math.random(70, 100);
self.Spores = 0;
self.HealthAdd = CurTime();

self:DrawShadow(false);
self.IsAlive = true;

end

function ENT:SpreadFire()
if NumberOfFires >= MaxFires then return false; end
// Try 25 times to spread.
for i = 1, 25 do
local RandomStart = self:GetPos() + Vector(math.Rand(-1, 1) * Distance, math.Rand(-1, 1) * Distance, 50);
local UsStart = self:GetPos() + Vector(0, 0, 10);

	// trace to the random spot from us
	local Trace = {};
	Trace.start = UsStart;
	Trace.endpos = RandomStart;
	Trace.filter = self.Entity;
	Trace.mask = MASK_OPAQUE;
	
	local TR1 = util.TraceLine(Trace);
	
	// trace back to make sure theres nothing there
		
	local Trace2 = {};
	Trace2.start = RandomStart;
	Trace2.endpos = UsStart;
	Trace2.filter = self.Entity;
	Trace2.mask = MASK_OPAQUE;
		
	local TR2 = util.TraceLine(Trace2);
	
	if (TR1.Hit and TR2.Hit) or (!TR1.Hit and !TR2.Hit) then
		// trace down to make sure it's not a sheer cliff, or the like
		
		local TrStart = RandomStart;
		local TrEnd = TrStart - Vector(0, 0, 100);
		
		local Trace = {};
		Trace.start = TrStart;
		Trace.endpos = TrEnd;
		Trace.filter = self.Entity;
			
		local TraceResults = util.TraceLine(Trace);
			
		if TraceResults.HitWorld then
			if util.IsInWorld(TraceResults.HitPos) then				
				if 	TraceResults.MatType == MAT_DIRT or 
					TraceResults.MatType == MAT_WOOD or
					TraceResults.MatType == MAT_COMPUTER or
					TraceResults.MatType == MAT_FOLIAGE or
					TraceResults.MatType == MAT_PLASTIC or
					TraceResults.MatType == MAT_SAND or
					TraceResults.MatType == MAT_SLOSH or
					TraceResults.MatType == MAT_TILE or
					TraceResults.MatType == MAT_VENT then

					local NearbyEnts = ents.FindInSphere(TraceResults.HitPos, Distance * .5);
								
					local NearShroom = false;
					for k, v in pairs(NearbyEnts) do
						if v:GetClass() == 'ent_fire' then
							NearShroom = true;
						end
					end
							
					if !NearShroom then
						local Shroom = ents.Create('ent_fire');
						Shroom:SetPos(TraceResults.HitPos);
						Shroom:Spawn();
						self.Spores = self.Spores + 1;
						return;
					end
				end
			end
		end
	end
end

end

function ENT:KillFire ( )
if self.IsAlive then
NumberOfFires = NumberOfFires - 1;
self.IsAlive = false;
end

self:Remove();

end

function ENT:HitByExtinguisher ( ByWho, IsHose )
if IsHose then
self.ExtinguisherLeft = self.ExtinguisherLeft - 3;
else
self.ExtinguisherLeft = self.ExtinguisherLeft - 1;
end

if self.ExtinguisherLeft &lt;= 0 then
	if ByWho and ByWho:IsValid() and ByWho:IsPlayer() then
		if IsHose then
			ByWho:GiveCash(5);
		else
			ByWho:GiveCash(10);
		end
	end
	
	self:KillFire();
end

end

function ENT:Think ( )
if self.Spores >= 60 then self:KillFire(); return false; end
if self:WaterLevel() > 0 then self:KillFire(); return false; end

local IsStorming = GAMEMODE.CloudCondition == CLOUDS_STORMY || GAMEMODE.CloudCondition == CLOUDS_STORMY_SEVERE
local IsRaining = IsStorming || GAMEMODE.CloudCondition == CLOUDS_STORMY_LIGHT

local Trace = {};
Trace.start = self:GetPos();
Trace.endpos = self:GetPos() + Vector(0, 0, 500)
Trace.mask = MASK_VISIBLE;
Trace.filter = self;

local TR = util.TraceLine(Trace);
local IsOutdoors = TR.HitPos == Trace.endpos;
	
if IsStorming and IsOutdoors then
	self:HitByExtinguisher();
else
	if self.HealthAdd + 10 &lt; CurTime() and (!IsRaining or !IsOutdoors) then 
		self.HealthAdd = CurTime(); 
		self.ExtinguisherLeft = math.Clamp(self.ExtinguisherLeft + 1, 0, 120); 
	end

	if (self.LastSpread + 10 &lt; CurTime() and (!IsRaining or !IsOutdoors)) or (self.LastSpread + 60 &lt; CurTime() and (IsRaining and IsOutdoors)) then
		self.Spores = self.Spores + 1;
		self:SpreadFire();
		
		self.LastSpread = CurTime();
	end
end

if self.LastDamage + .1 &lt; CurTime() then
	local CloseEnts = ents.FindInSphere(self:GetPos(), 70);
	
	
	self.LastDamage = CurTime();
	
	for k , v in pairs(CloseEnts) do
		if (v:GetClass() == 'prop_physics' or v:GetClass() == 'ent_item' or v:GetClass() == 'ent_prop_item' or v:GetClass() == "prop_clock" or v:GetClass() == "ent_pot") and !v:GetTable().UnBurnable then
			v:GetTable().FireDamage = v:GetTable().FireDamage or 60;
			v:GetTable().FireDamage = v:GetTable().FireDamage - 1;
			
			if v:GetTable().FireDamage == 0 then
				if v:GetModel() == 'models/props_junk/propanecanister001a.mdl' then
					WorldSound(Sound('ambient/explosions/explode_' .. math.random(1, 7) .. '.wav'), v:GetPos(), 150, 255);
					
					for i = 1, 10 do
						self:SpreadFire();
					end
				end
				
				if (v.costItem && v:GetTable().Owner) then
					v:GetTable().Owner.theirNumItems = v:GetTable().Owner.theirNumItems - 1;
				end
				
				v:Remove();
			else
				if !v:IsOnFire() then
					v:Ignite(60, 100);
				end
				
				local C = (v:GetTable().FireDamage / 60) * 255;
				v:SetColor(C, C, C, 255);
			end
		elseif v:IsPlayer() and v:Alive() and v:GetPos():Distance(self:GetPos()) &lt; 70 then
			if v:Team() != TEAM_FIREMAN then
				v:TakeDamage(2, v, self);
				
				if v:GetPos():Distance(self:GetPos()) &lt; 50 and v:Team() != TEAM_FIREMAN then
					v:TakeDamage(15, v, self);
				end
			else
				v:GetTable().LastFireDamage = v:GetTable().LastFireDamage or 0;
				
				if v:GetTable().LastFireDamage + 1 &lt; CurTime() then
					v:TakeDamage(1, v, self);
					v:GetTable().LastFireDamage = CurTime();
				end
			end
		end
	end
end

end

function ENT:Use( activator, caller )

end

[/lua]

The fire is on the ground, it burns me if i walk on it but i cant see it, any help?

Did you just copy that straight out of PERP? If so I dont think it would work with DarkRP/Sandbox/ect ect

///////////////////////////////
// © 2009-2010 Pulsar Effect //
// All rights reserved //
///////////////////////////////
// This material may not be //
// reproduced, displayed, //
// modified or distributed //
// without the express prior //
// written permission of the //
// the copyright holder. //
///////////////////////////////

The code I gave you is an entity.

ent_fire

The fire is an entity.

/facepalm

ent_fire is a base valve entity.
That ent looks like its based out of a larger mod. Tons of out of scope functions and variables.

He copied it directly from PERP…