commit
1bc145ff44
@ -2067,6 +2067,7 @@ a_Player:OpenWindow(Window);
|
||||
ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|cPlayer}})</pre>" },
|
||||
ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cWorld|cWorld}})</pre>" },
|
||||
Get = { Params = "", Return = "Root object", Notes = "(STATIC) This function returns the cRoot object." },
|
||||
GetBrewingRecipe = { Params = "{{cItem|cItem}}, {{cItem|cItem}}", Return = "{{cItem|cItem}}", Notes = "(STATIC) Returns the result item, if a recipe has been found. If no recipe is found, returns no value." },
|
||||
GetBuildCommitID = { Params = "", Return = "string", Notes = "(STATIC) For official builds (Travis CI / Jenkins) it returns the exact commit hash used for the build. For unofficial local builds, returns the approximate commit hash (since the true one cannot be determined), formatted as \"approx: <CommitHash>\"." },
|
||||
GetBuildDateTime = { Params = "", Return = "string", Notes = "(STATIC) For official builds (Travic CI / Jenkins) it returns the date and time of the build. For unofficial local builds, returns the approximate datetime of the commit (since the true one cannot be determined), formatted as \"approx: <DateTime-iso8601>\"." },
|
||||
GetBuildID = { Params = "", Return = "string", Notes = "(STATIC) For official builds (Travis CI / Jenkins) it returns the unique ID of the build, as recognized by the build system. For unofficial local builds, returns the string \"Unknown\"." },
|
||||
@ -2333,6 +2334,7 @@ local CompressedString = cStringCompression.CompressStringGZIP("DataToCompress")
|
||||
DigBlock = { Params = "X, Y, Z", Return = "", Notes = "Replaces the specified block with air, without dropping the usual pickups for the block. Wakes up the simulators for the block and its neighbors." },
|
||||
DoExplosionAt = { Params = "Force, X, Y, Z, CanCauseFire, Source, SourceData", Return = "", Notes = "Creates an explosion of the specified relative force in the specified position. If CanCauseFire is set, the explosion will set blocks on fire, too. The Source parameter specifies the source of the explosion, one of the esXXX constants. The SourceData parameter is specific to each source type, usually it provides more info about the source." },
|
||||
DoWithBlockEntityAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction", Return = "bool", Notes = "If there is a block entity at the specified coords, calls the CallbackFunction with the {{cBlockEntity}} parameter representing the block entity. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBlockEntity|BlockEntity}})</pre> The function returns false if there is no block entity, or if there is, it returns the bool value that the callback has returned. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." },
|
||||
DoWithBrewingstandAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction", Return = "bool", Notes = "If there is a brewingstand at the specified coords, calls the CallbackFunction with the {{cBrewingstandEntity}} parameter representing the brewingstand. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBrewingstandEntity|cBrewingstandEntity}})</pre> The function returns false if there is no brewingstand, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithBeaconAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction", Return = "bool", Notes = "If there is a beacon at the specified coords, calls the CallbackFunction with the {{cBeaconEntity}} parameter representing the beacon. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBeaconEntity|BeaconEntity}})</pre> The function returns false if there is no beacon, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithChestAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction", Return = "bool", Notes = "If there is a chest at the specified coords, calls the CallbackFunction with the {{cChestEntity}} parameter representing the chest. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cChestEntity|ChestEntity}})</pre> The function returns false if there is no chest, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithCommandBlockAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction", Return = "bool", Notes = "If there is a command block at the specified coords, calls the CallbackFunction with the {{cCommandBlockEntity}} parameter representing the command block. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cCommandBlockEntity|CommandBlockEntity}})</pre> The function returns false if there is no command block, or if there is, it returns the bool value that the callback has returned." },
|
||||
@ -2353,6 +2355,7 @@ local CompressedString = cStringCompression.CompressStringGZIP("DataToCompress")
|
||||
},
|
||||
FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "bool", Notes = "Calls the given callback function for the player with the name best matching the name string provided.<br>This function is case-insensitive and will match partial names.<br>Returns false if player not found or there is ambiguity, true otherwise. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}})</pre>" },
|
||||
ForEachBlockEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each block entity in the chunk. Returns true if all block entities in the chunk have been processed (including when there are zero block entities), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBlockEntity|BlockEntity}})</pre> The callback should return false or no value to continue with the next block entity, or true to abort the enumeration. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." },
|
||||
ForEachBrewingstandInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each brewingstand in the chunk. Returns true if all brewingstands in the chunk have been processed (including when there are zero brewingstands), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBrewingstandEntity|cBrewingstandEntity}})</pre> The callback should return false or no value to continue with the next brewingstand, or true to abort the enumeration." },
|
||||
ForEachChestInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each chest in the chunk. Returns true if all chests in the chunk have been processed (including when there are zero chests), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cChestEntity|ChestEntity}})</pre> The callback should return false or no value to continue with the next chest, or true to abort the enumeration." },
|
||||
ForEachEntity = { Params = "CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each entity in the loaded world. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}})</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachEntityInBox = { Params = "{{cBoundingBox|Box}}, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each entity in the specified bounding box. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. If any chunk within the bounding box is not valid, it is silently skipped without any notification. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}})</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
|
@ -76,6 +76,47 @@ return
|
||||
},
|
||||
},
|
||||
|
||||
cBrewingstandEntity =
|
||||
{
|
||||
Desc = [[
|
||||
This class represents a brewingstand entity in the world.</p>
|
||||
<p>
|
||||
See also the {{cRoot}}:GetBrewingRecipe() function.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
GetBrewingTimeLeft = { Params = "", Return = "number", Notes = "Returns the time until the current items finishes brewing, in ticks" },
|
||||
GetTimeBrewed = { Params = "", Return = "number", Notes = "Returns the time that the current items has been brewing, in ticks" },
|
||||
GetLeftBottleSlot = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item in the left bottle slot" },
|
||||
GetMiddleBottleSlot = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item in the middle bottle slot" },
|
||||
GetRightBottleSlot = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item in the right bottle slot" },
|
||||
GetIndgredientSlot = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item in the ingredient slot" },
|
||||
GetResultItem = { Params = "number", Return = "{{cItem|cItem}}", Notes = "Returns the expected result item for the given slot number." },
|
||||
SetLeftBottleSlot = { Params = "{{cItem|cItem}}", Return = "", Notes = "Sets the item in the left bottle slot" },
|
||||
SetMiddleBottleSlot = { Params = "{{cItem|cItem}}", Return = "", Notes = "Sets the item in the middle bottle slot" },
|
||||
SetRightBottleSlot = { Params = "{{cItem|cItem}}", Return = "", Notes = "Sets the item in the right bottle slot" },
|
||||
SetIngredientSlot = { Params = "{{cItem|cItem}}", Return = "", Notes = "Sets the item in the ingredient bottle slot" },
|
||||
},
|
||||
Constants =
|
||||
{
|
||||
bsLeftBottle = { Notes = "Index of the left bottle slot" },
|
||||
bsMiddleBottle = { Notes = "Index of the middle bottle slot" },
|
||||
bsRightBottle = { Notes = "Index of the right bottle slot" },
|
||||
bsIngredient = { Notes = "Index of the ingredient slot" },
|
||||
ContentsWidth = { Notes = "Width (X) of the {{cItemGrid|cItemGrid}} representing the contents" },
|
||||
ContentsHeight = { Notes = "Height (Y) of the {{cItemGrid|cItemGrid}} representing the contents" },
|
||||
},
|
||||
ConstantGroups =
|
||||
{
|
||||
SlotIndices =
|
||||
{
|
||||
Include = "bs.*",
|
||||
TextBefore = "When using the GetSlot() or SetSlot() function, use these constants for slot index:",
|
||||
},
|
||||
},
|
||||
Inherits = "cBlockEntityWithItems"
|
||||
}, -- cBrewingstandEntity
|
||||
|
||||
cChestEntity =
|
||||
{
|
||||
Desc = [[
|
||||
|
@ -110,6 +110,8 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
crUnknownCommand = { Notes = "When the given command doesn't exist." },
|
||||
HOOK_BLOCK_SPREAD = { Notes = "Called when a block spreads based on world conditions" },
|
||||
HOOK_BLOCK_TO_PICKUPS = { Notes = "Called when a block has been dug and is being converted to pickups. The server has provided the default pickups and the plugins may modify them." },
|
||||
HOOK_BREWING_COMPLETING = { "Called before a brewing stand completes a brewing process." },
|
||||
HOOK_BREWING_COMPLETED = { "Called when a brewing stand completed a brewing process." },
|
||||
HOOK_CHAT = { Notes = "Called when a client sends a chat message that is not a command. The plugin may modify the chat message" },
|
||||
HOOK_CHUNK_AVAILABLE = { Notes = "Called when a chunk is loaded or generated and becomes available in the {{cWorld|world}}." },
|
||||
HOOK_CHUNK_GENERATED = { Notes = "Called after a chunk is generated. A plugin may do last modifications on the generated chunk before it is handed of to the {{cWorld|world}}." },
|
||||
|
26
Server/Plugins/APIDump/Hooks/OnBrewingCompleted.lua
Normal file
26
Server/Plugins/APIDump/Hooks/OnBrewingCompleted.lua
Normal file
@ -0,0 +1,26 @@
|
||||
return
|
||||
{
|
||||
HOOK_BREWING_COMPLETED =
|
||||
{
|
||||
CalledWhen = "A brewing process is completed.",
|
||||
DefaultFnName = "OnBrewingCompleted", -- also used as pagename
|
||||
Desc = [[
|
||||
This hook is called whenever a {{cBrewingstand|brewing stand}} has completed the brewing process.
|
||||
See also the {{OnBrewingCompleting|HOOK_BREWING_COMPLETING}} hook for a similar hook, is called when a
|
||||
brewing process is completing.
|
||||
]],
|
||||
Params =
|
||||
{
|
||||
{ Name = "World", Type = "{{cWorld}}", Notes = "World where the brewing stand resides." },
|
||||
{ Name = "Brewingstand", Type = "{{cBrewingstand}}", Notes = "The brewing stand that completed the brewing process." },
|
||||
},
|
||||
Returns = [[
|
||||
If the function returns false or no value, Cuberite calls other plugins with this event. If the
|
||||
function returns true, no other plugin is called for this event.</p>
|
||||
]],
|
||||
}, -- HOOK_BREWING_COMPLETED
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
28
Server/Plugins/APIDump/Hooks/OnBrewingCompleting.lua
Normal file
28
Server/Plugins/APIDump/Hooks/OnBrewingCompleting.lua
Normal file
@ -0,0 +1,28 @@
|
||||
return
|
||||
{
|
||||
HOOK_BREWING_COMPLETING =
|
||||
{
|
||||
CalledWhen = "A brewing process is completing.",
|
||||
DefaultFnName = "OnBrewingCompleting", -- also used as pagename
|
||||
Desc = [[
|
||||
This hook is called whenever a {{cBrewingstand|brewing stand}} is completing the brewing process. Plugins may
|
||||
refuse the completing of the brewing process.<p>
|
||||
See also the {{OnBrewingCompleted|HOOK_BREWING_COMPLETED}} hook for a similar hook, is called after the
|
||||
brewing process has been completed.
|
||||
]],
|
||||
Params =
|
||||
{
|
||||
{ Name = "World", Type = "{{cWorld}}", Notes = "World where the brewing stand resides." },
|
||||
{ Name = "Brewingstand", Type = "{{cBrewingstand}}", Notes = "The brewing stand that completes the brewing process." },
|
||||
},
|
||||
Returns = [[
|
||||
If the function returns false or no value, Cuberite calls other plugins with this event. If the function returns true,
|
||||
no other plugin's callback is called and the brewing process is canceled.
|
||||
<p>
|
||||
]],
|
||||
}, -- HOOK_BREWING_COMPLETING
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
235
Server/brewing.txt
Normal file
235
Server/brewing.txt
Normal file
@ -0,0 +1,235 @@
|
||||
#*****************#
|
||||
# Brewing Recipes #
|
||||
#*****************#
|
||||
# The time for a brewing recipe is always 20 seconds (400 ticks).
|
||||
#
|
||||
# Minecraft-Wiki Brewing:
|
||||
# http://minecraft.gamepedia.com/Brewing
|
||||
#
|
||||
# A brewing recipe has this format:
|
||||
# Data Value + Ingredient = Potion
|
||||
|
||||
|
||||
### Primary ###
|
||||
# Akward Potion
|
||||
0 + netherwart = 16
|
||||
|
||||
# Mundane Potion
|
||||
0 + redstonedust = 64
|
||||
0 + ghasttear = 8192
|
||||
0 + glisteringmelon = 8192
|
||||
0 + blazepowder = 8192
|
||||
0 + magmacream = 8192
|
||||
0 + sugar = 8192
|
||||
0 + spidereye = 8192
|
||||
0 + rabbitsfoot = 8192
|
||||
|
||||
# Thick Potion
|
||||
0 + glowstonedust = 32
|
||||
|
||||
# Potion of Weakness
|
||||
0 + fermentedspidereye = 8264
|
||||
|
||||
|
||||
|
||||
|
||||
### Secondary ###
|
||||
|
||||
## Positive ##
|
||||
|
||||
# Potion of Healing
|
||||
16 + glisteringmelon = 8197
|
||||
|
||||
# Potion of Fire Resistance
|
||||
16 + magmacream = 8195
|
||||
|
||||
# Potion of Regeneration
|
||||
16 + ghasttear = 8193
|
||||
|
||||
# Potion of Strength
|
||||
16 + blazepowder = 8201
|
||||
|
||||
# Potion of Swiftness
|
||||
16 + sugar = 8194
|
||||
|
||||
# Potion of Night Vision
|
||||
16 + goldencarrot = 8198
|
||||
|
||||
# Potion of Water Breathing
|
||||
16 + pufferfish = 8205
|
||||
|
||||
# Potion of Leaping
|
||||
16 + rabbitsfoot = 8203
|
||||
|
||||
|
||||
## Negative ##
|
||||
|
||||
# Potion of Poison
|
||||
16 + spidereye = 8196
|
||||
|
||||
# Potion of Weakness
|
||||
16 + fermentedspidereye = 8200
|
||||
32 + fermentedspidereye = 8200
|
||||
64 + fermentedspidereye = 8200
|
||||
|
||||
# Potion of Weakness (extended)
|
||||
8192 + fermentedspidereye = 8264
|
||||
|
||||
|
||||
|
||||
|
||||
### Tertiary ###
|
||||
|
||||
## Positive ##
|
||||
|
||||
# Potion of Fire Resistance (extended)
|
||||
8195 + redstonedust = 8259
|
||||
8227 + redstonedust = 8259
|
||||
|
||||
# Potion of Healing II
|
||||
8197 + glowstonedust = 8229
|
||||
8261 + glowstonedust = 8229
|
||||
|
||||
# Potion of Regeneration (extended)
|
||||
8193 + redstonedust = 8257
|
||||
8225 + redstonedust = 8257
|
||||
|
||||
# Potion of Regeneration II
|
||||
8193 + glowstonedust = 8225
|
||||
8257 + glowstonedust = 8225
|
||||
|
||||
# Potion of Strength (extended)
|
||||
8201 + redstonedust = 8265
|
||||
8233 + redstonedust = 8265
|
||||
|
||||
# Potion of Strength II
|
||||
8201 + glowstonedust = 8233
|
||||
8265 + glowstonedust = 8233
|
||||
|
||||
# Potion of Swiftness (extended)
|
||||
8194 + redstonedust = 8258
|
||||
8226 + redstonedust = 8258
|
||||
|
||||
# Potion of Swiftness II
|
||||
8194 + glowstonedust = 8226
|
||||
8258 + glowstonedust = 8226
|
||||
|
||||
# Potion of Night Vision (extended)
|
||||
8198 + redstonedust = 8262
|
||||
|
||||
# Potion of Invisibility
|
||||
8198 + fermentedspidereye = 8206
|
||||
|
||||
# Potion of Invisibility (extended)
|
||||
8262 + fermentedspidereye = 8270
|
||||
|
||||
# Potion of Invisibility (extended)
|
||||
8206 + redstonedust = 8270
|
||||
|
||||
# Potion of Water Breathing (extended)
|
||||
8205 + redstonedust = 8269
|
||||
8237 + redstonedust = 8269
|
||||
|
||||
# Potion of Leaping II
|
||||
8203 + glowstonedust = 8235
|
||||
8267 + glowstonedust = 8235
|
||||
|
||||
# Potion of Leaping (extended)
|
||||
8203 + redstonedust = 8267
|
||||
8235 + redstonedust = 8267
|
||||
|
||||
|
||||
## Negative ##
|
||||
|
||||
# Potion of Harming
|
||||
8197 + fermentedspidereye = 8204
|
||||
8196 + fermentedspidereye = 8204
|
||||
8260 + fermentedspidereye = 8204
|
||||
|
||||
# Potion of Harming II
|
||||
8229 + fermentedspidereye = 8236
|
||||
8228 + fermentedspidereye = 8236
|
||||
|
||||
# Potion of Harming II
|
||||
8204 + glowstonedust = 8236
|
||||
8268 + glowstonedust = 8236
|
||||
|
||||
# Potion of Poison (extended)
|
||||
8196 + redstonedust = 8260
|
||||
8228 + redstonedust = 8260
|
||||
|
||||
# Potion of Poison II
|
||||
8196 + glowstonedust = 8228
|
||||
8260 + glowstonedust = 8228
|
||||
|
||||
# Potion of Slowness
|
||||
8195 + fermentedspidereye = 8202
|
||||
8194 + fermentedspidereye = 8202
|
||||
8203 + fermentedspidereye = 8202
|
||||
|
||||
# Potion of Slowness (extended)
|
||||
8202 + redstonedust = 8266
|
||||
8234 + redstonedust = 8266
|
||||
|
||||
# Potion of Slowness (extended)
|
||||
8259 + fermentedspidereye = 8266
|
||||
8258 + fermentedspidereye = 8266
|
||||
8267 + fermentedspidereye = 8266
|
||||
|
||||
# Potion of Weakness
|
||||
8201 + fermentedspidereye = 8200
|
||||
8193 + fermentedspidereye = 8200
|
||||
|
||||
# Potion of Weakness (extended)
|
||||
8265 + fermentedspidereye = 8264
|
||||
8257 + fermentedspidereye = 8264
|
||||
|
||||
# Potion of Weakness (extended)
|
||||
8200 + redstonedust = 8264
|
||||
8232 + redstonedust = 8264
|
||||
|
||||
|
||||
|
||||
|
||||
### Reverted ###
|
||||
|
||||
## Glowstone ##
|
||||
|
||||
# Potion of Fire Resistance (reverted)
|
||||
8259 + glowstonedust = 8227
|
||||
|
||||
# Potion of Night Vision (reverted)
|
||||
8262 + glowstonedust = 8230
|
||||
|
||||
# Potion of Weakness (reverted)
|
||||
8264 + glowstonedust = 8232
|
||||
|
||||
# Potion of Slowness (reverted)
|
||||
8266 + glowstonedust = 8234
|
||||
|
||||
# Potion of Water Breathing (reverted)
|
||||
8269 + glowstonedust = 8237
|
||||
|
||||
|
||||
## Redstone ##
|
||||
|
||||
# Potion of Healing (reverted)
|
||||
8229 + redstonedust = 8261
|
||||
|
||||
# Potion of Harming (reverted)
|
||||
8236 + redstonedust = 8268
|
||||
|
||||
|
||||
## Fermented Spider Eye ##
|
||||
|
||||
# Potion of Harming (reverted)
|
||||
8261 + fermentedspidereye = 8268
|
||||
8260 + fermentedspidereye = 8268
|
||||
|
||||
# Potion of Slowness (reverted)
|
||||
8227 + fermentedspidereye = 8234
|
||||
8226 + fermentedspidereye = 8234
|
||||
|
||||
# Potion of Weakness (reverted)
|
||||
8233 + fermentedspidereye = 8232
|
||||
8225 + fermentedspidereye = 8232
|
@ -98,6 +98,7 @@ $cfile "../Mobs/Monster.h"
|
||||
$cfile "../BlockEntities/BlockEntity.h"
|
||||
$cfile "../BlockEntities/BeaconEntity.h"
|
||||
$cfile "../BlockEntities/BlockEntityWithItems.h"
|
||||
$cfile "../BlockEntities/BrewingstandEntity.h"
|
||||
$cfile "../BlockEntities/ChestEntity.h"
|
||||
$cfile "../BlockEntities/CommandBlockEntity.h"
|
||||
$cfile "../BlockEntities/DropSpenserEntity.h"
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "../ClientHandle.h"
|
||||
#include "../BlockArea.h"
|
||||
#include "../BlockEntities/BeaconEntity.h"
|
||||
#include "../BlockEntities/BrewingstandEntity.h"
|
||||
#include "../BlockEntities/ChestEntity.h"
|
||||
#include "../BlockEntities/CommandBlockEntity.h"
|
||||
#include "../BlockEntities/DispenserEntity.h"
|
||||
@ -2516,6 +2517,54 @@ static int tolua_cRoot_GetBuildSeriesName(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cRoot_GetBrewingRecipe(lua_State * tolua_S)
|
||||
{
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserTable(1, "cRoot") ||
|
||||
!L.CheckParamUserType (2, "const cItem") ||
|
||||
!L.CheckParamUserType (3, "const cItem") ||
|
||||
!L.CheckParamEnd (4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check the bottle param:
|
||||
cItem * Bottle = nullptr;
|
||||
L.GetStackValue(2, Bottle);
|
||||
if (Bottle == nullptr)
|
||||
{
|
||||
LOGWARNING("cRoot:GetBrewingRecipe: the Bottle parameter is nil or missing.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cItem * Ingredient = nullptr;
|
||||
L.GetStackValue(3, Ingredient);
|
||||
if (Ingredient == nullptr)
|
||||
{
|
||||
LOGWARNING("cRoot:GetBrewingRecipe: the Ingredient parameter is nil or missing.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the recipe for the input
|
||||
cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes();
|
||||
const cBrewingRecipes::cRecipe * Recipe = BR->GetRecipeFrom(*Bottle, *Ingredient);
|
||||
if (Recipe == nullptr)
|
||||
{
|
||||
// There is no such brewing recipe for this bottle and ingredient, return no value
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Push the output item
|
||||
L.Push(Recipe->Output.get());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S)
|
||||
{
|
||||
cLuaState L(tolua_S);
|
||||
@ -3320,6 +3369,7 @@ void cManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "DoWithPlayerByUUID", DoWith <cRoot, cPlayer, &cRoot::DoWithPlayerByUUID>);
|
||||
tolua_function(tolua_S, "ForEachPlayer", ForEach<cRoot, cPlayer, &cRoot::ForEachPlayer>);
|
||||
tolua_function(tolua_S, "ForEachWorld", ForEach<cRoot, cWorld, &cRoot::ForEachWorld>);
|
||||
tolua_function(tolua_S, "GetBrewingRecipe", tolua_cRoot_GetBrewingRecipe);
|
||||
tolua_function(tolua_S, "GetBuildCommitID", tolua_cRoot_GetBuildCommitID);
|
||||
tolua_function(tolua_S, "GetBuildDateTime", tolua_cRoot_GetBuildDateTime);
|
||||
tolua_function(tolua_S, "GetBuildID", tolua_cRoot_GetBuildID);
|
||||
|
@ -580,6 +580,7 @@ void cManualBindings::BindWorld(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay);
|
||||
tolua_function(tolua_S, "DoWithBlockEntityAt", DoWithXYZ<cWorld, cBlockEntity, &cWorld::DoWithBlockEntityAt>);
|
||||
tolua_function(tolua_S, "DoWithBeaconAt", DoWithXYZ<cWorld, cBeaconEntity, &cWorld::DoWithBeaconAt>);
|
||||
tolua_function(tolua_S, "DoWithBrewingstandAt", DoWithXYZ<cWorld, cBrewingstandEntity, &cWorld::DoWithBrewingstandAt>);
|
||||
tolua_function(tolua_S, "DoWithChestAt", DoWithXYZ<cWorld, cChestEntity, &cWorld::DoWithChestAt>);
|
||||
tolua_function(tolua_S, "DoWithDispenserAt", DoWithXYZ<cWorld, cDispenserEntity, &cWorld::DoWithDispenserAt>);
|
||||
tolua_function(tolua_S, "DoWithDropSpenserAt", DoWithXYZ<cWorld, cDropSpenserEntity, &cWorld::DoWithDropSpenserAt>);
|
||||
@ -594,6 +595,7 @@ void cManualBindings::BindWorld(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
|
||||
tolua_function(tolua_S, "DoWithPlayerByUUID", DoWith< cWorld, cPlayer, &cWorld::DoWithPlayerByUUID>);
|
||||
tolua_function(tolua_S, "ForEachBlockEntityInChunk", ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
|
||||
tolua_function(tolua_S, "ForEachBrewingstandInChunk", ForEachInChunk<cWorld, cBrewingstandEntity, &cWorld::ForEachBrewingstandInChunk>);
|
||||
tolua_function(tolua_S, "ForEachChestInChunk", ForEachInChunk<cWorld, cChestEntity, &cWorld::ForEachChestInChunk>);
|
||||
tolua_function(tolua_S, "ForEachEntity", ForEach< cWorld, cEntity, &cWorld::ForEachEntity>);
|
||||
tolua_function(tolua_S, "ForEachEntityInBox", ForEachInBox< cWorld, cEntity, &cWorld::ForEachEntityInBox>);
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
/** 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 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 OnBrewingCompleting (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) = 0;
|
||||
virtual bool OnBrewingCompleted (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) = 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 OnChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) = 0;
|
||||
|
@ -294,6 +294,54 @@ bool cPluginLua::OnBlockToPickups(cWorld & a_World, cEntity * a_Digger, int a_Bl
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnBrewingCompleted(cWorld & a_World, cBrewingstandEntity & a_Brewingstand)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
if (!m_LuaState.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = false;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BREWING_COMPLETED];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call(static_cast<int>(**itr), &a_World, &a_Brewingstand, cLuaState::Return, res);
|
||||
if (res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnBrewingCompleting(cWorld & a_World, cBrewingstandEntity & a_Brewingstand)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
if (!m_LuaState.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = false;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BREWING_COMPLETING];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call(static_cast<int>(**itr), &a_World, &a_Brewingstand, cLuaState::Return, res);
|
||||
if (res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnChat(cPlayer & a_Player, AString & a_Message)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
|
@ -105,6 +105,8 @@ public:
|
||||
|
||||
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 OnBrewingCompleting (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) override;
|
||||
virtual bool OnBrewingCompleted (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) 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 OnChunkGenerated (cWorld & a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override;
|
||||
|
@ -269,6 +269,44 @@ bool cPluginManager::CallHookBlockToPickups(
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookBrewingCompleted(cWorld & a_World, cBrewingstandEntity & a_Brewingstand)
|
||||
{
|
||||
FIND_HOOK(HOOK_BREWING_COMPLETED);
|
||||
VERIFY_HOOK;
|
||||
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->OnBrewingCompleted(a_World, a_Brewingstand))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookBrewingCompleting(cWorld & a_World, cBrewingstandEntity & a_Brewingstand)
|
||||
{
|
||||
FIND_HOOK(HOOK_BREWING_COMPLETING);
|
||||
VERIFY_HOOK;
|
||||
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->OnBrewingCompleting(a_World, a_Brewingstand))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookChat(cPlayer & a_Player, AString & a_Message)
|
||||
{
|
||||
// Check if the message contains a command, execute it:
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
// fwd:
|
||||
class cBlockEntityWithItems;
|
||||
class cBrewingstandEntity;
|
||||
class cChunkDesc;
|
||||
class cClientHandle;
|
||||
class cCommandOutputCallback;
|
||||
@ -75,6 +76,8 @@ public:
|
||||
{
|
||||
HOOK_BLOCK_SPREAD,
|
||||
HOOK_BLOCK_TO_PICKUPS,
|
||||
HOOK_BREWING_COMPLETING,
|
||||
HOOK_BREWING_COMPLETED,
|
||||
HOOK_CHAT,
|
||||
HOOK_CHUNK_AVAILABLE,
|
||||
HOOK_CHUNK_GENERATED,
|
||||
@ -193,6 +196,8 @@ public:
|
||||
// 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 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 CallHookBrewingCompleting (cWorld & a_World, cBrewingstandEntity & a_Brewingstand);
|
||||
bool CallHookBrewingCompleted (cWorld & a_World, cBrewingstandEntity & a_Brewingstand);
|
||||
bool CallHookChat (cPlayer & a_Player, AString & a_Message);
|
||||
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);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "Globals.h"
|
||||
#include "BeaconEntity.h"
|
||||
#include "BlockEntity.h"
|
||||
#include "BrewingstandEntity.h"
|
||||
#include "ChestEntity.h"
|
||||
#include "CommandBlockEntity.h"
|
||||
#include "DispenserEntity.h"
|
||||
@ -36,6 +37,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
|
||||
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||
case E_BLOCK_BREWING_STAND: return new cBrewingstandEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_HOPPER: return new cHopperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_MOB_SPAWNER: return new cMobSpawnerEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
|
309
src/BlockEntities/BrewingstandEntity.cpp
Normal file
309
src/BlockEntities/BrewingstandEntity.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "BrewingstandEntity.h"
|
||||
#include "../Bindings/PluginManager.h"
|
||||
#include "../UI/BrewingstandWindow.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Root.h"
|
||||
#include "../Chunk.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBrewingstandEntity::cBrewingstandEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) :
|
||||
super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
|
||||
m_BlockMeta(a_BlockMeta),
|
||||
m_IsDestroyed(false),
|
||||
m_IsBrewing(false),
|
||||
m_TimeBrewed(0)
|
||||
{
|
||||
m_Contents.AddListener(*this);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
m_Results[i] = *(new cItem());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBrewingstandEntity::~cBrewingstandEntity()
|
||||
{
|
||||
// Tell window its owner is destroyed
|
||||
cWindow * Window = GetWindow();
|
||||
if (Window != nullptr)
|
||||
{
|
||||
Window->OwnerDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
cWindow * Window = GetWindow();
|
||||
if (Window == nullptr)
|
||||
{
|
||||
OpenWindow(new cBrewingstandWindow(m_PosX, m_PosY, m_PosZ, this));
|
||||
Window = GetWindow();
|
||||
}
|
||||
|
||||
if (Window != nullptr)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IsBrewing)
|
||||
{
|
||||
BroadcastProgress(0, m_NeedBrewingTime - m_TimeBrewed);
|
||||
}
|
||||
else
|
||||
{
|
||||
BroadcastProgress(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
UNUSED(a_Dt);
|
||||
|
||||
if (!m_IsBrewing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const cBrewingRecipes::cRecipe * Recipe = nullptr;
|
||||
// The necessary brewing time, has been reached
|
||||
if (m_TimeBrewed >= m_NeedBrewingTime)
|
||||
{
|
||||
BroadcastProgress(0, 0);
|
||||
m_IsBrewing = false;
|
||||
m_TimeBrewed = 0;
|
||||
|
||||
// Return if the hook has been canceled
|
||||
if (cPluginManager::Get()->CallHookBrewingCompleting(*m_World, *this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decrease item count, full stacks are allowed in the ingredient slot
|
||||
cItem Ingredient = m_Contents.GetSlot(bsIngredient);
|
||||
Ingredient.m_ItemCount -= 1;
|
||||
m_Contents.SetSlot(bsIngredient, Ingredient);
|
||||
|
||||
// Loop over all bottle slots and update available bottles
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (m_Contents.GetSlot(i).IsEmpty() || (m_CurrentBrewingRecipes[i] == nullptr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Recipe = m_CurrentBrewingRecipes[i];
|
||||
m_Contents.SetSlot(i, Recipe->Output->CopyOne());
|
||||
}
|
||||
|
||||
// Brewing process completed
|
||||
cPluginManager::Get()->CallHookBrewingCompleted(*m_World, *this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
m_TimeBrewed++;
|
||||
UpdateProgressBars(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::SendTo(cClientHandle & a_Client)
|
||||
{
|
||||
// Nothing needs to be sent
|
||||
UNUSED(a_Client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
|
||||
{
|
||||
cWindow * Window = GetWindow();
|
||||
if (Window != nullptr)
|
||||
{
|
||||
Window->SetProperty(a_ProgressbarID, a_Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
|
||||
{
|
||||
super::OnSlotChanged(a_ItemGrid, a_SlotNum);
|
||||
|
||||
if (m_IsDestroyed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(a_ItemGrid == &m_Contents);
|
||||
|
||||
// Check if still a item is in the ingredient slot
|
||||
if (GetSlot(bsIngredient).IsEmpty())
|
||||
{
|
||||
if (m_IsBrewing)
|
||||
{
|
||||
// Cancel brewing
|
||||
BroadcastProgress(0, 0);
|
||||
m_IsBrewing = false;
|
||||
m_TimeBrewed = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Recheck the bottles
|
||||
cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes();
|
||||
const cBrewingRecipes::cRecipe * Recipe = nullptr;
|
||||
bool Stop = true;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (GetSlot(i).IsEmpty())
|
||||
{
|
||||
m_CurrentBrewingRecipes[i] = nullptr;
|
||||
m_Results[i].Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_CurrentBrewingRecipes[i] != nullptr)
|
||||
{
|
||||
Recipe = m_CurrentBrewingRecipes[i];
|
||||
if (Recipe->Ingredient->IsEqual(GetSlot(bsIngredient)) && Recipe->Input->IsEqual(GetSlot(i)))
|
||||
{
|
||||
Stop = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Recipe = BR->GetRecipeFrom(m_Contents.GetSlot(i), m_Contents.GetSlot(bsIngredient));
|
||||
if (Recipe != nullptr)
|
||||
{
|
||||
// Found a brewing recipe for the items
|
||||
m_CurrentBrewingRecipes[i] = Recipe;
|
||||
m_Results[i] = Recipe->Output->CopyOne();
|
||||
Stop = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Stop)
|
||||
{
|
||||
if (m_IsBrewing)
|
||||
{
|
||||
// Cancel brewing
|
||||
BroadcastProgress(0, 0);
|
||||
m_IsBrewing = false;
|
||||
m_TimeBrewed = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Start brewing process, if not running
|
||||
if (!m_IsBrewing)
|
||||
{
|
||||
m_IsBrewing = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::UpdateProgressBars(bool a_ForceUpdate)
|
||||
{
|
||||
/** Sending an update every 3th tick, using a higher value lets look the progressbar ugly */
|
||||
if (!a_ForceUpdate && (m_World->GetWorldAge() % 3 != 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BroadcastProgress(0, m_NeedBrewingTime - m_TimeBrewed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::setTimeBrewed(short a_TimeBrewed)
|
||||
{
|
||||
m_TimeBrewed = a_TimeBrewed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::ContinueBrewing(void)
|
||||
{
|
||||
// Continue brewing if number is greater than 0
|
||||
if (m_TimeBrewed > 0)
|
||||
{
|
||||
m_IsBrewing = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingstandEntity::GetRecipes(void)
|
||||
{
|
||||
if (GetSlot(3).IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes();
|
||||
const cBrewingRecipes::cRecipe * Recipe = nullptr;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (GetSlot(i).IsEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Recipe = BR->GetRecipeFrom(GetSlot(i), GetSlot(bsIngredient));
|
||||
if (Recipe != nullptr)
|
||||
{
|
||||
m_CurrentBrewingRecipes[i] = Recipe;
|
||||
m_Results[i] = Recipe->Output->CopyOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
136
src/BlockEntities/BrewingstandEntity.h
Normal file
136
src/BlockEntities/BrewingstandEntity.h
Normal file
@ -0,0 +1,136 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntityWithItems.h"
|
||||
#include "../BrewingRecipes.h"
|
||||
#include "../Root.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cClientHandle;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
class cBrewingstandEntity :
|
||||
public cBlockEntityWithItems
|
||||
{
|
||||
typedef cBlockEntityWithItems super;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
bsLeftBottle = 0, // Left bottle slot number
|
||||
bsMiddleBottle = 1, // Middle bottle slot number
|
||||
bsRightBottle = 2, // Right bottle slot number
|
||||
bsIngredient = 3, // Top ingredient slot number
|
||||
|
||||
ContentsWidth = 4,
|
||||
ContentsHeight = 1,
|
||||
};
|
||||
|
||||
// tolua_end
|
||||
|
||||
BLOCKENTITY_PROTODEF(cBrewingstandEntity)
|
||||
|
||||
/** Constructor used for normal operation */
|
||||
cBrewingstandEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World);
|
||||
|
||||
virtual ~cBrewingstandEntity();
|
||||
|
||||
// cBlockEntity overrides:
|
||||
virtual void SendTo(cClientHandle & a_Client) override;
|
||||
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void UsedBy(cPlayer * a_Player) override;
|
||||
virtual void Destroy() override
|
||||
{
|
||||
m_IsDestroyed = true;
|
||||
super::Destroy();
|
||||
}
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the time until the current items finishes brewing, in ticks */
|
||||
short GetBrewingTimeLeft(void) const { return m_NeedBrewingTime - m_TimeBrewed; }
|
||||
|
||||
/** Returns the time that the current items has been brewing, in ticks */
|
||||
short GetTimeBrewed(void) { return m_TimeBrewed; }
|
||||
|
||||
/** Returns the item in the left bottle slot */
|
||||
const cItem & GetLeftBottleSlot(void) const { return GetSlot(bsLeftBottle); }
|
||||
|
||||
/** Returns the item in the middle bottle slot */
|
||||
const cItem & GetMiddleBottleSlot(void) const { return GetSlot(bsMiddleBottle); }
|
||||
|
||||
/** Returns the item in the right bottle slot */
|
||||
const cItem & GetRightBottleSlot(void) const { return GetSlot(bsRightBottle); }
|
||||
|
||||
/** Returns the item in the ingredient slot */
|
||||
const cItem & GetIndgredientSlot(void) const { return GetSlot(bsIngredient); }
|
||||
|
||||
/** Get the expected result item for the given slot number */
|
||||
const cItem & GetResultItem(int a_SlotNumber) { return m_Results[a_SlotNumber]; }
|
||||
|
||||
/** Sets the item in the left bottle slot */
|
||||
void SetLeftBottleSlot(const cItem & a_Item) { SetSlot(bsLeftBottle, a_Item); }
|
||||
|
||||
/** Sets the item in the middle bottle slot */
|
||||
void SetMiddleBottleSlot(const cItem & a_Item) { SetSlot(bsMiddleBottle, a_Item); }
|
||||
|
||||
/** Sets the item in the right bottle slot */
|
||||
void SetRightBottleSlot(const cItem & a_Item) { SetSlot(bsRightBottle, a_Item); }
|
||||
|
||||
/** Sets the item in the ingredient slot */
|
||||
void SetIngredientSlot(const cItem & a_Item) { SetSlot(bsIngredient, a_Item); }
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Sets the current brewing time. Will be called if the brewing stand gets loaded from the world. */
|
||||
void setTimeBrewed(short a_TimeBrewed);
|
||||
|
||||
/** Starts the brewing proccess. Will be called if the brewing stand gets loaded from the world. */
|
||||
void ContinueBrewing(void);
|
||||
|
||||
/** Gets the recipes. Will be called if the brewing stand gets loaded from the world. */
|
||||
void GetRecipes(void);
|
||||
protected:
|
||||
|
||||
/** Block meta of the block currently represented by this entity */
|
||||
NIBBLETYPE m_BlockMeta;
|
||||
|
||||
/** Set to true when the brewing stand entity has been destroyed to prevent the block being set again */
|
||||
bool m_IsDestroyed;
|
||||
|
||||
/** Set to true if the brewing stand is brewing an item */
|
||||
bool m_IsBrewing;
|
||||
|
||||
/** Brewing time is 400 ticks */
|
||||
const short m_NeedBrewingTime = 400;
|
||||
|
||||
/** Store the current brewing recipes */
|
||||
const cBrewingRecipes::cRecipe * m_CurrentBrewingRecipes[3] = {};
|
||||
|
||||
/** Result items for the bottle inputs */
|
||||
cItem m_Results[3] = {};
|
||||
|
||||
/** Amount of ticks that the current item has been brewed */
|
||||
short m_TimeBrewed;
|
||||
|
||||
/** Sends the specified progressbar value to all clients of the window */
|
||||
void BroadcastProgress(short a_ProgressbarID, short a_Value);
|
||||
|
||||
// /** Broadcasts progressbar updates, if needed */
|
||||
void UpdateProgressBars(bool a_ForceUpdate = false);
|
||||
|
||||
// cItemGrid::cListener overrides:
|
||||
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
|
||||
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ include_directories ("${PROJECT_SOURCE_DIR}/../")
|
||||
SET (SRCS
|
||||
BeaconEntity.cpp
|
||||
BlockEntity.cpp
|
||||
BrewingstandEntity.cpp
|
||||
ChestEntity.cpp
|
||||
CommandBlockEntity.cpp
|
||||
DispenserEntity.cpp
|
||||
@ -27,6 +28,7 @@ SET (HDRS
|
||||
BeaconEntity.h
|
||||
BlockEntity.h
|
||||
BlockEntityWithItems.h
|
||||
BrewingstandEntity.h
|
||||
ChestEntity.h
|
||||
CommandBlockEntity.h
|
||||
DispenserEntity.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntity.h"
|
||||
#include "BlockHandler.h"
|
||||
|
||||
|
||||
#include "MetaRotator.h"
|
||||
|
||||
|
||||
|
||||
class cBlockBrewingStandHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
||||
{
|
||||
public:
|
||||
cBlockBrewingStandHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: cMetaRotator<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
287
src/BrewingRecipes.cpp
Normal file
287
src/BrewingRecipes.cpp
Normal file
@ -0,0 +1,287 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "BrewingRecipes.h"
|
||||
#include "Item.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#define BREWING_RECIPE_FILE "brewing.txt"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef std::vector<std::unique_ptr<cBrewingRecipes::cRecipe>> RecipeList;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct cBrewingRecipes::sBrewingRecipeState
|
||||
{
|
||||
RecipeList Recipes;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBrewingRecipes::cBrewingRecipes()
|
||||
: m_pState(new sBrewingRecipeState)
|
||||
{
|
||||
ReloadRecipes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBrewingRecipes::~cBrewingRecipes()
|
||||
{
|
||||
ClearRecipes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingRecipes::ReloadRecipes(void)
|
||||
{
|
||||
ClearRecipes();
|
||||
LOGD("Loading brewing recipes...");
|
||||
|
||||
std::ifstream f(BREWING_RECIPE_FILE, std::ios::in);
|
||||
if (!f.good())
|
||||
{
|
||||
LOG("Could not open the brewing recipes file \"%s\". No brewing recipes are available.", BREWING_RECIPE_FILE);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int LineNum = 0;
|
||||
AString ParsingLine;
|
||||
|
||||
while (std::getline(f, ParsingLine))
|
||||
{
|
||||
LineNum++;
|
||||
// Remove comments from the line:
|
||||
size_t FirstCommentSymbol = ParsingLine.find('#');
|
||||
if (FirstCommentSymbol != AString::npos)
|
||||
{
|
||||
ParsingLine.erase(ParsingLine.begin() += static_cast<long>(FirstCommentSymbol), ParsingLine.end());
|
||||
}
|
||||
|
||||
if (ParsingLine.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AddRecipeFromLine(ParsingLine, LineNum);
|
||||
} // while (getline(ParsingLine))
|
||||
|
||||
LOG("Loaded " SIZE_T_FMT " brewing recipes", m_pState->Recipes.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingRecipes::AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum)
|
||||
{
|
||||
AString Line(a_Line);
|
||||
Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
|
||||
|
||||
short InputDamage;
|
||||
short OutputDamage;
|
||||
|
||||
std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>();
|
||||
std::unique_ptr<cItem> IngredientItem = cpp14::make_unique<cItem>();
|
||||
std::unique_ptr<cItem> OutputItem = cpp14::make_unique<cItem>();
|
||||
|
||||
const AStringVector & InputAndIngredient = StringSplit(Line, "+");
|
||||
|
||||
if (InputAndIngredient.size() != 2)
|
||||
{
|
||||
LOGWARNING("brewing.txt: line %d: A line with '+' was expected", a_LineNum);
|
||||
LOGINFO("Offending line: \"%s\"", a_Line.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const AStringVector & IngredientAndOutput = StringSplit(InputAndIngredient[1].c_str(), "=");
|
||||
if (IngredientAndOutput.size() != 2)
|
||||
{
|
||||
LOGWARNING("brewing.txt: line %d: A line with '=' was expected", a_LineNum);
|
||||
LOGINFO("Offending line: \"%s\"", a_Line.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ParseItem(IngredientAndOutput[0], *IngredientItem))
|
||||
{
|
||||
LOGWARNING("brewing.txt: Parsing of the item didn't worked.");
|
||||
LOGINFO("Offending line: \"%s\"", a_Line.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StringToInteger<short>(InputAndIngredient[0], InputDamage))
|
||||
{
|
||||
LOGWARNING("brewing.txt: line %d: Cannot parse the damage value for the input item\"%s\".", a_LineNum, InputAndIngredient[0].c_str());
|
||||
LOGINFO("Offending line: \"%s\"", a_Line.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StringToInteger<short>(IngredientAndOutput[1], OutputDamage))
|
||||
{
|
||||
LOGWARNING("brewing.txt: line %d: Cannot parse the damage value for the output item\"%s\".", a_LineNum, IngredientAndOutput[1].c_str());
|
||||
LOGINFO("Offending line: \"%s\"", a_Line.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// The items has always the same type
|
||||
InputItem->m_ItemType = E_ITEM_POTION;
|
||||
InputItem->m_ItemDamage = InputDamage;
|
||||
|
||||
OutputItem->m_ItemType = E_ITEM_POTION;
|
||||
OutputItem->m_ItemDamage = OutputDamage;
|
||||
|
||||
std::unique_ptr<cRecipe> Recipe = cpp14::make_unique<cRecipe>();
|
||||
Recipe->Input = std::move(InputItem);
|
||||
Recipe->Output = std::move(OutputItem);
|
||||
Recipe->Ingredient = std::move(IngredientItem);
|
||||
m_pState->Recipes.push_back(std::move(Recipe));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBrewingRecipes::ParseItem(const AString & a_String, cItem & a_Item)
|
||||
{
|
||||
return StringToItem(a_String, a_Item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBrewingRecipes::ClearRecipes(void)
|
||||
{
|
||||
m_pState->Recipes.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const cBrewingRecipes::cRecipe * cBrewingRecipes::GetRecipeFrom(const cItem & a_Input, const cItem & a_Ingredient) const
|
||||
{
|
||||
for (auto & Recipe : m_pState->Recipes)
|
||||
{
|
||||
if ((Recipe->Input->IsEqual(a_Input)) && (Recipe->Ingredient->IsEqual(a_Ingredient)))
|
||||
{
|
||||
return Recipe.get();
|
||||
}
|
||||
}
|
||||
|
||||
// Check for gunpowder
|
||||
if (a_Ingredient.m_ItemType == E_ITEM_GUNPOWDER)
|
||||
{
|
||||
if (a_Input.m_ItemDamage & 0x2000)
|
||||
{
|
||||
// Create new recipe and add it to list
|
||||
std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>();
|
||||
std::unique_ptr<cItem> IngredientItem = cpp14::make_unique<cItem>();
|
||||
std::unique_ptr<cItem> OutputItem = cpp14::make_unique<cItem>();
|
||||
|
||||
InputItem->m_ItemType = E_ITEM_POTION;
|
||||
InputItem->m_ItemDamage = a_Input.m_ItemDamage;
|
||||
OutputItem->m_ItemType = E_ITEM_POTION;
|
||||
OutputItem->m_ItemDamage = a_Input.m_ItemDamage + 8192;
|
||||
IngredientItem->m_ItemType = E_ITEM_GUNPOWDER;
|
||||
|
||||
std::unique_ptr<cRecipe> Recipe = cpp14::make_unique<cRecipe>();
|
||||
Recipe->Input = std::move(InputItem);
|
||||
Recipe->Output = std::move(OutputItem);
|
||||
Recipe->Ingredient = std::move(IngredientItem);
|
||||
m_pState->Recipes.push_back(std::move(Recipe));
|
||||
return Recipe.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check for splash potion
|
||||
if (a_Input.m_ItemDamage & 0x4000)
|
||||
{
|
||||
const std::unique_ptr<cRecipe> * FoundRecipe = nullptr;
|
||||
// Search for the drinkable potion, the ingredients are the same
|
||||
short SplashItemDamage = a_Input.m_ItemDamage - 8192;
|
||||
|
||||
for (auto & Recipe : m_pState->Recipes)
|
||||
{
|
||||
if ((Recipe->Input->m_ItemDamage == SplashItemDamage) && (Recipe->Ingredient->IsEqual(a_Ingredient)))
|
||||
{
|
||||
FoundRecipe = &Recipe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundRecipe == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create new recipe and add it to list
|
||||
std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>();
|
||||
std::unique_ptr<cItem> IngredientItem = cpp14::make_unique<cItem>();
|
||||
std::unique_ptr<cItem> OutputItem = cpp14::make_unique<cItem>();
|
||||
|
||||
InputItem->m_ItemType = E_ITEM_POTION;
|
||||
InputItem->m_ItemDamage = a_Input.m_ItemDamage;
|
||||
OutputItem->m_ItemType = E_ITEM_POTION;
|
||||
OutputItem->m_ItemDamage = (*FoundRecipe)->Output->m_ItemDamage + 8192;
|
||||
IngredientItem->m_ItemType = (*FoundRecipe)->Ingredient->m_ItemType;
|
||||
|
||||
std::unique_ptr<cRecipe> Recipe = cpp14::make_unique<cRecipe>();
|
||||
Recipe->Input = std::move(InputItem);
|
||||
Recipe->Output = std::move(OutputItem);
|
||||
Recipe->Ingredient = std::move(IngredientItem);
|
||||
m_pState->Recipes.push_back(std::move(Recipe));
|
||||
return Recipe.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBrewingRecipes::IsIngredient(const cItem & a_Ingredient) const
|
||||
{
|
||||
// Check for gunpowder
|
||||
if (a_Ingredient.m_ItemType == E_ITEM_GUNPOWDER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto & Recipe : m_pState->Recipes)
|
||||
{
|
||||
if (Recipe->Ingredient->IsEqual(a_Ingredient))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||