summaryrefslogtreecommitdiffstats
path: root/Plugins/Fire.lua
blob: 88bff84dae51a65df7b1646d866eb0cf3dfed84e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
local FirePlugin = {}
FirePlugin.__index = FirePlugin

FireBlocks = {}

function FirePlugin:new()
   local t = {}
   setmetatable(t, FirePlugin)
   local w = Lua__cPlugin:new()
   tolua.setpeer(w, t)
   w:tolua__set_instance(w)
   return w
end

function IsForeverBurnable( BlockID )
	if( BlockID == E_BLOCK_BLOODSTONE ) then
		return true
	end
	return false
end

function IsBurnable( BlockID )
	if( BlockID == E_BLOCK_LEAVES or BlockID == E_BLOCK_LOG ) then
		return true
	end

	return false
end

function FindBurnableAround( X, Y, Z )
	World = cRoot:Get():GetWorld()

	ListBurnables = {}
	if( IsBurnable( World:GetBlock(X-1, Y, Z) ) ) then
		table.insert( ListBurnables, { ["x"] = X-1, ["y"] = Y, ["z"] = Z } )
	end
	if( IsBurnable( World:GetBlock(X+1, Y, Z) ) ) then
		table.insert( ListBurnables, { ["x"] = X+1, ["y"] = Y, ["z"] = Z } )
	end
	if( IsBurnable( World:GetBlock(X, Y-1, Z) ) ) then
		table.insert( ListBurnables, { ["x"] = X, ["y"] = Y-1, ["z"] = Z } )
	end
	if( IsBurnable( World:GetBlock(X, Y+1, Z) ) ) then
		table.insert( ListBurnables, { ["x"] = X, ["y"] = Y+1, ["z"] = Z } )
	end
	if( IsBurnable( World:GetBlock(X, Y, Z-1) ) ) then
		table.insert( ListBurnables, { ["x"] = X, ["y"] = Y, ["z"] = Z-1 } )
	end
	if( IsBurnable( World:GetBlock(X, Y, Z+1) ) ) then
		table.insert( ListBurnables, { ["x"] = X, ["y"] = Y, ["z"] = Z+1 } )
	end

	return ListBurnables
end

function FirePlugin:OnDisable()
	Log( self:GetName() .. " v." .. self:GetVersion() .. " is shutting down..." )
end

function FirePlugin:Initialize()
	self:SetName( "Fire" )
	self:SetVersion( 1 )

	PluginManager = cRoot:Get():GetPluginManager()
	PluginManager:AddHook( self, cPluginManager.E_PLUGIN_TICK )
	PluginManager:AddHook( self, cPluginManager.E_PLUGIN_BLOCK_PLACE )
	PluginManager:AddHook( self, cPluginManager.E_PLUGIN_BLOCK_DIG )

	Log( "Initialized " .. self:GetName() .. " v." .. self:GetVersion() )
	return true
end

function FirePlugin:OnBlockPlace( PacketData, Player )

	if( PacketData.m_ItemType == E_BLOCK_FIRE or PacketData.m_ItemType == E_ITEM_FLINT_AND_STEEL ) then
		if( PacketData.m_Direction > -1 ) then
			local X = PacketData.m_PosX
			local Y = PacketData.m_PosY
			local Z = PacketData.m_PosZ

			X, Y, Z = AddDirection( X, Y, Z, PacketData.m_Direction )

			--Since flint and steel doesn't do anything on the server side yet
			if( PacketData.m_ItemType == E_ITEM_FLINT_AND_STEEL ) then
				local World = cRoot:Get():GetWorld()
				World:SetBlock( X, Y, Z, E_BLOCK_FIRE, 0 )
			end

			if( not IsForeverBurnable( World:GetBlock( X, Y-1, Z ) ) ) then
				table.insert( FireBlocks, { ["x"] = X, ["y"] = Y, ["z"] = Z } )
			end
		end
	end

	return false -- dont forbid placing the fire
end

-- To put out fires! :D
function FirePlugin:OnBlockDig( PacketData, Player )
	if( PacketData.m_Direction < 0 ) then
		return false
	end

	local X = PacketData.m_PosX
	local Y = PacketData.m_PosY
	local Z = PacketData.m_PosZ

	X, Y, Z = AddDirection( X, Y, Z, PacketData.m_Direction )

	local World = cRoot:Get():GetWorld()
	if( World:GetBlock( X, Y, Z ) == E_BLOCK_FIRE ) then
		World:SetBlock( X, Y, Z, E_BLOCK_AIR, 0 )
	end

	return false
end

NumTicks = 0
function FirePlugin:Tick( DeltaTime )
	if( NumTicks < 10 ) then	-- Only spread every 10 ticks, to make sure it doesnt happen too fast
		NumTicks = NumTicks + 1
		return
	end
	NumTicks = 0

	World = cRoot:Get():GetWorld()

	NewTable = {}
	for key,val in pairs(FireBlocks) do
		X = val["x"]
		Y = val["y"]
		Z = val["z"]
		Burnables = FindBurnableAround(X, Y, Z)
		if( math.random(10) > 5 ) then
			table.insert( NewTable, val )
		elseif( #Burnables > 0 ) then
			ToBurn = Burnables[ math.random( #Burnables ) ]
			World:SetBlock( ToBurn["x"], ToBurn["y"], ToBurn["z"], E_BLOCK_FIRE, 0 )
			table.insert( NewTable, ToBurn )
			table.insert( NewTable, val )
		else
			World:SetBlock( X, Y, Z, 0, 0 )
		end
	end
	FireBlocks = NewTable
end

Plugin = FirePlugin:new()
cRoot:Get():GetPluginManager():AddPlugin( Plugin )