1
0

Merge branch 'master' into ChunkLoader

Conflicts:
	src/ClientHandle.cpp
This commit is contained in:
Howaner 2014-10-21 16:55:22 +02:00
commit 44514e53fc
130 changed files with 1953 additions and 2315 deletions

2
.gitignore vendored
View File

@ -24,6 +24,8 @@ AllFiles.lst
*.*~ *.*~
*~ *~
*.orig *.orig
## CLion
.idea
## Eclipse ## Eclipse
.cproject .cproject
.project .project

12
.gitmodules vendored
View File

@ -7,6 +7,18 @@
[submodule "MCServer/Plugins/TransAPI"] [submodule "MCServer/Plugins/TransAPI"]
path = MCServer/Plugins/TransAPI path = MCServer/Plugins/TransAPI
url = https://github.com/bearbin/transapi.git url = https://github.com/bearbin/transapi.git
[submodule "MCServer/Plugins/ChunkWorx"]
path = MCServer/Plugins/ChunkWorx
url = https://github.com/mc-server/ChunkWorx.git
[submodule "MCServer/Plugins/ChatLog"]
path = MCServer/Plugins/ChatLog
url = https://github.com/mc-server/ChatLog.git
[submodule "MCServer/Plugins/Handy"]
path = MCServer/Plugins/Handy
url = https://github.com/mc-server/Handy.git
[submodule "MCServer/Plugins/MagicCarpet"]
path = MCServer/Plugins/MagicCarpet
url = https://github.com/mc-server/MagicCarpet.git
[submodule "lib/polarssl"] [submodule "lib/polarssl"]
path = lib/polarssl path = lib/polarssl
url = https://github.com/mc-server/polarssl.git url = https://github.com/mc-server/polarssl.git

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MCServerActivity!</string>
<string name="app_name">MCServer</string>
<string name="start">Start</string>
<string name="stop">Stop</string>
<string name="mcserver_is_running">MCServer jest włączony</string>
<string name="mcserver_is_not_running">MCServer jest wyłączony</string>
<string name="your_ip">Twoje IP …</string>
<string name="configure">Ustawienia</string>
</resources>

View File

@ -4,9 +4,8 @@ To compile MCServer from source, you need CMake and make, as well as a C compile
## Windows ## ## Windows ##
We use Microsoft Visual Studio for Windows compilation. It is possible to use other toolchains, but it isn't tested nor supported. Visual Studio versions 2008 Express and 2013 Express are being actively used for development, so either should work. We use Microsoft Visual Studio for Windows compilation. It is possible to use other toolchains, but it isn't tested nor supported. Visual Studio versions 2013 Express is being actively used for development.
You can find download links for VS2008 Express here: http://stackoverflow.com/questions/15318560/visual-c-2008-express-download-link-dead You can find download links for VS2013 Express here: http://www.microsoft.com/en-us/download/details.aspx?id=40787
And VS2013 Express here: http://www.microsoft.com/en-us/download/details.aspx?id=40787
Next, you need to download and install CMake. Download from here: http://cmake.org/cmake/resources/software.html . You should download a full installation package, so that the installer will set everything up for you (especially the paths). Next, you need to download and install CMake. Download from here: http://cmake.org/cmake/resources/software.html . You should download a full installation package, so that the installer will set everything up for you (especially the paths).

View File

@ -4,12 +4,14 @@ BasedDoge (Donated AlchemistVillage prefabs)
bearbin (Alexander Harkness) bearbin (Alexander Harkness)
derouinw derouinw
Diusrex Diusrex
Duralex Duralex
FakeTruth (founder) FakeTruth (founder)
Howaner
keyboard keyboard
Lapayo Lapayo
Luksor Luksor
marmot21 marmot21
Masy98
mborland mborland
mgueydan mgueydan
MikeHunsinger MikeHunsinger
@ -18,6 +20,7 @@ nesco
rs2k rs2k
SamJBarney SamJBarney
Sofapriester Sofapriester
SphinxC0re
STR_Warrior STR_Warrior
structinf (xdot) structinf (xdot)
Sxw1212 Sxw1212
@ -25,11 +28,9 @@ Taugeshtu
tigerw (Tiger Wang) tigerw (Tiger Wang)
tonibm19 tonibm19
UltraCoderRU UltraCoderRU
WebFreak001
worktycho worktycho
xoft xoft
Yeeeeezus (Donated AlchemistVillage prefabs) Yeeeeezus (Donated AlchemistVillage prefabs)
Howaner
Masy98
WebFreak001
Please add yourself to this list if you contribute to MCServer. Please add yourself to this list if you contribute to MCServer.

View File

@ -1,31 +0,0 @@
-- plugin.lua
-- Implements the main entrypoint for the plugin, as well as all the handling needed
-- ChatLog plugin logs all chat messages into the server log
function Initialize(Plugin)
Plugin:SetName("ChatLog")
Plugin:SetVersion(3)
cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChat)
LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
return true
end
function OnChat(Player, Message)
-- Lets get loggin'
LOGINFO("[" .. Player:GetName() .. "]: " .. StripColorCodes(Message));
return false
end

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<file>
<filename>chunkworx_main.lua</filename>
</file>
<file>
<filename>chunkworx_web.lua</filename>
</file>
</project>

View File

@ -1,128 +0,0 @@
-- Global variables
PLUGIN = {} -- Reference to own plugin object
GENERATION_STATE = 0
OPERATION_CODE = 0 -- 0 = generation
CX = 0
CZ = 0
CURRENT = 0
TOTAL = 0
-- AREA Variables
AreaStartX = -10
AreaStartZ = -10
AreaEndX = 10
AreaEndZ = 10
-- RADIAL Variables
RadialX = 0
RadialZ = 0
Radius = 10
-- WORLD
WORK_WORLD = cRoot:Get():GetDefaultWorld():GetName()
WW_instance = cRoot:Get():GetDefaultWorld()
WORLDS = {}
function Initialize(Plugin)
PLUGIN = Plugin
PLUGIN:SetName("ChunkWorx")
PLUGIN:SetVersion(6)
cPluginManager.AddHook(cPluginManager.HOOK_TICK, OnTick)
Plugin:AddWebTab("(Re)Generation", HandleRequest_Generation)
GENERATION_STATE = 0
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
if (WW_instance == nil) then
LOG("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": NO WORLD found :(")
end
-- Read the stored values:
local SettingsIni = cIniFile();
SettingsIni:ReadFile("ChunkWorx.ini"); -- ignore any read errors
AreaStartX = SettingsIni:GetValueSetI("Area data", "StartX", AreaStartX)
AreaStartZ = SettingsIni:GetValueSetI("Area data", "StartZ", AreaStartZ)
AreaEndX = SettingsIni:GetValueSetI("Area data", "EndX", AreaEndX)
AreaEndZ = SettingsIni:GetValueSetI("Area data", "EndZ", AreaEndZ)
RadialX = SettingsIni:GetValueSetI("Radial data", "RadialX", RadialX)
RadialZ = SettingsIni:GetValueSetI("Radial data", "RadialZ", RadialZ)
Radius = SettingsIni:GetValueSetI("Radial data", "Radius", Radius)
SettingsIni:WriteFile("ChunkWorx.ini");
LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
return true
end
function OnTick( DeltaTime )
if (GENERATION_STATE == 1 or GENERATION_STATE == 3) then
LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works STARTED!")
LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": At world: " .. WORK_WORLD)
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
if (GENERATION_STATE == 1) then GENERATION_STATE = 2 end
if (GENERATION_STATE == 3) then GENERATION_STATE = 4 end
-- Changing in case coordinates are flipped
local shifter = AreaEndX
if (AreaStartX > AreaEndX) then
AreaEndX = AreaStartX
AreaStartX = shifter
end
shifter = AreaEndZ
if (AreaStartZ > AreaEndZ) then
AreaEndZ = AreaStartZ
AreaStartZ = shifter
end
CX = AreaStartX
CZ = AreaStartZ
CURRENT = 0
if (WW_instance == nil) then
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED")
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": NO WORLD found :(")
GENERATION_STATE = 0
end
end
if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
if (WW_instance:GetGeneratorQueueLength() < 200
and WW_instance:GetLightingQueueLength() < 200
and (WW_instance:GetStorageSaveQueueLength() + WW_instance:GetStorageLoadQueueLength()) < 80) then
local chunk_sum = (1+ AreaEndX - AreaStartX) * (1+ AreaEndZ - AreaStartZ)
TOTAL = chunk_sum
LOG("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": PROCESSING 100 chunks, (" .. CURRENT .. "/" .. chunk_sum .. ")")
for C = 1, 100 do
if (GENERATION_STATE == 2) then WW_instance:GenerateChunk(CX, CZ) end
if (GENERATION_STATE == 4) then WW_instance:RegenerateChunk(CX, CZ) end
CX = CX + 1
CURRENT = CURRENT + 1
if (CX > AreaEndX) then
CX = AreaStartX
CZ = CZ + 1
if (CZ > AreaEndZ) then
if (GENERATION_STATE == 2) then LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " - generation ENDED!") end
if (GENERATION_STATE == 4) then LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " - REgeneration ENDED!") end
GENERATION_STATE = 0
break
end
end
end
WW_instance:QueueSaveAllChunks()
WW_instance:QueueUnloadUnusedChunks()
end
end
end

View File

@ -1,274 +0,0 @@
-- chunkworx_web.lua
-- WebAdmin-related functions
local function Buttons_Player( Name )
return "<form method='POST'><input type='hidden' name='PlayerName' value='"..Name.."'><input type='submit' name='PlayerExact' value='Exact'><input type='submit' name='Player3x3' value='3x3'></form>"
end
local function Button_World( Name )
return "<form method='POST'><input type='hidden' name='WorldName' value='"..Name.."'><input type='submit' name='SelectWorld' value='Select'></form>"
end
local function SaveSettings()
local SettingsIni = cIniFile()
SettingsIni:SetValueI("Area data", "StartX", AreaStartX)
SettingsIni:SetValueI("Area data", "StartZ", AreaStartZ)
SettingsIni:SetValueI("Area data", "EndX", AreaEndX)
SettingsIni:SetValueI("Area data", "EndZ", AreaEndZ)
SettingsIni:SetValueI("Radial data", "RadialX", RadialX)
SettingsIni:SetValueI("Radial data", "RadialZ", RadialZ)
SettingsIni:SetValueI("Radial data", "Radius", Radius)
SettingsIni:WriteFile("ChunkWorx.ini")
end
function HandleRequest_Generation( Request )
local Content = ""
if (Request.PostParams["AGHRRRR"] ~= nil) then
GENERATION_STATE = 0
WW_instance:QueueSaveAllChunks()
WW_instance:QueueUnloadUnusedChunks()
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
end
--Content = Content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
-- PROCESSING
--------------------------------------------------------------------------------------------------
local function ProcessingContent()
local _small_content = ""
_small_content = _small_content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
_small_content = _small_content .. "<h4>World for operations:</h4>"..WORK_WORLD
if (OPERATION_CODE == 0) then
_small_content = _small_content .. "<h4>Operation:</h4>Generation"
elseif (OPERATION_CODE == 1) then
_small_content = _small_content .. "<h4>Operation:</h4>Regeneration"
end
_small_content = _small_content .. "<h4>Area: </h4>["..AreaStartX..":"..AreaStartZ.."] ["..AreaEndX..":"..AreaEndZ.."]"
_small_content = _small_content .. "<h4>Progress:</h4>"..CURRENT.."/"..TOTAL
_small_content = _small_content .. "<br>"
_small_content = _small_content .. "<form method='POST'>"
_small_content = _small_content .. "<input type='submit' name='AGHRRRR' value='Stop'>"
_small_content = _small_content .. "</form>"
return _small_content
end
if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
Content = ProcessingContent()
return Content
end
-- SELECTING
--------------------------------------------------------------------------------------------------
if ( Request.PostParams["FormSetWorld"] ) then
WORK_WORLD = Request.PostParams["FormWorldName"]
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
end
if( Request.PostParams["SelectWorld"] ~= nil
and Request.PostParams["WorldName"] ~= nil ) then -- World is selected!
WORK_WORLD = Request.PostParams["WorldName"]
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
end
if(Request.PostParams["OperationGenerate"] ~= nil) then
OPERATION_CODE = 0
end
if(Request.PostParams["OperationReGenerate"] ~= nil) then
OPERATION_CODE = 1
end
if (GENERATION_STATE == 0) then
if( Request.PostParams["FormAreaStartX"] ~= nil
and Request.PostParams["FormAreaStartZ"] ~= nil
and Request.PostParams["FormAreaEndX"] ~= nil
and Request.PostParams["FormAreaEndZ"] ~= nil ) then --(Re)Generation valid!
-- COMMON (Re)gen
if( Request.PostParams["StartArea"]) then
AreaStartX = tonumber(Request.PostParams["FormAreaStartX"])
AreaStartZ = tonumber(Request.PostParams["FormAreaStartZ"])
AreaEndX = tonumber(Request.PostParams["FormAreaEndX"])
AreaEndZ = tonumber(Request.PostParams["FormAreaEndZ"])
SaveSettings();
if (OPERATION_CODE == 0) then
GENERATION_STATE = 1
elseif (OPERATION_CODE == 1) then
GENERATION_STATE = 3
end
Content = ProcessingContent()
return Content
end
end
if( Request.PostParams["FormRadialX"] ~= nil
and Request.PostParams["FormRadialZ"] ~= nil
and Request.PostParams["FormRadius"] ~= nil ) then --(Re)Generation valid!
-- COMMON (Re)gen
if( Request.PostParams["StartRadial"]) then
RadialX = tonumber(Request.PostParams["FormRadialX"]) or 0
RadialZ = tonumber(Request.PostParams["FormRadialZ"]) or 0
Radius = tonumber(Request.PostParams["FormRadius"]) or 10
AreaStartX = RadialX - Radius
AreaStartZ = RadialZ - Radius
AreaEndX = RadialX + Radius
AreaEndZ = RadialZ + Radius
SaveSettings()
if (OPERATION_CODE == 0) then
GENERATION_STATE = 1
elseif (OPERATION_CODE == 1) then
GENERATION_STATE = 3
end
Content = ProcessingContent()
return Content
end
end
-- POINT REGEN!
if( Request.PostParams["FormPointX"] ~= nil
and Request.PostParams["FormPointZ"] ~= nil ) then --ReGeneration valid!
-- EXACT
if ( Request.PostParams["PointExact"] ~= nil) then
AreaStartX = tonumber(Request.PostParams["FormPointX"])
AreaStartZ = tonumber(Request.PostParams["FormPointZ"])
AreaEndX = AreaStartX
AreaEndZ = AreaStartZ
GENERATION_STATE = 3
Content = ProcessingContent()
return Content
end
-- 3x3
if ( Request.PostParams["Point3x3"] ~= nil) then
AreaStartX = tonumber(Request.PostParams["FormPointX"]) - 1
AreaStartZ = tonumber(Request.PostParams["FormPointZ"]) - 1
AreaEndX = AreaStartX + 2
AreaEndZ = AreaStartZ + 2
GENERATION_STATE = 3
Content = ProcessingContent()
return Content
end
end
local GetAreaByPlayer = function(Player)
-- Player is valid only within this function, it cannot be stord and used later!
AreaStartX = Player:GetChunkX()
AreaStartZ = Player:GetChunkZ()
end
-- PLAYERS REGEN!
if( Request.PostParams["PlayerExact"] ~= nil
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
AreaEndX = AreaStartX
AreaEndZ = AreaStartZ
GENERATION_STATE = 3
Content = ProcessingContent()
return Content
end
if( Request.PostParams["Player3x3"] ~= nil
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
AreaStartX = AreaStartX - 1
AreaStartZ = AreaStartZ - 1
AreaEndX = AreaStartX + 2
AreaEndZ = AreaStartZ + 2
GENERATION_STATE = 3
Content = ProcessingContent()
return Content
end
end
--Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
--Content = Content .. "<form method='POST'>"
--Content = Content .. "<input type='text' name='FormWorldName' value='Input world name here'><input type='submit' name='FormSetWorld' value='Set world'>"
--Content = Content .. "</form>"
-- SELECTING WORK_WORLD
Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
Content = Content .. "<table>"
local WorldNum = 0
local AddWorldToTable = function(World)
WorldNum = WorldNum + 1
Content = Content .. "<tr>"
Content = Content .. "<td style='width: 10px;'>" .. WorldNum .. ".</td>"
Content = Content .. "<td>" .. World:GetName() .. "</td>"
Content = Content .. "<td>" .. Button_World(World:GetName()) .. "</td>"
Content = Content .. "</tr>"
end
cRoot:Get():ForEachWorld(AddWorldToTable)
if( WorldNum == 0 ) then
Content = Content .. "<tr><td>No worlds! O_O</td></tr>"
end
Content = Content .. "</table>"
Content = Content .. "<br>"
-- SELECTING OPERATION
if (OPERATION_CODE == 0) then
Content = Content .. "<h4>Operation: Generation</h4>"
elseif (OPERATION_CODE == 1) then
Content = Content .. "<h4>Operation: Regeneration</h4>"
end
Content = Content .. "<form method='POST'>"
Content = Content .. "<input type='submit' name='OperationGenerate' value='Generation'>"
Content = Content .. "<input type='submit' name='OperationReGenerate' value='Regeneration'>"
Content = Content .. "</form>"
-- SELECTING AREA
Content = Content .. "<h4>Area: </h4>Start X, Start Z; End X, End Z"
Content = Content .. "<form method='POST'>"
Content = Content .. "<input type='text' name='FormAreaStartX' value='" .. AreaStartX .. "'><input type='text' name='FormAreaStartZ' value='" .. AreaStartZ .. "'>"
Content = Content .. "<input type='text' name='FormAreaEndX' value='" .. AreaEndX .. "'><input type='text' name='FormAreaEndZ' value='" .. AreaEndZ .. "'>"
Content = Content .. "<input type='submit' name='StartArea' value='Start'>"
Content = Content .. "</form>"
-- SELECTING RADIAL
Content = Content .. "<h4>Radial: </h4>Center X, Center Z, Radius"
Content = Content .. "<form method='POST'>"
Content = Content .. "<input type='text' name='FormRadialX' value='" .. RadialX .. "'><input type='text' name='FormRadialZ' value='" .. RadialZ .. "'><input type='text' name='FormRadius' value='" .. Radius .. "'>"
Content = Content .. "<input type='submit' name='StartRadial' value='Start'>"
Content = Content .. "</form>"
Content = Content .. "<br>"
Content = Content .. "<br>"
Content = Content .. "<br>"
-- SELECTING POINT
Content = Content .. "<h4>Point regeneration:</h4> X, Z"
Content = Content .. "<form method='POST'>"
Content = Content .. "<input type='text' name='FormPointX' value='0'><input type='text' name='FormPointZ' value='0'>"
Content = Content .. "<input type='submit' name='PointExact' value='Exact'>"
Content = Content .. "<input type='submit' name='Point3x3' value='3x3'>"
Content = Content .. "</form>"
-- SELECTING PLAYERS
Content = Content .. "<h4>Player-based regeneration:</h4>"
Content = Content .. "<table>"
local PlayerNum = 0
local AddPlayerToTable = function( Player )
PlayerNum = PlayerNum + 1
Content = Content .. "<tr>"
Content = Content .. "<td style='width: 10px;'>" .. PlayerNum .. ".</td>"
Content = Content .. "<td>" .. Player:GetName() .. "</td>"
Content = Content .. "<td>" .. Buttons_Player(Player:GetName()) .. "</td>"
Content = Content .. "</tr>"
end
if (cRoot:Get():GetWorld(WORK_WORLD) == nil) then
Content = Content .. "<tr><td>Incorrect world selection</td></tr>"
else
cRoot:Get():GetWorld(WORK_WORLD):ForEachPlayer( AddPlayerToTable )
if( PlayerNum == 0 ) then
Content = Content .. "<tr><td>No connected players</td></tr>"
end
end
Content = Content .. "</table>"
Content = Content .. "<br>"
return Content
end

@ -1 +1 @@
Subproject commit f8c2531fbef9bfd0b6f024d4d3319384a70a0831 Subproject commit 3a0e0597b7a24c44bf87ec90beb9be48d0b99709

View File

@ -10,9 +10,6 @@ g_ShowFoodStats = false; -- When true, each player's food stats are sent to the
function Initialize(Plugin) function Initialize(Plugin)
Plugin:SetName("Debuggers")
Plugin:SetVersion(1)
--[[ --[[
-- Test multiple hook handlers: -- Test multiple hook handlers:
cPluginManager.AddHook(cPluginManager.HOOK_TICK, OnTick1); cPluginManager.AddHook(cPluginManager.HOOK_TICK, OnTick1);
@ -68,6 +65,8 @@ function Initialize(Plugin)
PM:BindCommand("/rmitem", "debuggers", HandleRMItem, "- Remove the specified item from the inventory."); PM:BindCommand("/rmitem", "debuggers", HandleRMItem, "- Remove the specified item from the inventory.");
PM:BindCommand("/pickups", "debuggers", HandlePickups, "- Spawns random pickups around you"); PM:BindCommand("/pickups", "debuggers", HandlePickups, "- Spawns random pickups around you");
PM:BindCommand("/poof", "debuggers", HandlePoof, "- Nudges pickups close to you away from you"); PM:BindCommand("/poof", "debuggers", HandlePoof, "- Nudges pickups close to you away from you");
PM:BindConsoleCommand("sched", HandleConsoleSchedule, "Tests the world scheduling");
Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers) Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers)
Plugin:AddWebTab("StressTest", HandleRequest_StressTest) Plugin:AddWebTab("StressTest", HandleRequest_StressTest)
@ -1630,3 +1629,17 @@ end
function HandleConsoleSchedule(a_Split)
LOG("Scheduling a task for 2 seconds in the future")
cRoot:Get():GetDefaultWorld():ScheduleTask(40,
function ()
LOG("Scheduled function is called.")
end
)
return true, "Task scheduled"
end

View File

@ -1,28 +0,0 @@
-- Global variables
PLUGIN = {} -- Reference to own plugin object
CHEST_WIDTH = 9
HANDY_VERSION = 2
--[[
Handy is a plugin for other plugins. It contain no commands, no hooks, but functions to ease plugins developers' life.
API:
TODO:
1. GetChestSlot wrapper, so it will detect double chest neighbour chest and will be able to access it.
]]
function Initialize(Plugin)
PLUGIN = Plugin
PLUGIN:SetName("Handy")
PLUGIN:SetVersion(HANDY_VERSION)
PluginManager = cRoot:Get():GetPluginManager()
LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
return true
end
function OnDisable()
LOG(PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " is shutting down...")
end

View File

@ -1,216 +0,0 @@
--[[
General stuff
]]
-- Returns Handy plugin version number
function GetHandyVersion()
return HANDY_VERSION
end
-- Checks if handy is in proper version
function CheckForRequiredVersion( inVersion )
if( inVersion > HANDY_VERSION ) then return false end
return true
end
--[[
MCS-specific _functions and nasty hacks :D
]]
function GetChestHeightCheat( inChest )
local chestGrid = inChest:GetContents()
LOGINFO( "This function serves no purpose now! You should consider chest:GetContents():GetHeight() now!" )
LOGINFO( "Also, you might find Handy's new 'IsChestDouble()' useful for your case" )
return chestGrid:GetHeight()
end
function IsChestDouble( inChest )
local chestHeight = inChest:GetContents():GetHeight()
if( chestHeight == 3 ) then
return false
end
return true
end
-- Those two checks how many items of given inItemID chest and player have, and how much they could fit inside them
function ReadChestForItem( inChest, inItemID )
return ReadGridForItems( inChest:GetContents(), inItemID )
end
function ReadPlayerForItem( inPlayer, inItemID )
local inventoryFound, inventoryFree = ReadGridForItems( inPlayer:GetInventory():GetInventoryGrid(), inItemID )
local hotbarFound, hotbarFree = ReadGridForItems( inPlayer:GetInventory():GetHotbarGrid(), inItemID )
local itemsFound = inventoryFound + hotbarFound
local freeSpace = inventoryFree + hotbarFree
return itemsFound, freeSpace
end
-- Following functions are for chest-related operations
-- BEWARE! Those assume you did checked if chest has items/space in it!
function ReadGridForItems( inGrid, inItemID )
local itemsFound = 0
local freeSpace = 0
local slotsCount = inGrid:GetNumSlots()
local testerItem = cItem( inItemID )
local maxStackSize = testerItem:GetMaxStackSize()
for index = 0, (slotsCount - 1) do
slotItem = inGrid:GetSlot( index )
if( slotItem:IsEmpty() ) then
freeSpace = freeSpace + maxStackSize
else
if( slotItem:IsStackableWith( testerItem ) ) then
itemsFound = itemsFound + slotItem.m_ItemCount
freeSpace = maxStackSize - slotItem.m_ItemCount
end
end
end
return itemsFound, freeSpace
end
function TakeItemsFromGrid( inGrid, inItem )
local slotsCount = inGrid:GetNumSlots()
local removedItem = cItem( inItem )
for index = 0, (slotsCount - 1) do
slotItem = inGrid:GetSlot( index )
if( slotItem:IsSameType( removedItem ) ) then
if( slotItem.m_ItemCount <= removedItem.m_ItemCount ) then
removedItem.m_ItemCount = removedItem.m_ItemCount - slotItem.m_ItemCount
inGrid:EmptySlot( index )
else
removedItem.m_ItemCount = slotItem.m_ItemCount - removedItem.m_ItemCount
inGrid:SetSlot( index, removedItem )
removedItem.m_ItemCount = 0
end
if( removedItem.m_ItemCount <= 0 ) then break end
end
end
return removedItem.m_ItemCount
end
--------------
function TakeItemsFromChest( inChest, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FOR ITEMS FIRST!!
local chestGrid = inChest:GetContents()
local removedItem = cItem( inItemID, inAmount )
TakeItemsFromGrid( chestGrid, removedItem )
end
function PutItemsToChest( inChest, inItemID, inAmount )
local chestGrid = inChest:GetContents()
local addedItem = cItem( inItemID, inAmount )
chestGrid:AddItem( addedItem )
end
-- Similar to chest-related.
function TakeItemsFromPlayer( inPlayer, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FIRST!
local removedItem = cItem( inItemID, inAmount )
local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid()
local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid()
local itemsLeft = TakeItemsFromGrid( inventoryGrid, removedItem )
if( itemsLeft > 0 ) then
removedItem = cItem( inItemID, itemsLeft )
TakeItemsFromGrid( hotbarGrid, removedItem )
end
end
function GiveItemsToPlayer( inPlayer, inItemID, inAmount )
local addedItem = cItem( inItemID, inAmount )
local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid()
local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid()
local itemsAdded = inventoryGrid:AddItem( addedItem )
if( itemsAdded < inAmount ) then
addedItem.m_ItemCount = addedItem.m_ItemCount - itemsAdded
hotbarGrid:AddItem( addedItem )
end
end
-- This function returns item max stack for a given itemID. It uses vanilla max stack size, and uses several non-common items notations;
-- Those are:
-- oneonerecord( because aparently 11record wasn't the best idea in lua scripting application )
-- carrotonastick( because it wasn't added to items.txt yet )
-- waitrecord( for same reason )
-- Feel free to ignore the difference, or to add those to items.txt
function GetItemMaxStack( inItemID )
local testerItem = cItem( inItemID )
LOGINFO( "This function serves no real purpose now, maybe consider using cItem:GetMaxStackSize()?" )
return testerItem:GetMaxStackSize()
end
function ItemIsArmor( inItemID, inCheckForHorseArmor )
inCheckForHorseArmor = inCheckForHorseArmor or false
if( inItemID == E_ITEM_LEATHER_CAP ) then return true end
if( inItemID == E_ITEM_LEATHER_TUNIC ) then return true end
if( inItemID == E_ITEM_LEATHER_PANTS ) then return true end
if( inItemID == E_ITEM_LEATHER_BOOTS ) then return true end
if( inItemID == E_ITEM_CHAIN_HELMET ) then return true end
if( inItemID == E_ITEM_CHAIN_CHESTPLATE ) then return true end
if( inItemID == E_ITEM_CHAIN_LEGGINGS ) then return true end
if( inItemID == E_ITEM_CHAIN_BOOTS ) then return true end
if( inItemID == E_ITEM_IRON_HELMET ) then return true end
if( inItemID == E_ITEM_IRON_CHESTPLATE ) then return true end
if( inItemID == E_ITEM_IRON_LEGGINGS ) then return true end
if( inItemID == E_ITEM_IRON_BOOTS ) then return true end
if( inItemID == E_ITEM_DIAMOND_HELMET ) then return true end
if( inItemID == E_ITEM_DIAMOND_CHESTPLATE ) then return true end
if( inItemID == E_ITEM_DIAMOND_LEGGINGS ) then return true end
if( inItemID == E_ITEM_DIAMOND_BOOTS ) then return true end
if( inItemID == E_ITEM_GOLD_HELMET ) then return true end
if( inItemID == E_ITEM_GOLD_CHESTPLATE ) then return true end
if( inItemID == E_ITEM_GOLD_LEGGINGS ) then return true end
if( inItemID == E_ITEM_GOLD_BOOTS ) then return true end
if( inCheckForHorseArmor ) then
if( inItemID == E_ITEM_IRON_HORSE_ARMOR ) then return true end
if( inItemID == E_ITEM_GOLD_HORSE_ARMOR ) then return true end
if( inItemID == E_ITEM_DIAMOND_HORSE_ARMOR ) then return true end
end
return false
end
-- Returns full-length playername for a short name( usefull for parsing commands )
function GetExactPlayername( inPlayerName )
local _result = inPlayerName
local function SetProcessingPlayername( inPlayer )
_result = inPlayer:GetName()
end
cRoot:Get():FindAndDoWithPlayer( inPlayerName, SetProcessingPlayername )
return _result
end
function GetPlayerByName( inPlayerName )
local _player
local PlayerSetter = function( Player )
_player = Player
end
cRoot:Get():FindAndDoWithPlayer( inPlayerName, PlayerSetter )
return _player
end
--[[
Not-so-usual math _functions
]]
-- Rounds floating point number. Because lua guys think this function doesn't deserve to be presented in lua's math
function round( inX )
if( inX%2 ~= 0.5 ) then
return math.floor( inX + 0.5 )
end
return inX - 0.5
end
--[[
Functions I use for filework and stringswork
]]
function PluralString( inValue, inSingularString, inPluralString )
local _value_string = tostring( inValue )
if( _value_string[#_value_string] == "1" ) then
return inSingularString
end
return inPluralString
end
function PluralItemName( inItemID, inAmount ) -- BEWARE! TEMPORAL SOLUTION THERE! :D
local _value_string = tostring( inValue )
local _name = ""
if( _value_string[#_value_string] == "1" ) then
-- singular names
_name = ItemTypeToString( inItemID )
else
-- plural names
_name = ItemTypeToString( inItemID ).."s"
end
return _name
end
-- for filewriting purposes. 0 = false, 1 = true
function StringToBool( inValue )
if( inValue == "1" ) then return true end
return false
end
-- same, but reversal
function BoolToString( inValue )
if( inValue == true ) then return 1 end
return 0
end

View File

@ -20,8 +20,8 @@ only that one plugin's documentation. This mode of operation doesn't require Lua
-- Check Lua version. We use 5.1-specific construct when loading the plugin info, 5.2 is not compatible! -- Check Lua version. We use 5.1-specific construct when loading the plugin info, 5.2 is not compatible!
if (_VERSION ~= "Lua 5.1") then if (_VERSION ~= "Lua 5.1") then
print("Unsupported Lua version. This script requires Lua version 5.1, this Lua is version " .. (_VERSION or "<nil>")); print("Unsupported Lua version. This script requires Lua version 5.1, this Lua is version " .. (_VERSION or "<nil>"))
return; return
end end
@ -31,38 +31,38 @@ end
--- Replaces generic formatting with forum-specific formatting --- Replaces generic formatting with forum-specific formatting
-- Also removes the single line-ends -- Also removes the single line-ends
local function ForumizeString(a_Str) local function ForumizeString(a_Str)
assert(type(a_Str) == "string"); assert(type(a_Str) == "string")
-- Remove the indentation, unless in the code tag: -- Remove the indentation, unless in the code tag:
-- Only one code or /code tag per line is supported! -- Only one code or /code tag per line is supported!
local IsInCode = false; local IsInCode = false
local function RemoveIndentIfNotInCode(s) local function RemoveIndentIfNotInCode(s)
if (IsInCode) then if (IsInCode) then
-- we're in code section, check if this line terminates it -- we're in code section, check if this line terminates it
IsInCode = (s:find("{%%/code}") ~= nil); IsInCode = (s:find("{%%/code}") ~= nil)
return s .. "\n"; return s .. "\n"
else else
-- we're not in code section, check if this line starts it -- we're not in code section, check if this line starts it
IsInCode = (s:find("{%%code}") ~= nil); IsInCode = (s:find("{%%code}") ~= nil)
return s:gsub("^%s*", "") .. "\n"; return s:gsub("^%s*", "") .. "\n"
end end
end end
a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode); a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode)
-- Replace multiple line ends with {%p} and single line ends with a space, -- Replace multiple line ends with {%p} and single line ends with a space,
-- so that manual word-wrap in the Info.lua file doesn't wrap in the forum. -- so that manual word-wrap in the Info.lua file doesn't wrap in the forum.
a_Str = a_Str:gsub("\n\n", "{%%p}"); a_Str = a_Str:gsub("\n\n", "{%%p}")
a_Str = a_Str:gsub("\n", " "); a_Str = a_Str:gsub("\n", " ")
-- Replace the generic formatting: -- Replace the generic formatting:
a_Str = a_Str:gsub("{%%p}", "\n\n"); a_Str = a_Str:gsub("{%%p}", "\n\n")
a_Str = a_Str:gsub("{%%b}", "[b]"):gsub("{%%/b}", "[/b]"); a_Str = a_Str:gsub("{%%b}", "[b]"):gsub("{%%/b}", "[/b]")
a_Str = a_Str:gsub("{%%i}", "[i]"):gsub("{%%/i}", "[/i]"); a_Str = a_Str:gsub("{%%i}", "[i]"):gsub("{%%/i}", "[/i]")
a_Str = a_Str:gsub("{%%list}", "[list]"):gsub("{%%/list}", "[/list]"); a_Str = a_Str:gsub("{%%list}", "[list]"):gsub("{%%/list}", "[/list]")
a_Str = a_Str:gsub("{%%li}", "[*]"):gsub("{%%/li}", ""); a_Str = a_Str:gsub("{%%li}", "[*]"):gsub("{%%/li}", "")
-- TODO: Other formatting -- TODO: Other formatting
return a_Str; return a_Str
end end
@ -72,38 +72,38 @@ end
--- Replaces generic formatting with forum-specific formatting --- Replaces generic formatting with forum-specific formatting
-- Also removes the single line-ends -- Also removes the single line-ends
local function GithubizeString(a_Str) local function GithubizeString(a_Str)
assert(type(a_Str) == "string"); assert(type(a_Str) == "string")
-- Remove the indentation, unless in the code tag: -- Remove the indentation, unless in the code tag:
-- Only one code or /code tag per line is supported! -- Only one code or /code tag per line is supported!
local IsInCode = false; local IsInCode = false
local function RemoveIndentIfNotInCode(s) local function RemoveIndentIfNotInCode(s)
if (IsInCode) then if (IsInCode) then
-- we're in code section, check if this line terminates it -- we're in code section, check if this line terminates it
IsInCode = (s:find("{%%/code}") ~= nil); IsInCode = (s:find("{%%/code}") ~= nil)
return s .. "\n"; return s .. "\n"
else else
-- we're not in code section, check if this line starts it -- we're not in code section, check if this line starts it
IsInCode = (s:find("{%%code}") ~= nil); IsInCode = (s:find("{%%code}") ~= nil)
return s:gsub("^%s*", "") .. "\n"; return s:gsub("^%s*", "") .. "\n"
end end
end end
a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode); a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode)
-- Replace multiple line ends with {%p} and single line ends with a space, -- Replace multiple line ends with {%p} and single line ends with a space,
-- so that manual word-wrap in the Info.lua file doesn't wrap in the forum. -- so that manual word-wrap in the Info.lua file doesn't wrap in the forum.
a_Str = a_Str:gsub("\n\n", "{%%p}"); a_Str = a_Str:gsub("\n\n", "{%%p}")
a_Str = a_Str:gsub("\n", " "); a_Str = a_Str:gsub("\n", " ")
-- Replace the generic formatting: -- Replace the generic formatting:
a_Str = a_Str:gsub("{%%p}", "\n\n"); a_Str = a_Str:gsub("{%%p}", "\n\n")
a_Str = a_Str:gsub("{%%b}", "**"):gsub("{%%/b}", "**"); a_Str = a_Str:gsub("{%%b}", "**"):gsub("{%%/b}", "**")
a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*"); a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*")
a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/list}", ""); a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/list}", "")
a_Str = a_Str:gsub("{%%li}", " - "):gsub("{%%/li}", ""); a_Str = a_Str:gsub("{%%li}", " - "):gsub("{%%/li}", "")
-- TODO: Other formatting -- TODO: Other formatting
return a_Str; return a_Str
end end
@ -117,7 +117,7 @@ end
local function BuildCategories(a_PluginInfo) local function BuildCategories(a_PluginInfo)
-- The returned result -- The returned result
-- This will contain both an array and a dict of the categories, to allow fast search -- This will contain both an array and a dict of the categories, to allow fast search
local res = {}; local res = {}
-- For each command add a reference to it into all of its categories: -- For each command add a reference to it into all of its categories:
local function AddCommands(a_CmdPrefix, a_Commands) local function AddCommands(a_CmdPrefix, a_Commands)
@ -130,39 +130,39 @@ local function BuildCategories(a_PluginInfo)
if ((info.HelpString ~= nil) and (info.HelpString ~= "")) then if ((info.HelpString ~= nil) and (info.HelpString ~= "")) then
-- Add to each specified category: -- Add to each specified category:
local Category = info.Category; local Category = info.Category
if (type(Category) == "string") then if (type(Category) == "string") then
Category = {Category}; Category = {Category}
end end
for idx, cat in ipairs(Category or {""}) do for idx, cat in ipairs(Category or {""}) do
local CatEntry = res[cat]; local CatEntry = res[cat]
if (CatEntry == nil) then if (CatEntry == nil) then
-- First time we came across this category, create it: -- First time we came across this category, create it:
local NewCat = {Name = cat, Description = "", Commands = {NewCmd}}; local NewCat = {Name = cat, Description = "", Commands = {NewCmd}}
table.insert(res, NewCat); table.insert(res, NewCat)
res[cat] = NewCat; res[cat] = NewCat
else else
-- We already have this category, just add the command to its list of commands: -- We already have this category, just add the command to its list of commands:
table.insert(CatEntry.Commands, NewCmd); table.insert(CatEntry.Commands, NewCmd)
end end
end -- for idx, cat - Category[] end -- for idx, cat - Category[]
end -- if (HelpString valid) end -- if (HelpString valid)
-- Recurse all subcommands: -- Recurse all subcommands:
if (info.Subcommands ~= nil) then if (info.Subcommands ~= nil) then
AddCommands(a_CmdPrefix .. cmd .. " ", info.Subcommands); AddCommands(a_CmdPrefix .. cmd .. " ", info.Subcommands)
end end
end -- for cmd, info - a_Commands[] end -- for cmd, info - a_Commands[]
end -- AddCommands() end -- AddCommands()
AddCommands("", a_PluginInfo.Commands); AddCommands("", a_PluginInfo.Commands)
-- Assign descriptions to categories: -- Assign descriptions to categories:
for name, desc in pairs(a_PluginInfo.Categories or {}) do for name, desc in pairs(a_PluginInfo.Categories or {}) do
local CatEntry = res[name]; local CatEntry = res[name]
if (CatEntry ~= nil) then if (CatEntry ~= nil) then
-- The result has this category, add the description: -- The result has this category, add the description:
CatEntry.Description = desc.Description; CatEntry.Description = desc.Description
end end
end end
@ -170,12 +170,12 @@ local function BuildCategories(a_PluginInfo)
for idx, cat in ipairs(res) do for idx, cat in ipairs(res) do
table.sort(cat.Commands, table.sort(cat.Commands,
function (cmd1, cmd2) function (cmd1, cmd2)
return (string.lower(cmd1.CommandString) < string.lower(cmd2.CommandString)); return (string.lower(cmd1.CommandString) < string.lower(cmd2.CommandString))
end end
); )
end end
return res; return res
end end
@ -188,9 +188,9 @@ end
-- colorizes command name blue and params green -- colorizes command name blue and params green
local function GetCommandRefForum(a_Command) local function GetCommandRefForum(a_Command)
if (type(a_Command) == "string") then if (type(a_Command) == "string") then
return "[color=blue]" .. a_Command .. "[/color]"; return "[color=blue]" .. a_Command .. "[/color]"
end end
return "[color=blue]" .. a_Command.Name .. "[/color] [color=green]" .. (a_Command.Params or "") .. "[/color]"; return "[color=blue]" .. a_Command.Name .. "[/color] [color=green]" .. (a_Command.Params or "") .. "[/color]"
end end
@ -201,18 +201,18 @@ end
-- If a_CommandParams is nil, returns a_CommandName apostrophed -- If a_CommandParams is nil, returns a_CommandName apostrophed
-- If a_CommandParams is a string, apostrophes a_CommandName with a_CommandParams -- If a_CommandParams is a string, apostrophes a_CommandName with a_CommandParams
local function GetCommandRefGithub(a_CommandName, a_CommandParams) local function GetCommandRefGithub(a_CommandName, a_CommandParams)
assert(type(a_CommandName) == "string"); assert(type(a_CommandName) == "string")
if (a_CommandParams == nil) then if (a_CommandParams == nil) then
return "`" .. a_CommandName .. "`"; return "`" .. a_CommandName .. "`"
end end
assert(type(a_CommandParams) == "table"); assert(type(a_CommandParams) == "table")
if ((a_CommandParams.Params == nil) or (a_CommandParams.Params == "")) then if ((a_CommandParams.Params == nil) or (a_CommandParams.Params == "")) then
return "`" .. a_CommandName .. "`"; return "`" .. a_CommandName .. "`"
end end
assert(type(a_CommandParams.Params) == "string"); assert(type(a_CommandParams.Params) == "string")
return "`" .. a_CommandName .. " " .. a_CommandParams.Params .. "`"; return "`" .. a_CommandName .. " " .. a_CommandParams.Params .. "`"
end end
@ -221,25 +221,25 @@ end
--- Writes the specified command detailed help array to the output file, in the forum dump format --- Writes the specified command detailed help array to the output file, in the forum dump format
local function WriteCommandParameterCombinationsForum(a_CmdString, a_ParameterCombinations, f) local function WriteCommandParameterCombinationsForum(a_CmdString, a_ParameterCombinations, f)
assert(type(a_CmdString) == "string"); assert(type(a_CmdString) == "string")
assert(type(a_ParameterCombinations) == "table"); assert(type(a_ParameterCombinations) == "table")
assert(f ~= nil); assert(f ~= nil)
if (#a_ParameterCombinations == 0) then if (#a_ParameterCombinations == 0) then
-- No explicit parameter combinations to write -- No explicit parameter combinations to write
return; return
end end
f:write("The following parameter combinations are recognized:\n"); f:write("The following parameter combinations are recognized:\n")
for idx, combination in ipairs(a_ParameterCombinations) do for idx, combination in ipairs(a_ParameterCombinations) do
f:write("[color=blue]", a_CmdString, "[/color] [color=green]", combination.Params or "", "[/color]"); f:write("[color=blue]", a_CmdString, "[/color] [color=green]", combination.Params or "", "[/color]")
if (combination.Help ~= nil) then if (combination.Help ~= nil) then
f:write(" - ", ForumizeString(combination.Help)); f:write(" - ", ForumizeString(combination.Help))
end end
if (combination.Permission ~= nil) then if (combination.Permission ~= nil) then
f:write(" (Requires permission '[color=red]", combination.Permission, "[/color]')"); f:write(" (Requires permission '[color=red]", combination.Permission, "[/color]')")
end end
f:write("\n"); f:write("\n")
end end
end end
@ -249,25 +249,25 @@ end
--- Writes the specified command detailed help array to the output file, in the forum dump format --- Writes the specified command detailed help array to the output file, in the forum dump format
local function WriteCommandParameterCombinationsGithub(a_CmdString, a_ParameterCombinations, f) local function WriteCommandParameterCombinationsGithub(a_CmdString, a_ParameterCombinations, f)
assert(type(a_CmdString) == "string"); assert(type(a_CmdString) == "string")
assert(type(a_ParameterCombinations) == "table"); assert(type(a_ParameterCombinations) == "table")
assert(f ~= nil); assert(f ~= nil)
if (#a_ParameterCombinations == 0) then if (#a_ParameterCombinations == 0) then
-- No explicit parameter combinations to write -- No explicit parameter combinations to write
return; return
end end
f:write("The following parameter combinations are recognized:\n\n"); f:write("The following parameter combinations are recognized:\n\n")
for idx, combination in ipairs(a_ParameterCombinations) do for idx, combination in ipairs(a_ParameterCombinations) do
f:write(GetCommandRefGithub(a_CmdString, combination)); f:write(GetCommandRefGithub(a_CmdString, combination))
if (combination.Help ~= nil) then if (combination.Help ~= nil) then
f:write(" - ", GithubizeString(combination.Help)); f:write(" - ", GithubizeString(combination.Help))
end end
if (combination.Permission ~= nil) then if (combination.Permission ~= nil) then
f:write(" (Requires permission '**", combination.Permission, "**')"); f:write(" (Requires permission '**", combination.Permission, "**')")
end end
f:write("\n"); f:write("\n")
end end
end end
@ -278,29 +278,29 @@ end
--- Writes all commands in the specified category to the output file, in the forum dump format --- Writes all commands in the specified category to the output file, in the forum dump format
local function WriteCommandsCategoryForum(a_Category, f) local function WriteCommandsCategoryForum(a_Category, f)
-- Write category name: -- Write category name:
local CategoryName = a_Category.Name; local CategoryName = a_Category.Name
if (CategoryName == "") then if (CategoryName == "") then
CategoryName = "General"; CategoryName = "General"
end end
f:write("\n[size=Large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n"); f:write("\n[size=Large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n")
-- Write description: -- Write description:
if (a_Category.Description ~= "") then if (a_Category.Description ~= "") then
f:write(ForumizeString(a_Category.Description), "\n"); f:write(ForumizeString(a_Category.Description), "\n")
end end
-- Write commands: -- Write commands:
f:write("\n[list]"); f:write("\n[list]")
for idx2, cmd in ipairs(a_Category.Commands) do for idx2, cmd in ipairs(a_Category.Commands) do
f:write("\n[b]", cmd.CommandString, "[/b] - ", ForumizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n"); f:write("\n[b]", cmd.CommandString, "[/b] - ", ForumizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n")
if (cmd.Info.Permission ~= nil) then if (cmd.Info.Permission ~= nil) then
f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n"); f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n")
end end
if (cmd.Info.DetailedDescription ~= nil) then if (cmd.Info.DetailedDescription ~= nil) then
f:write(ForumizeString(cmd.Info.DetailedDescription)); f:write(ForumizeString(cmd.Info.DetailedDescription))
end end
if (cmd.Info.ParameterCombinations ~= nil) then if (cmd.Info.ParameterCombinations ~= nil) then
WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f); WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f)
end end
end end
f:write("[/list]\n\n") f:write("[/list]\n\n")
@ -313,23 +313,23 @@ end
--- Writes all commands in the specified category to the output file, in the Github dump format --- Writes all commands in the specified category to the output file, in the Github dump format
local function WriteCommandsCategoryGithub(a_Category, f) local function WriteCommandsCategoryGithub(a_Category, f)
-- Write category name: -- Write category name:
local CategoryName = a_Category.Name; local CategoryName = a_Category.Name
if (CategoryName == "") then if (CategoryName == "") then
CategoryName = "General"; CategoryName = "General"
end end
f:write("\n### ", GithubizeString(a_Category.DisplayName or CategoryName), "\n"); f:write("\n### ", GithubizeString(a_Category.DisplayName or CategoryName), "\n")
-- Write description: -- Write description:
if (a_Category.Description ~= "") then if (a_Category.Description ~= "") then
f:write(GithubizeString(a_Category.Description), "\n\n"); f:write(GithubizeString(a_Category.Description), "\n\n")
end end
f:write("| Command | Permission | Description | \n") f:write("| Command | Permission | Description |\n")
f:write("| ------- | ---------- | ----------- | \n") f:write("| ------- | ---------- | ----------- |\n")
-- Write commands: -- Write commands:
for idx2, cmd in ipairs(a_Category.Commands) do for idx2, cmd in ipairs(a_Category.Commands) do
f:write("|", cmd.CommandString, " | ", cmd.Info.Permission or "", " | ", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "| \n") f:write("|", cmd.CommandString, " | ", cmd.Info.Permission or "", " | ", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "|\n")
end end
f:write("\n\n") f:write("\n\n")
end end
@ -340,24 +340,24 @@ end
local function DumpCommandsForum(a_PluginInfo, f) local function DumpCommandsForum(a_PluginInfo, f)
-- Copy all Categories from a dictionary into an array: -- Copy all Categories from a dictionary into an array:
local Categories = BuildCategories(a_PluginInfo); local Categories = BuildCategories(a_PluginInfo)
-- Sort the categories by name: -- Sort the categories by name:
table.sort(Categories, table.sort(Categories,
function(cat1, cat2) function(cat1, cat2)
return (string.lower(cat1.Name) < string.lower(cat2.Name)); return (string.lower(cat1.Name) < string.lower(cat2.Name))
end end
); )
if (#Categories == 0) then if (#Categories == 0) then
return; return
end end
f:write("\n[size=X-Large]Commands[/size]\n"); f:write("\n[size=X-Large]Commands[/size]\n")
-- Dump per-category commands: -- Dump per-category commands:
for idx, cat in ipairs(Categories) do for idx, cat in ipairs(Categories) do
WriteCommandsCategoryForum(cat, f); WriteCommandsCategoryForum(cat, f)
end end
end end
@ -367,24 +367,24 @@ end
local function DumpCommandsGithub(a_PluginInfo, f) local function DumpCommandsGithub(a_PluginInfo, f)
-- Copy all Categories from a dictionary into an array: -- Copy all Categories from a dictionary into an array:
local Categories = BuildCategories(a_PluginInfo); local Categories = BuildCategories(a_PluginInfo)
-- Sort the categories by name: -- Sort the categories by name:
table.sort(Categories, table.sort(Categories,
function(cat1, cat2) function(cat1, cat2)
return (string.lower(cat1.Name) < string.lower(cat2.Name)); return (string.lower(cat1.Name) < string.lower(cat2.Name))
end end
); )
if (#Categories == 0) then if (#Categories == 0) then
return; return
end end
f:write("\n# Commands\n"); f:write("\n# Commands\n")
-- Dump per-category commands: -- Dump per-category commands:
for idx, cat in ipairs(Categories) do for idx, cat in ipairs(Categories) do
WriteCommandsCategoryGithub(cat, f); WriteCommandsCategoryGithub(cat, f)
end end
end end
@ -393,16 +393,16 @@ end
local function DumpAdditionalInfoForum(a_PluginInfo, f) local function DumpAdditionalInfoForum(a_PluginInfo, f)
local AInfo = a_PluginInfo.AdditionalInfo; local AInfo = a_PluginInfo.AdditionalInfo
if (type(AInfo) ~= "table") then if (type(AInfo) ~= "table") then
-- There is no AdditionalInfo in a_PluginInfo -- There is no AdditionalInfo in a_PluginInfo
return; return
end end
for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do
if ((info.Title ~= nil) and (info.Contents ~= nil)) then if ((info.Title ~= nil) and (info.Contents ~= nil)) then
f:write("\n[size=X-Large]", ForumizeString(info.Title), "[/size]\n"); f:write("\n[size=X-Large]", ForumizeString(info.Title), "[/size]\n")
f:write(ForumizeString(info.Contents), "\n"); f:write(ForumizeString(info.Contents), "\n")
end end
end end
end end
@ -412,16 +412,16 @@ end
local function DumpAdditionalInfoGithub(a_PluginInfo, f) local function DumpAdditionalInfoGithub(a_PluginInfo, f)
local AInfo = a_PluginInfo.AdditionalInfo; local AInfo = a_PluginInfo.AdditionalInfo
if (type(AInfo) ~= "table") then if (type(AInfo) ~= "table") then
-- There is no AdditionalInfo in a_PluginInfo -- There is no AdditionalInfo in a_PluginInfo
return; return
end end
for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do
if ((info.Title ~= nil) and (info.Contents ~= nil)) then if ((info.Title ~= nil) and (info.Contents ~= nil)) then
f:write("\n# ", GithubizeString(info.Title), "\n"); f:write("\n# ", GithubizeString(info.Title), "\n")
f:write(GithubizeString(info.Contents), "\n"); f:write(GithubizeString(info.Contents), "\n")
end end
end end
end end
@ -434,53 +434,53 @@ end
-- Each array item is {Name = "PermissionName", Info = { PermissionInfo }} -- Each array item is {Name = "PermissionName", Info = { PermissionInfo }}
local function BuildPermissions(a_PluginInfo) local function BuildPermissions(a_PluginInfo)
-- Collect all used permissions from Commands, reference the commands that use the permission: -- Collect all used permissions from Commands, reference the commands that use the permission:
local Permissions = a_PluginInfo.Permissions or {}; local Permissions = a_PluginInfo.Permissions or {}
local function CollectPermissions(a_CmdPrefix, a_Commands) local function CollectPermissions(a_CmdPrefix, a_Commands)
for cmd, info in pairs(a_Commands) do for cmd, info in pairs(a_Commands) do
CommandString = a_CmdPrefix .. cmd; CommandString = a_CmdPrefix .. cmd
if ((info.Permission ~= nil) and (info.Permission ~= "")) then if ((info.Permission ~= nil) and (info.Permission ~= "")) then
-- Add the permission to the list of permissions: -- Add the permission to the list of permissions:
local Permission = Permissions[info.Permission] or {}; local Permission = Permissions[info.Permission] or {}
Permissions[info.Permission] = Permission; Permissions[info.Permission] = Permission
-- Add the command to the list of commands using this permission: -- Add the command to the list of commands using this permission:
Permission.CommandsAffected = Permission.CommandsAffected or {}; Permission.CommandsAffected = Permission.CommandsAffected or {}
table.insert(Permission.CommandsAffected, CommandString); table.insert(Permission.CommandsAffected, CommandString)
end end
-- Process the command param combinations for permissions: -- Process the command param combinations for permissions:
local ParamCombinations = info.ParameterCombinations or {}; local ParamCombinations = info.ParameterCombinations or {}
for idx, comb in ipairs(ParamCombinations) do for idx, comb in ipairs(ParamCombinations) do
if ((comb.Permission ~= nil) and (comb.Permission ~= "")) then if ((comb.Permission ~= nil) and (comb.Permission ~= "")) then
-- Add the permission to the list of permissions: -- Add the permission to the list of permissions:
local Permission = Permissions[comb.Permission] or {}; local Permission = Permissions[comb.Permission] or {}
Permissions[info.Permission] = Permission; Permissions[info.Permission] = Permission
-- Add the command to the list of commands using this permission: -- Add the command to the list of commands using this permission:
Permission.CommandsAffected = Permission.CommandsAffected or {}; Permission.CommandsAffected = Permission.CommandsAffected or {}
table.insert(Permission.CommandsAffected, {Name = CommandString, Params = comb.Params}); table.insert(Permission.CommandsAffected, {Name = CommandString, Params = comb.Params})
end end
end end
-- Process subcommands: -- Process subcommands:
if (info.Subcommands ~= nil) then if (info.Subcommands ~= nil) then
CollectPermissions(CommandString .. " ", info.Subcommands); CollectPermissions(CommandString .. " ", info.Subcommands)
end end
end end
end end
CollectPermissions("", a_PluginInfo.Commands); CollectPermissions("", a_PluginInfo.Commands)
-- Copy the list of permissions to an array: -- Copy the list of permissions to an array:
local PermArray = {}; local PermArray = {}
for name, perm in pairs(Permissions) do for name, perm in pairs(Permissions) do
table.insert(PermArray, {Name = name, Info = perm}); table.insert(PermArray, {Name = name, Info = perm})
end end
-- Sort the permissions array: -- Sort the permissions array:
table.sort(PermArray, table.sort(PermArray,
function(p1, p2) function(p1, p2)
return (p1.Name < p2.Name); return (p1.Name < p2.Name)
end end
); )
return PermArray; return PermArray
end end
@ -489,32 +489,32 @@ end
local function DumpPermissionsForum(a_PluginInfo, f) local function DumpPermissionsForum(a_PluginInfo, f)
-- Get the processed sorted array of permissions: -- Get the processed sorted array of permissions:
local Permissions = BuildPermissions(a_PluginInfo); local Permissions = BuildPermissions(a_PluginInfo)
if ((Permissions == nil) or (#Permissions <= 0)) then if ((Permissions == nil) or (#Permissions <= 0)) then
return; return
end end
-- Dump the permissions: -- Dump the permissions:
f:write("\n[size=X-Large]Permissions[/size]\n[list]\n"); f:write("\n[size=X-Large]Permissions[/size]\n[list]\n")
for idx, perm in ipairs(Permissions) do for idx, perm in ipairs(Permissions) do
f:write(" - [color=red]", perm.Name, "[/color] - "); f:write(" - [color=red]", perm.Name, "[/color] - ")
f:write(ForumizeString(perm.Info.Description or "")); f:write(ForumizeString(perm.Info.Description or ""))
local CommandsAffected = perm.Info.CommandsAffected or {}; local CommandsAffected = perm.Info.CommandsAffected or {}
if (#CommandsAffected > 0) then if (#CommandsAffected > 0) then
f:write("\n[list] Commands affected:\n- "); f:write("\n[list] Commands affected:\n- ")
local Affects = {}; local Affects = {}
for idx2, cmd in ipairs(CommandsAffected) do for idx2, cmd in ipairs(CommandsAffected) do
table.insert(Affects, GetCommandRefForum(cmd)); table.insert(Affects, GetCommandRefForum(cmd))
end end
f:write(table.concat(Affects, "\n - ")); f:write(table.concat(Affects, "\n - "))
f:write("\n[/list]"); f:write("\n[/list]")
end end
if (perm.Info.RecommendedGroups ~= nil) then if (perm.Info.RecommendedGroups ~= nil) then
f:write("\n[list] Recommended groups: ", perm.Info.RecommendedGroups, "[/list]"); f:write("\n[list] Recommended groups: ", perm.Info.RecommendedGroups, "[/list]")
end end
f:write("\n"); f:write("\n")
end end
f:write("[/list]"); f:write("[/list]")
end end
@ -523,34 +523,35 @@ end
local function DumpPermissionsGithub(a_PluginInfo, f) local function DumpPermissionsGithub(a_PluginInfo, f)
-- Get the processed sorted array of permissions: -- Get the processed sorted array of permissions:
local Permissions = BuildPermissions(a_PluginInfo); local Permissions = BuildPermissions(a_PluginInfo)
if ((Permissions == nil) or (#Permissions <= 0)) then if ((Permissions == nil) or (#Permissions <= 0)) then
return; return
end end
-- Dump the permissions: -- Dump the permissions:
f:write("\n# Permissions\n"); f:write("\n# Permissions\n")
f:write("| Permissions | Description | Commands | Recommended groups |\n") f:write("| Permissions | Description | Commands | Recommended groups |\n")
f:write("| ----------- | ----------- | -------- | ------------------ |\n") f:write("| ----------- | ----------- | -------- | ------------------ |\n")
for idx, perm in ipairs(Permissions) do for idx, perm in ipairs(Permissions) do
f:write(perm.Name, " | "); f:write("| ", perm.Name, " | ")
f:write(GithubizeString(perm.Info.Description or ""), " | "); f:write(GithubizeString(perm.Info.Description or ""), " | ")
local CommandsAffected = perm.Info.CommandsAffected or {}; local CommandsAffected = perm.Info.CommandsAffected or {}
if (#CommandsAffected > 0) then if (#CommandsAffected > 0) then
local Affects = {}; local Affects = {}
for idx2, cmd in ipairs(CommandsAffected) do for idx2, cmd in ipairs(CommandsAffected) do
if (type(cmd) == "string") then if (type(cmd) == "string") then
table.insert(Affects, GetCommandRefGithub(cmd)); table.insert(Affects, GetCommandRefGithub(cmd))
else else
table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd)); table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd))
end end
end end
f:write(table.concat(Affects, ", "), " | "); f:write(table.concat(Affects, ", "))
end end
f:write(" | ")
if (perm.Info.RecommendedGroups ~= nil) then if (perm.Info.RecommendedGroups ~= nil) then
f:write(perm.Info.RecommendedGroups, " |"); f:write(perm.Info.RecommendedGroups)
end end
f:write("\n"); f:write(" |\n")
end end
end end
@ -558,45 +559,53 @@ end
--- Dumps the forum-format info for the plugin
-- Returns true on success, nil and error message on failure
local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo) local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo)
-- Open the output file: -- Open the output file:
local f, msg = io.open(a_PluginInfo.Name .. "_forum.txt", "w"); local f, msg = io.open(a_PluginFolder .. "/forum_info.txt", "w")
if (f == nil) then if (f == nil) then
print("\tCannot dump forum info for plugin " .. a_PluginFolder .. ": " .. msg); return nil, msg
return;
end end
-- Write the description: -- Write the description:
f:write(ForumizeString(a_PluginInfo.Description), "\n"); f:write(ForumizeString(a_PluginInfo.Description), "\n")
DumpAdditionalInfoForum(a_PluginInfo, f); DumpAdditionalInfoForum(a_PluginInfo, f)
DumpCommandsForum(a_PluginInfo, f); DumpCommandsForum(a_PluginInfo, f)
DumpPermissionsForum(a_PluginInfo, f); DumpPermissionsForum(a_PluginInfo, f)
if (a_PluginInfo.SourceLocation ~= nil) then if (a_PluginInfo.SourceLocation ~= nil) then
f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]"); f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]")
end end
f:close()
f:close(); return true
end end
--- Dumps the README.md file into the plugin's folder with the GitHub Markdown format
-- Returns true on success, nil and error message on failure
local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo) local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo)
-- Check the params:
assert(type(a_PluginFolder) == "string")
assert(type(a_PluginInfo) == "table")
-- Open the output file: -- Open the output file:
local f, msg = io.open(a_PluginInfo.Name .. ".md", "w"); -- TODO: Save to a_PluginFolder .. "/Readme.md" instead local f, msg = io.open(a_PluginFolder .. "/README.md", "w")
if (f == nil) then if (f == nil) then
print("\tCannot dump github info for plugin " .. a_PluginFolder .. ": " .. msg); print("\tCannot dump github info for plugin " .. a_PluginFolder .. ": " .. msg)
return; return nil, msg
end end
-- Write the description: -- Write the description:
f:write(GithubizeString(a_PluginInfo.Description), "\n"); f:write(GithubizeString(a_PluginInfo.Description), "\n")
DumpAdditionalInfoGithub(a_PluginInfo, f); DumpAdditionalInfoGithub(a_PluginInfo, f)
DumpCommandsGithub(a_PluginInfo, f); DumpCommandsGithub(a_PluginInfo, f)
DumpPermissionsGithub(a_PluginInfo, f); DumpPermissionsGithub(a_PluginInfo, f)
f:close(); f:close()
return true
end end
@ -607,36 +616,54 @@ end
-- Returns the g_PluginInfo table on success, or nil and error message on failure -- Returns the g_PluginInfo table on success, or nil and error message on failure
local function LoadPluginInfo(a_FolderName) local function LoadPluginInfo(a_FolderName)
-- Load and compile the Info file: -- Load and compile the Info file:
local cfg, err = loadfile(a_FolderName .. "/Info.lua"); local cfg, err = loadfile(a_FolderName .. "/Info.lua")
if (cfg == nil) then if (cfg == nil) then
return nil, "Cannot open 'Info.lua': " .. err; return nil, "Cannot open 'Info.lua': " .. err
end end
-- Execute the loaded file in a sandbox: -- Execute the loaded file in a sandbox:
-- This is Lua-5.1-specific and won't work in Lua 5.2! -- This is Lua-5.1-specific and won't work in Lua 5.2!
local Sandbox = {}; local Sandbox = {}
setfenv(cfg, Sandbox); setfenv(cfg, Sandbox)
cfg(); local isSuccess, errMsg = pcall(cfg)
if (Sandbox.g_PluginInfo == nil) then if not(isSuccess) then
return nil, "Info.lua doesn't contain the g_PluginInfo declaration"; return nil, "Cannot load Info.lua: " .. (errMsg or "<unknown error>")
end end
return Sandbox.g_PluginInfo;
if (Sandbox.g_PluginInfo == nil) then
return nil, "Info.lua doesn't contain the g_PluginInfo declaration"
end
return Sandbox.g_PluginInfo
end end
--- Processes the info for one plugin
-- Returns true on success, nil and error message on failure
local function ProcessPluginFolder(a_FolderName) local function ProcessPluginFolder(a_FolderName)
local PluginInfo, Msg = LoadPluginInfo(a_FolderName); -- Load the plugin info:
local PluginInfo, Msg = LoadPluginInfo(a_FolderName)
if (PluginInfo == nil) then if (PluginInfo == nil) then
if (Msg ~= nil) then return nil, "Cannot load info for plugin " .. a_FolderName .. ": " .. (Msg or "<unknown error>")
print("\t" .. Msg);
end
return;
end end
DumpPluginInfoForum(a_FolderName, PluginInfo);
DumpPluginInfoGithub(a_FolderName, PluginInfo); -- Dump the forum format:
local isSuccess
isSuccess, Msg = DumpPluginInfoForum(a_FolderName, PluginInfo)
if not(isSuccess) then
return nil, "Cannot dump forum info for plugin " .. a_FolderName .. ": " .. (Msg or "<unknown error>")
end
-- Dump the GitHub format:
isSuccess, Msg = DumpPluginInfoGithub(a_FolderName, PluginInfo)
if not(isSuccess) then
return nil, "Cannot dump GitHub info for plugin " .. a_FolderName .. ": " .. (Msg or "<unknown error>")
end
-- All OK, return success
return true
end end
@ -650,7 +677,7 @@ local function LoadLFS()
function() function()
return require("lfs") return require("lfs")
end end
); )
-- ... rather, print a nice message with instructions: -- ... rather, print a nice message with instructions:
if not(lfs) then if not(lfs) then
@ -663,44 +690,50 @@ local function LoadLFS()
If you don't have luarocks installed, you need to install them using your OS's package manager, usually: If you don't have luarocks installed, you need to install them using your OS's package manager, usually:
sudo apt-get install luarocks (Ubuntu / Debian) sudo apt-get install luarocks (Ubuntu / Debian)
On windows, a binary distribution can be downloaded from the LuaRocks homepage, http://luarocks.org/en/Download On windows, a binary distribution can be downloaded from the LuaRocks homepage, http://luarocks.org/en/Download
]]); ]])
print("Original error text: ", err); print("Original error text: ", err)
return nil; return nil
end end
-- We now know that LFS is present, get it normally: -- We now know that LFS is present, get it normally:
return require("lfs"); return require("lfs")
end end
local Arg1 = ...; local Arg1 = arg[1]
if ((Arg1 ~= nil) and (Arg1 ~= "")) then if ((Arg1 ~= nil) and (Arg1 ~= "")) then
-- Called with a plugin folder name, export only that one -- Called with a plugin folder name, export only that one
ProcessPluginFolder(Arg1) local isSuccess, msg = ProcessPluginFolder(Arg1)
if not(isSuccess) then
print(msg or "<unknown error>")
end
else else
-- Called without any arguments, process all subfolders: -- Called without any arguments, process all subfolders:
local lfs = LoadLFS(); local lfs = LoadLFS()
if (lfs == nil) then if (lfs == nil) then
-- LFS not loaded, error has already been printed, just bail out -- LFS not loaded, error has already been printed, just bail out
return; return
end end
print("Processing plugin subfolders:"); print("Processing plugin subfolders:")
for fnam in lfs.dir(".") do for fnam in lfs.dir(".") do
if ((fnam ~= ".") and (fnam ~= "..")) then if ((fnam ~= ".") and (fnam ~= "..")) then
local Attributes = lfs.attributes(fnam); local Attributes = lfs.attributes(fnam)
if (Attributes ~= nil) then if (Attributes ~= nil) then
if (Attributes.mode == "directory") then if (Attributes.mode == "directory") then
print(fnam); print(fnam)
ProcessPluginFolder(fnam); local isSuccess, msg = ProcessPluginFolder(fnam)
if not(isSuccess) then
print(" " .. (msg or "<unknown error>"))
end
end end
end end
end end
end end
end end
print("Done."); print("Done.")

View File

@ -1,97 +0,0 @@
-- Location object
cLocation = {}
function cLocation:new( x, y, z )
local object = { x = x, y = y, z = z }
setmetatable(object, { __index = cLocation })
return object
end
-- Offsets
cFibers = { }
function cFibers:new()
local object = {
cLocation:new( 2, -1, 2 ),
cLocation:new( 2, -1, 1 ),
cLocation:new( 2, -1, 0 ),
cLocation:new( 2, -1, -1 ),
cLocation:new( 2, -1, -2 ),
cLocation:new( 1, -1, 2 ),
cLocation:new( 1, -1, 1 ),
cLocation:new( 1, -1, 0 ),
cLocation:new( 1, -1, -1 ),
cLocation:new( 1, -1, -2 ),
cLocation:new( 0, -1, 2 ),
cLocation:new( 0, -1, 1 ),
cLocation:new( 0, -1, 0 ),
cLocation:new( 0, -1, -1 ),
cLocation:new( 0, -1, -2 ),
cLocation:new( -1, -1, 2 ),
cLocation:new( -1, -1, 1 ),
cLocation:new( -1, -1, 0 ),
cLocation:new( -1, -1, -1 ),
cLocation:new( -1, -1, -2 ),
cLocation:new( -2, -1, 2 ),
cLocation:new( -2, -1, 1 ),
cLocation:new( -2, -1, 0 ),
cLocation:new( -2, -1, -1 ),
cLocation:new( -2, -1, -2 ),
imadeit = false,
}
setmetatable(object, { __index = cFibers })
return object;
end
-- Carpet object
cCarpet = {}
function cCarpet:new()
local object = { Location = cLocation:new(0,0,0),
Fibers = cFibers:new(),
}
setmetatable(object, { __index = cCarpet })
return object
end
function cCarpet:remove()
local World = cRoot:Get():GetDefaultWorld()
for i, fib in ipairs( self.Fibers ) do
local x = self.Location.x + fib.x
local y = self.Location.y + fib.y
local z = self.Location.z + fib.z
local BlockID = World:GetBlock( x, y, z )
if( fib.imadeit == true and BlockID == E_BLOCK_GLASS ) then
World:SetBlock( x, y, z, 0, 0 )
fib.imadeit = false
end
end
end
function cCarpet:draw()
local World = cRoot:Get():GetDefaultWorld()
for i, fib in ipairs( self.Fibers ) do
local x = self.Location.x + fib.x
local y = self.Location.y + fib.y
local z = self.Location.z + fib.z
local BlockID = World:GetBlock( x, y, z )
if( BlockID == 0 ) then
fib.imadeit = true
World:SetBlock( x, y, z, E_BLOCK_GLASS, 0 )
else
fib.imadeit = false
end
end
end
function cCarpet:moveTo( NewPos )
local x = math.floor( NewPos.x )
local y = math.floor( NewPos.y )
local z = math.floor( NewPos.z )
if( self.Location.x ~= x or self.Location.y ~= y or self.Location.z ~= z ) then
self:remove()
self.Location = cLocation:new( x, y, z )
self:draw()
end
end
function cCarpet:getY()
return self.Location.y
end

View File

@ -1,81 +0,0 @@
local Carpets = {}
local PLUGIN
function Initialize( Plugin )
Plugin:SetName( "MagicCarpet" )
Plugin:SetVersion( 2 )
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_DESTROYED, OnDisconnect)
local PluginManager = cPluginManager:Get()
PluginManager:BindCommand("/mc", "magiccarpet", HandleCarpetCommand, " - Spawns a magical carpet");
PLUGIN = Plugin
LOG( "Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() )
return true
end
function OnDisable()
LOG( PLUGIN:GetName() .. " v." .. PLUGIN:GetVersion() .. " is shutting down..." )
for i, Carpet in pairs( Carpets ) do
Carpet:remove()
end
end
function HandleCarpetCommand( Split, Player )
Carpet = Carpets[ Player ]
if( Carpet == nil ) then
Carpets[ Player ] = cCarpet:new()
Player:SendMessageSuccess("You're on a magic carpet!")
Player:SendMessageInfo("Look straight down to descend. Jump to ascend.")
else
Carpet:remove()
Carpets[ Player ] = nil
Player:SendMessageSuccess("The carpet vanished!")
end
return true
end
function OnDisconnect( Reason, Player )
local Carpet = Carpets[ Player ]
if( Carpet ~= nil ) then
Carpet:remove()
end
Carpets[ Player ] = nil
end
function OnPlayerMoving(Player)
local Carpet = Carpets[ Player ]
if( Carpet == nil ) then
return
end
if( Player:GetPitch() == 90 ) then
Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY() - 1, Player:GetPosZ() ) )
else
if( Player:GetPosY() < Carpet:getY() ) then
Player:TeleportToCoords(Player:GetPosX(), Carpet:getY() + 0.2, Player:GetPosZ())
end
Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() ) )
end
end

File diff suppressed because one or more lines are too long

View File

@ -1,129 +1,140 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>{TITLE} | {PLUGIN_NAME}</title> <title>{TITLE} | {PLUGIN_NAME}</title>
<style type="text/css"> <style type="text/css">
body { body {
line-height: 1; line-height: 1;
background: #B8B8B8; background: #B8B8B8;
} }
#maincontent { #maincontent {
padding: 0px 25px 10px 25px; padding: 0px 25px 10px 25px;
} }
#wrapper { #wrapper {
min-width: 850px; min-width: 850px;
width: 75%; width: 75%;
margin: 10px auto; margin: 10px auto;
background-color: white; background-color: white;
border: 4px #888888 solid; border: 4px #888888 solid;
border-radius: 10px; border-radius: 10px;
font-family: Calibri, Trebuchet MS; font-family: Calibri, Trebuchet MS;
} }
header { header {
text-align:center; text-align:center;
padding: 10px; 0px; padding: 10px; 0px;
} }
span { span {
text-align: right; text-align: right;
float: right; float: right;
border-left: 2px #C8C8C8 solid; border-left: 2px #C8C8C8 solid;
border-bottom: 2px #C8C8C8 solid; border-bottom: 2px #C8C8C8 solid;
padding: 2px 10px; padding: 2px 10px;
} }
footer { footer {
font-family: helvetica; font-family: helvetica;
font-size: 10px; font-size: 10px;
text-align: center; text-align: center;
border-top: 1px #000 dotted; border-top: 1px #000 dotted;
padding: 1px 0px 1px 0px; padding: 1px 0px 1px 0px;
} }
table { table {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 10; border-spacing: 10;
} }
table { table {
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
width: 700px; width: 700px;
} }
table tr th { table tr th {
text-align: left; text-align: left;
background: #f6f6f6; background: #f6f6f6;
padding: 0px 20px; padding: 0px 20px;
height: 25px; height: 25px;
line-height: 25px; line-height: 25px;
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 3px; border-radius: 3px;
} }
table tr td { table tr td {
background: #f6f6f6; background: #f6f6f6;
padding: 0px 20px; padding: 0px 20px;
height: 29px; height: 29px;
line-height: 29px; line-height: 29px;
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 3px; border-radius: 3px;
} }
#main table tr.odd td {
background: #fbfbfb; #main table tr.odd td {
} background: #fbfbfb;
}
table tr:hover td { background: #fdfcf6; }
table .action { table tr:hover td {
text-align: right; background: #fdfcf6;
padding: 0 20px 0 10px; }
}
table .action {
table tr .action a { color: #9b9b9b; } text-align: right;
padding: 0 20px 0 10px;
#cssmenu{ height:10px; display:table; padding:0; margin: 0 auto; border:1px #707070 solid; border-radius:5px; } }
#cssmenu > ul {list-style:inside none; padding:0; margin:0;}
#cssmenu > ul > li {list-style:inside none; padding:0; margin:0; float:left; display:block; position:relative;} table tr .action a {
#cssmenu > ul > li > a{ outline:none; display:block; position:relative; color:#E8E8E8; padding:10px 10px; font:bold 13px/100% Arial, Helvetica, sans-serif; text-align:center; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.4); } color: #9b9b9b;
#cssmenu > ul > li:first-child > a{border-radius:5px 0 0 5px;} }
/* #cssmenu > ul > li > a:after{ content:''; position:absolute; border-right:1px solid #FFFFFF; top:-1px; bottom:-1px; right:-2px; z-index:99; } */
#cssmenu ul li.has-sub:hover > a:after{top:0; bottom:0;} #cssmenu{ height:10px; display:table; padding:0; margin: 0 auto; border:1px #707070 solid; border-radius:5px; }
#cssmenu > ul > li.has-sub > a:before{ content:''; position:absolute; top:18px; right:6px; border:5px solid transparent; border-top:5px solid #707070; } #cssmenu > ul {list-style:inside none; padding:0; margin:0;}
#cssmenu > ul > li.has-sub:hover > a:before{top:19px;} #cssmenu > ul > li {list-style:inside none; padding:0; margin:0; float:left; display:block; position:relative;}
#cssmenu ul li.has-sub:hover > a{ background:#3f3f3f; border-color:#707070; padding-bottom:13px; padding-top:13px; top:-1px; z-index:999; } #cssmenu > ul > li > a{ outline:none; display:block; position:relative; color:#E8E8E8; padding:10px 10px; font:bold 13px/100% Arial, Helvetica, sans-serif; text-align:center; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.4); }
#cssmenu ul li.has-sub:hover > ul, #cssmenu ul li.has-sub:hover > div{display:block;} #cssmenu > ul > li:first-child > a{border-radius:5px 0 0 5px;}
#cssmenu ul li.has-sub > a:hover{background:#3f3f3f; border-color:#3f3f3f;} /* #cssmenu > ul > li > a:after{ content:''; position:absolute; border-right:1px solid #FFFFFF; top:-1px; bottom:-1px; right:-2px; z-index:99; } */
#cssmenu ul li > ul, #cssmenu ul li > div{ display:none; width:auto; position:absolute; top:38px; padding:10px 0; background:#3f3f3f; border-radius:0 0 5px 5px; z-index:999; } #cssmenu ul li.has-sub:hover > a:after{top:0; bottom:0;}
#cssmenu ul li > ul{width:200px;} #cssmenu > ul > li.has-sub > a:before{ content:''; position:absolute; top:18px; right:6px; border:5px solid transparent; border-top:5px solid #707070; }
#cssmenu ul li > ul li{display:block; list-style:inside none; padding:0; margin:0; position:relative;} #cssmenu > ul > li.has-sub:hover > a:before{top:19px;}
#cssmenu ul li > ul li a{ outline:none; display:block; position:relative; margin:0; padding:8px 20px; font:10pt Arial, Helvetica, sans-serif; color:#fff; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.5); } #cssmenu ul li.has-sub:hover > a{ background:#3f3f3f; border-color:#707070; padding-bottom:13px; padding-top:13px; top:-1px; z-index:999; }
#cssmenu, #cssmenu > ul > li > ul > li a:hover{ background:#C8C8C8;} #cssmenu ul li.has-sub:hover > ul, #cssmenu ul li.has-sub:hover > div{display:block;}
#cssmenu > ul > li > a{border-right:1px solid #707070; color:#FFFFFF;} #cssmenu ul li.has-sub > a:hover{background:#3f3f3f; border-color:#3f3f3f;}
#cssmenu > ul > li > a:after{border-color:#707070;} #cssmenu ul li > ul, #cssmenu ul li > div{ display:none; width:auto; position:absolute; top:38px; padding:10px 0; background:#3f3f3f; border-radius:0 0 5px 5px; z-index:999; }
#cssmenu > ul > li > a:hover{background:#B8B8B8;} #cssmenu ul li > ul{width:200px;}
</style> #cssmenu ul li > ul li{display:block; list-style:inside none; padding:0; margin:0; position:relative;}
<meta name="msapplication-tooltip" content="MCServer WebAdministrator"/> #cssmenu ul li > ul li a{ outline:none; display:block; position:relative; margin:0; padding:8px 20px; font:10pt Arial, Helvetica, sans-serif; color:#fff; text-decoration:none; text-shadow:1px 1px 0 rgba(0,0,0, 0.5); }
<meta name="msapplication-navbutton-color" content="#B8B8B8" /> #cssmenu, #cssmenu > ul > li > ul > li a:hover{ background:#C8C8C8;}
<link rel="shortcut icon" href="http://mc-server.org/favicon.ico" /> #cssmenu > ul > li > a { border-right:1px solid #707070; color:#FFFFFF; }
</head> #cssmenu > ul > li > a:after { border-color:#707070; }
#cssmenu > ul > li > a:hover { background:#B8B8B8; }
<body> </style>
<div id="wrapper"> <meta name="msapplication-tooltip" content="MCServer WebAdministrator"/>
<span><b>Login: {USERNAME}</b></span><br /> <meta name="msapplication-navbutton-color" content="#B8B8B8" />
<header> <link rel="shortcut icon" href="http://mc-server.org/favicon.ico" />
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAAkCAMAAAAXdeBDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAuVQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs7OzAAAAAAAAoqKiAAAAvLy8AAAAlZWVtbW1j4+Pra2tiYmJp6enAAAAhISEoaGhAAAAgICAm5ube3t7lZWVd3d3kZGRc3NzjIyMbGxsg4ODgICAeHh43NzcdXV1cnJyy8vLWVlZbGxswcHB09PTvLy8uLi4tLS0sLCwvLy8uLi4tbW1oaGhnp6era2tm5ubqqqq39/f29vblZWV09PT4ODgz8/P3NzckZGRxcXF0tLSwsLCzs7Oy8vLyMjIt7e3vLy85ubm7u7u3d3d5+fn2tra5OTk19fX1dXV3t7e29vb2dnZ1tbW0dHRv7+/8PDw7u7u6+vr8fHx5ubm4+Pj7Ozs4eHh3t7e5+fn5OTk2tra4uLi39/f1dXV3d3d29vb2dnZ19fX1dXV0tLS9fX18/Pzzs7O7u7u8/PzycnJ6urq6Ojo7+/v5ubm7Ozs4+Pj4eHh39/f5ubm5OTk4uLi4ODg2NjY3Nzc29vb19fX8vLy9/f39fX17e3t8/Pz6+vr8fHx7+/v5+fn7e3t5eXl6+vr6enp6Ojo4ODg39/f9PT0+Pj48fHx9vb27+/v9PT07e3t8/Pz7Ozs8fHx7+/v6Ojo7u7u5+fn7Ozs5eXl6urq5OTk6enp5+fn5ubm5OTk+Pj49/f39fX19PT0+fn58vLy8fHx9fX19PT08vLy8fHx6urq+Pj49vb29fX19PT08vLy8PDw+/v7+vr6+Pj49/f39vb29fX18/Pz/f39+/v7+vr6+fn5+Pj49/f3/f39/Pz8+vr6/v7+/f39a5KrdZmxf6G2iai8kq/BnLbHpr7NsMXSuszYxNPdxmZTynBeznpqztvj0YV11Y+B2OLp2ZmM3aOY4a2j4enu5Liv6MK66/D07MzG8NbR9ODd9fj59+vo+/X0ucu1kQAAANl0Uk5TAAECAwQFBgcICQoLDA0ODxAREhMUFBUWFhcXGBgYGRkaGhsbGxwcHB0dHh4fHyEhIiQkJSYnKCgpKSorLC0uLzAxMjIzMzc4Ojo6Ozs8Pj4/P0BBQ0VISUtLTExNTk5PUFFTV1dYWVpbXFxdXl5fYGBhYmJjZGVmZ2doaWprbGxtbW5ub3BxcXJzdHV2d3l6e3x9fX5+f4CAgYGCg4SIi4yNjY6Oj4+QkJGSkpOTlJSVlZaXmJqbnJ2dnp+foKGip6+wsbKztb6/wMHCw8TOz9DR0tPf4OHv8LXp8fEAAAi/SURBVHja3Zh/dBRXFcdhZ+a9eTPzZnaXmJam0FYUEQWLrVVbqdZaf6EWQW2txN/SWiAmxFqtIlWr9bdWqkbwF6WQYIq/+WFpwSZqTahhg6RhNptkl9nsbjeb2eyv+dv73g6wlcyewXMazvGek3Dm5jLv8+689733vTn/q81ldr5zzsWxuVWr55sbCAiiBCYKAeZ1nYIgigJ4Zh2Zj+0OXesTgQ987pOEZUVVVYXISIJQPi3mJETG0kXADggIL5CRWDMy57kCaDgdBMgK1de0gi2jGsESZJt5iXpjS8utGkHiLFMDIHrNgfJBFYs1i0Ei73iifIAggIEHrNDWnuGpFFg50vEKVYbcArNye0+lUCj13aUgYbahRbInbqbu1zAf2XXpR8bN1CZZYItA1jb0pcaiJrdYorxzIRYFYN7qZC2wTOVXMuR+dqGR2hU3Y4NLFSlwJtGIfmbKNFOt4BIkQndOj5rR8dMpsETMjCae+gASJbLKSSftUsWeSJbWz3aqgXBvPGomOnWWajfRoWOjAN2uIWBedOh0NJoYPvJgW1tb+47I1Jg5Vl6AsPrkZLLU+f5bdjjpzNOzDo1pdzw2Fi2vVlBVFgRMf5oyYXl8lmIk00MJc7S8e6mhU02jerC5JzFavgyRlztWbl9j2NC3lvJbpMDFgJ6Ojh/VZb4XA5KycmhkNAXQOpG1ncDfv9HQQNsQZsK3cNvTn5SQ0lKwCveEdYWQd25BrugxUQHjAl/fPKL9Q2t747F/x82pjSpXC0Gme+EJoNt1Vb2jHI1FVlMmawFWYiQgB6mWCIcOaVgCA2ZX3BEGQyI4vAsXWN1of9Bd8diJZ0dG+3QiwuSRsq4cHf8rgzao3jMWnX5Al88oMdNnAQRPlOlwMrcvrBMYk2WrWmyIqlGqqYRJPE+kwK2a0Jr8wo9nNPzRL/QvTpupH4HsAQ4DLX+ZQQeNN02b8W6DSLWVh5mA+EbcHaKkWhF5sdGWdfREIj0dyzSCBDAJY1nGCKo/r/9uguEB/uQZLQZ8Qe+JxwZffGx0ZGixgiSsbXzOTDz2RQYdDm1PmFNrNXTee+ZKMpO8fP+DhiYjAGLF5oYux86m01nb6bqBACr+4Id1/cZHH7pUxne+HkE63fp7522A5xn9IiHgF7ppM6DuokRWjD7Av+7zDHrevEgsFgkq0vndnVtcMvmhjkUKJFvEyqf7ckkrmU7Dr1zfXQTLXyoWv95ZydnblB8UKut5BYL/Rw4Uih9S6Qav6B9CnD/oSGPj0fFouVmn+sOwUH7W9DmmHg0Nw9H4Xp0IM1Z/KOOFjDVhR7ZqMpbVO5yMlS2eGhw8VYTJOC9RtOPp9Ak7adk/picnMv/UZL5jyO0ly+4INntGP+QfOhxeXY6O9c4L31QeGettaLyHQTeuKJsALQdm3PyI0Na+UtZKl3ZSjS7uzVr23z7e0Nj00t8Wk2nnZaoeSadtK1s6uJD+xLYKLSBOTJp6sklnxXLP6AOXin6XRyRoGLsS5nObm34HctccCrdz6GsYNJ0JmquFrOjNvcV0srQrFN5tW/bh5aHQvPm/KQHFVkULDsK3n/x7s0bURZDqPtAg+DxrSlau+5JOz2gVCX434nGod4uhpDzzielo/HFdD7bXzbSbbBHJmvEAbMjK5qZTyUz/8qCuhzsZxf0qUUODaSt94n06rB3aYVulZhVLMgXRcd5SL1oM+IamCtEeTpmn/wFyt1JV9ba6a9qlZtgKUE9kjn0vb+W/FdapsYtTaBgrDCP/3bAiQX4XD01ke6B8qisdkPf5364TDcy+oQkmRu/YyGmmITKhbXXVwy10DFtSgjsgjX/KWc41IeMshQj+wTT4dBxg3cx2iGHbvCuXdN58yb560XP8Q8sSUpunzOho/xICX73trE5P33yeTgOre0KDNYLp1Y5l/xkwrm0In6UICMSArTUYVmHGMLNlTjLbGw69chj+aWjorhftHxoECWrh43HoouEluAodNNZMzVQRWQty2wJJ5NRIexU0fAz6tU2dVQomyVUM+ExCtXGspvjnLOGh0N460RcELQQkcn15/AnAFxCHbvPqPUSE9xedKyBDHPpqBm1blXc/5lKwfkRSOIbBNwQ8vQEW8x+uexaWtqEb2z2jLxSaadjb/vJWLAUCLnRtlye4bQ7CYPK7Slb+ayrMhfUqt1Ss/PeLlv17RvFVqsisEcQqx2C7+FyqfwmJXqcp2ke9oi8YGl4tSkgSAM6Fph799KcU7SSkLEgJxoSGYYVW3v5MZqIAFN8I65qqvu6RLUQLcgx4r9ukO0n7X5lsr04w0fu9on1CI5VDY4F/fN5DAnRriq3u2pMLrTm5XKVBjcvvDoPTCO8uJSePzr+3YFlp5ztNDUEjuO6pXP4rtAaDp/rI5ETBKn5MRbDl2zyifUMrDFrFgdoeTuHQyrkz4hCcEcF29PMz4lXKlVAk8r3fXHtzey8rw+8JzTtsW5POH++9dkV7twM1ehtlH/w4K6duqteWLCgphiyyJeUd7cMAkDwK0AQ9D5psAuhN5NxpfMQ9jY/y07gsK6ucSSubL1UKWYttJ5UuBY5kruA4BWjf7IOXqxRaoLPJgK5Dh36j0Mo6EJjBEo9on9AifiQeG8BSLbSA7wbou7HHvYcsSUhZ9aQ9YYFN5CJbVRnJ6pLDxYzFLVM8dDkhykA6PSDDe91UQ39X7fV4i+gZ7ceA6tW/HviCVNumwAh4f3k/ljxvmAQBkSs7TpYKheLQnusVJIIMErqxr1TI5QqVvg0gZAjfNzBwH3Lfy0DJeod31ezBO9qXsfOPexqqnQlagGa8y1MJFqviB85bW1o+QiHNTHEENrn3tnZ1tb6RsmMBkyJUcznJ5PIyyRX8OtF+jEsGG/S/fPyIOdOtKZuf2+NhonAPBLqTI6qmKQTDLPhrmbjXjnPmuW60/wtqryt07/tp3oA8z8MdCHHXjBcC7mOd6Bfk7r3udC94aDf6/9T+AzWzIkAbVeu4AAAAAElFTkSuQmCC" /> </head>
</header> <body>
<nav id="cssmenu"> <div id="wrapper">
<ul> <span>
{MENU} <b>Login: {USERNAME}</b>
</ul> </span>
</nav> <br />
<div id="maincontent"> <header>
{CONTENT} <img alt="" src="files/logo.png" />
</header>
<nav id="cssmenu">
<ul>
{MENU}
</ul>
</nav>
<div id="maincontent">
{CONTENT}
</div>
<footer>
<p>MCServer is using {MEM}MB of memory, with {NUMCHUNKS} chunks loaded.</p>
<p>Web Design by <a href="https://github.com/WebFreak001"@WebFreak001</a></p>
</footer>
</div> </div>
<footer><p>MCServer is using {MEM}MB of memory, with {NUMCHUNKS} chunks loaded.</p><p>Web Design by Tiger</p></footer> </body>
</div>
</head>
</html> </html>

View File

@ -3,26 +3,30 @@ MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](
MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API. MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API.
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis. MCServer can run on Windows, *nix and Android operating systems. This includes Android phones and tablets as well as Raspberry Pis.
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.8. We currently support Release 1.7 and 1.8 (not beta) Minecraft protocol versions.
Installation Installation
------------ ------------
Normally, you will want to download a pre-compiled version of MCServer from one of the buildservers: For Linux there is an easy installation method, just run this in your terminal:
* [Windows and Linux](http://builds.mc-server.org) curl -s https://raw.githubusercontent.com/mc-server/MCServer/master/easyinstall.sh | sh
* [Raspberry Pi](http://ci.bearbin.net)
You simply need to download and extract these files before you can use the server. For Windows, you just need to download a file and extract it:
If you're a more advanced user, you may want to compile the server yourself for more performance. See the [COMPILING.md](https://github.com/mc-server/MCServer/blob/master/COMPILING.md) file for more details. - [Windows 32 bit](http://builds.cuberite.org/job/MCServer%20Windows%20x86/lastSuccessfulBuild/artifact/Install/MCServer.zip)
- [Windows 64 bit](http://builds.cuberite.org/job/MCServer%20Windows%20x64/lastSuccessfulBuild/artifact/Install/MCServer.zip)
For other operating systems you need to download and compile yourself. There is also an archive of binary builds on the buildserver: http://builds.cuberite.org
Compiling the server yourself has other benefits: you may get better performance performance (1.5-3x as fast) and it supports more operating systems. See the [COMPILING.md](https://github.com/mc-server/MCServer/blob/master/COMPILING.md) file for more details.
Contributing Contributing
------------ ------------
MCServer is licensed under the Apache license V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team. MCServer is licensed under the Apache License V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team.
Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more details. Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more details.

View File

@ -59,12 +59,25 @@ macro(set_flags)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG") set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
elseif(APPLE) elseif(APPLE)
#on os x clang adds pthread for us but we need to add it for gcc
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (NOT GCC_VERSION VERSION_GREATER 4.6))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++0x")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
endif()
#on os x clang adds pthread for us but we need to add it for gcc
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_flags_cxx("-stdlib=libc++") add_flags_cxx("-stdlib=libc++")
add_flags_lnk("-stdlib=libc++") add_flags_lnk("-stdlib=libc++")
else() else()
@ -77,8 +90,17 @@ macro(set_flags)
add_flags_cxx("-pthread") add_flags_cxx("-pthread")
endif() endif()
# Make CLang use C++11, otherwise MSVC2008-supported extensions don't work ("override" keyword etc.): if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (NOT GCC_VERSION VERSION_GREATER 4.6))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++0x")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")

View File

@ -43,7 +43,7 @@ void BioGenSource::reload()
int seed = m_IniFile->GetValueSetI("Seed", "Seed", 0); int seed = m_IniFile->GetValueSetI("Seed", "Seed", 0);
bool unused = false; bool unused = false;
QMutexLocker lock(&m_Mtx); QMutexLocker lock(&m_Mtx);
m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused)); m_BiomeGen = cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused);
} }

View File

@ -53,7 +53,7 @@ protected:
cIniFilePtr m_IniFile; cIniFilePtr m_IniFile;
/** The generator used for generating biomes. */ /** The generator used for generating biomes. */
std::unique_ptr<cBiomeGen> m_BiomeGen; cBiomeGenPtr m_BiomeGen;
/** Guards m_BiomeGen against multithreaded access. */ /** Guards m_BiomeGen against multithreaded access. */
QMutex m_Mtx; QMutex m_Mtx;

View File

@ -59,7 +59,7 @@ GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent
m_IniFile->SetValue("Generator", "Generator", "Composable"); m_IniFile->SetValue("Generator", "Generator", "Composable");
m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString()); m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString());
bool dummy; bool dummy;
delete cBiomeGen::CreateBiomeGen(*m_IniFile, 0, dummy); cBiomeGen::CreateBiomeGen(*m_IniFile, 0, dummy);
} }
updateFromIni(); updateFromIni();
@ -91,7 +91,7 @@ void GeneratorSetup::generatorChanged(const QString & a_NewName)
// Create a dummy biome gen from the INI file, this will create the defaults in the INI file: // Create a dummy biome gen from the INI file, this will create the defaults in the INI file:
bool dummy; bool dummy;
delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy);
// Read all values from the INI file and put them into the form layout: // Read all values from the INI file and put them into the form layout:
updateFromIni(); updateFromIni();

17
easyinstall.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
PLATFORM=$(uname -m)
echo "Identifying platform: $PLATFORM"
case $PLATFORM in
"i686") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x86/lastSuccessfulBuild/artifact/MCServer.tar" ;;
"x86_64") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20x64/lastSuccessfulBuild/artifact/MCServer.tar" ;;
# Assume that all arm devices are a raspi for now.
"arm*") DOWNLOADURL="http://builds.cuberite.org/job/MCServer%20Linux%20armhf/lastSuccessfulBuild/artifact/MCServer.tar"
esac
echo "Downloading precompiled binaries."
curl -s $DOWNLOADURL | tar -xzf -
echo "Done."
echo "MCServer is now installed, run using 'cd MCServer; ./MCServer'."

@ -1 +1 @@
Subproject commit d6a15321ae51762098e49a976d26efa2493c94f6 Subproject commit 1ed82759c68f92c4acc7e3f33b850cf9f01c8aba

View File

@ -37,14 +37,12 @@ SET (HDRS
set (BINDING_OUTPUTS set (BINDING_OUTPUTS
${CMAKE_CURRENT_SOURCE_DIR}/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bindings.h ${CMAKE_CURRENT_SOURCE_DIR}/Bindings.h
${CMAKE_CURRENT_SOURCE_DIR}/LuaState_Call.inc
) )
set(BINDING_DEPENDENCIES set(BINDING_DEPENDENCIES
tolua tolua
../Bindings/virtual_method_hooks.lua ../Bindings/virtual_method_hooks.lua
../Bindings/AllToLua.pkg ../Bindings/AllToLua.pkg
../Bindings/gen_LuaState_Call.lua
../Bindings/LuaFunctions.h ../Bindings/LuaFunctions.h
../Bindings/LuaWindow.h ../Bindings/LuaWindow.h
../Bindings/Plugin.h ../Bindings/Plugin.h
@ -127,7 +125,6 @@ if (NOT MSVC)
endif () endif ()
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE)
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE)
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/LuaState_Call.inc PROPERTIES GENERATED TRUE)
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS -Wno-error) set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS -Wno-error)

View File

@ -130,8 +130,11 @@ void cLuaChunkStay::Enable(cChunkMap & a_ChunkMap, int a_OnChunkAvailableStackPo
void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ) void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ)
{ {
cPluginLua::cOperation Op(m_Plugin); if (m_OnChunkAvailable.IsValid())
Op().Call((int)m_OnChunkAvailable, a_ChunkX, a_ChunkZ); {
cPluginLua::cOperation Op(m_Plugin);
Op().Call((int)m_OnChunkAvailable, a_ChunkX, a_ChunkZ);
}
} }
@ -140,6 +143,7 @@ void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ)
bool cLuaChunkStay::OnAllChunksAvailable(void) bool cLuaChunkStay::OnAllChunksAvailable(void)
{ {
if (m_OnAllChunksAvailable.IsValid())
{ {
// Call the callback: // Call the callback:
cPluginLua::cOperation Op(m_Plugin); cPluginLua::cOperation Op(m_Plugin);

View File

@ -16,6 +16,8 @@ extern "C"
#include "Bindings.h" #include "Bindings.h"
#include "ManualBindings.h" #include "ManualBindings.h"
#include "DeprecatedBindings.h" #include "DeprecatedBindings.h"
#include "../Entities/Entity.h"
#include "../BlockEntities/BlockEntity.h"
// fwd: SQLite/lsqlite3.c // fwd: SQLite/lsqlite3.c
extern "C" extern "C"
@ -520,7 +522,7 @@ void cLuaState::Push(cBlockEntity * a_BlockEntity)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_pushusertype(m_LuaState, a_BlockEntity, "cBlockEntity"); tolua_pushusertype(m_LuaState, a_BlockEntity, (a_BlockEntity == nullptr) ? "cBlockEntity" : a_BlockEntity->GetClass());
m_NumCurrentFunctionArgs += 1; m_NumCurrentFunctionArgs += 1;
} }
@ -556,7 +558,61 @@ void cLuaState::Push(cEntity * a_Entity)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_pushusertype(m_LuaState, a_Entity, "cEntity"); if (a_Entity == nullptr)
{
lua_pushnil(m_LuaState);
}
else
{
switch (a_Entity->GetEntityType())
{
case cEntity::etMonster:
{
// Don't push specific mob types, as those are not exported in the API:
tolua_pushusertype(m_LuaState, a_Entity, "cMonster");
break;
}
case cEntity::etPlayer:
{
tolua_pushusertype(m_LuaState, a_Entity, "cPlayer");
break;
}
case cEntity::etPickup:
{
tolua_pushusertype(m_LuaState, a_Entity, "cPickup");
break;
}
case cEntity::etTNT:
{
tolua_pushusertype(m_LuaState, a_Entity, "cTNTEntity");
break;
}
case cEntity::etProjectile:
{
tolua_pushusertype(m_LuaState, a_Entity, "cProjectileEntity");
break;
}
case cEntity::etFloater:
{
tolua_pushusertype(m_LuaState, a_Entity, "cFloater");
break;
}
case cEntity::etEntity:
case cEntity::etEnderCrystal:
case cEntity::etFallingBlock:
case cEntity::etMinecart:
case cEntity::etBoat:
case cEntity::etExpOrb:
case cEntity::etItemFrame:
case cEntity::etPainting:
{
// Push the generic entity class type:
tolua_pushusertype(m_LuaState, a_Entity, "cEntity");
}
} // switch (EntityType)
}
m_NumCurrentFunctionArgs += 1; m_NumCurrentFunctionArgs += 1;
} }

View File

@ -240,10 +240,24 @@ public:
/** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */ /** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, pWorld & a_Value); void GetStackValue(int a_StackPos, pWorld & a_Value);
/** Call the specified Lua function.
Returns true if call succeeded, false if there was an error.
A special param of cRet & signifies the end of param list and the start of return values.
Example call: Call(Fn, Param1, Param2, Param3, cLuaState::Return, Ret1, Ret2) */
template <typename FnT, typename... Args>
bool Call(const FnT & a_Function, Args &&... args)
{
PushFunction(a_Function);
return PushCallPop(args...);
}
// Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script: /** Retrieves a list of values from the Lua stack, starting at the specified index. */
#include "LuaState_Call.inc" template <typename T, typename... Args>
inline void GetStackValues(int a_StartStackPos, T & a_Ret, Args &&... args)
{
GetStackValue(a_StartStackPos, a_Ret);
GetStackValues(a_StartStackPos + 1, args...);
}
/** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */ /** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */
bool CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam = -1); bool CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam = -1);
@ -310,6 +324,7 @@ public:
static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL); static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL);
protected: protected:
lua_State * m_LuaState; lua_State * m_LuaState;
/** If true, the state is owned by this object and will be auto-Closed. False => attached state */ /** If true, the state is owned by this object and will be auto-Closed. False => attached state */
@ -327,6 +342,63 @@ protected:
int m_NumCurrentFunctionArgs; int m_NumCurrentFunctionArgs;
/** Variadic template terminator: Counting zero args returns zero. */
int CountArgs(void)
{
return 0;
}
/** Variadic template: Counting args means add one to the count of the rest. */
template <typename T, typename... Args>
int CountArgs(T, Args... args)
{
return 1 + CountArgs(args...);
}
/** Variadic template terminator: If there's nothing more to push / pop, just call the function.
Note that there are no return values either, because those are prefixed by a cRet value, so the arg list is never empty. */
bool PushCallPop(void)
{
return CallFunction(0);
}
/** Variadic template recursor: More params to push. Push them and recurse. */
template <typename T, typename... Args>
inline bool PushCallPop(T a_Param, Args &&... args)
{
Push(a_Param);
return PushCallPop(args...);
}
/** Variadic template terminator: If there's nothing more to push, but return values to collect, call the function and collect the returns. */
template <typename... Args>
bool PushCallPop(cLuaState::cRet, Args &&... args)
{
// Calculate the number of return values (number of args left):
int NumReturns = CountArgs(args...);
// Call the function:
if (!CallFunction(NumReturns))
{
return false;
}
// Collect the return values:
GetStackValues(-NumReturns, args...);
lua_pop(m_LuaState, NumReturns);
// All successful:
return true;
}
/** Variadic template terminator: If there are no more values to get, bail out.
This function is not available in the public API, because it's an error to request no values directly; only internal functions can do that.
If you get a compile error saying this function is not accessible, check your calling code, you aren't reading any stack values. */
void GetStackValues(int a_StartingStackPos)
{
// Do nothing
}
/** Pushes the function of the specified name onto the stack. /** Pushes the function of the specified name onto the stack.
Returns true if successful. Logs a warning on failure (incl. m_SubsystemName) Returns true if successful. Logs a warning on failure (incl. m_SubsystemName)
*/ */

View File

@ -1160,7 +1160,7 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S)
return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1"); return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
} }
self->QueueTask(new cLuaWorldTask(*Plugin, FnRef)); self->QueueTask(make_unique<cLuaWorldTask>(*Plugin, FnRef));
return 0; return 0;
} }

View File

@ -34,7 +34,7 @@ static int tolua_cRankManager_AddGroup(lua_State * L)
S.GetStackValue(2, GroupName); S.GetStackValue(2, GroupName);
// Add the group: // Add the group:
cRoot::Get()->GetRankManager().AddGroup(GroupName); cRoot::Get()->GetRankManager()->AddGroup(GroupName);
return 0; return 0;
} }
@ -63,7 +63,7 @@ static int tolua_cRankManager_AddGroupToRank(lua_State * L)
S.GetStackValues(2, GroupName, RankName); S.GetStackValues(2, GroupName, RankName);
// Add the group to the rank: // Add the group to the rank:
S.Push(cRoot::Get()->GetRankManager().AddGroupToRank(GroupName, RankName)); S.Push(cRoot::Get()->GetRankManager()->AddGroupToRank(GroupName, RankName));
return 1; return 1;
} }
@ -92,7 +92,7 @@ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L)
S.GetStackValues(2, Permission, GroupName); S.GetStackValues(2, Permission, GroupName);
// Add the group to the rank: // Add the group to the rank:
S.Push(cRoot::Get()->GetRankManager().AddPermissionToGroup(Permission, GroupName)); S.Push(cRoot::Get()->GetRankManager()->AddPermissionToGroup(Permission, GroupName));
return 1; return 1;
} }
@ -121,7 +121,7 @@ static int tolua_cRankManager_AddRank(lua_State * L)
S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode);
// Add the rank: // Add the rank:
cRoot::Get()->GetRankManager().AddRank(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); cRoot::Get()->GetRankManager()->AddRank(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode);
return 0; return 0;
} }
@ -142,7 +142,7 @@ static int tolua_cRankManager_ClearPlayerRanks(lua_State * L)
} }
// Remove all players: // Remove all players:
cRoot::Get()->GetRankManager().ClearPlayerRanks(); cRoot::Get()->GetRankManager()->ClearPlayerRanks();
return 1; return 1;
} }
@ -166,7 +166,7 @@ static int tolua_cRankManager_GetAllGroups(lua_State * L)
} }
// Get the groups: // Get the groups:
AStringVector Groups = cRoot::Get()->GetRankManager().GetAllGroups(); AStringVector Groups = cRoot::Get()->GetRankManager()->GetAllGroups();
// Push the results: // Push the results:
S.Push(Groups); S.Push(Groups);
@ -193,7 +193,7 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L)
} }
// Get the permissions: // Get the permissions:
AStringVector Permissions = cRoot::Get()->GetRankManager().GetAllPermissions(); AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllPermissions();
// Push the results: // Push the results:
S.Push(Permissions); S.Push(Permissions);
@ -220,7 +220,7 @@ static int tolua_cRankManager_GetAllPlayerUUIDs(lua_State * L)
} }
// Get the player uuid's: // Get the player uuid's:
AStringVector Players = cRoot::Get()->GetRankManager().GetAllPlayerUUIDs(); AStringVector Players = cRoot::Get()->GetRankManager()->GetAllPlayerUUIDs();
// Push the results: // Push the results:
S.Push(Players); S.Push(Players);
@ -247,7 +247,7 @@ static int tolua_cRankManager_GetAllRanks(lua_State * L)
} }
// Get the ranks: // Get the ranks:
AStringVector Ranks = cRoot::Get()->GetRankManager().GetAllRanks(); AStringVector Ranks = cRoot::Get()->GetRankManager()->GetAllRanks();
// Push the results: // Push the results:
S.Push(Ranks); S.Push(Ranks);
@ -274,7 +274,7 @@ static int tolua_cRankManager_GetDefaultRank(lua_State * L)
} }
// Return the rank name: // Return the rank name:
S.Push(cRoot::Get()->GetRankManager().GetDefaultRank()); S.Push(cRoot::Get()->GetRankManager()->GetDefaultRank());
return 1; return 1;
} }
@ -303,7 +303,7 @@ static int tolua_cRankManager_GetGroupPermissions(lua_State * L)
S.GetStackValue(2, GroupName); S.GetStackValue(2, GroupName);
// Get the permissions: // Get the permissions:
AStringVector Permissions = cRoot::Get()->GetRankManager().GetGroupPermissions(GroupName); AStringVector Permissions = cRoot::Get()->GetRankManager()->GetGroupPermissions(GroupName);
// Push the results: // Push the results:
S.Push(Permissions); S.Push(Permissions);
@ -335,7 +335,7 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L)
S.GetStackValue(2, PlayerUUID); S.GetStackValue(2, PlayerUUID);
// Get the groups: // Get the groups:
AStringVector Groups = cRoot::Get()->GetRankManager().GetPlayerGroups(PlayerUUID); AStringVector Groups = cRoot::Get()->GetRankManager()->GetPlayerGroups(PlayerUUID);
// Push the results: // Push the results:
S.Push(Groups); S.Push(Groups);
@ -368,7 +368,7 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L)
// Get the permissions: // Get the permissions:
AString MsgPrefix, MsgSuffix, MsgNameColorCode; AString MsgPrefix, MsgSuffix, MsgNameColorCode;
if (!cRoot::Get()->GetRankManager().GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode)) if (!cRoot::Get()->GetRankManager()->GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode))
{ {
return 0; return 0;
} }
@ -405,7 +405,7 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L)
S.GetStackValue(2, PlayerUUID); S.GetStackValue(2, PlayerUUID);
// Get the permissions: // Get the permissions:
AStringVector Permissions = cRoot::Get()->GetRankManager().GetPlayerPermissions(PlayerUUID); AStringVector Permissions = cRoot::Get()->GetRankManager()->GetPlayerPermissions(PlayerUUID);
// Push the results: // Push the results:
S.Push(Permissions); S.Push(Permissions);
@ -437,7 +437,7 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L)
S.GetStackValue(2, PlayerUUID); S.GetStackValue(2, PlayerUUID);
// Get the rank name: // Get the rank name:
AString RankName = cRoot::Get()->GetRankManager().GetPlayerRankName(PlayerUUID); AString RankName = cRoot::Get()->GetRankManager()->GetPlayerRankName(PlayerUUID);
// Push the result: // Push the result:
S.Push(RankName); S.Push(RankName);
@ -469,7 +469,7 @@ static int tolua_cRankManager_GetPlayerName(lua_State * L)
S.GetStackValue(2, PlayerUUID); S.GetStackValue(2, PlayerUUID);
// Get the player name: // Get the player name:
AString PlayerName = cRoot::Get()->GetRankManager().GetPlayerName(PlayerUUID); AString PlayerName = cRoot::Get()->GetRankManager()->GetPlayerName(PlayerUUID);
// Push the result: // Push the result:
S.Push(PlayerName); S.Push(PlayerName);
@ -501,7 +501,7 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L)
S.GetStackValue(2, RankName); S.GetStackValue(2, RankName);
// Get the groups: // Get the groups:
AStringVector Groups = cRoot::Get()->GetRankManager().GetRankGroups(RankName); AStringVector Groups = cRoot::Get()->GetRankManager()->GetRankGroups(RankName);
// Push the results: // Push the results:
S.Push(Groups); S.Push(Groups);
@ -533,7 +533,7 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L)
S.GetStackValue(2, RankName); S.GetStackValue(2, RankName);
// Get the permissions: // Get the permissions:
AStringVector Permissions = cRoot::Get()->GetRankManager().GetRankPermissions(RankName); AStringVector Permissions = cRoot::Get()->GetRankManager()->GetRankPermissions(RankName);
// Push the results: // Push the results:
S.Push(Permissions); S.Push(Permissions);
@ -566,7 +566,7 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L)
// Get the visuals: // Get the visuals:
AString MsgPrefix, MsgSuffix, MsgNameColorCode; AString MsgPrefix, MsgSuffix, MsgNameColorCode;
if (!cRoot::Get()->GetRankManager().GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode)) if (!cRoot::Get()->GetRankManager()->GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode))
{ {
// No such rank, return nothing: // No such rank, return nothing:
return 0; return 0;
@ -604,7 +604,7 @@ static int tolua_cRankManager_GroupExists(lua_State * L)
S.GetStackValue(2, GroupName); S.GetStackValue(2, GroupName);
// Get the response: // Get the response:
bool res = cRoot::Get()->GetRankManager().GroupExists(GroupName); bool res = cRoot::Get()->GetRankManager()->GroupExists(GroupName);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -636,7 +636,7 @@ static int tolua_cRankManager_IsGroupInRank(lua_State * L)
S.GetStackValues(2, GroupName, RankName); S.GetStackValues(2, GroupName, RankName);
// Get the response: // Get the response:
bool res = cRoot::Get()->GetRankManager().IsGroupInRank(GroupName, RankName); bool res = cRoot::Get()->GetRankManager()->IsGroupInRank(GroupName, RankName);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -668,7 +668,7 @@ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L)
S.GetStackValues(2, Permission, GroupName); S.GetStackValues(2, Permission, GroupName);
// Get the response: // Get the response:
bool res = cRoot::Get()->GetRankManager().IsPermissionInGroup(Permission, GroupName); bool res = cRoot::Get()->GetRankManager()->IsPermissionInGroup(Permission, GroupName);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -700,7 +700,7 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L)
S.GetStackValue(2, PlayerUUID); S.GetStackValue(2, PlayerUUID);
// Get the response: // Get the response:
bool res = cRoot::Get()->GetRankManager().IsPlayerRankSet(PlayerUUID); bool res = cRoot::Get()->GetRankManager()->IsPlayerRankSet(PlayerUUID);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -732,7 +732,7 @@ static int tolua_cRankManager_RankExists(lua_State * L)
S.GetStackValue(2, RankName); S.GetStackValue(2, RankName);
// Get the response: // Get the response:
bool res = cRoot::Get()->GetRankManager().RankExists(RankName); bool res = cRoot::Get()->GetRankManager()->RankExists(RankName);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -764,7 +764,7 @@ static int tolua_cRankManager_RemoveGroup(lua_State * L)
S.GetStackValue(2, GroupName); S.GetStackValue(2, GroupName);
// Remove the group: // Remove the group:
cRoot::Get()->GetRankManager().RemoveGroup(GroupName); cRoot::Get()->GetRankManager()->RemoveGroup(GroupName);
return 0; return 0;
} }
@ -793,7 +793,7 @@ static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L)
S.GetStackValues(2, GroupName, RankName); S.GetStackValues(2, GroupName, RankName);
// Remove the group: // Remove the group:
cRoot::Get()->GetRankManager().RemoveGroupFromRank(GroupName, RankName); cRoot::Get()->GetRankManager()->RemoveGroupFromRank(GroupName, RankName);
return 0; return 0;
} }
@ -822,7 +822,7 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L)
S.GetStackValues(2, Permission, GroupName); S.GetStackValues(2, Permission, GroupName);
// Remove the group: // Remove the group:
cRoot::Get()->GetRankManager().RemovePermissionFromGroup(Permission, GroupName); cRoot::Get()->GetRankManager()->RemovePermissionFromGroup(Permission, GroupName);
return 0; return 0;
} }
@ -851,7 +851,7 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L)
S.GetStackValue(2, PlayerUUID); S.GetStackValue(2, PlayerUUID);
// Remove the player's rank: // Remove the player's rank:
cRoot::Get()->GetRankManager().RemovePlayerRank(PlayerUUID); cRoot::Get()->GetRankManager()->RemovePlayerRank(PlayerUUID);
return 0; return 0;
} }
@ -881,7 +881,7 @@ static int tolua_cRankManager_RemoveRank(lua_State * L)
S.GetStackValues(2, RankName, ReplacementRankName); S.GetStackValues(2, RankName, ReplacementRankName);
// Remove the rank: // Remove the rank:
cRoot::Get()->GetRankManager().RemoveRank(RankName, ReplacementRankName); cRoot::Get()->GetRankManager()->RemoveRank(RankName, ReplacementRankName);
return 0; return 0;
} }
@ -910,7 +910,7 @@ static int tolua_cRankManager_RenameGroup(lua_State * L)
S.GetStackValues(2, OldName, NewName); S.GetStackValues(2, OldName, NewName);
// Remove the group: // Remove the group:
bool res = cRoot::Get()->GetRankManager().RenameGroup(OldName, NewName); bool res = cRoot::Get()->GetRankManager()->RenameGroup(OldName, NewName);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -942,7 +942,7 @@ static int tolua_cRankManager_RenameRank(lua_State * L)
S.GetStackValues(2, OldName, NewName); S.GetStackValues(2, OldName, NewName);
// Remove the rank: // Remove the rank:
bool res = cRoot::Get()->GetRankManager().RenameRank(OldName, NewName); bool res = cRoot::Get()->GetRankManager()->RenameRank(OldName, NewName);
// Push the result: // Push the result:
S.Push(res); S.Push(res);
@ -974,7 +974,7 @@ static int tolua_cRankManager_SetDefaultRank(lua_State * L)
S.GetStackValue(2, RankName); S.GetStackValue(2, RankName);
// Set the rank, return the result: // Set the rank, return the result:
S.Push(cRoot::Get()->GetRankManager().SetDefaultRank(RankName)); S.Push(cRoot::Get()->GetRankManager()->SetDefaultRank(RankName));
return 1; return 1;
} }
@ -1003,7 +1003,7 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L)
S.GetStackValues(2, PlayerUUID, PlayerName, RankName); S.GetStackValues(2, PlayerUUID, PlayerName, RankName);
// Set the rank: // Set the rank:
cRoot::Get()->GetRankManager().SetPlayerRank(PlayerUUID, PlayerName, RankName); cRoot::Get()->GetRankManager()->SetPlayerRank(PlayerUUID, PlayerName, RankName);
return 0; return 0;
} }
@ -1032,7 +1032,7 @@ static int tolua_cRankManager_SetRankVisuals(lua_State * L)
S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode);
// Set the visuals: // Set the visuals:
cRoot::Get()->GetRankManager().SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); cRoot::Get()->GetRankManager()->SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode);
return 0; return 0;
} }

View File

@ -45,26 +45,26 @@ public:
virtual void Tick(float a_Dt) = 0; virtual void Tick(float a_Dt) = 0;
/** Calls the specified hook with the params given. Returns the bool that the hook callback returns.*/ /** Calls the specified hook with the params given. Returns the bool that the hook callback returns.*/
virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; virtual bool OnBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0;
virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool OnBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0;
virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; virtual bool OnChat (cPlayer & a_Player, AString & a_Message) = 0;
virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; virtual bool OnChunkAvailable (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0;
virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0; virtual bool OnChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0;
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0; virtual bool OnChunkGenerating (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0;
virtual bool OnChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; virtual bool OnChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0;
virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; virtual bool OnChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ) = 0;
virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) = 0; virtual bool OnCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup) = 0;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) = 0;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) = 0; virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) = 0;
virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) = 0; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) = 0;
virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0;
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) = 0; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) = 0;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) = 0; virtual bool OnLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username) = 0;
virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0; virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0;
virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
@ -89,8 +89,8 @@ public:
virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0;
virtual bool OnPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message) = 0; virtual bool OnPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message) = 0;
virtual bool OnPluginsLoaded (void) = 0; virtual bool OnPluginsLoaded (void) = 0;
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPostCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) = 0;
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPreCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) = 0;
virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0;
virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0;
virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0; virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0;
@ -99,8 +99,8 @@ public:
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0;
virtual bool OnSpawningMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningMonster (cWorld & a_World, cMonster & a_Monster) = 0;
virtual bool OnTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) = 0; virtual bool OnTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) = 0;
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) = 0; virtual bool OnUpdatedSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) = 0;
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0; virtual bool OnUpdatingSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0;
virtual bool OnWeatherChanged (cWorld & a_World) = 0; virtual bool OnWeatherChanged (cWorld & a_World) = 0;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0; virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0;
virtual bool OnWorldStarted (cWorld & a_World) = 0; virtual bool OnWorldStarted (cWorld & a_World) = 0;
@ -110,7 +110,7 @@ public:
Command permissions have already been checked. Command permissions have already been checked.
Returns true if command handled successfully Returns true if command handled successfully
*/ */
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) = 0; virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) = 0;
/** Handles the console command split into a_Split. /** Handles the console command split into a_Split.
Returns true if command handled successfully. Output is to be sent to the a_Output callback. Returns true if command handled successfully. Output is to be sent to the a_Output callback.

View File

@ -202,14 +202,14 @@ void cPluginLua::Tick(float a_Dt)
bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) bool cPluginLua::OnBlockSpread(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -222,14 +222,14 @@ bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int
bool cPluginLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) bool cPluginLua::OnBlockToPickups(cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_TO_PICKUPS]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_TO_PICKUPS];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, &a_Pickups, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, &a_Pickups, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -242,14 +242,14 @@ bool cPluginLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int a_Bl
bool cPluginLua::OnChat(cPlayer * a_Player, AString & a_Message) bool cPluginLua::OnChat(cPlayer & a_Player, AString & a_Message)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHAT]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHAT];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_Player, a_Message, cLuaState::Return, res, a_Message); m_LuaState.Call((int)(**itr), &a_Player, a_Message, cLuaState::Return, res, a_Message);
if (res) if (res)
{ {
return true; return true;
@ -262,14 +262,14 @@ bool cPluginLua::OnChat(cPlayer * a_Player, AString & a_Message)
bool cPluginLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPluginLua::OnChunkAvailable(cWorld & a_World, int a_ChunkX, int a_ChunkZ)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_AVAILABLE]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_AVAILABLE];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -282,14 +282,14 @@ bool cPluginLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
bool cPluginLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) bool cPluginLua::OnChunkGenerated(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_GENERATED]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_GENERATED];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -302,14 +302,14 @@ bool cPluginLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ,
bool cPluginLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) bool cPluginLua::OnChunkGenerating(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_GENERATING]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_GENERATING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -322,14 +322,14 @@ bool cPluginLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ,
bool cPluginLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPluginLua::OnChunkUnloaded(cWorld & a_World, int a_ChunkX, int a_ChunkZ)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_UNLOADED]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_UNLOADED];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -342,14 +342,14 @@ bool cPluginLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
bool cPluginLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPluginLua::OnChunkUnloading(cWorld & a_World, int a_ChunkX, int a_ChunkZ)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_UNLOADING]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CHUNK_UNLOADING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_ChunkX, a_ChunkZ, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -362,14 +362,14 @@ bool cPluginLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
bool cPluginLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) bool cPluginLua::OnCollectingPickup(cPlayer & a_Player, cPickup & a_Pickup)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_COLLECTING_PICKUP]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_COLLECTING_PICKUP];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_Player, a_Pickup, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Player, &a_Pickup, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -382,14 +382,14 @@ bool cPluginLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup)
bool cPluginLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginLua::OnCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CRAFTING_NO_RECIPE]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_CRAFTING_NO_RECIPE];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), (cPlayer *)a_Player, a_Grid, a_Recipe, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Player, &a_Grid, &a_Recipe, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -471,12 +471,12 @@ bool cPluginLua::OnExploded(cWorld & a_World, double a_ExplosionSize, bool a_Can
{ {
switch (a_Source) switch (a_Source)
{ {
case esOther: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; case esOther: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break;
case esPrimedTNT: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cTNTEntity *)a_SourceData, cLuaState::Return, res); break; case esPrimedTNT: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cTNTEntity *)a_SourceData, cLuaState::Return, res); break;
case esMonster: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cMonster *)a_SourceData, cLuaState::Return, res); break; case esMonster: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cMonster *)a_SourceData, cLuaState::Return, res); break;
case esBed: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break; case esBed: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break;
case esEnderCrystal: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break; case esEnderCrystal: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res); break;
case esGhastFireball: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; case esGhastFireball: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break;
case esWitherSkullBlack: case esWitherSkullBlack:
case esWitherSkullBlue: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; case esWitherSkullBlue: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break;
case esWitherBirth: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break; case esWitherBirth: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res); break;
@ -536,14 +536,14 @@ bool cPluginLua::OnExploding(cWorld & a_World, double & a_ExplosionSize, bool &
bool cPluginLua::OnHandshake(cClientHandle * a_Client, const AString & a_Username) bool cPluginLua::OnHandshake(cClientHandle & a_Client, const AString & a_Username)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_HANDSHAKE]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_HANDSHAKE];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_Client, a_Username, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Client, a_Username, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -617,14 +617,14 @@ bool cPluginLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer, TakeDamageInf
bool cPluginLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) bool cPluginLua::OnLogin(cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_LOGIN]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_LOGIN];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_Client, a_ProtocolVersion, a_Username, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Client, a_ProtocolVersion, a_Username, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -784,7 +784,7 @@ bool cPluginLua::OnPlayerFishing(cPlayer & a_Player, cItems & a_Reward)
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FISHING]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FISHING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), &a_Player, a_Reward, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Player, &a_Reward, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -1115,14 +1115,14 @@ bool cPluginLua::OnPluginsLoaded(void)
bool cPluginLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginLua::OnPostCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_POST_CRAFTING]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_POST_CRAFTING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_Player, a_Grid, a_Recipe, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Player, &a_Grid, &a_Recipe, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -1135,14 +1135,14 @@ bool cPluginLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid *
bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginLua::OnPreCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PRE_CRAFTING]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PRE_CRAFTING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_Player, a_Grid, a_Recipe, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Player, &a_Grid, &a_Recipe, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -1316,7 +1316,7 @@ bool cPluginLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI)
bool cPluginLua::OnUpdatedSign( bool cPluginLua::OnUpdatedSign(
cWorld * a_World, cWorld & a_World,
int a_BlockX, int a_BlockY, int a_BlockZ, int a_BlockX, int a_BlockY, int a_BlockZ,
const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4,
cPlayer * a_Player cPlayer * a_Player
@ -1327,7 +1327,7 @@ bool cPluginLua::OnUpdatedSign(
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_UPDATED_SIGN]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_UPDATED_SIGN];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res);
if (res) if (res)
{ {
return true; return true;
@ -1341,7 +1341,7 @@ bool cPluginLua::OnUpdatedSign(
bool cPluginLua::OnUpdatingSign( bool cPluginLua::OnUpdatingSign(
cWorld * a_World, cWorld & a_World,
int a_BlockX, int a_BlockY, int a_BlockZ, int a_BlockX, int a_BlockY, int a_BlockZ,
AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4,
cPlayer * a_Player cPlayer * a_Player
@ -1352,7 +1352,7 @@ bool cPluginLua::OnUpdatingSign(
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_UPDATING_SIGN]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_UPDATING_SIGN];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res, a_Line1, a_Line2, a_Line3, a_Line4); m_LuaState.Call((int)(**itr), &a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player, cLuaState::Return, res, a_Line1, a_Line2, a_Line3, a_Line4);
if (res) if (res)
{ {
return true; return true;
@ -1435,7 +1435,7 @@ bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDuratio
bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player)
{ {
ASSERT(!a_Split.empty()); ASSERT(!a_Split.empty());
CommandMap::iterator cmd = m_Commands.find(a_Split[0]); CommandMap::iterator cmd = m_Commands.find(a_Split[0]);
@ -1447,7 +1447,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
m_LuaState.Call(cmd->second, a_Split, a_Player, cLuaState::Return, res); m_LuaState.Call(cmd->second, a_Split, &a_Player, cLuaState::Return, res);
return res; return res;
} }

View File

@ -69,26 +69,26 @@ public:
virtual void Tick(float a_Dt) override; virtual void Tick(float a_Dt) override;
virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override; virtual bool OnBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override;
virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; virtual bool OnBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override;
virtual bool OnChat (cPlayer * a_Player, AString & a_Message) override; virtual bool OnChat (cPlayer & a_Player, AString & a_Message) override;
virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnChunkAvailable (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; virtual bool OnChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override;
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; virtual bool OnChunkGenerating (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override;
virtual bool OnChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; virtual bool OnChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) override; virtual bool OnCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup) override;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) override; virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) override;
virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) override; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) override;
virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override;
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) override; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override; virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override;
virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
@ -113,8 +113,8 @@ public:
virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
virtual bool OnPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message) override; virtual bool OnPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message) override;
virtual bool OnPluginsLoaded (void) override; virtual bool OnPluginsLoaded (void) override;
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPostCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override;
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPreCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override;
virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override;
virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override;
virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override; virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override;
@ -123,14 +123,14 @@ public:
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override;
virtual bool OnSpawningMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningMonster (cWorld & a_World, cMonster & a_Monster) override;
virtual bool OnTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override; virtual bool OnTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override;
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override; virtual bool OnUpdatedSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override; virtual bool OnUpdatingSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnWeatherChanged (cWorld & a_World) override; virtual bool OnWeatherChanged (cWorld & a_World) override;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override; virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override;
virtual bool OnWorldStarted (cWorld & a_World) override; virtual bool OnWorldStarted (cWorld & a_World) override;
virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override; virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override;
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override; virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) override;
virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) override; virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) override;

View File

@ -225,7 +225,7 @@ void cPluginManager::Tick(float a_Dt)
bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) bool cPluginManager::CallHookBlockSpread(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source)
{ {
FIND_HOOK(HOOK_BLOCK_SPREAD); FIND_HOOK(HOOK_BLOCK_SPREAD);
VERIFY_HOOK; VERIFY_HOOK;
@ -245,7 +245,7 @@ bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_B
bool cPluginManager::CallHookBlockToPickups( bool cPluginManager::CallHookBlockToPickups(
cWorld * a_World, cEntity * a_Digger, cWorld & a_World, cEntity * a_Digger,
int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
cItems & a_Pickups cItems & a_Pickups
) )
@ -267,7 +267,7 @@ bool cPluginManager::CallHookBlockToPickups(
bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) bool cPluginManager::CallHookChat(cPlayer & a_Player, AString & a_Message)
{ {
// Check if the message contains a command, execute it: // Check if the message contains a command, execute it:
switch (HandleCommand(a_Player, a_Message, true)) switch (HandleCommand(a_Player, a_Message, true))
@ -288,14 +288,14 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
case crError: case crError:
{ {
// An error in the plugin has prevented the command from executing. Report the error to the player: // An error in the plugin has prevented the command from executing. Report the error to the player:
a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); a_Player.SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str()));
return true; return true;
} }
case crNoPermission: case crNoPermission:
{ {
// The player is not allowed to execute this command // The player is not allowed to execute this command
a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); a_Player.SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str()));
return true; return true;
} }
@ -311,8 +311,8 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
{ {
AStringVector Split(StringSplit(a_Message, " ")); AStringVector Split(StringSplit(a_Message, " "));
ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long
a_Player->SendMessageInfo(Printf("Unknown command: \"%s\"", a_Message.c_str())); a_Player.SendMessageInfo(Printf("Unknown command: \"%s\"", a_Message.c_str()));
LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player->GetName().c_str(), a_Message.c_str()); LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player.GetName().c_str(), a_Message.c_str());
return true; // Cancel sending return true; // Cancel sending
} }
@ -334,7 +334,7 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPluginManager::CallHookChunkAvailable(cWorld & a_World, int a_ChunkX, int a_ChunkZ)
{ {
FIND_HOOK(HOOK_CHUNK_AVAILABLE); FIND_HOOK(HOOK_CHUNK_AVAILABLE);
VERIFY_HOOK; VERIFY_HOOK;
@ -353,7 +353,7 @@ bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) bool cPluginManager::CallHookChunkGenerated(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc)
{ {
FIND_HOOK(HOOK_CHUNK_GENERATED); FIND_HOOK(HOOK_CHUNK_GENERATED);
VERIFY_HOOK; VERIFY_HOOK;
@ -372,7 +372,7 @@ bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) bool cPluginManager::CallHookChunkGenerating(cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc)
{ {
FIND_HOOK(HOOK_CHUNK_GENERATING); FIND_HOOK(HOOK_CHUNK_GENERATING);
VERIFY_HOOK; VERIFY_HOOK;
@ -391,7 +391,7 @@ bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPluginManager::CallHookChunkUnloaded(cWorld & a_World, int a_ChunkX, int a_ChunkZ)
{ {
FIND_HOOK(HOOK_CHUNK_UNLOADED); FIND_HOOK(HOOK_CHUNK_UNLOADED);
VERIFY_HOOK; VERIFY_HOOK;
@ -410,7 +410,7 @@ bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a
bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) bool cPluginManager::CallHookChunkUnloading(cWorld & a_World, int a_ChunkX, int a_ChunkZ)
{ {
FIND_HOOK(HOOK_CHUNK_UNLOADING); FIND_HOOK(HOOK_CHUNK_UNLOADING);
VERIFY_HOOK; VERIFY_HOOK;
@ -429,14 +429,14 @@ bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookCollectingPickup(cPlayer * a_Player, cPickup & a_Pickup) bool cPluginManager::CallHookCollectingPickup(cPlayer & a_Player, cPickup & a_Pickup)
{ {
FIND_HOOK(HOOK_COLLECTING_PICKUP); FIND_HOOK(HOOK_COLLECTING_PICKUP);
VERIFY_HOOK; VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{ {
if ((*itr)->OnCollectingPickup(a_Player, &a_Pickup)) if ((*itr)->OnCollectingPickup(a_Player, a_Pickup))
{ {
return true; return true;
} }
@ -448,7 +448,7 @@ bool cPluginManager::CallHookCollectingPickup(cPlayer * a_Player, cPickup & a_Pi
bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginManager::CallHookCraftingNoRecipe(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe)
{ {
FIND_HOOK(HOOK_CRAFTING_NO_RECIPE); FIND_HOOK(HOOK_CRAFTING_NO_RECIPE);
VERIFY_HOOK; VERIFY_HOOK;
@ -562,7 +562,7 @@ bool cPluginManager::CallHookExploding(cWorld & a_World, double & a_ExplosionSiz
bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const AString & a_Username) bool cPluginManager::CallHookHandshake(cClientHandle & a_ClientHandle, const AString & a_Username)
{ {
FIND_HOOK(HOOK_HANDSHAKE); FIND_HOOK(HOOK_HANDSHAKE);
VERIFY_HOOK; VERIFY_HOOK;
@ -638,7 +638,7 @@ bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer, Tak
bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) bool cPluginManager::CallHookLogin(cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username)
{ {
FIND_HOOK(HOOK_LOGIN); FIND_HOOK(HOOK_LOGIN);
VERIFY_HOOK; VERIFY_HOOK;
@ -1111,7 +1111,7 @@ bool cPluginManager::CallHookPluginsLoaded(void)
bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginManager::CallHookPostCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe)
{ {
FIND_HOOK(HOOK_POST_CRAFTING); FIND_HOOK(HOOK_POST_CRAFTING);
VERIFY_HOOK; VERIFY_HOOK;
@ -1130,7 +1130,7 @@ bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraft
bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) bool cPluginManager::CallHookPreCrafting(cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe)
{ {
FIND_HOOK(HOOK_PRE_CRAFTING); FIND_HOOK(HOOK_PRE_CRAFTING);
VERIFY_HOOK; VERIFY_HOOK;
@ -1299,7 +1299,7 @@ bool cPluginManager::CallHookTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a
bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) bool cPluginManager::CallHookUpdatingSign(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player)
{ {
FIND_HOOK(HOOK_UPDATING_SIGN); FIND_HOOK(HOOK_UPDATING_SIGN);
VERIFY_HOOK; VERIFY_HOOK;
@ -1318,7 +1318,7 @@ bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_
bool cPluginManager::CallHookUpdatedSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) bool cPluginManager::CallHookUpdatedSign(cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player)
{ {
FIND_HOOK(HOOK_UPDATED_SIGN); FIND_HOOK(HOOK_UPDATED_SIGN);
VERIFY_HOOK; VERIFY_HOOK;
@ -1413,10 +1413,8 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT
cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
{ {
ASSERT(a_Player != NULL);
AStringVector Split(StringSplit(a_Command, " ")); AStringVector Split(StringSplit(a_Command, " "));
if (Split.empty()) if (Split.empty())
{ {
@ -1431,19 +1429,19 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player,
} }
// Ask plugins first if a command is okay to execute the command: // Ask plugins first if a command is okay to execute the command:
if (CallHookExecuteCommand(a_Player, Split)) if (CallHookExecuteCommand(&a_Player, Split))
{ {
LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str()); LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player.GetName().c_str(), Split[0].c_str());
return crBlocked; return crBlocked;
} }
if ( if (
a_ShouldCheckPermissions && a_ShouldCheckPermissions &&
!cmd->second.m_Permission.empty() && !cmd->second.m_Permission.empty() &&
!a_Player->HasPermission(cmd->second.m_Permission) !a_Player.HasPermission(cmd->second.m_Permission)
) )
{ {
LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player.GetName().c_str(), Split[0].c_str());
return crNoPermission; return crNoPermission;
} }
@ -1652,7 +1650,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command)
cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer & a_Player, const AString & a_Command)
{ {
return HandleCommand(a_Player, a_Command, true); return HandleCommand(a_Player, a_Command, true);
} }
@ -1661,7 +1659,7 @@ cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player,
cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer & a_Player, const AString & a_Command)
{ {
return HandleCommand(a_Player, a_Command, false); return HandleCommand(a_Player, a_Command, false);
} }
@ -1830,6 +1828,7 @@ bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback
bool cPluginManager::AddPlugin(cPlugin * a_Plugin) bool cPluginManager::AddPlugin(cPlugin * a_Plugin)
{ {
m_Plugins[a_Plugin->GetDirectory()] = a_Plugin; m_Plugins[a_Plugin->GetDirectory()] = a_Plugin;
if (a_Plugin->Initialize()) if (a_Plugin->Initialize())
{ {
// Initialization OK // Initialization OK

View File

@ -178,26 +178,26 @@ public:
size_t GetNumPlugins() const; // tolua_export size_t GetNumPlugins() const; // tolua_export
// Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort
bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source); bool CallHookBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source);
bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); bool CallHookBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups);
bool CallHookChat (cPlayer * a_Player, AString & a_Message); bool CallHookChat (cPlayer & a_Player, AString & a_Message);
bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); bool CallHookChunkAvailable (cWorld & a_World, int a_ChunkX, int a_ChunkZ);
bool CallHookChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); bool CallHookChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc);
bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); bool CallHookChunkGenerating (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc);
bool CallHookChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ); bool CallHookChunkUnloaded (cWorld & a_World, int a_ChunkX, int a_ChunkZ);
bool CallHookChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ); bool CallHookChunkUnloading (cWorld & a_World, int a_ChunkX, int a_ChunkZ);
bool CallHookCollectingPickup (cPlayer * a_Player, cPickup & a_Pickup); bool CallHookCollectingPickup (cPlayer & a_Player, cPickup & a_Pickup);
bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason);
bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier);
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd
bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookHandshake (cClientHandle * a_ClientHandle, const AString & a_Username); bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username);
bool CallHookHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum); bool CallHookHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum);
bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum); bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum);
bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI); bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI);
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); bool CallHookLogin (cClientHandle & a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation); bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation);
bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
@ -222,8 +222,8 @@ public:
bool CallHookPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); bool CallHookPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
bool CallHookPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message); bool CallHookPluginMessage (cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message);
bool CallHookPluginsLoaded (void); bool CallHookPluginsLoaded (void);
bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPostCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe);
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe);
bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos);
bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity);
bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon); bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon);
@ -232,8 +232,8 @@ public:
bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity);
bool CallHookSpawningMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningMonster (cWorld & a_World, cMonster & a_Monster);
bool CallHookTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TDI); bool CallHookTakeDamage (cEntity & a_Receiver, TakeDamageInfo & a_TDI);
bool CallHookUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player); bool CallHookUpdatedSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player);
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); bool CallHookUpdatingSign (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld & a_World); bool CallHookWeatherChanged (cWorld & a_World);
bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather); bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather);
bool CallHookWorldStarted (cWorld & a_World); bool CallHookWorldStarted (cWorld & a_World);
@ -264,10 +264,10 @@ public:
AString GetCommandPermission(const AString & a_Command); // tolua_export AString GetCommandPermission(const AString & a_Command); // tolua_export
/** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */ /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */
CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export CommandResult ExecuteCommand(cPlayer & a_Player, const AString & a_Command); // tolua_export
/** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */ /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */
CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export CommandResult ForceExecuteCommand(cPlayer & a_Player, const AString & a_Command); // tolua_export
/** Removes all console command bindings that the specified plugin has made */ /** Removes all console command bindings that the specified plugin has made */
void RemovePluginConsoleCommands(cPlugin * a_Plugin); void RemovePluginConsoleCommands(cPlugin * a_Plugin);
@ -341,7 +341,7 @@ private:
bool AddPlugin(cPlugin * a_Plugin); bool AddPlugin(cPlugin * a_Plugin);
/** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */ /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */
cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); CommandResult HandleCommand(cPlayer & a_Player, const AString & a_Command, bool a_ShouldCheckPermissions);
} ; // tolua_export } ; // tolua_export

View File

@ -1,224 +0,0 @@
-- gen_LuaState_Call.lua
-- Generates the cLuaState::Call() function templates that are included from LuaState.h
--[[
The cLuaState::Call() family of functions provides a template-based system for calling any Lua function
either by name or by reference with almost any number of parameters and return values. This is done by
providing a number of overloads of the same name with variable number of template-type parameters. To
separate the arguments from the return values, a special type of cLuaState::cRet is used.
--]]
print("Generating LuaState_Call.inc . . .")
-- List of combinations (# params, # returns) to generate:
local Combinations =
{
-- no return values:
{0, 0},
{1, 0},
{2, 0},
{3, 0},
{4, 0},
-- 1 return value:
{0, 1},
{1, 1},
{2, 1},
{3, 1},
{4, 1},
{5, 1},
{6, 1},
{7, 1},
{8, 1},
{9, 1},
{10, 1},
-- 2 return values:
{0, 2},
{1, 2},
{2, 2},
{3, 2},
{4, 2},
{5, 2},
{6, 2},
{7, 2},
{8, 2},
{9, 2},
-- Special combinations:
{5, 5},
{7, 3},
{8, 3},
{9, 5},
}
--- Writes a single overloaded function definition for the specified number of params and returns into f
--[[
The format for the generated function is this:
/** Call the specified 3-param 2-return Lua function:
Returns true if call succeeded, false if there was an error. */
template <typename FnT, typename ParamT1, typename ParamT2, typename ParamT3, typename RetT1, typename RetT2>
bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2)
{
UNUSED(a_RetMark);
if (!PushFunction(a_Function))
{
return false;
}
Push(a_Param1);
Push(a_Param2);
Push(a_Param3);
if (!CallFunction(2))
{
return false;
}
GetStackValue(-2, a_Ret1);
GetStackValue(-1, a_Ret2);
lua_pop(m_LuaState, 2);
return true;
}
Note especially the negative numbers in GetStackValue() calls.
--]]
local function WriteOverload(f, a_NumParams, a_NumReturns)
-- Write the function doxy-comments:
f:write("/** Call the specified ", a_NumParams, "-param ", a_NumReturns, "-return Lua function:\n")
f:write("Returns true if call succeeded, false if there was an error. */\n")
-- Write the template <...> line:
f:write("template <typename FnT")
for i = 1, a_NumParams do
f:write(", typename ParamT", i)
end
if (a_NumReturns > 0) then
for i = 1, a_NumReturns do
f:write(", typename RetT", i)
end
end
f:write(">\n")
-- Write the function signature:
f:write("bool Call(")
f:write("const FnT & a_Function")
for i = 1, a_NumParams do
f:write(", ParamT", i, " a_Param", i)
end
if (a_NumReturns > 0) then
f:write(", const cLuaState::cRet & a_RetMark")
for i = 1, a_NumReturns do
f:write(", RetT", i, " & a_Ret", i)
end
end
f:write(")\n")
-- Common code:
f:write("{\n")
if (a_NumReturns > 0) then
f:write("\tUNUSED(a_RetMark);\n")
end
f:write("\tif (!PushFunction(a_Function))\n")
f:write("\t{\n")
f:write("\t\treturn false;\n")
f:write("\t}\n")
-- Push the params:
for i = 1, a_NumParams do
f:write("\tPush(a_Param", i, ");\n")
end
-- Call the function:
f:write("\tif (!CallFunction(", a_NumReturns, "))\n")
f:write("\t{\n")
f:write("\t\treturn false;\n")
f:write("\t}\n")
-- Get the return values:
for i = 1, a_NumReturns do
f:write("\tGetStackValue(", -1 - a_NumReturns + i, ", a_Ret", i, ");\n")
end
-- Pop the returns off the stack, if needed:
if (a_NumReturns > 0) then
f:write("\tlua_pop(m_LuaState, ", a_NumReturns, ");\n")
end
-- Everything ok:
f:write("\treturn true;\n")
f:write("}\n")
-- Separate from the next function:
f:write("\n\n\n\n\n")
end
local f = assert(io.open("LuaState_Call.inc", "w"))
-- Write file header:
f:write([[
// LuaState_Call.inc
// This file is auto-generated by gen_LuaState_Call.lua
// Make changes to the generator instead of to this file!
// This file contains the various overloads for the cLuaState::Call() function
// Each overload handles a different number of parameters / return values
]])
f:write("\n\n\n\n\n")
-- Write out a template function for each overload:
for _, combination in ipairs(Combinations) do
WriteOverload(f, combination[1], combination[2])
end
-- Generate the cLuaState::GetStackValues() multi-param templates:
for i = 2, 6 do
f:write("/** Reads ", i, " consecutive values off the stack */\ntemplate <\n")
-- Write the template function header:
local txt = {}
for idx = 1, i do
table.insert(txt, "\ttypename ArgT" .. idx)
end
f:write(table.concat(txt, ",\n"))
-- Write the argument declarations:
txt = {}
f:write("\n>\nvoid GetStackValues(\n\tint a_BeginPos,\n")
for idx = 1, i do
table.insert(txt, "\tArgT" .. idx .. " & Arg" .. idx)
end
f:write(table.concat(txt, ",\n"))
-- Write the function body:
f:write("\n)\n{\n")
for idx = 1, i do
f:write("\tGetStackValue(a_BeginPos + ", idx - 1, ", Arg", idx, ");\n")
end
f:write("}\n\n\n\n\n\n")
end
-- Close the generated file
f:close()
print("LuaState_Call.inc generated.")

View File

@ -7,16 +7,6 @@ local default_private_access = false
-- Code generators used by the build
-- Note that these are not exactly needed for the bindings, but rather we
-- misuse tolua's Lua engine to process files for us
dofile("gen_LuaState_Call.lua")
local access = {public = 0, protected = 1, private = 2} local access = {public = 0, protected = 1, private = 2}
function preparse_hook(p) function preparse_hook(p)

View File

@ -32,6 +32,8 @@ class cBeaconEntity :
public: public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cBeaconEntity);
cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
// cBlockEntity overrides: // cBlockEntity overrides:

View File

@ -5,6 +5,28 @@
/** Place this macro in the declaration of each cBlockEntity descendant. */
#define BLOCKENTITY_PROTODEF(classname) \
virtual bool IsA(const char * a_ClassName) const override \
{ \
return ((strcmp(a_ClassName, #classname) == 0) || super::IsA(a_ClassName)); \
} \
virtual const char * GetClass(void) const override \
{ \
return #classname; \
} \
static const char * GetClassStatic(void) \
{ \
return #classname; \
} \
virtual const char * GetParentClass(void) const override \
{ \
return super::GetClass(); \
}
namespace Json namespace Json
{ {
@ -55,6 +77,15 @@ public:
{ {
return "cBlockEntity"; return "cBlockEntity";
} }
/** Returns true if the object is the specified class, or its descendant. */
virtual bool IsA(const char * a_ClassName) const { return (strcmp(a_ClassName, "cBlockEntity") == 0); }
/** Returns the name of the tompost class (the most descendant). Used for Lua bindings to push the correct object type. */
virtual const char * GetClass(void) const { return GetClassStatic(); }
/** Returns the name of the parent class, or empty string if no parent class. */
virtual const char * GetParentClass(void) const { return ""; }
// tolua_begin // tolua_begin

View File

@ -25,10 +25,12 @@ class cBlockEntityWithItems :
public cBlockEntityWindowOwner public cBlockEntityWindowOwner
{ {
typedef cBlockEntity super; typedef cBlockEntity super;
public: public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cBlockEntityWithItems);
cBlockEntityWithItems( cBlockEntityWithItems(
BLOCKTYPE a_BlockType, // Type of the block that the entity represents BLOCKTYPE a_BlockType, // Type of the block that the entity represents
int a_BlockX, int a_BlockY, int a_BlockZ, // Position of the block entity int a_BlockX, int a_BlockY, int a_BlockZ, // Position of the block entity

View File

@ -33,13 +33,13 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cChestEntity);
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type); cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type);
virtual ~cChestEntity(); virtual ~cChestEntity();
static const char * GetClassStatic(void) { return "cChestEntity"; }
// cBlockEntity overrides: // cBlockEntity overrides:
virtual void SendTo(cClientHandle & a_Client) override; virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;

View File

@ -36,6 +36,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cCommandBlockEntity);
/// Creates a new empty command block entity /// Creates a new empty command block entity
cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);

View File

@ -17,11 +17,11 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cDispenserEntity);
/** Constructor used for normal operation */ /** Constructor used for normal operation */
cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
static const char * GetClassStatic(void) { return "cDispenserEntity"; }
// tolua_begin // tolua_begin
/** Spawns a projectile of the given kind in front of the dispenser with the specified speed. */ /** Spawns a projectile of the given kind in front of the dispenser with the specified speed. */

View File

@ -45,11 +45,11 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cDropSpenserEntity);
cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cDropSpenserEntity(); virtual ~cDropSpenserEntity();
static const char * GetClassStatic(void) { return "cDropSpenserEntity"; }
// cBlockEntity overrides: // cBlockEntity overrides:
virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
virtual void SendTo(cClientHandle & a_Client) override; virtual void SendTo(cClientHandle & a_Client) override;

View File

@ -25,11 +25,11 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cDropperEntity);
/// Constructor used for normal operation /// Constructor used for normal operation
cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
static const char * GetClassStatic(void) { return "cDropperEntity"; }
protected: protected:
// cDropSpenserEntity overrides: // cDropSpenserEntity overrides:
virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override; virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override;

View File

@ -18,11 +18,11 @@ class cEnderChestEntity :
public: public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cEnderChestEntity);
cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cEnderChestEntity(); virtual ~cEnderChestEntity();
static const char * GetClassStatic(void) { return "cEnderChestEntity"; }
// cBlockEntity overrides: // cBlockEntity overrides:
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); } virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); }

View File

@ -36,6 +36,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cFlowerPotEntity);
/** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */ /** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */
cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World);
@ -59,8 +61,6 @@ public:
static bool IsFlower(short m_ItemType, short m_ItemData); static bool IsFlower(short m_ItemType, short m_ItemData);
static const char * GetClassStatic(void) { return "cFlowerPotEntity"; }
private: private:
cItem m_Item; cItem m_Item;

View File

@ -5,6 +5,7 @@
#include "../UI/Window.h" #include "../UI/Window.h"
#include "../Entities/Player.h" #include "../Entities/Player.h"
#include "../Root.h" #include "../Root.h"
#include "../Chunk.h"
@ -13,8 +14,9 @@
enum enum
{ {
PROGRESSBAR_SMELTING = 0, PROGRESSBAR_FUEL = 0,
PROGRESSBAR_FUEL = 1, PROGRESSBAR_SMELTING = 2,
PROGRESSBAR_SMELTING_CONFIRM = 3,
} ; } ;
@ -22,17 +24,15 @@ enum
cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) : cFurnaceEntity::cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) :
super(E_BLOCK_FURNACE, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World), super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
m_BlockType(a_BlockType),
m_BlockMeta(a_BlockMeta), m_BlockMeta(a_BlockMeta),
m_CurrentRecipe(NULL), m_CurrentRecipe(NULL),
m_IsCooking((a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_LIT_FURNACE)), m_IsDestroyed(false),
m_IsCooking(a_BlockType == E_BLOCK_LIT_FURNACE),
m_NeedCookTime(0), m_NeedCookTime(0),
m_TimeCooked(0), m_TimeCooked(0),
m_FuelBurnTime(0), m_FuelBurnTime(0),
m_TimeBurned(0), m_TimeBurned(0)
m_LastProgressFuel(0),
m_LastProgressCook(0)
{ {
m_Contents.AddListener(*this); m_Contents.AddListener(*this);
} }
@ -57,27 +57,28 @@ cFurnaceEntity::~cFurnaceEntity()
void cFurnaceEntity::UsedBy(cPlayer * a_Player) void cFurnaceEntity::UsedBy(cPlayer * a_Player)
{ {
if (GetWindow() == NULL) cWindow * Window = GetWindow();
if (Window == nullptr)
{ {
OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this)); OpenWindow(new cFurnaceWindow(m_PosX, m_PosY, m_PosZ, this));
Window = GetWindow();
} }
cWindow * Window = GetWindow();
if (Window != NULL) if (Window != nullptr)
{ {
if (a_Player->GetWindow() != Window) if (a_Player->GetWindow() != Window)
{ {
a_Player->OpenWindow(Window); a_Player->OpenWindow(Window);
BroadcastProgress(PROGRESSBAR_FUEL, (short)m_LastProgressFuel);
BroadcastProgress(PROGRESSBAR_SMELTING, (short)m_LastProgressCook);
} }
} }
UpdateProgressBars(true);
} }
/// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking.
bool cFurnaceEntity::ContinueCooking(void) bool cFurnaceEntity::ContinueCooking(void)
{ {
UpdateInput(); UpdateInput();
@ -92,14 +93,16 @@ bool cFurnaceEntity::ContinueCooking(void)
bool cFurnaceEntity::Tick(float a_Dt, cChunk & a_Chunk) bool cFurnaceEntity::Tick(float a_Dt, cChunk & a_Chunk)
{ {
UNUSED(a_Dt); UNUSED(a_Dt);
UNUSED(a_Chunk);
if (m_FuelBurnTime <= 0) if (m_FuelBurnTime <= 0)
{ {
// No fuel is burning, reset progressbars and bail out // If a furnace is out of fuel, the progress bar reverses at twice the speed of cooking.
if ((m_LastProgressCook > 0) || (m_LastProgressFuel > 0)) m_TimeCooked = std::max((m_TimeCooked - 2), 0);
{
UpdateProgressBars(); // Reset progressbars, block type, and bail out
} m_BlockType = E_BLOCK_FURNACE;
a_Chunk.FastSetBlock(GetRelX(), m_PosY, GetRelZ(), E_BLOCK_FURNACE, m_BlockMeta);
UpdateProgressBars();
return false; return false;
} }
@ -139,12 +142,12 @@ void cFurnaceEntity::SendTo(cClientHandle & a_Client)
void cFurnaceEntity::BroadcastProgress(int a_ProgressbarID, short a_Value) void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
{ {
cWindow * Window = GetWindow(); cWindow * Window = GetWindow();
if (Window != NULL) if (Window != NULL)
{ {
Window->BroadcastProgress(a_ProgressbarID, a_Value); Window->SetProperty(a_ProgressbarID, a_Value);
} }
} }
@ -152,7 +155,6 @@ void cFurnaceEntity::BroadcastProgress(int a_ProgressbarID, short a_Value)
/// One item finished cooking
void cFurnaceEntity::FinishOne() void cFurnaceEntity::FinishOne()
{ {
m_TimeCooked = 0; m_TimeCooked = 0;
@ -166,8 +168,6 @@ void cFurnaceEntity::FinishOne()
m_Contents.ChangeSlotCount(fsOutput, m_CurrentRecipe->Out->m_ItemCount); m_Contents.ChangeSlotCount(fsOutput, m_CurrentRecipe->Out->m_ItemCount);
} }
m_Contents.ChangeSlotCount(fsInput, -m_CurrentRecipe->In->m_ItemCount); m_Contents.ChangeSlotCount(fsInput, -m_CurrentRecipe->In->m_ItemCount);
UpdateIsCooking();
} }
@ -181,8 +181,7 @@ void cFurnaceEntity::BurnNewFuel(void)
if (NewTime == 0) if (NewTime == 0)
{ {
// The item in the fuel slot is not suitable // The item in the fuel slot is not suitable
m_FuelBurnTime = 0; SetBurnTimes(0, 0);
m_TimeBurned = 0;
SetIsCooking(false); SetIsCooking(false);
return; return;
} }
@ -194,8 +193,7 @@ void cFurnaceEntity::BurnNewFuel(void)
} }
// Burn one new fuel: // Burn one new fuel:
m_FuelBurnTime = NewTime; SetBurnTimes(NewTime, 0);
m_TimeBurned = 0;
SetIsCooking(true); SetIsCooking(true);
if (m_Contents.GetSlot(fsFuel).m_ItemType == E_ITEM_LAVA_BUCKET) if (m_Contents.GetSlot(fsFuel).m_ItemType == E_ITEM_LAVA_BUCKET)
{ {
@ -214,33 +212,19 @@ void cFurnaceEntity::BurnNewFuel(void)
void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{ {
super::OnSlotChanged(a_ItemGrid, a_SlotNum); super::OnSlotChanged(a_ItemGrid, a_SlotNum);
if (m_World == NULL) if (m_IsDestroyed)
{ {
// The furnace isn't initialized yet, do no processing
return; return;
} }
ASSERT(a_ItemGrid == &m_Contents); ASSERT(a_ItemGrid == &m_Contents);
switch (a_SlotNum) switch (a_SlotNum)
{ {
case fsInput: case fsInput: UpdateInput(); break;
{ case fsFuel: UpdateFuel(); break;
UpdateInput(); case fsOutput: UpdateOutput(); break;
break; default: ASSERT(!"Invalid furnace slot update!"); break;
}
case fsFuel:
{
UpdateFuel();
break;
}
case fsOutput:
{
UpdateOutput();
break;
}
} }
} }
@ -249,7 +233,6 @@ void cFurnaceEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
/// Updates the current recipe, based on the current input
void cFurnaceEntity::UpdateInput(void) void cFurnaceEntity::UpdateInput(void)
{ {
if (!m_Contents.GetSlot(fsInput).IsEqual(m_LastInput)) if (!m_Contents.GetSlot(fsInput).IsEqual(m_LastInput))
@ -263,8 +246,8 @@ void cFurnaceEntity::UpdateInput(void)
m_CurrentRecipe = FR->GetRecipeFrom(m_Contents.GetSlot(fsInput)); m_CurrentRecipe = FR->GetRecipeFrom(m_Contents.GetSlot(fsInput));
if (!CanCookInputToOutput()) if (!CanCookInputToOutput())
{ {
// This input cannot be cooked // This input cannot be cooked, reset cook counter immediately
m_NeedCookTime = 0; SetCookTimes(0, 0);
SetIsCooking(false); SetIsCooking(false);
} }
else else
@ -284,7 +267,6 @@ void cFurnaceEntity::UpdateInput(void)
/// Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate
void cFurnaceEntity::UpdateFuel(void) void cFurnaceEntity::UpdateFuel(void)
{ {
if (m_FuelBurnTime > m_TimeBurned) if (m_FuelBurnTime > m_TimeBurned)
@ -301,14 +283,12 @@ void cFurnaceEntity::UpdateFuel(void)
/// Called when the output slot changes; starts burning if space became available
void cFurnaceEntity::UpdateOutput(void) void cFurnaceEntity::UpdateOutput(void)
{ {
if (!CanCookInputToOutput()) if (!CanCookInputToOutput())
{ {
// Cannot cook anymore: // Cannot cook anymore:
m_TimeCooked = 0; SetCookTimes(0, 0);
m_NeedCookTime = 0;
SetIsCooking(false); SetIsCooking(false);
return; return;
} }
@ -324,30 +304,6 @@ void cFurnaceEntity::UpdateOutput(void)
/// Updates the m_IsCooking, based on the input slot, output slot and m_FuelBurnTime / m_TimeBurned
void cFurnaceEntity::UpdateIsCooking(void)
{
if (
!CanCookInputToOutput() || // Cannot cook this
(m_FuelBurnTime <= 0) || // No fuel
(m_TimeBurned >= m_FuelBurnTime) // Fuel burnt out
)
{
// Reset everything
SetIsCooking(false);
m_TimeCooked = 0;
m_NeedCookTime = 0;
return;
}
SetIsCooking(true);
}
/// Returns true if the input can be cooked into output and the item counts allow for another cooking operation
bool cFurnaceEntity::CanCookInputToOutput(void) const bool cFurnaceEntity::CanCookInputToOutput(void) const
{ {
if (m_CurrentRecipe == NULL) if (m_CurrentRecipe == NULL)
@ -382,25 +338,20 @@ bool cFurnaceEntity::CanCookInputToOutput(void) const
/// Broadcasts progressbar updates, if needed void cFurnaceEntity::UpdateProgressBars(bool a_ForceUpdate)
void cFurnaceEntity::UpdateProgressBars(void)
{ {
// In order to preserve bandwidth, an update is sent only every 10th tick // In order to preserve bandwidth, an update is sent only every 10th tick
// That's why the comparisons use the division by eight if (!a_ForceUpdate && (m_World->GetWorldAge() % 10 != 0))
int CurFuel = (m_FuelBurnTime > 0) ? (200 - 200 * m_TimeBurned / m_FuelBurnTime) : 0;
if ((CurFuel / 8) != (m_LastProgressFuel / 8))
{ {
BroadcastProgress(PROGRESSBAR_FUEL, (short)CurFuel); return;
m_LastProgressFuel = CurFuel;
} }
int CurCook = (m_NeedCookTime > 0) ? (200 * m_TimeCooked / m_NeedCookTime) : 0; int CurFuel = (m_FuelBurnTime > 0) ? 200 - (200 * m_TimeBurned / m_FuelBurnTime) : 0;
if ((CurCook / 8) != (m_LastProgressCook / 8)) BroadcastProgress(PROGRESSBAR_FUEL, static_cast<short>(CurFuel));
{
BroadcastProgress(PROGRESSBAR_SMELTING, (short)CurCook); int CurCook = (m_NeedCookTime > 0) ? (200 * m_TimeCooked / m_NeedCookTime) : 0;
m_LastProgressCook = CurCook; BroadcastProgress(PROGRESSBAR_SMELTING_CONFIRM, 200); // Post 1.8, Mojang requires a random packet with an ID of three and value of 200. Wat. Wat. Wat.
} BroadcastProgress(PROGRESSBAR_SMELTING, static_cast<short>(CurCook));
} }
@ -413,11 +364,14 @@ void cFurnaceEntity::SetIsCooking(bool a_IsCooking)
{ {
return; return;
} }
m_IsCooking = a_IsCooking; m_IsCooking = a_IsCooking;
// Light or extinguish the furnace: // Only light the furnace as it is extinguished only when the fuel runs out, not when cooking stops - handled in this::Tick()
m_World->FastSetBlock(m_PosX, m_PosY, m_PosZ, m_IsCooking ? E_BLOCK_LIT_FURNACE : E_BLOCK_FURNACE, m_BlockMeta); if (m_IsCooking)
{
m_BlockType = E_BLOCK_LIT_FURNACE;
m_World->FastSetBlock(m_PosX, m_PosY, m_PosZ, E_BLOCK_LIT_FURNACE, m_BlockMeta);
}
} }

View File

@ -38,114 +38,128 @@ public:
// tolua_end // tolua_end
/// Constructor used for normal operation BLOCKENTITY_PROTODEF(cFurnaceEntity);
/** Constructor used for normal operation */
cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World); cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World);
virtual ~cFurnaceEntity(); virtual ~cFurnaceEntity();
static const char * GetClassStatic() { return "cFurnaceEntity"; }
// cBlockEntity overrides: // cBlockEntity overrides:
virtual void SendTo(cClientHandle & a_Client) override; virtual void SendTo(cClientHandle & a_Client) override;
virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;
virtual void Destroy() override
{
m_IsDestroyed = true;
super::Destroy();
}
/// Restarts cooking. Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active. Returns true if cooking. /** Restarts cooking
Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active
Returns true if cooking */
bool ContinueCooking(void); bool ContinueCooking(void);
void ResetCookTimer();
// tolua_begin // tolua_begin
/// Returns the item in the input slot /** Returns the item in the input slot */
const cItem & GetInputSlot(void) const { return GetSlot(fsInput); } const cItem & GetInputSlot(void) const { return GetSlot(fsInput); }
/// Returns the item in the fuel slot /** Returns the item in the fuel slot */
const cItem & GetFuelSlot(void) const { return GetSlot(fsFuel); } const cItem & GetFuelSlot(void) const { return GetSlot(fsFuel); }
/// Returns the item in the output slot /** Returns the item in the output slot */
const cItem & GetOutputSlot(void) const { return GetSlot(fsOutput); } const cItem & GetOutputSlot(void) const { return GetSlot(fsOutput); }
/// Sets the item in the input slot /** Sets the item in the input slot */
void SetInputSlot(const cItem & a_Item) { SetSlot(fsInput, a_Item); } void SetInputSlot(const cItem & a_Item) { SetSlot(fsInput, a_Item); }
/// Sets the item in the fuel slot /** Sets the item in the fuel slot */
void SetFuelSlot(const cItem & a_Item) { SetSlot(fsFuel, a_Item); } void SetFuelSlot(const cItem & a_Item) { SetSlot(fsFuel, a_Item); }
/// Sets the item in the output slot /** Sets the item in the output slot */
void SetOutputSlot(const cItem & a_Item) { SetSlot(fsOutput, a_Item); } void SetOutputSlot(const cItem & a_Item) { SetSlot(fsOutput, a_Item); }
/// Returns the time that the current item has been cooking, in ticks /** Returns the time that the current item has been cooking, in ticks */
int GetTimeCooked(void) const {return m_TimeCooked; } int GetTimeCooked(void) const { return m_TimeCooked; }
/// Returns the time until the current item finishes cooking, in ticks /** Returns the time until the current item finishes cooking, in ticks */
int GetCookTimeLeft(void) const { return m_NeedCookTime - m_TimeCooked; } int GetCookTimeLeft(void) const { return m_NeedCookTime - m_TimeCooked; }
/// Returns the time until the current fuel is depleted, in ticks /** Returns the time until the current fuel is depleted, in ticks */
int GetFuelBurnTimeLeft(void) const {return m_FuelBurnTime - m_TimeBurned; } int GetFuelBurnTimeLeft(void) const { return m_FuelBurnTime - m_TimeBurned; }
/// Returns true if there's time left before the current fuel is depleted /** Returns true if there's time left before the current fuel is depleted */
bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); } bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); }
// tolua_end // tolua_end
void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned) {m_FuelBurnTime = a_FuelBurnTime; m_TimeBurned = a_TimeBurned; } void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned)
void SetCookTimes(int a_NeedCookTime, int a_TimeCooked) {m_NeedCookTime = a_NeedCookTime; m_TimeCooked = a_TimeCooked; } {
m_FuelBurnTime = a_FuelBurnTime;
m_TimeBurned = a_TimeBurned;
}
void SetCookTimes(int a_NeedCookTime, int a_TimeCooked)
{
m_NeedCookTime = a_NeedCookTime;
m_TimeCooked = a_TimeCooked;
}
protected: protected:
/// Block type of the block currently represented by this entity (changes when furnace lights up)
BLOCKTYPE m_BlockType;
/// Block meta of the block currently represented by this entity /** Block meta of the block currently represented by this entity */
NIBBLETYPE m_BlockMeta; NIBBLETYPE m_BlockMeta;
/// The recipe for the current input slot /** The recipe for the current input slot */
const cFurnaceRecipe::cRecipe * m_CurrentRecipe; const cFurnaceRecipe::cRecipe * m_CurrentRecipe;
/// The item that is being smelted /** The item that is being smelted */
cItem m_LastInput; cItem m_LastInput;
/** Set to true when the furnace entity has been destroyed to prevent the block being set again */
bool m_IsDestroyed;
bool m_IsCooking; ///< Set to true if the furnace is cooking an item /** Set to true if the furnace is cooking an item */
bool m_IsCooking;
// All timers are in ticks /** Amount of ticks needed to fully cook current item */
int m_NeedCookTime; ///< Amount of time needed to fully cook current item int m_NeedCookTime;
int m_TimeCooked; ///< Amount of time that the current item has been cooking
int m_FuelBurnTime; ///< Amount of time that the current fuel can burn (in total); zero if no fuel burning /** Amount of ticks that the current item has been cooking */
int m_TimeBurned; ///< Amount of time that the current fuel has been burning int m_TimeCooked;
/** Amount of ticks that the current fuel can burn (in total); zero if no fuel burning */
int m_FuelBurnTime;
/** Amount of ticks that the current fuel has been burning */
int m_TimeBurned;
int m_LastProgressFuel; ///< Last value sent as the progress for the fuel /** Sends the specified progressbar value to all clients of the window */
int m_LastProgressCook; ///< Last value sent as the progress for the cooking void BroadcastProgress(short a_ProgressbarID, short a_Value);
/** One item finished cooking */
/// Sends the specified progressbar value to all clients of the window
void BroadcastProgress(int a_ProgressbarID, short a_Value);
/// One item finished cooking
void FinishOne(); void FinishOne();
/// Starts burning a new fuel, if possible /** Starts burning a new fuel, if possible */
void BurnNewFuel(void); void BurnNewFuel(void);
/// Updates the recipe, based on the current input /** Updates the recipe, based on the current input */
void UpdateInput(void); void UpdateInput(void);
/// Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate /** Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate */
void UpdateFuel(void); void UpdateFuel(void);
/// Called when the output slot changes /** Called when the output slot changes */
void UpdateOutput(void); void UpdateOutput(void);
/// Updates the m_IsCooking, based on the input slot, output slot and m_FuelBurnTime / m_TimeBurned /** Returns true if the input can be cooked into output and the item counts allow for another cooking operation */
void UpdateIsCooking(void);
/// Returns true if the input can be cooked into output and the item counts allow for another cooking operation
bool CanCookInputToOutput(void) const; bool CanCookInputToOutput(void) const;
/// Broadcasts progressbar updates, if needed /** Broadcasts progressbar updates, if needed */
void UpdateProgressBars(void); void UpdateProgressBars(bool a_ForceUpdate = false);
/// Sets the m_IsCooking variable, updates the furnace block type based on the value /** Sets the m_IsCooking variable, updates the furnace block type based on the value */
void SetIsCooking(bool a_IsCooking); void SetIsCooking(bool a_IsCooking);
// cItemGrid::cListener overrides: // cItemGrid::cListener overrides:

View File

@ -31,6 +31,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cHopperEntity);
/// Constructor used for normal operation /// Constructor used for normal operation
cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
@ -40,8 +42,6 @@ public:
*/ */
bool GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ); bool GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ);
static const char * GetClassStatic(void) { return "cHopperEntity"; }
protected: protected:
Int64 m_LastMoveItemsInTick; Int64 m_LastMoveItemsInTick;

View File

@ -26,6 +26,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cJukeboxEntity);
cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cJukeboxEntity(); virtual ~cJukeboxEntity();
@ -51,8 +53,6 @@ public:
// tolua_end // tolua_end
static const char * GetClassStatic(void) { return "cJukeboxEntity"; }
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle &) override {} virtual void SendTo(cClientHandle &) override {}

View File

@ -34,6 +34,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cMobHeadEntity);
/** Creates a new mob head entity at the specified block coords. a_World may be NULL */ /** Creates a new mob head entity at the specified block coords. a_World may be NULL */
cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
@ -62,8 +64,6 @@ public:
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle & a_Client) override; virtual void SendTo(cClientHandle & a_Client) override;
static const char * GetClassStatic(void) { return "cMobHeadEntity"; }
private: private:
eMobHeadType m_Type; eMobHeadType m_Type;

View File

@ -40,6 +40,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cNoteEntity);
/// Creates a new note entity. a_World may be NULL /// Creates a new note entity. a_World may be NULL
cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
virtual ~cNoteEntity() {} virtual ~cNoteEntity() {}
@ -64,8 +66,6 @@ public:
} }
} }
static const char * GetClassStatic(void) { return "cNoteEntity"; }
private: private:
char m_Pitch; char m_Pitch;
} ; // tolua_export } ; // tolua_export

View File

@ -34,6 +34,8 @@ public:
// tolua_end // tolua_end
BLOCKENTITY_PROTODEF(cSignEntity);
/// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be NULL /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be NULL
cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World);
@ -53,8 +55,6 @@ public:
virtual void UsedBy(cPlayer * a_Player) override; virtual void UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle & a_Client) override; virtual void SendTo(cClientHandle & a_Client) override;
static const char * GetClassStatic(void) { return "cSignEntity"; }
private: private:
AString m_Line[4]; AString m_Line[4];

View File

@ -445,6 +445,21 @@ enum
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Block metas: // Block metas:
// E_BLOCK_ANVIL metas
E_BLOCK_ANVIL_Z = 0,
E_BLOCK_ANVIL_X = 1,
E_BLOCK_ANVIL_NO_DAMAGE = 0,
E_BLOCK_ANVIL_LOW_DAMAGE = 4,
E_BLOCK_ANVIL_HIGH_DAMAGE = 8,
// E_BLOCK_BED metas:
E_BLOCK_BED_ZP = 0,
E_BLOCK_BED_XM = 1,
E_BLOCK_BED_ZM = 2,
E_BLOCK_BED_XP = 3,
E_BLOCK_BED_OCCUPIED = 4,
E_BLOCK_BED_BED_HEAD = 8,
// E_BLOCK_BIG_FLOWER metas: // E_BLOCK_BIG_FLOWER metas:
E_META_BIG_FLOWER_SUNFLOWER = 0, E_META_BIG_FLOWER_SUNFLOWER = 0,
E_META_BIG_FLOWER_LILAC = 1, E_META_BIG_FLOWER_LILAC = 1,
@ -453,6 +468,20 @@ enum
E_META_BIG_FLOWER_ROSE_BUSH = 4, E_META_BIG_FLOWER_ROSE_BUSH = 4,
E_META_BIG_FLOWER_PEONY = 5, E_META_BIG_FLOWER_PEONY = 5,
// E_BLOCK_BREWING_STAND metas
E_META_BREWING_STAND_FILLED_SLOT_XP = 1,
E_META_BREWING_STAND_FILLED_SLOT_XM_ZP = 2,
E_META_BREWING_STAND_FILLED_SLOT_XM_ZM = 4,
// E_BLOCK_BUTTON metas
E_BLOCK_BUTTON_YM = 0,
E_BLOCK_BUTTON_XP = 1,
E_BLOCK_BUTTON_XM = 2,
E_BLOCK_BUTTON_ZP = 3,
E_BLOCK_BUTTON_ZM = 4,
E_BLOCK_BUTTON_YP = 5,
E_BLOCK_BUTTON_PRESSED = 8,
// E_BLOCK_CARPET metas: // E_BLOCK_CARPET metas:
E_META_CARPET_WHITE = 0, E_META_CARPET_WHITE = 0,
E_META_CARPET_ORANGE = 1, E_META_CARPET_ORANGE = 1,
@ -492,14 +521,17 @@ enum
E_META_DROPSPENSER_FACING_XP = 5, E_META_DROPSPENSER_FACING_XP = 5,
// E_BLOCK_DOUBLE_STONE_SLAB metas: // E_BLOCK_DOUBLE_STONE_SLAB metas:
E_META_DOUBLE_STONE_SLAB_STONE = 0, E_META_DOUBLE_STONE_SLAB_STONE = 0,
E_META_DOUBLE_STONE_SLAB_SANDSTONE = 1, E_META_DOUBLE_STONE_SLAB_SANDSTON = 1,
E_META_DOUBLE_STONE_SLAB_WOODEN = 2, E_META_DOUBLE_STONE_SLAB_WOODEN = 2,
E_META_DOUBLE_STONE_SLAB_COBBLESTONE = 3, E_META_DOUBLE_STONE_SLAB_COBBLESTONE = 3,
E_META_DOUBLE_STONE_SLAB_BRICK = 4, E_META_DOUBLE_STONE_SLAB_BRICK = 4,
E_META_DOUBLE_STONE_SLAB_STONE_BRICK = 5, E_META_DOUBLE_STONE_SLAB_STONE_BRICK = 5,
E_META_DOUBLE_STONE_SLAB_NETHER_BRICK = 6, E_META_DOUBLE_STONE_SLAB_NETHER_BRICK = 6,
E_META_DOUBLE_STONE_SLAB_STONE_SECRET = 7, E_META_DOUBLE_STONE_SLAB_QUARTZ = 7,
E_META_DOUBLE_STONE_SLAB_SMOOTH_STONE = 8,
E_META_DOUBLE_STONE_SLAB_SMOOTH_SANDSTONE = 9,
E_META_DOUBLE_STONE_SLAB_TILE_QUARTZ = 10,
// E_BLOCK_FLOWER metas: // E_BLOCK_FLOWER metas:
E_META_FLOWER_POPPY = 0, E_META_FLOWER_POPPY = 0,
@ -512,8 +544,8 @@ enum
E_META_FLOWER_OXEYE_DAISY = 8, E_META_FLOWER_OXEYE_DAISY = 8,
// E_BLOCK_JUKEBOX metas: // E_BLOCK_JUKEBOX metas:
E_META_JUKEBOX_OFF = 0, E_META_JUKEBOX_OFF = 0,
E_META_JUKEBOX_ON = 1, E_META_JUKEBOX_ON = 1,
// E_BLOCK_HOPPER metas: // E_BLOCK_HOPPER metas:
E_META_HOPPER_FACING_YM = 0, E_META_HOPPER_FACING_YM = 0,
@ -524,10 +556,26 @@ enum
E_META_HOPPER_FACING_XP = 5, E_META_HOPPER_FACING_XP = 5,
// E_BLOCK_LEAVES metas: // E_BLOCK_LEAVES metas:
E_META_LEAVES_APPLE = 0, E_META_LEAVES_APPLE = 0,
E_META_LEAVES_CONIFER = 1, E_META_LEAVES_CONIFER = 1,
E_META_LEAVES_BIRCH = 2, E_META_LEAVES_BIRCH = 2,
E_META_LEAVES_JUNGLE = 3, E_META_LEAVES_JUNGLE = 3,
E_META_LEAVES_APPLE_NO_DECAY = 4,
E_META_LEAVES_CONIFER_NO_DECAY = 5,
E_META_LEAVES_BIRCH_NO_DECAY = 6,
E_META_LEAVES_JUNGLE_NO_DECAY = 7,
E_META_LEAVES_APPLE_CHECK_DECAY = 8,
E_META_LEAVES_CONIFER_CHECK_DECAY = 9,
E_META_LEAVES_BIRCH_CHECK_DECAY = 10,
E_META_LEAVES_JUNGLE_CHECK_DECAY = 11,
// E_BLOCK_LEAVES meta cont. (Block ID 161):
E_META_NEWLEAVES_ACACIA = 0,
E_META_NEWLEAVES_DARK_OAK = 1,
E_META_NEWLEAVES_ACACIA_NO_DECAY = 4,
E_META_NEWLEAVES_DARK_OAK_NO_DECAY = 5,
E_META_NEWLEAVES_ACACIA_CHECK_DECAY = 8,
E_META_NEWLEAVES_DARK_OAK_CHECK_DECAY = 9,
// E_BLOCK_LOG metas: // E_BLOCK_LOG metas:
E_META_LOG_APPLE = 0, E_META_LOG_APPLE = 0,
@ -540,9 +588,19 @@ enum
E_META_NEW_LEAVES_DARK_OAK_WOOD = 1, E_META_NEW_LEAVES_DARK_OAK_WOOD = 1,
// E_BLOCK_NEW_LOG metas: // E_BLOCK_NEW_LOG metas:
E_META_NEW_LOG_ACACIA_WOOD = 0, E_META_NEW_LOG_ACACIA_WOOD = 0,
E_META_NEW_LOG_DARK_OAK_WOOD = 1, E_META_NEW_LOG_DARK_OAK_WOOD = 1,
// E_BLOCK_PISTON metas:
E_META_PISTON_DOWN = 0,
E_META_PISTON_U = 1,
E_META_PISTON_ZM = 2,
E_META_PISTON_ZP = 3,
E_META_PISTON_XM = 4,
E_META_PISTON_XP = 5,
E_META_PISTON_HEAD_STICKY = 8,
E_META_PISTON_EXTENDED = 8,
// E_BLOCK_PLANKS metas: // E_BLOCK_PLANKS metas:
E_META_PLANKS_APPLE = 0, E_META_PLANKS_APPLE = 0,
E_META_PLANKS_CONIFER = 1, E_META_PLANKS_CONIFER = 1,
@ -552,7 +610,7 @@ enum
E_META_PLANKS_DARK_OAK = 5, E_META_PLANKS_DARK_OAK = 5,
// E_BLOCK_(XXX_WEIGHTED)_PRESSURE_PLATE metas: // E_BLOCK_(XXX_WEIGHTED)_PRESSURE_PLATE metas:
E_META_PRESSURE_PLATE_RAISED = 0, E_META_PRESSURE_PLATE_RAISED = 0,
E_META_PRESSURE_PLATE_DEPRESSED = 1, E_META_PRESSURE_PLATE_DEPRESSED = 1,
// E_BLOCK_PRISMARINE_BLOCK metas: // E_BLOCK_PRISMARINE_BLOCK metas:
@ -561,21 +619,21 @@ enum
E_META_PRISMARINE_BLOCK_DARK = 2, E_META_PRISMARINE_BLOCK_DARK = 2,
// E_BLOCK_QUARTZ_BLOCK metas: // E_BLOCK_QUARTZ_BLOCK metas:
E_META_QUARTZ_NORMAL = 0, E_META_QUARTZ_NORMAL = 0,
E_META_QUARTZ_CHISELLED = 1, E_META_QUARTZ_CHISELLED = 1,
E_META_QUARTZ_PILLAR = 2, E_META_QUARTZ_PILLAR = 2,
// E_BLOCK_RAIL metas: // E_BLOCK_RAIL metas
E_META_RAIL_ZM_ZP = 0, E_META_RAIL_ZM_ZP = 0,
E_META_RAIL_XM_XP = 1, E_META_RAIL_XM_XP = 1,
E_META_RAIL_ASCEND_XP = 2, E_META_RAIL_ASCEND_XP = 2,
E_META_RAIL_ASCEND_XM = 3, E_META_RAIL_ASCEND_XM = 3,
E_META_RAIL_ASCEND_ZM = 4, E_META_RAIL_ASCEND_ZM = 4,
E_META_RAIL_ASCEND_ZP = 5, E_META_RAIL_ASCEND_ZP = 5,
E_META_RAIL_CURVED_ZP_XP = 6, E_META_RAIL_CURVED_ZP_XP = 6,
E_META_RAIL_CURVED_ZP_XM = 7, E_META_RAIL_CURVED_ZP_XM = 7,
E_META_RAIL_CURVED_ZM_XM = 8, E_META_RAIL_CURVED_ZM_XM = 8,
E_META_RAIL_CURVED_ZM_XP = 9, E_META_RAIL_CURVED_ZM_XP = 9,
// E_BLOCK_RED_SANDSTONE metas: // E_BLOCK_RED_SANDSTONE metas:
E_META_RED_SANDSTONE_NORMAL = 0, E_META_RED_SANDSTONE_NORMAL = 0,
@ -668,8 +726,15 @@ enum
E_META_STAINED_GLASS_PANE_RED = 14, E_META_STAINED_GLASS_PANE_RED = 14,
E_META_STAINED_GLASS_PANE_BLACK = 15, E_META_STAINED_GLASS_PANE_BLACK = 15,
// E_BLOCK_STAIRS metas:
E_BLOCK_STAIRS_XP = 0,
E_BLOCK_STAIRS_XM = 1,
E_BLOCK_STAIRS_ZP = 2,
E_BLOCK_STAIRS_ZM = 3,
E_BLOCK_STAIRS_UPSIDE_DOWN = 4,
// E_BLOCK_STONE metas: // E_BLOCK_STONE metas:
E_META_STONE = 0, E_META_STONE_STONE = 0,
E_META_STONE_GRANITE = 1, E_META_STONE_GRANITE = 1,
E_META_STONE_POLISHED_GRANITE = 2, E_META_STONE_POLISHED_GRANITE = 2,
E_META_STONE_DIORITE = 3, E_META_STONE_DIORITE = 3,
@ -685,18 +750,19 @@ enum
E_META_STONE_SLAB_BRICK = 4, E_META_STONE_SLAB_BRICK = 4,
E_META_STONE_SLAB_STONE_BRICK = 5, E_META_STONE_SLAB_STONE_BRICK = 5,
E_META_STONE_SLAB_NETHER_BRICK = 6, E_META_STONE_SLAB_NETHER_BRICK = 6,
E_META_STONE_SLAB_STONE_SECRET = 7, E_META_STONE_SLAB_QUARTZ = 7,
// E_BLOCK_STONE_BRICKS metas: // E_BLOCK_STONE_BRICKS metas:
E_META_STONE_BRICK_NORMAL = 0, E_META_STONE_BRICK_NORMAL = 0,
E_META_STONE_BRICK_MOSSY = 1, E_META_STONE_BRICK_MOSSY = 1,
E_META_STONE_BRICK_CRACKED = 2, E_META_STONE_BRICK_CRACKED = 2,
E_META_STONE_BRICK_ORNAMENT = 3, E_META_STONE_BRICK_ORNAMENT = 3,
// E_BLOCK_TALL_GRASS metas: // E_BLOCK_TALL_GRASS metas:
E_META_TALL_GRASS_DEAD_SHRUB = 0, E_META_TALL_GRASS_DEAD_SHRUB = 0,
E_META_TALL_GRASS_GRASS = 1, E_META_TALL_GRASS_GRASS = 1,
E_META_TALL_GRASS_FERN = 2, E_META_TALL_GRASS_FERN = 2,
E_META_TALL_GRASS_BIOME = 3,
// E_BLOCK_TORCH, E_BLOCK_REDSTONE_TORCH_OFF, E_BLOCK_REDSTONE_TORCH_ON metas: // E_BLOCK_TORCH, E_BLOCK_REDSTONE_TORCH_OFF, E_BLOCK_REDSTONE_TORCH_ON metas:
E_META_TORCH_EAST = 1, // east face of the block, pointing east E_META_TORCH_EAST = 1, // east face of the block, pointing east
@ -704,26 +770,55 @@ enum
E_META_TORCH_SOUTH = 3, E_META_TORCH_SOUTH = 3,
E_META_TORCH_NORTH = 4, E_META_TORCH_NORTH = 4,
E_META_TORCH_FLOOR = 5, E_META_TORCH_FLOOR = 5,
E_META_TORCH_XM = 1, // Torch attached to the XM side of its block E_META_TORCH_XM = 1, // Torch attached to the XM side of its block
E_META_TORCH_XP = 2, // Torch attached to the XP side of its block E_META_TORCH_XP = 2, // Torch attached to the XP side of its block
E_META_TORCH_ZM = 3, // Torch attached to the ZM side of its block E_META_TORCH_ZM = 3, // Torch attached to the ZM side of its block
E_META_TORCH_ZP = 4, // Torch attached to the ZP side of its block E_META_TORCH_ZP = 4, // Torch attached to the ZP side of its block
// E_META_LOG metas:
E_META_LOG_OAK_UP_DOWN = 0,
E_META_LOG_SPRUCE_UP_DOWN = 1,
E_META_LOG_BIRCH_UP_DOWN = 2,
E_META_LOG_JUNGLE_UP_DOWN = 3,
E_META_LOG_OAK_X = 4,
E_META_LOG_SPRUCE_X = 5,
E_META_LOG_BIRCH_X = 6,
E_META_LOG_JUNGLE_X = 7,
E_META_LOG_OAK_Z = 8,
E_META_LOG_SPRUCE_Z = 9,
E_META_LOG_BIRCH_Z = 10,
E_META_LOG_JUNGLE_Z = 11,
E_META_LOG_OAK_BARK_ONLY = 12,
E_META_LOG_SPRUCE_BARK_ONLY = 13,
E_META_LOG_BIRCH_BARK_ONLY = 14,
E_META_LOG_JUNGLE_BARK_ONLY = 15,
// E_META_LOG metas cont. (Block ID 162):
E_META_NEWLOG_ACACIA_UP_DOWN = 0,
E_META_NEWLOG_DARK_OAK_UP_DOWN = 1,
E_META_NEWLOG_ACACIA_X = 4,
E_META_NEWLOG_DARK_OAK_X = 5,
E_META_NEWLOG_ACACIA_Z = 8,
E_META_NEWLOG_DARK_OAK_Z = 9,
E_META_NEWLOG_ACACIA_BARK_ONLY = 12,
E_META_NEWLOG_DARK_OAK_BARK_ONLY = 13,
// E_BLOCK_WOODEN_DOUBLE_SLAB metas: // E_BLOCK_WOODEN_DOUBLE_SLAB metas:
E_META_WOODEN_DOUBLE_SLAB_APPLE = 0, E_META_WOODEN_DOUBLE_SLAB_APPLE = 0,
E_META_WOODEN_DOUBLE_SLAB_CONIFER = 1, E_META_WOODEN_DOUBLE_SLAB_CONIFER = 1,
E_META_WOODEN_DOUBLE_SLAB_BIRCH = 2, E_META_WOODEN_DOUBLE_SLAB_BIRCH = 2,
E_META_WOODEN_DOUBLE_SLAB_JUNGLE = 3, E_META_WOODEN_DOUBLE_SLAB_JUNGLE = 3,
E_META_WOODEN_DOUBLE_SLAB_ACACIA = 4, E_META_WOODEN_DOUBLE_SLAB_ACACIA = 4,
E_META_WOODEN_DOUBLE_SLAB_DARK_OAK = 5, E_META_WOODEN_DOUBLE_SLAB_DARK_OAK = 5,
// E_BLOCK_WOODEN_SLAB metas: // E_BLOCK_WOODEN_SLAB metas:
E_META_WOODEN_SLAB_APPLE = 0, E_META_WOODEN_SLAB_APPLE = 0,
E_META_WOODEN_SLAB_CONIFER = 1, E_META_WOODEN_SLAB_CONIFER = 1,
E_META_WOODEN_SLAB_BIRCH = 2, E_META_WOODEN_SLAB_BIRCH = 2,
E_META_WOODEN_SLAB_JUNGLE = 3, E_META_WOODEN_SLAB_JUNGLE = 3,
E_META_WOODEN_SLAB_ACACIA = 4, E_META_WOODEN_SLAB_ACACIA = 4,
E_META_WOODEN_SLAB_DARK_OAK = 5, E_META_WOODEN_SLAB_DARK_OAK = 5,
E_META_WOODEN_SLAB_UPSIDE_DOWN = 8,
// E_BLOCK_WOOL metas: // E_BLOCK_WOOL metas:
E_META_WOOL_WHITE = 0, E_META_WOOL_WHITE = 0,

View File

@ -6,14 +6,30 @@
#include "Root.h" #include "Root.h"
#include "Bindings/PluginManager.h" #include "Bindings/PluginManager.h"
class cBlockInServerPluginInterface : public cBlockPluginInterface
class cBlockInServerPluginInterface :
public cBlockPluginInterface
{ {
public: public:
cBlockInServerPluginInterface(cWorld & a_World) : m_World(a_World) {} cBlockInServerPluginInterface(cWorld & a_World) : m_World(a_World) {}
virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source)
{
return cPluginManager::Get()->CallHookBlockSpread(m_World, a_BlockX, a_BlockY, a_BlockZ, a_Source);
}
virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override
{ {
return cRoot::Get()->GetPluginManager()->CallHookBlockToPickups(&m_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups); return cPluginManager::Get()->CallHookBlockToPickups(m_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups);
} }
private: private:
cWorld & m_World; cWorld & m_World;
}; };

View File

@ -89,7 +89,7 @@ public:
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta)) if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta))
{ {
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread)) if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(*Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread))
{ {
Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0);
} }

View File

@ -4,6 +4,7 @@
#include "../Item.h" #include "../Item.h"
#include "../World.h" #include "../World.h"
#include "../Chunk.h" #include "../Chunk.h"
#include "BlockPluginInterface.h"
#include "BlockAnvil.h" #include "BlockAnvil.h"
#include "BlockBed.h" #include "BlockBed.h"
#include "BlockBigFlower.h" #include "BlockBigFlower.h"
@ -36,7 +37,6 @@
#include "BlockGlass.h" #include "BlockGlass.h"
#include "BlockGlowstone.h" #include "BlockGlowstone.h"
#include "BlockGravel.h" #include "BlockGravel.h"
#include "BlockHayBale.h"
#include "BlockMobHead.h" #include "BlockMobHead.h"
#include "BlockHopper.h" #include "BlockHopper.h"
#include "BlockIce.h" #include "BlockIce.h"
@ -83,7 +83,6 @@
#include "BlockWorkbench.h" #include "BlockWorkbench.h"
#include "BlockPluginInterface.h"
@ -231,7 +230,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType); case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType); case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType); case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType); case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType); case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType); case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType); case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);

View File

@ -1,22 +0,0 @@
#pragma once
#include "BlockSideways.h"
class cBlockHayBaleHandler :
public cBlockSidewaysHandler
{
public:
cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
: cBlockSidewaysHandler(a_BlockType)
{
}
} ;

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "BlockHandler.h" #include "BlockHandler.h"
#include "../Chunk.h"
#include "MetaRotator.h" #include "MetaRotator.h"
#include "BlockSlab.h"
class cBlockLeverHandler : class cBlockLeverHandler :
@ -93,13 +93,35 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{ {
NIBBLETYPE Meta; NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
eBlockFace Face = BlockMetaDataToBlockFace(Meta);
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true);
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height -1))
{
return false;
}
BLOCKTYPE BlockIsOn;
a_Chunk.UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockIsOn, Meta);
if (cBlockInfo::FullyOccupiesVoxel(BlockIsOn))
{
return true;
}
else if (cBlockSlabHandler::IsAnySlabType(BlockIsOn))
{
// Check if the slab is turned up side down
if (((Meta & 0x08) == 0x08) && (Face == BLOCK_FACE_TOP))
{
return true;
}
}
return false;
} }

View File

@ -1,7 +1,11 @@
#pragma once #pragma once
/** This interface is used to decouple block handlers from the cPluginManager dependancy through cWorld.
/** This interface is used to decouple block handlers from the cPluginManager dependency through cWorld.
The block handlers call this interface, which is then implemented by the specific classes that The block handlers call this interface, which is then implemented by the specific classes that
the caller provides. the caller provides.
*/ */
@ -10,5 +14,10 @@ class cBlockPluginInterface
public: public:
virtual ~cBlockPluginInterface() {} virtual ~cBlockPluginInterface() {}
virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0;
virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0;
}; };

View File

@ -3,6 +3,7 @@
#include "BlockHandler.h" #include "BlockHandler.h"
#include "../World.h" #include "../World.h"
#include "BlockSlab.h"
@ -16,11 +17,33 @@ public:
: cBlockHandler(a_BlockType) : cBlockHandler(a_BlockType)
{ {
} }
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{ {
return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); if (a_RelY <= 0)
{
return false;
}
BLOCKTYPE BelowBlock;
NIBBLETYPE BelowBlockMeta;
a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BelowBlock, BelowBlockMeta);
if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
{
return true;
}
else if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
{
// Check if the slab is turned up side down
if ((BelowBlockMeta & 0x08) == 0x08)
{
return true;
}
}
return false;
} }

View File

@ -5,6 +5,7 @@
#include "Chunk.h" #include "Chunk.h"
#include "MetaRotator.h" #include "MetaRotator.h"
#include "ChunkInterface.h" #include "ChunkInterface.h"
#include "BlockSlab.h"
@ -44,6 +45,7 @@ public:
} }
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
// Reset meta to zero // Reset meta to zero
@ -59,7 +61,28 @@ public:
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{ {
return ((a_RelY > 0) && cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); if (a_RelY <= 0)
{
return false;
}
BLOCKTYPE BelowBlock;
NIBBLETYPE BelowBlockMeta;
a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, BelowBlock, BelowBlockMeta);
if (cBlockInfo::FullyOccupiesVoxel(BelowBlock))
{
return true;
}
else if (cBlockSlabHandler::IsAnySlabType(BelowBlock))
{
// Check if the slab is turned up side down
if ((BelowBlockMeta & 0x08) == 0x08)
{
return true;
}
}
return false;
} }

View File

@ -13,6 +13,7 @@
#include "../Items/ItemHandler.h" #include "../Items/ItemHandler.h"
#include "Root.h" #include "Root.h"
#include "ChunkInterface.h" #include "ChunkInterface.h"
#include "../Entities/Player.h"

View File

@ -18,7 +18,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
if (a_BlockMeta == E_META_STONE) if (a_BlockMeta == E_META_STONE_STONE)
{ {
a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0)); a_Pickups.push_back(cItem(E_BLOCK_COBBLESTONE, 1, 0));
return; return;

View File

@ -166,23 +166,31 @@ public:
return false; return false;
} }
virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
{ {
UNUSED(a_ChunkInterface); UNUSED(a_ChunkInterface);
UNUSED(a_WorldInterface); UNUSED(a_WorldInterface);
UNUSED(a_BlockPluginInterface);
// Vine cannot grow down if at the bottom:
if (a_RelY < 1)
{
return;
}
// Grow one block down, if possible:
BLOCKTYPE Block; BLOCKTYPE Block;
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
if (Block == E_BLOCK_AIR) if (Block == E_BLOCK_AIR)
{ {
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread)) if (!a_BlockPluginInterface.CallHookBlockSpread(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread))
{ {
a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
} }
} }
} }
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
{ {
return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right

View File

@ -45,7 +45,6 @@ SET (HDRS
BlockGlowstone.h BlockGlowstone.h
BlockGravel.h BlockGravel.h
BlockHandler.h BlockHandler.h
BlockHayBale.h
BlockHopper.h BlockHopper.h
BlockIce.h BlockIce.h
BlockLadder.h BlockLadder.h

View File

@ -41,6 +41,7 @@ local g_ShouldProcessExt =
--- The list of files not to be processed: --- The list of files not to be processed:
local g_IgnoredFiles = local g_IgnoredFiles =
{ {
"Bindings/Bindings.h",
"Bindings/Bindings.cpp", "Bindings/Bindings.cpp",
"LeakFinder.cpp", "LeakFinder.cpp",
"LeakFinder.h", "LeakFinder.h",

View File

@ -119,7 +119,7 @@ cChunk::cChunk(
cChunk::~cChunk() cChunk::~cChunk()
{ {
cPluginManager::Get()->CallHookChunkUnloaded(m_World, m_PosX, m_PosZ); cPluginManager::Get()->CallHookChunkUnloaded(*m_World, m_PosX, m_PosZ);
// LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId()); // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId());
@ -333,7 +333,7 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData)
{ {
BLOCKTYPE EntityBlockType = (*itr)->GetBlockType(); BLOCKTYPE EntityBlockType = (*itr)->GetBlockType();
BLOCKTYPE WorldBlockType = GetBlock((*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ()); BLOCKTYPE WorldBlockType = GetBlock((*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ());
ASSERT(EntityBlockType == WorldBlockType); ASSERT(WorldBlockType == EntityBlockType);
} // for itr - m_BlockEntities } // for itr - m_BlockEntities
#endif // _DEBUG #endif // _DEBUG
@ -1750,11 +1750,11 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max
void cChunk::CollectPickupsByPlayer(cPlayer * a_Player) void cChunk::CollectPickupsByPlayer(cPlayer & a_Player)
{ {
double PosX = a_Player->GetPosX(); double PosX = a_Player.GetPosX();
double PosY = a_Player->GetPosY(); double PosY = a_Player.GetPosY();
double PosZ = a_Player->GetPosZ(); double PosZ = a_Player.GetPosZ();
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
{ {
@ -2614,7 +2614,7 @@ BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const
{ {
a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ); a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
a_BlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ); a_BlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);

View File

@ -33,7 +33,7 @@ class cChunkMap;
class cBeaconEntity; class cBeaconEntity;
class cBoundingBox; class cBoundingBox;
class cChestEntity; class cChestEntity;
class cCHunkDataCallback; class cChunkDataCallback;
class cCommandBlockEntity; class cCommandBlockEntity;
class cDispenserEntity; class cDispenserEntity;
class cFurnaceEntity; class cFurnaceEntity;
@ -186,7 +186,7 @@ public:
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const;
BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); } BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); }
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
/** Returns the chunk into which the specified block belongs, by walking the neighbors. /** Returns the chunk into which the specified block belongs, by walking the neighbors.
@ -218,7 +218,7 @@ public:
Sends the chunk to all relevant clients. */ Sends the chunk to all relevant clients. */
void SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_MaxRelZ, EMCSBiome a_Biome); void SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_MaxRelZ, EMCSBiome a_Biome);
void CollectPickupsByPlayer(cPlayer * a_Player); void CollectPickupsByPlayer(cPlayer & a_Player);
/** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */ /** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */
bool SetSignLines(int a_RelX, int a_RelY, int a_RelZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); bool SetSignLines(int a_RelX, int a_RelY, int a_RelZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);

View File

@ -954,7 +954,7 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData)
} }
// Notify plugins of the chunk becoming available // Notify plugins of the chunk becoming available
cPluginManager::Get()->CallHookChunkAvailable(m_World, ChunkX, ChunkZ); cPluginManager::Get()->CallHookChunkAvailable(*m_World, ChunkX, ChunkZ);
} }
@ -1145,11 +1145,11 @@ void cChunkMap::FastSetBlocks(sSetBlockList & a_BlockList)
void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player)
{ {
int BlockX = (int)(a_Player->GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway int BlockX = (int)(a_Player.GetPosX()); // Truncating doesn't matter much; we're scanning entire chunks anyway
int BlockY = (int)(a_Player->GetPosY()); int BlockY = (int)(a_Player.GetPosY());
int BlockZ = (int)(a_Player->GetPosZ()); int BlockZ = (int)(a_Player.GetPosZ());
int ChunkX = 0, ChunkZ = 0; int ChunkX = 0, ChunkZ = 0;
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1);
@ -2973,7 +2973,7 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void)
if ( if (
(m_Chunks[i] != NULL) && // Is valid (m_Chunks[i] != NULL) && // Is valid
(m_Chunks[i]->CanUnload()) && // Can unload (m_Chunks[i]->CanUnload()) && // Can unload
!cPluginManager::Get()->CallHookChunkUnloading(m_Parent->GetWorld(), m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()) // Plugins agree !cPluginManager::Get()->CallHookChunkUnloading(*(m_Parent->GetWorld()), m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()) // Plugins agree
) )
{ {
// The cChunk destructor calls our GetChunk() while removing its entities // The cChunk destructor calls our GetChunk() while removing its entities
@ -2987,6 +2987,8 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void)
void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{ {
cCSLock Lock(m_CSFastSetBlock); cCSLock Lock(m_CSFastSetBlock);

View File

@ -144,7 +144,7 @@ public:
void FastSetQueuedBlocks(); void FastSetQueuedBlocks();
void FastSetBlocks (sSetBlockList & a_BlockList); void FastSetBlocks (sSetBlockList & a_BlockList);
void CollectPickupsByPlayer(cPlayer * a_Player); void CollectPickupsByPlayer(cPlayer & a_Player);
BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ); BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ);
NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ);

View File

@ -248,9 +248,12 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
// xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B
// Note that we generate a short UUID (without the dashes) // Note that we generate a short UUID (without the dashes)
// First make the username lowercase:
AString lcUsername = StrToLower(a_Username);
// Generate an md5 checksum, and use it as base for the ID: // Generate an md5 checksum, and use it as base for the ID:
unsigned char MD5[16]; unsigned char MD5[16];
md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5); md5((const unsigned char *)lcUsername.c_str(), lcUsername.length(), MD5);
MD5[6] &= 0x0f; // Need to trim to 4 bits only... MD5[6] &= 0x0f; // Need to trim to 4 bits only...
MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars
return Printf("%02x%02x%02x%02x%02x%02x3%01x%02x8%01x%02x%02x%02x%02x%02x%02x%02x", return Printf("%02x%02x%02x%02x%02x%02x3%01x%02x8%01x%02x%02x%02x%02x%02x%02x%02x",
@ -639,9 +642,11 @@ void cClientHandle::RemoveFromAllChunks()
} }
{ {
// Reset all chunk lists:
cCSLock Lock(m_CSChunkLists); cCSLock Lock(m_CSChunkLists);
m_LoadedChunks.clear(); m_LoadedChunks.clear();
m_ChunksToSend.clear(); m_ChunksToSend.clear();
m_SentChunks.clear();
// Also reset the LastStreamedChunk coords to bogus coords, // Also reset the LastStreamedChunk coords to bogus coords,
// so that all chunks are streamed in subsequent StreamChunks() call (FS #407) // so that all chunks are streamed in subsequent StreamChunks() call (FS #407)
@ -695,7 +700,7 @@ bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Usernam
m_Username = a_Username; m_Username = a_Username;
// Let the plugins know about this event, they may refuse the player: // Let the plugins know about this event, they may refuse the player:
if (cRoot::Get()->GetPluginManager()->CallHookLogin(this, a_ProtocolVersion, a_Username)) if (cRoot::Get()->GetPluginManager()->CallHookLogin(*this, a_ProtocolVersion, a_Username))
{ {
Destroy(); Destroy();
return false; return false;
@ -1814,7 +1819,7 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID)
bool cClientHandle::HandleHandshake(const AString & a_Username) bool cClientHandle::HandleHandshake(const AString & a_Username)
{ {
if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(this, a_Username)) if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(*this, a_Username))
{ {
if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers()) if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers())
{ {
@ -2147,7 +2152,17 @@ void cClientHandle::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_Block
void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{ {
m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); int ChunkX, ChunkZ = 0;
cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
cChunkCoords ChunkCoords = cChunkCoords(ChunkX, ChunkZ);
// Do not send block changes in chunks that weren't sent to the client yet:
cCSLock Lock(m_CSChunkLists);
if (std::find(m_SentChunks.begin(), m_SentChunks.end(), ChunkCoords) != m_SentChunks.end())
{
Lock.Unlock();
m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
} }
@ -2157,8 +2172,15 @@ void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BL
void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes)
{ {
ASSERT(!a_Changes.empty()); // We don't want to be sending empty change packets! ASSERT(!a_Changes.empty()); // We don't want to be sending empty change packets!
m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); // Do not send block changes in chunks that weren't sent to the client yet:
cChunkCoords ChunkCoords = cChunkCoords(a_ChunkX, a_ChunkZ);
cCSLock Lock(m_CSChunkLists);
if (std::find(m_SentChunks.begin(), m_SentChunks.end(), ChunkCoords) != m_SentChunks.end())
{
Lock.Unlock();
m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes);
}
} }
@ -2222,6 +2244,12 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ
m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer); m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer);
// Add the chunk to the list of chunks sent to the player:
{
cCSLock Lock(m_CSChunkLists);
m_SentChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
}
// If it is the chunk the player's in, make them spawn (in the tick thread): // If it is the chunk the player's in, make them spawn (in the tick thread):
if ((m_State == csAuthenticated) || (m_State == csDownloadingWorld)) if ((m_State == csAuthenticated) || (m_State == csDownloadingWorld))
{ {
@ -2751,6 +2779,12 @@ void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_D
void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
{ {
// Remove the chunk from the list of chunks sent to the client:
{
cCSLock Lock(m_CSChunkLists);
m_SentChunks.remove(cChunkCoords(a_ChunkX, a_ChunkZ));
}
m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ); m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ);
} }
@ -2825,7 +2859,7 @@ void cClientHandle::SendWindowOpen(const cWindow & a_Window)
void cClientHandle::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) void cClientHandle::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value)
{ {
m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value); m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value);
} }

View File

@ -209,7 +209,7 @@ public:
void SendWholeInventory (const cWindow & a_Window); void SendWholeInventory (const cWindow & a_Window);
void SendWindowClose (const cWindow & a_Window); void SendWindowClose (const cWindow & a_Window);
void SendWindowOpen (const cWindow & a_Window); void SendWindowOpen (const cWindow & a_Window);
void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value); void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value);
// tolua_begin // tolua_begin
const AString & GetUsername(void) const; const AString & GetUsername(void) const;
@ -348,6 +348,7 @@ private:
cCriticalSection m_CSChunkLists; cCriticalSection m_CSChunkLists;
cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to
cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them) cChunkCoordsList m_ChunksToSend; // Chunks that need to be sent to the player (queued because they weren't generated yet or there's not enough time to send them)
cChunkCoordsList m_SentChunks; // Chunks that are currently sent to the client
cProtocol * m_Protocol; cProtocol * m_Protocol;

View File

@ -280,10 +280,10 @@ cCraftingRecipes::~cCraftingRecipes()
void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe)
{ {
// Allow plugins to intercept recipes using a pre-craft hook: // Allow plugins to intercept recipes using a pre-craft hook:
if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, &a_CraftingGrid, &a_Recipe)) if (cRoot::Get()->GetPluginManager()->CallHookPreCrafting(a_Player, a_CraftingGrid, a_Recipe))
{ {
return; return;
} }
@ -294,7 +294,7 @@ void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid &
if (Recipe.get() == NULL) if (Recipe.get() == NULL)
{ {
// Allow plugins to intercept a no-recipe-found situation: // Allow plugins to intercept a no-recipe-found situation:
cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, &a_CraftingGrid, &a_Recipe); cRoot::Get()->GetPluginManager()->CallHookCraftingNoRecipe(a_Player, a_CraftingGrid, &a_Recipe);
return; return;
} }
for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr)
@ -304,7 +304,7 @@ void cCraftingRecipes::GetRecipe(const cPlayer * a_Player, const cCraftingGrid &
a_Recipe.SetResult(Recipe->m_Result); a_Recipe.SetResult(Recipe->m_Result);
// Allow plugins to intercept recipes after they are processed: // Allow plugins to intercept recipes after they are processed:
cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, &a_CraftingGrid, &a_Recipe); cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, a_CraftingGrid, a_Recipe);
} }

View File

@ -115,7 +115,7 @@ public:
~cCraftingRecipes(); ~cCraftingRecipes();
/// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found. /// Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found.
void GetRecipe(const cPlayer * a_Player, const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); void GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe);
protected: protected:

View File

@ -6,6 +6,7 @@
#include "Enchantments.h" #include "Enchantments.h"
#include "WorldStorage/FastNBT.h" #include "WorldStorage/FastNBT.h"
#include "FastRandom.h" #include "FastRandom.h"
#include "Noise.h"
@ -1019,3 +1020,30 @@ cEnchantments cEnchantments::GetRandomEnchantmentFromVector(cWeightedEnchantment
cEnchantments cEnchantments::GenerateEnchantmentFromVector(cWeightedEnchantments & a_Enchantments, int a_Seed)
{
int AllWeights = 0;
for (const auto Enchantment : a_Enchantments)
{
AllWeights += Enchantment.m_Weight;
}
cNoise Noise(a_Seed);
int RandomNumber = Noise.IntNoise1DInt(AllWeights) / 7 % AllWeights;
for (const auto Enchantment : a_Enchantments)
{
RandomNumber -= Enchantment.m_Weight;
if (RandomNumber < 0)
{
return Enchantment.m_Enchantments;
}
}
return cEnchantments();
}

View File

@ -128,6 +128,9 @@ public:
/** Gets random enchantment from Vector and returns it */ /** Gets random enchantment from Vector and returns it */
static cEnchantments GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments); static cEnchantments GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments);
/** Returns an enchantment from a Vector using cNoise. Mostly used for generators.*/
static cEnchantments GenerateEnchantmentFromVector(cWeightedEnchantments & a_Enchantments, int a_Seed);
/** Returns true if a_Other doesn't contain exactly the same enchantments and levels */ /** Returns true if a_Other doesn't contain exactly the same enchantments and levels */
bool operator !=(const cEnchantments & a_Other) const; bool operator !=(const cEnchantments & a_Other) const;

View File

@ -149,14 +149,14 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
void cArrowEntity::CollectedBy(cPlayer * a_Dest) void cArrowEntity::CollectedBy(cPlayer & a_Dest)
{ {
if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) if (m_IsInGround && !m_bIsCollected && CanPickup(a_Dest))
{ {
// Do not add the arrow to the inventory when the player is in creative: // Do not add the arrow to the inventory when the player is in creative:
if (!a_Dest->IsGameModeCreative()) if (!a_Dest.IsGameModeCreative())
{ {
int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); int NumAdded = a_Dest.GetInventory().AddItem(E_ITEM_ARROW);
if (NumAdded == 0) if (NumAdded == 0)
{ {
// No space in the inventory // No space in the inventory
@ -164,7 +164,7 @@ void cArrowEntity::CollectedBy(cPlayer * a_Dest)
} }
} }
GetWorld()->BroadcastCollectEntity(*this, *a_Dest); GetWorld()->BroadcastCollectEntity(*this, a_Dest);
GetWorld()->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); GetWorld()->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
m_bIsCollected = true; m_bIsCollected = true;
} }
@ -229,3 +229,7 @@ void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk)
} }
} }
} }

View File

@ -97,7 +97,7 @@ protected:
// cProjectileEntity overrides: // cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
virtual void CollectedBy(cPlayer * a_Player) override; virtual void CollectedBy(cPlayer & a_Player) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
}; // tolua_export }; // tolua_export

View File

@ -27,9 +27,9 @@
return super::GetClass(); \ return super::GetClass(); \
} }
#define POSX_TOINT (int)floor(GetPosX()) #define POSX_TOINT FloorC(GetPosX())
#define POSY_TOINT (int)floor(GetPosY()) #define POSY_TOINT FloorC(GetPosY())
#define POSZ_TOINT (int)floor(GetPosZ()) #define POSZ_TOINT FloorC(GetPosZ())
#define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT) #define POS_TOINT Vector3i(POSXTOINT, POSYTOINT, POSZTOINT)
#define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; } #define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z) cChunk * ChunkVarName = a_Chunk.GetNeighborChunk(X, Z); if ((ChunkVarName == NULL) || !ChunkVarName->IsValid()) { return; }
@ -172,13 +172,13 @@ public:
/// Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true) /// Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true)
virtual bool IsA(const char * a_ClassName) const; virtual bool IsA(const char * a_ClassName) const;
/// Returns the topmost class name for the object /** Returns the class name of this class */
virtual const char * GetClass(void) const;
// Returns the class name of this class
static const char * GetClassStatic(void); static const char * GetClassStatic(void);
/// Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent). /** Returns the topmost class name for the object */
virtual const char * GetClass(void) const;
/** Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent). */
virtual const char * GetParentClass(void) const; virtual const char * GetParentClass(void) const;
cWorld * GetWorld(void) const { return m_World; } cWorld * GetWorld(void) const { return m_World; }

View File

@ -127,7 +127,7 @@ public:
ContentsWidth = 9, ContentsWidth = 9,
}; };
const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); }
void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); } void SetSlot(size_t a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); }
protected: protected:

View File

@ -191,10 +191,8 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
bool cPickup::CollectedBy(cPlayer * a_Dest) bool cPickup::CollectedBy(cPlayer & a_Dest)
{ {
ASSERT(a_Dest != NULL);
if (m_bCollected) if (m_bCollected)
{ {
// LOG("Pickup %d cannot be collected by \"%s\", because it has already been collected.", m_UniqueID, a_Dest->GetName().c_str()); // LOG("Pickup %d cannot be collected by \"%s\", because it has already been collected.", m_UniqueID, a_Dest->GetName().c_str());
@ -214,21 +212,21 @@ bool cPickup::CollectedBy(cPlayer * a_Dest)
return false; return false;
} }
int NumAdded = a_Dest->GetInventory().AddItem(m_Item); int NumAdded = a_Dest.GetInventory().AddItem(m_Item);
if (NumAdded > 0) if (NumAdded > 0)
{ {
// Check achievements // Check achievements
switch (m_Item.m_ItemType) switch (m_Item.m_ItemType)
{ {
case E_BLOCK_LOG: a_Dest->AwardAchievement(achMineWood); break; case E_BLOCK_LOG: a_Dest.AwardAchievement(achMineWood); break;
case E_ITEM_LEATHER: a_Dest->AwardAchievement(achKillCow); break; case E_ITEM_LEATHER: a_Dest.AwardAchievement(achKillCow); break;
case E_ITEM_DIAMOND: a_Dest->AwardAchievement(achDiamonds); break; case E_ITEM_DIAMOND: a_Dest.AwardAchievement(achDiamonds); break;
case E_ITEM_BLAZE_ROD: a_Dest->AwardAchievement(achBlazeRod); break; case E_ITEM_BLAZE_ROD: a_Dest.AwardAchievement(achBlazeRod); break;
default: break; default: break;
} }
m_Item.m_ItemCount -= NumAdded; m_Item.m_ItemCount -= NumAdded;
m_World->BroadcastCollectEntity(*this, *a_Dest); m_World->BroadcastCollectEntity(*this, a_Dest);
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
m_World->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); m_World->BroadcastSoundEffect("random.pop", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
if (m_Item.m_ItemCount <= 0) if (m_Item.m_ItemCount <= 0)

View File

@ -32,7 +32,7 @@ public:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
bool CollectedBy(cPlayer * a_Dest); // tolua_export bool CollectedBy(cPlayer & a_Dest); // tolua_export
virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override;

View File

@ -244,7 +244,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
if (m_Health > 0) // make sure player is alive if (m_Health > 0) // make sure player is alive
{ {
m_World->CollectPickupsByPlayer(this); m_World->CollectPickupsByPlayer(*this);
if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge())) if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge()))
{ {
@ -2133,19 +2133,19 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
void cPlayer::LoadRank(void) void cPlayer::LoadRank(void)
{ {
// Load the values from cRankManager: // Load the values from cRankManager:
cRankManager & RankMgr = cRoot::Get()->GetRankManager(); cRankManager * RankMgr = cRoot::Get()->GetRankManager();
m_Rank = RankMgr.GetPlayerRankName(m_UUID); m_Rank = RankMgr->GetPlayerRankName(m_UUID);
if (m_Rank.empty()) if (m_Rank.empty())
{ {
m_Rank = RankMgr.GetDefaultRank(); m_Rank = RankMgr->GetDefaultRank();
} }
else else
{ {
// Update the name: // Update the name:
RankMgr.UpdatePlayerName(m_UUID, m_PlayerName); RankMgr->UpdatePlayerName(m_UUID, m_PlayerName);
} }
m_Permissions = RankMgr.GetPlayerPermissions(m_UUID); m_Permissions = RankMgr->GetPlayerPermissions(m_UUID);
RankMgr.GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); RankMgr->GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode);
// Break up the individual permissions on each dot, into m_SplitPermissions: // Break up the individual permissions on each dot, into m_SplitPermissions:
m_SplitPermissions.clear(); m_SplitPermissions.clear();

View File

@ -424,8 +424,12 @@ void cProjectileEntity::SpawnOn(cClientHandle & a_Client)
void cProjectileEntity::CollectedBy(cPlayer * a_Dest) void cProjectileEntity::CollectedBy(cPlayer & a_Dest)
{ {
// Overriden in arrow // Overriden in arrow
UNUSED(a_Dest); UNUSED(a_Dest);
} }

View File

@ -59,7 +59,7 @@ public:
} }
/// Called by Chunk when the projectile is eligible for player collection /// Called by Chunk when the projectile is eligible for player collection
virtual void CollectedBy(cPlayer * a_Dest); virtual void CollectedBy(cPlayer & a_Dest);
// tolua_begin // tolua_begin

View File

@ -45,7 +45,7 @@ void cBioGenConstant::InitializeBiomeGen(cIniFile & a_IniFile)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cBioGenCache: // cBioGenCache:
cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) : cBioGenCache::cBioGenCache(cBiomeGenPtr a_BioGenToCache, int a_CacheSize) :
m_BioGenToCache(a_BioGenToCache), m_BioGenToCache(a_BioGenToCache),
m_CacheSize(a_CacheSize), m_CacheSize(a_CacheSize),
m_CacheOrder(new int[a_CacheSize]), m_CacheOrder(new int[a_CacheSize]),
@ -145,25 +145,13 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cBioGenMulticache: // cBioGenMulticache:
cBioGenMulticache::cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength) : cBioGenMulticache::cBioGenMulticache(cBiomeGenPtr a_BioGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches) :
m_CachesLength(a_CachesLength) m_NumSubCaches(a_NumSubCaches)
{ {
m_Caches.reserve(a_CachesLength); m_Caches.reserve(a_NumSubCaches);
for (size_t i = 0; i < a_CachesLength; i++) for (size_t i = 0; i < a_NumSubCaches; i++)
{ {
m_Caches.push_back(new cBioGenCache(a_BioGenToCache, a_CacheSize)); m_Caches.push_back(cBiomeGenPtr(new cBioGenCache(a_BioGenToCache, a_SubCacheSize)));
}
}
cBioGenMulticache::~cBioGenMulticache()
{
for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++)
{
delete *it;
} }
} }
@ -174,7 +162,7 @@ cBioGenMulticache::~cBioGenMulticache()
void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
{ {
const size_t coefficient = 3; const size_t coefficient = 3;
const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_CachesLength; const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_NumSubCaches;
m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap);
} }
@ -185,10 +173,9 @@ void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMa
void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile) void cBioGenMulticache::InitializeBiomeGen(cIniFile & a_IniFile)
{ {
for (cBiomeGens::iterator it = m_Caches.begin(); it != m_Caches.end(); it++) for (auto itr : m_Caches)
{ {
cBiomeGen * tmp = *it; itr->InitializeBiomeGen(a_IniFile);
tmp->InitializeBiomeGen(a_IniFile);
} }
} }
@ -760,8 +747,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1];
for (int x = 0; x <= 4; x++) for (int z = 0; z <= 4; z++) for (int x = 0; x <= 4; x++) for (int z = 0; z <= 4; z++)
{ {
float BlockX = BaseX + x * 4; float BlockX = static_cast<float>(BaseX + x * 4);
float BlockZ = BaseZ + z * 4; float BlockZ = static_cast<float>(BaseZ + z * 4);
double NoiseX = m_AmpX1 * m_Noise1.CubicNoise2D(BlockX * m_FreqX1, BlockZ * m_FreqX1); double NoiseX = m_AmpX1 * m_Noise1.CubicNoise2D(BlockX * m_FreqX1, BlockZ * m_FreqX1);
NoiseX += m_AmpX2 * m_Noise2.CubicNoise2D(BlockX * m_FreqX2, BlockZ * m_FreqX2); NoiseX += m_AmpX2 * m_Noise2.CubicNoise2D(BlockX * m_FreqX2, BlockZ * m_FreqX2);
NoiseX += m_AmpX3 * m_Noise3.CubicNoise2D(BlockX * m_FreqX3, BlockZ * m_FreqX3); NoiseX += m_AmpX3 * m_Noise3.CubicNoise2D(BlockX * m_FreqX3, BlockZ * m_FreqX3);
@ -785,7 +772,7 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 7; int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 7;
int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11; int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11;
int MinDist1 = (DistortX[x][z] - SeedX) * (DistortX[x][z] - SeedX) + (DistortZ[x][z] - SeedZ) * (DistortZ[x][z] - SeedZ); int MinDist1 = (DistortX[x][z] - SeedX) * (DistortX[x][z] - SeedX) + (DistortZ[x][z] - SeedZ) * (DistortZ[x][z] - SeedZ);
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1)); cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 1 : 0));
} }
} }
} }
@ -932,7 +919,7 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cBiomeGen: // cBiomeGen:
cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault) cBiomeGenPtr cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault)
{ {
AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", ""); AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
if (BiomeGenName.empty()) if (BiomeGenName.empty())
@ -988,7 +975,7 @@ cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a
} }
res->InitializeBiomeGen(a_IniFile); res->InitializeBiomeGen(a_IniFile);
return res; return cBiomeGenPtr(res);
} }

View File

@ -48,12 +48,12 @@ class cBioGenCache :
typedef cBiomeGen super; typedef cBiomeGen super;
public: public:
cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize); // Doesn't take ownership of a_BioGenToCache cBioGenCache(cBiomeGenPtr a_BioGenToCache, int a_CacheSize);
~cBioGenCache(); virtual ~cBioGenCache();
protected: protected:
cBiomeGen * m_BioGenToCache; cBiomeGenPtr m_BioGenToCache;
struct sCacheData struct sCacheData
{ {
@ -87,19 +87,21 @@ class cBioGenMulticache :
typedef cBiomeGen super; typedef cBiomeGen super;
public: public:
/* /* Creates a new multicache - a cache that divides the caching into several sub-caches based on the chunk coords.
a_CacheSize defines the size of each singular cache This allows us to use shorter cache depths with faster lookups for more covered area. (#381)
a_CachesLength defines how many caches are used for the multicache a_SubCacheSize defines the size of each sub-cache
*/ a_NumSubCaches defines how many sub-caches are used for the multicache. */
cBioGenMulticache(cBiomeGen * a_BioGenToCache, size_t a_CacheSize, size_t a_CachesLength); // Doesn't take ownership of a_BioGenToCache cBioGenMulticache(cBiomeGenPtr a_BioGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches);
~cBioGenMulticache();
protected: protected:
typedef std::vector<cBiomeGen *> cBiomeGens; typedef std::vector<cBiomeGenPtr> cBiomeGenPtrs;
size_t m_CachesLength; /** Number of sub-caches. Pulled out of m_Caches.size() for faster access. */
cBiomeGens m_Caches; size_t m_NumSubCaches;
/** Individual sub-caches. */
cBiomeGenPtrs m_Caches;
virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;

View File

@ -269,10 +269,10 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX
LOGWARNING("%s: MaxRelX less than zero, adjusting to zero", __FUNCTION__); LOGWARNING("%s: MaxRelX less than zero, adjusting to zero", __FUNCTION__);
a_MaxRelX = 0; a_MaxRelX = 0;
} }
else if (a_MaxRelX >= cChunkDef::Width) else if (a_MaxRelX > cChunkDef::Width)
{ {
LOGWARNING("%s: MaxRelX more than chunk width, adjusting to chunk width", __FUNCTION__); LOGWARNING("%s: MaxRelX more than chunk width, adjusting to chunk width", __FUNCTION__);
a_MaxRelX = cChunkDef::Width - 1; a_MaxRelX = cChunkDef::Width;
} }
if (a_MinRelY < 0) if (a_MinRelY < 0)
@ -290,10 +290,10 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX
LOGWARNING("%s: MaxRelY less than zero, adjusting to zero", __FUNCTION__); LOGWARNING("%s: MaxRelY less than zero, adjusting to zero", __FUNCTION__);
a_MaxRelY = 0; a_MaxRelY = 0;
} }
else if (a_MaxRelY >= cChunkDef::Height) else if (a_MaxRelY > cChunkDef::Height)
{ {
LOGWARNING("%s: MaxRelY more than chunk height, adjusting to chunk height", __FUNCTION__); LOGWARNING("%s: MaxRelY more than chunk height, adjusting to chunk height", __FUNCTION__);
a_MaxRelY = cChunkDef::Height - 1; a_MaxRelY = cChunkDef::Height;
} }
if (a_MinRelZ < 0) if (a_MinRelZ < 0)
@ -311,10 +311,10 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX
LOGWARNING("%s: MaxRelZ less than zero, adjusting to zero", __FUNCTION__); LOGWARNING("%s: MaxRelZ less than zero, adjusting to zero", __FUNCTION__);
a_MaxRelZ = 0; a_MaxRelZ = 0;
} }
else if (a_MaxRelZ >= cChunkDef::Width) else if (a_MaxRelZ > cChunkDef::Width)
{ {
LOGWARNING("%s: MaxRelZ more than chunk width, adjusting to chunk width", __FUNCTION__); LOGWARNING("%s: MaxRelZ more than chunk width, adjusting to chunk width", __FUNCTION__);
a_MaxRelZ = cChunkDef::Width - 1; a_MaxRelZ = cChunkDef::Width;
} }
// Prepare the block area: // Prepare the block area:

View File

@ -663,7 +663,7 @@ void cCompoGenNether::InitializeCompoGen(cIniFile & a_IniFile)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cCompoGenCache: // cCompoGenCache:
cCompoGenCache::cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_CacheSize) : cCompoGenCache::cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_CacheSize) :
m_Underlying(a_Underlying), m_Underlying(a_Underlying),
m_CacheSize(a_CacheSize), m_CacheSize(a_CacheSize),
m_CacheOrder(new int[a_CacheSize]), m_CacheOrder(new int[a_CacheSize]),
@ -739,7 +739,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc)
// Not in the cache: // Not in the cache:
m_NumMisses++; m_NumMisses++;
m_Underlying.ComposeTerrain(a_ChunkDesc); m_Underlying->ComposeTerrain(a_ChunkDesc);
// Insert it as the first item in the MRU order: // Insert it as the first item in the MRU order:
int Idx = m_CacheOrder[m_CacheSize - 1]; int Idx = m_CacheOrder[m_CacheSize - 1];
@ -760,7 +760,7 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc)
void cCompoGenCache::InitializeCompoGen(cIniFile & a_IniFile) void cCompoGenCache::InitializeCompoGen(cIniFile & a_IniFile)
{ {
m_Underlying.InitializeCompoGen(a_IniFile); m_Underlying->InitializeCompoGen(a_IniFile);
} }

View File

@ -144,12 +144,12 @@ protected:
/// Caches most-recently-used chunk composition of another composition generator. Caches only the types and metas /** Caches most-recently-used chunk composition of another composition generator. Caches only the types and metas */
class cCompoGenCache : class cCompoGenCache :
public cTerrainCompositionGen public cTerrainCompositionGen
{ {
public: public:
cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_CacheSize); // Doesn't take ownership of a_Underlying cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_CacheSize); // Doesn't take ownership of a_Underlying
~cCompoGenCache(); ~cCompoGenCache();
// cTerrainCompositionGen override: // cTerrainCompositionGen override:
@ -158,7 +158,7 @@ public:
protected: protected:
cTerrainCompositionGen & m_Underlying; cTerrainCompositionGenPtr m_Underlying;
struct sCacheData struct sCacheData
{ {

View File

@ -39,7 +39,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cTerrainCompositionGen: // cTerrainCompositionGen:
cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed)
{ {
AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", "");
if (CompoGenName.empty()) if (CompoGenName.empty())
@ -107,7 +107,7 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile &
// Read the settings from the ini file: // Read the settings from the ini file:
res->InitializeCompoGen(a_IniFile); res->InitializeCompoGen(a_IniFile);
return res; return cTerrainCompositionGenPtr(res);
} }
@ -119,12 +119,9 @@ cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile &
cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) :
super(a_ChunkGenerator), super(a_ChunkGenerator),
m_BiomeGen(NULL), m_BiomeGen(nullptr),
m_HeightGen(NULL), m_HeightGen(nullptr),
m_CompositionGen(NULL), m_CompositionGen(nullptr)
m_UnderlyingBiomeGen(NULL),
m_UnderlyingHeightGen(NULL),
m_UnderlyingCompositionGen(NULL)
{ {
} }
@ -132,33 +129,6 @@ cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) :
cComposableGenerator::~cComposableGenerator()
{
// Delete the generating composition:
for (cFinishGenList::const_iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr)
{
delete *itr;
}
m_FinishGens.clear();
delete m_CompositionGen;
m_CompositionGen = NULL;
delete m_HeightGen;
m_HeightGen = NULL;
delete m_BiomeGen;
m_BiomeGen = NULL;
delete m_UnderlyingCompositionGen;
m_UnderlyingCompositionGen = NULL;
delete m_UnderlyingHeightGen;
m_UnderlyingHeightGen = NULL;
delete m_UnderlyingBiomeGen;
m_UnderlyingBiomeGen = NULL;
}
void cComposableGenerator::Initialize(cIniFile & a_IniFile) void cComposableGenerator::Initialize(cIniFile & a_IniFile)
{ {
super::Initialize(a_IniFile); super::Initialize(a_IniFile);
@ -245,15 +215,14 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile)
CacheSize = 4; CacheSize = 4;
} }
LOGD("Using a cache for biomegen of size %d.", CacheSize); LOGD("Using a cache for biomegen of size %d.", CacheSize);
m_UnderlyingBiomeGen = m_BiomeGen;
if (MultiCacheLength > 0) if (MultiCacheLength > 0)
{ {
LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength); LOGD("Enabling multicache for biomegen of length %d.", MultiCacheLength);
m_BiomeGen = new cBioGenMulticache(m_UnderlyingBiomeGen, CacheSize, MultiCacheLength); m_BiomeGen = cBiomeGenPtr(new cBioGenMulticache(m_BiomeGen, CacheSize, MultiCacheLength));
} }
else else
{ {
m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize); m_BiomeGen = cBiomeGenPtr(new cBioGenCache(m_BiomeGen, CacheSize));
} }
} }
@ -264,7 +233,7 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile)
void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile) void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile)
{ {
bool CacheOffByDefault = false; bool CacheOffByDefault = false;
m_HeightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, *m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); m_HeightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault);
// Add a cache, if requested: // Add a cache, if requested:
int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64); int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64);
@ -278,8 +247,7 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile)
CacheSize = 4; CacheSize = 4;
} }
LOGD("Using a cache for Heightgen of size %d.", CacheSize); LOGD("Using a cache for Heightgen of size %d.", CacheSize);
m_UnderlyingHeightGen = m_HeightGen; m_HeightGen = cTerrainHeightGenPtr(new cHeiGenCache(m_HeightGen, CacheSize));
m_HeightGen = new cHeiGenCache(*m_UnderlyingHeightGen, CacheSize);
} }
} }
@ -289,13 +257,12 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile)
void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile)
{ {
m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, *m_BiomeGen, *m_HeightGen, m_ChunkGenerator.GetSeed()); m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, *m_HeightGen, m_ChunkGenerator.GetSeed());
int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64);
if (CompoGenCacheSize > 1) if (CompoGenCacheSize > 1)
{ {
m_UnderlyingCompositionGen = m_CompositionGen; m_CompositionGen = cTerrainCompositionGenPtr(new cCompoGenCache(m_CompositionGen, 32));
m_CompositionGen = new cCompoGenCache(*m_UnderlyingCompositionGen, 32);
} }
} }
@ -319,7 +286,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{ {
int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10;
int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenBottomLava(BottomLavaLevel)));
} }
else if (NoCaseCompare(*itr, "DeadBushes") == 0) else if (NoCaseCompare(*itr, "DeadBushes") == 0)
{ {
@ -341,20 +308,20 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
AllowedBlocks.push_back(E_BLOCK_HARDENED_CLAY); AllowedBlocks.push_back(E_BLOCK_HARDENED_CLAY);
AllowedBlocks.push_back(E_BLOCK_STAINED_CLAY); AllowedBlocks.push_back(E_BLOCK_STAINED_CLAY);
m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks)));
} }
else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) else if (NoCaseCompare(*itr, "DirectOverhangs") == 0)
{ {
m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenDirectOverhangs(Seed)));
} }
else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0)
{ {
m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenDistortedMembraneOverhangs(Seed)));
} }
else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0)
{ {
float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3);
m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenDualRidgeCaves(Seed, Threshold)));
} }
else if (NoCaseCompare(*itr, "DungeonRooms") == 0) else if (NoCaseCompare(*itr, "DungeonRooms") == 0)
{ {
@ -362,24 +329,24 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7); int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7);
int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5); int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5);
AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1"); AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1");
m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib)); m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib)));
} }
else if (NoCaseCompare(*itr, "Ice") == 0) else if (NoCaseCompare(*itr, "Ice") == 0)
{ {
m_FinishGens.push_back(new cFinishGenIce); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenIce));
} }
else if (NoCaseCompare(*itr, "LavaLakes") == 0) else if (NoCaseCompare(*itr, "LavaLakes") == 0)
{ {
int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10);
m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_HeightGen, Probability)));
} }
else if (NoCaseCompare(*itr, "LavaSprings") == 0) else if (NoCaseCompare(*itr, "LavaSprings") == 0)
{ {
m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)));
} }
else if (NoCaseCompare(*itr, "MarbleCaves") == 0) else if (NoCaseCompare(*itr, "MarbleCaves") == 0)
{ {
m_FinishGens.push_back(new cStructGenMarbleCaves(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenMarbleCaves(Seed)));
} }
else if (NoCaseCompare(*itr, "MineShafts") == 0) else if (NoCaseCompare(*itr, "MineShafts") == 0)
{ {
@ -389,10 +356,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600);
int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200);
int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200);
m_FinishGens.push_back(new cStructGenMineShafts( m_FinishGens.push_back(cFinishGenPtr(new cStructGenMineShafts(
Seed, GridSize, MaxOffset, MaxSystemSize, Seed, GridSize, MaxOffset, MaxSystemSize,
ChanceCorridor, ChanceCrossing, ChanceStaircase ChanceCorridor, ChanceCrossing, ChanceStaircase
)); )));
} }
else if (NoCaseCompare(*itr, "Lilypads") == 0) else if (NoCaseCompare(*itr, "Lilypads") == 0)
{ {
@ -406,7 +373,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
AllowedBlocks.push_back(E_BLOCK_WATER); AllowedBlocks.push_back(E_BLOCK_WATER);
AllowedBlocks.push_back(E_BLOCK_STATIONARY_WATER); AllowedBlocks.push_back(E_BLOCK_STATIONARY_WATER);
m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks)));
} }
else if (NoCaseCompare(*itr, "NaturalPatches") == 0) else if (NoCaseCompare(*itr, "NaturalPatches") == 0)
{ {
@ -455,18 +422,18 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
AndesiteVein.NestSize = 32; AndesiteVein.NestSize = 32;
Ores.push_back(AndesiteVein); Ores.push_back(AndesiteVein);
m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)));
} }
else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0)
{ {
m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenNetherClumpFoliage(Seed)));
} }
else if (NoCaseCompare(*itr, "NetherForts") == 0) else if (NoCaseCompare(*itr, "NetherForts") == 0)
{ {
int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128); int MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth)); m_FinishGens.push_back(cFinishGenPtr(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth)));
} }
else if (NoCaseCompare(*itr, "NetherOreNests") == 0) else if (NoCaseCompare(*itr, "NetherOreNests") == 0)
{ {
@ -480,7 +447,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
QuartzVein.NestSize = 8; QuartzVein.NestSize = 8;
Ores.push_back(QuartzVein); Ores.push_back(QuartzVein);
m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK)));
} }
else if (NoCaseCompare(*itr, "OreNests") == 0) else if (NoCaseCompare(*itr, "OreNests") == 0)
@ -535,11 +502,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
DiamondVein.NestSize = 4; DiamondVein.NestSize = 4;
Ores.push_back(DiamondVein); Ores.push_back(DiamondVein);
m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE)));
} }
else if (NoCaseCompare(*itr, "POCPieces") == 0) else if (NoCaseCompare(*itr, "POCPieces") == 0)
{ {
m_FinishGens.push_back(new cPOCPieceGenerator(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cPOCPieceGenerator(Seed)));
} }
else if (NoCaseCompare(*itr, "PreSimulator") == 0) else if (NoCaseCompare(*itr, "PreSimulator") == 0)
{ {
@ -548,7 +515,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
bool PreSimulateWater = a_IniFile.GetValueSetB("Generator", "PreSimulatorWater", true); bool PreSimulateWater = a_IniFile.GetValueSetB("Generator", "PreSimulatorWater", true);
bool PreSimulateLava = a_IniFile.GetValueSetB("Generator", "PreSimulatorLava", true); bool PreSimulateLava = a_IniFile.GetValueSetB("Generator", "PreSimulatorLava", true);
m_FinishGens.push_back(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava)));
} }
else if (NoCaseCompare(*itr, "RainbowRoads") == 0) else if (NoCaseCompare(*itr, "RainbowRoads") == 0)
{ {
@ -556,11 +523,11 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128); int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30); int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30);
int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260); int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260);
m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize)); m_FinishGens.push_back(cFinishGenPtr(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize)));
} }
else if (NoCaseCompare(*itr, "Ravines") == 0) else if (NoCaseCompare(*itr, "Ravines") == 0)
{ {
m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenRavines(Seed, 128)));
} }
else if (NoCaseCompare(*itr, "RoughRavines") == 0) else if (NoCaseCompare(*itr, "RoughRavines") == 0)
{ {
@ -580,7 +547,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
double MinCeilingHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightEdge", 38); double MinCeilingHeightEdge = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightEdge", 38);
double MaxCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightCenter", 58); double MaxCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightCenter", 58);
double MinCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightCenter", 36); double MinCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightCenter", 36);
m_FinishGens.push_back(new cRoughRavines( m_FinishGens.push_back(cFinishGenPtr(new cRoughRavines(
Seed, MaxSize, MinSize, Seed, MaxSize, MinSize,
(float)MaxCenterWidth, (float)MinCenterWidth, (float)MaxCenterWidth, (float)MinCenterWidth,
(float)MaxRoughness, (float)MinRoughness, (float)MaxRoughness, (float)MinRoughness,
@ -589,27 +556,27 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
(float)MaxCeilingHeightEdge, (float)MinCeilingHeightEdge, (float)MaxCeilingHeightEdge, (float)MinCeilingHeightEdge,
(float)MaxCeilingHeightCenter, (float)MinCeilingHeightCenter, (float)MaxCeilingHeightCenter, (float)MinCeilingHeightCenter,
GridSize, MaxOffset GridSize, MaxOffset
)); )));
} }
else if (NoCaseCompare(*itr, "Snow") == 0) else if (NoCaseCompare(*itr, "Snow") == 0)
{ {
m_FinishGens.push_back(new cFinishGenSnow); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow));
} }
else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0)
{ {
m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSprinkleFoliage(Seed)));
} }
else if (NoCaseCompare(*itr, "TallGrass") == 0) else if (NoCaseCompare(*itr, "TallGrass") == 0)
{ {
m_FinishGens.push_back(new cFinishGenTallGrass(Seed)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenTallGrass(Seed)));
} }
else if (NoCaseCompare(*itr, "TestRails") == 0) else if (NoCaseCompare(*itr, "TestRails") == 0)
{ {
m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50)); m_FinishGens.push_back(cFinishGenPtr(new cTestRailsGen(Seed, 100, 1, 7, 50)));
} }
else if (NoCaseCompare(*itr, "Trees") == 0) else if (NoCaseCompare(*itr, "Trees") == 0)
{ {
m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)));
} }
else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) else if (NoCaseCompare(*itr, "UnderwaterBases") == 0)
{ {
@ -617,7 +584,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128); int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128);
int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7);
int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128);
m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, *m_BiomeGen)); m_FinishGens.push_back(cFinishGenPtr(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, m_BiomeGen)));
} }
else if (NoCaseCompare(*itr, "Villages") == 0) else if (NoCaseCompare(*itr, "Villages") == 0)
{ {
@ -627,23 +594,23 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128);
int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50); int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80); int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen)); m_FinishGens.push_back(cFinishGenPtr(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_HeightGen)));
} }
else if (NoCaseCompare(*itr, "WaterLakes") == 0) else if (NoCaseCompare(*itr, "WaterLakes") == 0)
{ {
int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25);
m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_HeightGen, Probability)));
} }
else if (NoCaseCompare(*itr, "WaterSprings") == 0) else if (NoCaseCompare(*itr, "WaterSprings") == 0)
{ {
m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)));
} }
else if (NoCaseCompare(*itr, "WormNestCaves") == 0) else if (NoCaseCompare(*itr, "WormNestCaves") == 0)
{ {
int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64); int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64);
int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96); int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96);
int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32); int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32);
m_FinishGens.push_back(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset)); m_FinishGens.push_back(cFinishGenPtr(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset)));
} }
else else
{ {

View File

@ -24,6 +24,16 @@ See http://forum.mc-server.org/showthread.php?tid=409 for details.
// Forward-declare the shared pointers to subgenerator classes:
class cBiomeGen;
class cTerrainHeightGen;
class cTerrainCompositionGen;
class cFinishGen;
typedef SharedPtr<cBiomeGen> cBiomeGenPtr;
typedef SharedPtr<cTerrainHeightGen> cTerrainHeightGenPtr;
typedef SharedPtr<cTerrainCompositionGen> cTerrainCompositionGenPtr;
typedef SharedPtr<cFinishGen> cFinishGenPtr;
// fwd: Noise3DGenerator.h // fwd: Noise3DGenerator.h
class cNoise3DComposable; class cNoise3DComposable;
@ -53,8 +63,7 @@ public:
a_CacheOffByDefault gets set to whether the cache should be disabled by default. a_CacheOffByDefault gets set to whether the cache should be disabled by default.
Used in BiomeVisualiser, too. Used in BiomeVisualiser, too.
Implemented in BioGen.cpp! */ Implemented in BioGen.cpp! */
static cBiomeGen * CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault); static cBiomeGenPtr CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault);
} ; } ;
@ -83,7 +92,7 @@ public:
a_CacheOffByDefault gets set to whether the cache should be disabled by default a_CacheOffByDefault gets set to whether the cache should be disabled by default
Implemented in HeiGen.cpp! Implemented in HeiGen.cpp!
*/ */
static cTerrainHeightGen * CreateHeightGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault); static cTerrainHeightGenPtr CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault);
} ; } ;
@ -109,7 +118,7 @@ public:
a_BiomeGen is the underlying biome generator, some composition generators may depend on it to generate more biomes a_BiomeGen is the underlying biome generator, some composition generators may depend on it to generate more biomes
a_HeightGen is the underlying height generator, some composition generators may depend on it providing additional values a_HeightGen is the underlying height generator, some composition generators may depend on it providing additional values
*/ */
static cTerrainCompositionGen * CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed); static cTerrainCompositionGenPtr CreateCompositionGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed);
} ; } ;
@ -131,7 +140,7 @@ public:
virtual void GenFinish(cChunkDesc & a_ChunkDesc) = 0; virtual void GenFinish(cChunkDesc & a_ChunkDesc) = 0;
} ; } ;
typedef std::list<cFinishGen *> cFinishGenList; typedef std::list<cFinishGenPtr> cFinishGenList;
@ -144,7 +153,6 @@ class cComposableGenerator :
public: public:
cComposableGenerator(cChunkGenerator & a_ChunkGenerator); cComposableGenerator(cChunkGenerator & a_ChunkGenerator);
virtual ~cComposableGenerator();
virtual void Initialize(cIniFile & a_IniFile) override; virtual void Initialize(cIniFile & a_IniFile) override;
virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
@ -152,15 +160,10 @@ public:
protected: protected:
// The generation composition: // The generation composition:
cBiomeGen * m_BiomeGen; cBiomeGenPtr m_BiomeGen;
cTerrainHeightGen * m_HeightGen; cTerrainHeightGenPtr m_HeightGen;
cTerrainCompositionGen * m_CompositionGen; cTerrainCompositionGenPtr m_CompositionGen;
cFinishGenList m_FinishGens; cFinishGenList m_FinishGens;
// Generators underlying the caches:
cBiomeGen * m_UnderlyingBiomeGen;
cTerrainHeightGen * m_UnderlyingHeightGen;
cTerrainCompositionGen * m_UnderlyingCompositionGen;
/** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */ /** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */

View File

@ -276,13 +276,13 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen) : cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) :
m_NoiseDistortX(a_Seed + 1000), m_NoiseDistortX(a_Seed + 1000),
m_NoiseDistortZ(a_Seed + 2000), m_NoiseDistortZ(a_Seed + 2000),
m_OceanFloorSelect(a_Seed + 3000), m_OceanFloorSelect(a_Seed + 3000),
m_MesaFloor(a_Seed + 4000), m_MesaFloor(a_Seed + 4000),
m_BiomeGen(a_BiomeGen), m_BiomeGen(a_BiomeGen),
m_UnderlyingHeiGen(a_Seed, a_BiomeGen), m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)),
m_HeightGen(m_UnderlyingHeiGen, 64), m_HeightGen(m_UnderlyingHeiGen, 64),
m_IsInitialized(false) m_IsInitialized(false)
{ {
@ -540,10 +540,11 @@ void cDistortedHeightmap::InitializeCompoGen(cIniFile & a_IniFile)
int cDistortedHeightmap::GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z) int cDistortedHeightmap::GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z)
{ {
int ChunkX = (int)floor(a_X / (NOISE_DATATYPE)16); int RelX = (int)std::floor(a_X);
int ChunkZ = (int)floor(a_Z / (NOISE_DATATYPE)16); int RelY = 0;
int RelX = (int)(a_X - (NOISE_DATATYPE)ChunkX * cChunkDef::Width); int RelZ = (int)std::floor(a_Z);
int RelZ = (int)(a_Z - (NOISE_DATATYPE)ChunkZ * cChunkDef::Width); int ChunkX, ChunkZ;
cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
// If we're withing the same chunk, return the pre-cached heightmap: // If we're withing the same chunk, return the pre-cached heightmap:
if ((ChunkX == m_CurChunkX) && (ChunkZ == m_CurChunkZ)) if ((ChunkX == m_CurChunkX) && (ChunkZ == m_CurChunkZ))
@ -576,7 +577,7 @@ void cDistortedHeightmap::UpdateDistortAmps(void)
{ {
for (int x = -1; x <= 1; x++) for (int x = -1; x <= 1; x++)
{ {
m_BiomeGen.GenBiomes(m_CurChunkX + x, m_CurChunkZ + z, Biomes[x + 1][z + 1]); m_BiomeGen->GenBiomes(m_CurChunkX + x, m_CurChunkZ + z, Biomes[x + 1][z + 1]);
} // for x } // for x
} // for z } // for z

View File

@ -35,7 +35,7 @@ public:
NIBBLETYPE BlockMeta; NIBBLETYPE BlockMeta;
} ; } ;
cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen); cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen);
protected: protected:
typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; typedef cChunkDef::BiomeMap BiomeNeighbors[3][3];
@ -64,9 +64,14 @@ protected:
int m_CurChunkZ; int m_CurChunkZ;
NOISE_DATATYPE m_DistortedHeightmap[17 * 257 * 17]; NOISE_DATATYPE m_DistortedHeightmap[17 * 257 * 17];
cBiomeGen & m_BiomeGen; /** The bime generator to query for biomes. */
cHeiGenBiomal m_UnderlyingHeiGen; // This generator provides us with base heightmap (before distortion) cBiomeGenPtr m_BiomeGen;
cHeiGenCache m_HeightGen; // Cache above m_UnderlyingHeiGen
/** The generator that provides the base heightmap (before distortion). */
cTerrainHeightGenPtr m_UnderlyingHeiGen;
/** Cache for m_UnderlyingHeiGen. */
cHeiGenCache m_HeightGen;
/// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. /// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization.
cChunkDef::HeightMap m_CurChunkHeights; cChunkDef::HeightMap m_CurChunkHeights;

View File

@ -6,6 +6,7 @@
#include "Globals.h" #include "Globals.h"
#include "DungeonRoomsFinisher.h" #include "DungeonRoomsFinisher.h"
#include "../FastRandom.h" #include "../FastRandom.h"
#include "../BlockEntities/ChestEntity.h"
@ -175,7 +176,33 @@ protected:
} }
a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y); a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y);
// TODO: Fill the chest with random loot // Fill the chest with random loot
static const cLootProbab LootProbab[] =
{
// Item, MinAmount, MaxAmount, Weight
{ cItem(E_ITEM_GOLDEN_APPLE), 1, 1, 1 },
{ cItem(E_ITEM_DIAMOND_HORSE_ARMOR), 1, 1, 1 },
{ cItem(E_ITEM_GOLD_HORSE_ARMOR), 1, 1, 2 },
{ cItem(E_ITEM_13_DISC), 1, 1, 4 },
{ cItem(E_ITEM_CAT_DISC), 1, 1, 4 },
{ cItem(E_ITEM_IRON_HORSE_ARMOR), 1, 1, 5 },
{ cItem(E_ITEM_IRON), 1, 4, 10 },
{ cItem(E_ITEM_WHEAT), 1, 4, 10 },
{ cItem(E_ITEM_GUNPOWDER), 1, 4, 10 },
{ cItem(E_ITEM_STRING), 1, 4, 10 },
{ cItem(E_ITEM_REDSTONE_DUST), 1, 4, 10 },
{ cItem(E_ITEM_SADDLE), 1, 1, 10 },
{ cItem(E_ITEM_BUCKET), 1, 1, 10 },
{ cItem(E_ITEM_BREAD), 1, 1, 10 },
{ cItem(E_ITEM_NAME_TAG), 1, 1, 10 },
} ;
cChestEntity * ChestEntity = (cChestEntity *)a_ChunkDesc.GetBlockEntity(RelX, m_FloorHeight + 1, RelZ);
ASSERT((ChestEntity != NULL) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST));
cNoise Noise(a_ChunkDesc.GetChunkX() ^ a_ChunkDesc.GetChunkZ());
int NumSlots = 3 + ((Noise.IntNoise3DInt(a_Chest.x, a_Chest.y, a_Chest.z) / 11) % 4);
int Seed = Noise.IntNoise2DInt(RelX, RelZ);
ChestEntity->GetContents().GenerateRandomLootWithBooks(LootProbab, ARRAYCOUNT(LootProbab), NumSlots, Seed);
} }
@ -193,6 +220,7 @@ protected:
// The chunk is not intersecting the room at all, bail out // The chunk is not intersecting the room at all, bail out
return; return;
} }
int b = m_FloorHeight + 1; // Bottom int b = m_FloorHeight + 1; // Bottom
int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top
ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor
@ -230,7 +258,7 @@ protected:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cDungeonRoomsFinisher: // cDungeonRoomsFinisher:
cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) : cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) :
super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024), super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024),
m_HeightGen(a_HeightGen), m_HeightGen(a_HeightGen),
m_MaxHalfSize((a_MaxSize + 1) / 2), m_MaxHalfSize((a_MaxSize + 1) / 2),
@ -266,7 +294,7 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int
int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ; int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ;
cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
cChunkDef::HeightMap HeightMap; cChunkDef::HeightMap HeightMap;
m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap); m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap);
int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ} int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ}
Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5); Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5);

View File

@ -26,12 +26,12 @@ public:
a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain. a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain.
a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across. a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across.
a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */ a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */
cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib); cDungeonRoomsFinisher(cTerrainHeightGenPtr a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib);
protected: protected:
/** The height gen that is used for limiting the rooms' Y coords */ /** The height gen that is used for limiting the rooms' Y coords */
cTerrainHeightGen & m_HeightGen; cTerrainHeightGenPtr m_HeightGen;
/** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */ /** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */
int m_MaxHalfSize; int m_MaxHalfSize;

View File

@ -19,7 +19,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cTerrainHeightGen: // cTerrainHeightGen:
cTerrainHeightGen * cTerrainHeightGen::CreateHeightGen(cIniFile &a_IniFile, cBiomeGen & a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault) cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cBiomeGenPtr a_BiomeGen, int a_Seed, bool & a_CacheOffByDefault)
{ {
AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", ""); AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", "");
if (HeightGenName.empty()) if (HeightGenName.empty())
@ -84,7 +84,7 @@ cTerrainHeightGen * cTerrainHeightGen::CreateHeightGen(cIniFile &a_IniFile, cBio
// Read the settings: // Read the settings:
res->InitializeHeightGen(a_IniFile); res->InitializeHeightGen(a_IniFile);
return res; return cTerrainHeightGenPtr(res);
} }
@ -118,7 +118,7 @@ void cHeiGenFlat::InitializeHeightGen(cIniFile & a_IniFile)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cHeiGenCache: // cHeiGenCache:
cHeiGenCache::cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize) : cHeiGenCache::cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, int a_CacheSize) :
m_HeiGenToCache(a_HeiGenToCache), m_HeiGenToCache(a_HeiGenToCache),
m_CacheSize(a_CacheSize), m_CacheSize(a_CacheSize),
m_CacheOrder(new int[a_CacheSize]), m_CacheOrder(new int[a_CacheSize]),
@ -190,7 +190,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap
// Not in the cache: // Not in the cache:
m_NumMisses++; m_NumMisses++;
m_HeiGenToCache.GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap);
// Insert it as the first item in the MRU order: // Insert it as the first item in the MRU order:
int Idx = m_CacheOrder[m_CacheSize - 1]; int Idx = m_CacheOrder[m_CacheSize - 1];
@ -210,7 +210,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap
void cHeiGenCache::InitializeHeightGen(cIniFile & a_IniFile) void cHeiGenCache::InitializeHeightGen(cIniFile & a_IniFile)
{ {
m_HeiGenToCache.InitializeHeightGen(a_IniFile); m_HeiGenToCache->InitializeHeightGen(a_IniFile);
} }
@ -317,7 +317,9 @@ void cHeiGenClassic::InitializeHeightGen(cIniFile & a_IniFile)
cHeiGenMountains::cHeiGenMountains(int a_Seed) : cHeiGenMountains::cHeiGenMountains(int a_Seed) :
m_Seed(a_Seed), m_Seed(a_Seed),
m_Noise(a_Seed) m_MountainNoise(a_Seed + 100),
m_DitchNoise(a_Seed + 200),
m_Perlin(a_Seed + 300)
{ {
} }
@ -332,9 +334,11 @@ void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Heigh
NOISE_DATATYPE StartZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width); NOISE_DATATYPE StartZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width);
NOISE_DATATYPE EndZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + cChunkDef::Width - 1); NOISE_DATATYPE EndZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + cChunkDef::Width - 1);
NOISE_DATATYPE Workspace[16 * 16]; NOISE_DATATYPE Workspace[16 * 16];
NOISE_DATATYPE Noise[16 * 16]; NOISE_DATATYPE MountainNoise[16 * 16];
NOISE_DATATYPE DitchNoise[16 * 16];
NOISE_DATATYPE PerlinNoise[16 * 16]; NOISE_DATATYPE PerlinNoise[16 * 16];
m_Noise.Generate2D(Noise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); m_MountainNoise.Generate2D(MountainNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace);
m_DitchNoise.Generate2D(DitchNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace);
m_Perlin.Generate2D(PerlinNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); m_Perlin.Generate2D(PerlinNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace);
for (int z = 0; z < cChunkDef::Width; z++) for (int z = 0; z < cChunkDef::Width; z++)
{ {
@ -342,7 +346,7 @@ void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Heigh
for (int x = 0; x < cChunkDef::Width; x++) for (int x = 0; x < cChunkDef::Width; x++)
{ {
int idx = IdxZ + x; int idx = IdxZ + x;
int hei = 100 - (int)((Noise[idx] + PerlinNoise[idx]) * 15); int hei = 100 - (int)((MountainNoise[idx] - DitchNoise[idx] + PerlinNoise[idx]) * 15);
if (hei < 10) if (hei < 10)
{ {
hei = 10; hei = 10;
@ -363,9 +367,12 @@ void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::Heigh
void cHeiGenMountains::InitializeHeightGen(cIniFile & a_IniFile) void cHeiGenMountains::InitializeHeightGen(cIniFile & a_IniFile)
{ {
// TODO: Read the params from an INI file // TODO: Read the params from an INI file
m_Noise.AddOctave(0.1f, 0.1f); m_MountainNoise.AddOctave(0.1f, 0.2f);
m_Noise.AddOctave(0.05f, 0.5f); m_MountainNoise.AddOctave(0.05f, 0.4f);
m_Noise.AddOctave(0.02f, 1.5f); m_MountainNoise.AddOctave(0.02f, 1.0f);
m_DitchNoise.AddOctave(0.1f, 0.2f);
m_DitchNoise.AddOctave(0.05f, 0.4f);
m_DitchNoise.AddOctave(0.02f, 1.0f);
m_Perlin.AddOctave(0.01f, 1.5f); m_Perlin.AddOctave(0.01f, 1.5f);
} }
@ -479,7 +486,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa
{ {
for (int x = -1; x <= 1; x++) for (int x = -1; x <= 1; x++)
{ {
m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); m_BiomeGen->GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]);
} // for x } // for x
} // for z } // for z

Some files were not shown because too many files have changed in this diff Show More