Merged branch 'origin/master' into c++11.
This commit is contained in:
commit
c014f5624c
|
@ -10,6 +10,7 @@ Howaner
|
||||||
keyboard
|
keyboard
|
||||||
Lapayo
|
Lapayo
|
||||||
Luksor
|
Luksor
|
||||||
|
M10360
|
||||||
marmot21
|
marmot21
|
||||||
Masy98
|
Masy98
|
||||||
mborland
|
mborland
|
||||||
|
|
|
@ -1668,13 +1668,14 @@ a_Player:OpenWindow(Window);
|
||||||
SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of the monster. You see the name over the monster. If you want to disable the custom name, simply set an empty string." },
|
SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of the monster. You see the name over the monster. If you want to disable the custom name, simply set an empty string." },
|
||||||
IsCustomNameAlwaysVisible = { Params = "", Return = "bool", Notes = "Is the custom name of this monster always visible? If not, you only see the name when you sight the mob." },
|
IsCustomNameAlwaysVisible = { Params = "", Return = "bool", Notes = "Is the custom name of this monster always visible? If not, you only see the name when you sight the mob." },
|
||||||
SetCustomNameAlwaysVisible = { Params = "bool", Return = "", Notes = "Sets the custom name visiblity of this monster. If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name." },
|
SetCustomNameAlwaysVisible = { Params = "bool", Return = "", Notes = "Sets the custom name visiblity of this monster. If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name." },
|
||||||
FamilyFromType = { Params = "{{cMonster#MobType|MobType}}", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "(STATIC) Returns the mob family ({{cMonster#MobFamily|mfXXX}} constants) based on the mob type ({{cMonster#MobType|mtXXX}} constants)" },
|
FamilyFromType = { Params = "{{Globals#MobType|MobType}}", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "(STATIC) Returns the mob family ({{cMonster#MobFamily|mfXXX}} constants) based on the mob type ({{Globals#MobType|mtXXX}} constants)" },
|
||||||
GetMobFamily = { Params = "", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "Returns this mob's family ({{cMonster#MobFamily|mfXXX}} constant)" },
|
GetMobFamily = { Params = "", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "Returns this mob's family ({{cMonster#MobFamily|mfXXX}} constant)" },
|
||||||
GetMobType = { Params = "", Return = "{{cMonster#MobType|MobType}}", Notes = "Returns the type of this mob ({{cMonster#MobType|mtXXX}} constant)" },
|
GetMobType = { Params = "", Return = "{{Globals#MobType|MobType}}", Notes = "Returns the type of this mob ({{Globals#MobType|mtXXX}} constant)" },
|
||||||
GetSpawnDelay = { Params = "{{cMonster#MobFamily|MobFamily}}", Return = "number", Notes = "(STATIC) Returns the spawn delay - the number of game ticks between spawn attempts - for the specified mob family." },
|
GetSpawnDelay = { Params = "{{cMonster#MobFamily|MobFamily}}", Return = "number", Notes = "(STATIC) Returns the spawn delay - the number of game ticks between spawn attempts - for the specified mob family." },
|
||||||
MobTypeToString = { Params = "{{cMonster#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{cMonster#MobType|mtXXX}} constant), or empty string if unknown type." },
|
MobTypeToString = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{Globals#MobType|mtXXX}} constant), or empty string if unknown type." },
|
||||||
|
MobTypeToVanillaName = { Params = "{{Globals#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the vanilla name of the given mob type, or empty string if unknown type." },
|
||||||
MoveToPosition = { Params = "Position", Return = "", Notes = "Moves mob to the specified position" },
|
MoveToPosition = { Params = "Position", Return = "", Notes = "Moves mob to the specified position" },
|
||||||
StringToMobType = { Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{cMonster#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." },
|
StringToMobType = { Params = "string", Return = "{{Globals#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{Globals#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." },
|
||||||
GetRelativeWalkSpeed = { Params = "", Return = "number", Notes = "Returns the relative walk speed of this mob. Standard is 1.0" },
|
GetRelativeWalkSpeed = { Params = "", Return = "number", Notes = "Returns the relative walk speed of this mob. Standard is 1.0" },
|
||||||
SetRelativeWalkSpeed = { Params = "number", Return = "", Notes = "Sets the relative walk speed of this mob. Standard is 1.0" },
|
SetRelativeWalkSpeed = { Params = "number", Return = "", Notes = "Sets the relative walk speed of this mob. Standard is 1.0" },
|
||||||
},
|
},
|
||||||
|
@ -1725,13 +1726,6 @@ a_Player:OpenWindow(Window);
|
||||||
Mobs are divided into families. The following constants are used for individual family types:
|
Mobs are divided into families. The following constants are used for individual family types:
|
||||||
]],
|
]],
|
||||||
},
|
},
|
||||||
MobType =
|
|
||||||
{
|
|
||||||
Include = "mt.*",
|
|
||||||
TextBefore = [[
|
|
||||||
The following constants are used for distinguishing between the individual mob types:
|
|
||||||
]],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Inherits = "cPawn",
|
Inherits = "cPawn",
|
||||||
}, -- cMonster
|
}, -- cMonster
|
||||||
|
@ -2571,7 +2565,7 @@ World:ForEachEntity(
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
local Monster = tolua.cast(a_Entity, "cMonster"); -- Get the cMonster out of cEntity, now that we know the entity represents one.
|
local Monster = tolua.cast(a_Entity, "cMonster"); -- Get the cMonster out of cEntity, now that we know the entity represents one.
|
||||||
if (Monster:GetMobType() == cMonster.mtSpider) then
|
if (Monster:GetMobType() == mtSpider) then
|
||||||
Monster:TeleportToCoords(Monster:GetPosX(), Monster:GetPosY() + 100, Monster:GetPosZ());
|
Monster:TeleportToCoords(Monster:GetPosX(), Monster:GetPosY() + 100, Monster:GetPosZ());
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2928,7 +2922,7 @@ end
|
||||||
StringToDamageType = {Params = "string", Return = "{{Globals#DamageType|DamageType}}", Notes = "Converts a string representation to a {{Globals#DamageType|DamageType}} enumerated value."},
|
StringToDamageType = {Params = "string", Return = "{{Globals#DamageType|DamageType}}", Notes = "Converts a string representation to a {{Globals#DamageType|DamageType}} enumerated value."},
|
||||||
StringToDimension = {Params = "string", Return = "{{Globals#WorldDimension|Dimension}}", Notes = "Converts a string representation to a {{Globals#WorldDimension|Dimension}} enumerated value"},
|
StringToDimension = {Params = "string", Return = "{{Globals#WorldDimension|Dimension}}", Notes = "Converts a string representation to a {{Globals#WorldDimension|Dimension}} enumerated value"},
|
||||||
StringToItem = {Params = "string, {{cItem|cItem}}", Return = "bool", Notes = "Parses the given string and sets the item; returns true if successful"},
|
StringToItem = {Params = "string, {{cItem|cItem}}", Return = "bool", Notes = "Parses the given string and sets the item; returns true if successful"},
|
||||||
StringToMobType = {Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "Converts a string representation to a {{cMonster#MobType|MobType}} enumerated value"},
|
StringToMobType = {Params = "string", Return = "{{Globals#MobType|MobType}}", Notes = "<b>DEPRECATED!</b> Please use cMonster:StringToMobType(). Converts a string representation to a {{Globals#MobType|MobType}} enumerated value"},
|
||||||
StripColorCodes = {Params = "string", Return = "string", Notes = "Removes all control codes used by MC for colors and styles"},
|
StripColorCodes = {Params = "string", Return = "string", Notes = "Removes all control codes used by MC for colors and styles"},
|
||||||
TrimString = {Params = "string", Return = "string", Notes = "Trims whitespace at both ends of the string"},
|
TrimString = {Params = "string", Return = "string", Notes = "Trims whitespace at both ends of the string"},
|
||||||
md5 = {Params = "string", Return = "string", Notes = "converts a string to an md5 hash"},
|
md5 = {Params = "string", Return = "string", Notes = "converts a string to an md5 hash"},
|
||||||
|
@ -3014,6 +3008,13 @@ end
|
||||||
gmXXX constants, the eGameMode_ constants are deprecated and will be removed from the API.
|
gmXXX constants, the eGameMode_ constants are deprecated and will be removed from the API.
|
||||||
]],
|
]],
|
||||||
},
|
},
|
||||||
|
MobType =
|
||||||
|
{
|
||||||
|
Include = { "^mt.*" },
|
||||||
|
TextBefore = [[
|
||||||
|
The following constants are used for distinguishing between the individual mob types:
|
||||||
|
]],
|
||||||
|
},
|
||||||
Weather =
|
Weather =
|
||||||
{
|
{
|
||||||
Include = { "^eWeather_.*", "wSunny", "wRain", "wStorm", "wThunderstorm" },
|
Include = { "^eWeather_.*", "wSunny", "wRain", "wStorm", "wThunderstorm" },
|
||||||
|
|
|
@ -231,6 +231,43 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(),
|
||||||
},
|
},
|
||||||
}, -- cJukeboxEntity
|
}, -- cJukeboxEntity
|
||||||
|
|
||||||
|
cMobHeadEntity =
|
||||||
|
{
|
||||||
|
Desc = [[
|
||||||
|
This class represents a mob head block entity in the world.
|
||||||
|
]],
|
||||||
|
Inherits = "cBlockEntity",
|
||||||
|
Functions =
|
||||||
|
{
|
||||||
|
SetType = { Params = "eMobHeadType", Return = "", Notes = "Set the type of the mob head" },
|
||||||
|
SetRotation = { Params = "eMobHeadRotation", Return = "", Notes = "Sets the rotation of the mob head" },
|
||||||
|
SetOwner = { Params = "string", Return = "", Notes = "Set the player name for mob heads with player type" },
|
||||||
|
GetType = { Params = "", Return = "eMobHeadType", Notes = "Returns the type of the mob head" },
|
||||||
|
GetRotation = { Params = "", Return = "eMobHeadRotation", Notes = "Returns the rotation of the mob head" },
|
||||||
|
GetOwner = { Params = "", Return = "string", Notes = "Returns the player name of the mob head" },
|
||||||
|
},
|
||||||
|
}, -- cMobHeadEntity
|
||||||
|
|
||||||
|
cMobSpawnerEntity =
|
||||||
|
{
|
||||||
|
Desc = [[
|
||||||
|
This class represents a mob spawner block entity in the world.
|
||||||
|
]],
|
||||||
|
Inherits = "cBlockEntity",
|
||||||
|
Functions =
|
||||||
|
{
|
||||||
|
UpdateActiveState = { Params = "", Return = "", Notes = "Upate the active flag from the mob spawner. This function will called every 5 seconds from the Tick() function." },
|
||||||
|
ResetTimer = { Params = "", Return = "", Notes = "Sets the spawn delay to a new random value." },
|
||||||
|
SpawnEntity = { Params = "", Return = "", Notes = "Spawns the entity. This function automaticly change the spawn delay!" },
|
||||||
|
GetEntity = { Params = "", Return = "{{Globals#MobType|MobType}}", Notes = "Returns the entity type that will be spawn by this mob spawner." },
|
||||||
|
SetEntity = { Params = "{{Globals#MobType|MobType}}", Return = "", Notes = "Sets the entity type who will be spawn by this mob spawner." },
|
||||||
|
GetSpawnDelay = { Params = "", Return = "number", Notes = "Returns the spawn delay. This is the tick delay that is needed to spawn new monsters." },
|
||||||
|
SetSpawnDelay = { Params = "number", Return = "", Notes = "Sets the spawn delay." },
|
||||||
|
GetNearbyPlayersNum = { Params = "", Return = "number", Notes = "Returns the amount of the nearby players in a 16-block radius." },
|
||||||
|
GetNearbyMonsterNum = { Params = "", Return = "number", Notes = "Returns the amount of this monster type in a 8-block radius (Y: 4-block radius)." },
|
||||||
|
},
|
||||||
|
}, -- cMobSpawnerEntity
|
||||||
|
|
||||||
cNoteEntity =
|
cNoteEntity =
|
||||||
{
|
{
|
||||||
Desc = [[
|
Desc = [[
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4702471943511f641458c7e8e89b430a723f43ea
|
Subproject commit 4183d6cfb2049d0757d811a65bd4e75ed78b9f41
|
|
@ -75,7 +75,6 @@ Wool = String, 1:1, 1:2, 2:1, 2:2
|
||||||
TNT = Gunpowder, 1:1, 3:1, 2:2, 1:3, 3:3 | Sand, 2:1, 1:2, 3:2, 2:3
|
TNT = Gunpowder, 1:1, 3:1, 2:2, 1:3, 3:3 | Sand, 2:1, 1:2, 3:2, 2:3
|
||||||
PillarQuartzBlock = QuartzSlab, 1:1, 1:2
|
PillarQuartzBlock = QuartzSlab, 1:1, 1:2
|
||||||
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
||||||
CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
|
||||||
HayBale = Wheat, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
HayBale = Wheat, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||||
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
||||||
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
||||||
|
|
|
@ -52,7 +52,7 @@ RawBeef = Steak
|
||||||
RawChicken = CookedChicken
|
RawChicken = CookedChicken
|
||||||
Clay = Brick
|
Clay = Brick
|
||||||
ClayBlock = HardenedClay
|
ClayBlock = HardenedClay
|
||||||
TallGrass = NetherBrickItem
|
Netherrack = NetherBrickItem
|
||||||
RawFish = CookedFish
|
RawFish = CookedFish
|
||||||
Log = CharCoal
|
Log = CharCoal
|
||||||
Cactus = GreenDye
|
Cactus = GreenDye
|
||||||
|
@ -90,6 +90,25 @@ RawMutton = CookedMutton
|
||||||
! CoalBlock = 16000 # -> 800 sec
|
! CoalBlock = 16000 # -> 800 sec
|
||||||
! BlazeRod = 2400 # -> 120 sec
|
! BlazeRod = 2400 # -> 120 sec
|
||||||
! NoteBlock = 300 # -> 15 sec
|
! NoteBlock = 300 # -> 15 sec
|
||||||
|
! HugeRedMushroom = 300 # -> 15 sec
|
||||||
|
! HugeBrownMushroom = 300 # -> 15 sec
|
||||||
|
! Banner = 300 # -> 15 sec
|
||||||
|
! BlackBanner = 300 # -> 15 sec
|
||||||
|
! RedBanner = 300 # -> 15 sec
|
||||||
|
! GreenBanner = 300 # -> 15 sec
|
||||||
|
! BrownBanner = 300 # -> 15 sec
|
||||||
|
! BlueBanner = 300 # -> 15 sec
|
||||||
|
! PurpleBanner = 300 # -> 15 sec
|
||||||
|
! CyanBanner = 300 # -> 15 sec
|
||||||
|
! SilverBanner = 300 # -> 15 sec
|
||||||
|
! GrayBanner = 300 # -> 15 sec
|
||||||
|
! PinkBanner = 300 # -> 15 sec
|
||||||
|
! LimeBanner = 300 # -> 15 sec
|
||||||
|
! YellowBanner = 300 # -> 15 sec
|
||||||
|
! LightBlueBanner = 300 # -> 15 sec
|
||||||
|
! MagentaBanner = 300 # -> 15 sec
|
||||||
|
! OrangeBanner = 300 # -> 15 sec
|
||||||
|
! WhiteBanner = 300 # -> 15 sec
|
||||||
! DaylightSensor = 300 # -> 15 sec
|
! DaylightSensor = 300 # -> 15 sec
|
||||||
! FenceGate = 300 # -> 15 sec
|
! FenceGate = 300 # -> 15 sec
|
||||||
! SpruceFenceGate = 300 # -> 15 sec
|
! SpruceFenceGate = 300 # -> 15 sec
|
||||||
|
|
|
@ -46,6 +46,7 @@ set(SHARED_HDR
|
||||||
../../src/ByteBuffer.h
|
../../src/ByteBuffer.h
|
||||||
../../src/StringUtils.h
|
../../src/StringUtils.h
|
||||||
)
|
)
|
||||||
|
|
||||||
flatten_files(SHARED_SRC)
|
flatten_files(SHARED_SRC)
|
||||||
flatten_files(SHARED_HDR)
|
flatten_files(SHARED_HDR)
|
||||||
source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
|
source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
|
||||||
|
@ -54,13 +55,22 @@ set(SHARED_OSS_SRC
|
||||||
../../src/OSSupport/CriticalSection.cpp
|
../../src/OSSupport/CriticalSection.cpp
|
||||||
../../src/OSSupport/File.cpp
|
../../src/OSSupport/File.cpp
|
||||||
../../src/OSSupport/IsThread.cpp
|
../../src/OSSupport/IsThread.cpp
|
||||||
|
../../src/OSSupport/StackTrace.cpp
|
||||||
|
../../src/OSSupport/Timer.cpp
|
||||||
)
|
)
|
||||||
set(SHARED_OSS_HDR
|
set(SHARED_OSS_HDR
|
||||||
../../src/OSSupport/CriticalSection.h
|
../../src/OSSupport/CriticalSection.h
|
||||||
../../src/OSSupport/File.h
|
../../src/OSSupport/File.h
|
||||||
../../src/OSSupport/IsThread.h
|
../../src/OSSupport/IsThread.h
|
||||||
|
../../src/OSSupport/StackTrace.h
|
||||||
|
../../src/OSSupport/Timer.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
list (APPEND SHARED_OSS_SRC ../../src/StackWalker.cpp)
|
||||||
|
list (APPEND SHARED_OSS_HDR ../../src/StackWalker.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
flatten_files(SHARED_OSS_SRC)
|
flatten_files(SHARED_OSS_SRC)
|
||||||
flatten_files(SHARED_OSS_HDR)
|
flatten_files(SHARED_OSS_HDR)
|
||||||
|
|
||||||
|
|
|
@ -57,12 +57,22 @@ set(SHARED_OSS_SRC
|
||||||
../../src/OSSupport/CriticalSection.cpp
|
../../src/OSSupport/CriticalSection.cpp
|
||||||
../../src/OSSupport/File.cpp
|
../../src/OSSupport/File.cpp
|
||||||
../../src/OSSupport/IsThread.cpp
|
../../src/OSSupport/IsThread.cpp
|
||||||
|
../../src/OSSupport/StackTrace.cpp
|
||||||
|
../../src/OSSupport/Timer.cpp
|
||||||
)
|
)
|
||||||
set(SHARED_OSS_HDR
|
set(SHARED_OSS_HDR
|
||||||
../../src/OSSupport/CriticalSection.h
|
../../src/OSSupport/CriticalSection.h
|
||||||
../../src/OSSupport/File.h
|
../../src/OSSupport/File.h
|
||||||
../../src/OSSupport/IsThread.h
|
../../src/OSSupport/IsThread.h
|
||||||
|
../../src/OSSupport/StackTrace.h
|
||||||
|
../../src/OSSupport/Timer.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
list (APPEND SHARED_OSS_SRC ../../src/StackWalker.cpp)
|
||||||
|
list (APPEND SHARED_OSS_HDR ../../src/StackWalker.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
flatten_files(SHARED_SRC)
|
flatten_files(SHARED_SRC)
|
||||||
flatten_files(SHARED_HDR)
|
flatten_files(SHARED_HDR)
|
||||||
flatten_files(SHARED_OSS_SRC)
|
flatten_files(SHARED_OSS_SRC)
|
||||||
|
|
|
@ -17,7 +17,7 @@ SOURCES += \
|
||||||
BiomeView.cpp \
|
BiomeView.cpp \
|
||||||
../../src/Generating/BioGen.cpp \
|
../../src/Generating/BioGen.cpp \
|
||||||
../../src/VoronoiMap.cpp \
|
../../src/VoronoiMap.cpp \
|
||||||
../../src/Noise.cpp \
|
../../src/Noise/Noise.cpp \
|
||||||
../../src/StringUtils.cpp \
|
../../src/StringUtils.cpp \
|
||||||
../../src/LoggerListeners.cpp \
|
../../src/LoggerListeners.cpp \
|
||||||
../../src/Logger.cpp \
|
../../src/Logger.cpp \
|
||||||
|
@ -25,7 +25,9 @@ SOURCES += \
|
||||||
../../src/OSSupport/File.cpp \
|
../../src/OSSupport/File.cpp \
|
||||||
../../src/OSSupport/CriticalSection.cpp \
|
../../src/OSSupport/CriticalSection.cpp \
|
||||||
../../src/OSSupport/IsThread.cpp \
|
../../src/OSSupport/IsThread.cpp \
|
||||||
|
../../src/OSSupport/StackTrace.cpp \
|
||||||
../../src/BiomeDef.cpp \
|
../../src/BiomeDef.cpp \
|
||||||
|
../../src/StackWalker.cpp \
|
||||||
../../src/StringCompression.cpp \
|
../../src/StringCompression.cpp \
|
||||||
../../src/WorldStorage/FastNBT.cpp \
|
../../src/WorldStorage/FastNBT.cpp \
|
||||||
../../lib/zlib/adler32.c \
|
../../lib/zlib/adler32.c \
|
||||||
|
@ -62,7 +64,7 @@ HEADERS += \
|
||||||
../../src/Generating/IntGen.h \
|
../../src/Generating/IntGen.h \
|
||||||
../../src/Generating/ProtIntGen.h \
|
../../src/Generating/ProtIntGen.h \
|
||||||
../../src/VoronoiMap.h \
|
../../src/VoronoiMap.h \
|
||||||
../../src/Noise.h \
|
../../src/Noise/Noise.h \
|
||||||
../../src/StringUtils.h \
|
../../src/StringUtils.h \
|
||||||
../../src/LoggerListeners.h \
|
../../src/LoggerListeners.h \
|
||||||
../../src/Logger.h \
|
../../src/Logger.h \
|
||||||
|
@ -70,7 +72,9 @@ HEADERS += \
|
||||||
../../src/OSSupport/File.h \
|
../../src/OSSupport/File.h \
|
||||||
../../src/OSSupport/CriticalSection.h \
|
../../src/OSSupport/CriticalSection.h \
|
||||||
../../src/OSSupport/IsThread.h \
|
../../src/OSSupport/IsThread.h \
|
||||||
|
../../src/OSSupport/StackTrace.h \
|
||||||
../../src/BiomeDef.h \
|
../../src/BiomeDef.h \
|
||||||
|
../../src/StackWalker.h \
|
||||||
../../src/StringCompression.h \
|
../../src/StringCompression.h \
|
||||||
../../src/WorldStorage/FastNBT.h \
|
../../src/WorldStorage/FastNBT.h \
|
||||||
../../lib/zlib/crc32.h \
|
../../lib/zlib/crc32.h \
|
||||||
|
@ -107,4 +111,15 @@ CONFIG += C++11
|
||||||
|
|
||||||
OTHER_FILES +=
|
OTHER_FILES +=
|
||||||
|
|
||||||
|
win* {
|
||||||
|
# Add the advapi32 library for windows compiles; needed for the StackWalker:
|
||||||
|
LIBS += advapi32.lib
|
||||||
|
|
||||||
|
# StackWalker doesn't like how Qt inconsistently defines only UNICODE, but not _UNICODE:
|
||||||
|
DEFINES -= UNICODE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ $cfile "../BlockEntities/JukeboxEntity.h"
|
||||||
$cfile "../BlockEntities/NoteEntity.h"
|
$cfile "../BlockEntities/NoteEntity.h"
|
||||||
$cfile "../BlockEntities/SignEntity.h"
|
$cfile "../BlockEntities/SignEntity.h"
|
||||||
$cfile "../BlockEntities/MobHeadEntity.h"
|
$cfile "../BlockEntities/MobHeadEntity.h"
|
||||||
|
$cfile "../BlockEntities/MobSpawnerEntity.h"
|
||||||
$cfile "../BlockEntities/FlowerPotEntity.h"
|
$cfile "../BlockEntities/FlowerPotEntity.h"
|
||||||
$cfile "../WebAdmin.h"
|
$cfile "../WebAdmin.h"
|
||||||
$cfile "../Root.h"
|
$cfile "../Root.h"
|
||||||
|
|
|
@ -225,6 +225,42 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* function: StringToMobType */
|
||||||
|
static int tolua_AllToLua_StringToMobType00(lua_State* tolua_S)
|
||||||
|
{
|
||||||
|
cLuaState LuaState(tolua_S);
|
||||||
|
|
||||||
|
#ifndef TOLUA_RELEASE
|
||||||
|
tolua_Error tolua_err;
|
||||||
|
if (
|
||||||
|
!tolua_iscppstring(tolua_S, 1, 0, &tolua_err) ||
|
||||||
|
!tolua_isnoobj(tolua_S, 2, &tolua_err)
|
||||||
|
)
|
||||||
|
goto tolua_lerror;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const AString a_MobString = tolua_tocppstring(LuaState, 1, 0);
|
||||||
|
eMonsterType MobType = cMonster::StringToMobType(a_MobString);
|
||||||
|
tolua_pushnumber(LuaState, (lua_Number) MobType);
|
||||||
|
tolua_pushcppstring(LuaState, (const char *) a_MobString);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGWARNING("Warning in function call 'StringToMobType': StringToMobType() is deprecated. Please use cMonster:StringToMobType()");
|
||||||
|
LuaState.LogStackTrace(0);
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
#ifndef TOLUA_RELEASE
|
||||||
|
tolua_lerror:
|
||||||
|
tolua_error(LuaState, "#ferror in function 'StringToMobType'.", &tolua_err);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** function: cWorld:SetSignLines */
|
/** function: cWorld:SetSignLines */
|
||||||
static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
|
static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
|
||||||
{
|
{
|
||||||
|
@ -296,6 +332,8 @@ void DeprecatedBindings::Bind(lua_State * tolua_S)
|
||||||
tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr);
|
tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr);
|
||||||
tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr);
|
tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr);
|
||||||
|
|
||||||
|
tolua_function(tolua_S, "StringToMobType", tolua_AllToLua_StringToMobType00);
|
||||||
|
|
||||||
tolua_beginmodule(tolua_S, "cWorld");
|
tolua_beginmodule(tolua_S, "cWorld");
|
||||||
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
|
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
|
||||||
tolua_endmodule(tolua_S);
|
tolua_endmodule(tolua_S);
|
||||||
|
|
|
@ -247,15 +247,16 @@ void cBeaconEntity::GiveEffects(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryEffect, cEntityEffect::eType a_SecondaryEffect, short a_EffectLevel)
|
cPlayerCallback(int a_Radius, int a_PosX, int a_PosY, int a_PosZ, cEntityEffect::eType a_PrimaryEffect, cEntityEffect::eType a_SecondaryEffect, short a_EffectLevel):
|
||||||
: m_Radius(a_Radius)
|
m_Radius(a_Radius),
|
||||||
, m_PosX(a_PosX)
|
m_PosX(a_PosX),
|
||||||
, m_PosY(a_PosY)
|
m_PosY(a_PosY),
|
||||||
, m_PosZ(a_PosZ)
|
m_PosZ(a_PosZ),
|
||||||
, m_PrimaryEffect(a_PrimaryEffect)
|
m_PrimaryEffect(a_PrimaryEffect),
|
||||||
, m_SecondaryEffect(a_SecondaryEffect)
|
m_SecondaryEffect(a_SecondaryEffect),
|
||||||
, m_EffectLevel(a_EffectLevel)
|
m_EffectLevel(a_EffectLevel)
|
||||||
{};
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryEffect, SecondaryEffect, EffectLevel);
|
} PlayerCallback(Radius, m_PosX, m_PosY, m_PosZ, m_PrimaryEffect, SecondaryEffect, EffectLevel);
|
||||||
GetWorld()->ForEachPlayer(PlayerCallback);
|
GetWorld()->ForEachPlayer(PlayerCallback);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
// BeaconEntity.h
|
// BeaconEntity.h
|
||||||
|
|
||||||
// Declares the cBeaconEntity class representing a single beacon in the world
|
// Declares the cBeaconEntity class representing a single beacon in the world
|
||||||
|
@ -14,15 +15,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
class cBeaconEntity :
|
class cBeaconEntity :
|
||||||
public cBlockEntityWithItems
|
public cBlockEntityWithItems
|
||||||
|
@ -32,7 +24,7 @@ class cBeaconEntity :
|
||||||
public:
|
public:
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cBeaconEntity);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
#include "FlowerPotEntity.h"
|
#include "FlowerPotEntity.h"
|
||||||
#include "FurnaceEntity.h"
|
#include "FurnaceEntity.h"
|
||||||
#include "HopperEntity.h"
|
#include "HopperEntity.h"
|
||||||
|
#include "MobHeadEntity.h"
|
||||||
|
#include "MobSpawnerEntity.h"
|
||||||
#include "JukeboxEntity.h"
|
#include "JukeboxEntity.h"
|
||||||
#include "NoteEntity.h"
|
#include "NoteEntity.h"
|
||||||
#include "SignEntity.h"
|
#include "SignEntity.h"
|
||||||
#include "MobHeadEntity.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
|
||||||
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
case E_BLOCK_FURNACE: return new cFurnaceEntity (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_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_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);
|
||||||
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_JUKEBOX: return new cJukeboxEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||||
case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
|
case E_BLOCK_SIGN_POST: return new cSignEntity (a_BlockType, a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class cChunk;
|
class cChunk;
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
|
@ -115,7 +110,7 @@ public:
|
||||||
virtual void SendTo(cClientHandle & a_Client) = 0;
|
virtual void SendTo(cClientHandle & a_Client) = 0;
|
||||||
|
|
||||||
/// Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking. By default does nothing.
|
/// Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking. By default does nothing.
|
||||||
virtual bool Tick(float a_Dt, cChunk & /* a_Chunk */)
|
virtual bool Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
UNUSED(a_Dt);
|
UNUSED(a_Dt);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,7 +29,7 @@ class cBlockEntityWithItems :
|
||||||
public:
|
public:
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cBlockEntityWithItems);
|
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
|
||||||
|
|
|
@ -18,6 +18,7 @@ SET (SRCS
|
||||||
HopperEntity.cpp
|
HopperEntity.cpp
|
||||||
JukeboxEntity.cpp
|
JukeboxEntity.cpp
|
||||||
MobHeadEntity.cpp
|
MobHeadEntity.cpp
|
||||||
|
MobSpawnerEntity.cpp
|
||||||
NoteEntity.cpp
|
NoteEntity.cpp
|
||||||
SignEntity.cpp)
|
SignEntity.cpp)
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ SET (HDRS
|
||||||
HopperEntity.h
|
HopperEntity.h
|
||||||
JukeboxEntity.h
|
JukeboxEntity.h
|
||||||
MobHeadEntity.h
|
MobHeadEntity.h
|
||||||
|
MobSpawnerEntity.h
|
||||||
NoteEntity.h
|
NoteEntity.h
|
||||||
SignEntity.h)
|
SignEntity.h)
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class cClientHandle;
|
class cClientHandle;
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +28,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cChestEntity);
|
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);
|
||||||
|
|
|
@ -15,14 +15,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
|
@ -36,7 +28,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cCommandBlockEntity);
|
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);
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cDispenserEntity);
|
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);
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
class cClientHandle;
|
class cClientHandle;
|
||||||
|
|
||||||
|
@ -45,7 +41,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cDropSpenserEntity);
|
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();
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cDropperEntity);
|
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);
|
||||||
|
|
|
@ -18,7 +18,7 @@ class cEnderChestEntity :
|
||||||
public:
|
public:
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cEnderChestEntity);
|
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();
|
||||||
|
|
|
@ -15,16 +15,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
class cFlowerPotEntity :
|
class cFlowerPotEntity :
|
||||||
|
@ -36,7 +26,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cFlowerPotEntity);
|
BLOCKENTITY_PROTODEF(cFlowerPotEntity)
|
||||||
|
|
||||||
/** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */
|
/** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */
|
||||||
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);
|
||||||
|
|
|
@ -8,11 +8,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
class cClientHandle;
|
class cClientHandle;
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +33,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cFurnaceEntity);
|
BLOCKENTITY_PROTODEF(cFurnaceEntity)
|
||||||
|
|
||||||
/** Constructor used for normal operation */
|
/** 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);
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cHopperEntity);
|
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);
|
||||||
|
|
|
@ -7,15 +7,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
class cJukeboxEntity :
|
class cJukeboxEntity :
|
||||||
|
@ -26,7 +17,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cJukeboxEntity);
|
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();
|
||||||
|
|
|
@ -14,14 +14,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
|
@ -34,29 +26,29 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cMobHeadEntity);
|
BLOCKENTITY_PROTODEF(cMobHeadEntity)
|
||||||
|
|
||||||
/** Creates a new mob head entity at the specified block coords. a_World may be nullptr */
|
/** Creates a new mob head entity at the specified block coords. a_World may be nullptr */
|
||||||
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);
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
/** Set the Type */
|
/** Set the type of the mob head */
|
||||||
void SetType(const eMobHeadType & a_SkullType);
|
void SetType(const eMobHeadType & a_SkullType);
|
||||||
|
|
||||||
/** Set the Rotation */
|
/** Set the rotation of the mob head */
|
||||||
void SetRotation(eMobHeadRotation a_Rotation);
|
void SetRotation(eMobHeadRotation a_Rotation);
|
||||||
|
|
||||||
/** Set the Player Name for Mobheads with Player type */
|
/** Set the player name for mob heads with player type */
|
||||||
void SetOwner(const AString & a_Owner);
|
void SetOwner(const AString & a_Owner);
|
||||||
|
|
||||||
/** Get the Type */
|
/** Returns the type of the mob head */
|
||||||
eMobHeadType GetType(void) const { return m_Type; }
|
eMobHeadType GetType(void) const { return m_Type; }
|
||||||
|
|
||||||
/** Get the Rotation */
|
/** Returns the rotation of the mob head */
|
||||||
eMobHeadRotation GetRotation(void) const { return m_Rotation; }
|
eMobHeadRotation GetRotation(void) const { return m_Rotation; }
|
||||||
|
|
||||||
/** Get the setted Player Name */
|
/** Returns the player name of the mob head */
|
||||||
AString GetOwner(void) const { return m_Owner; }
|
AString GetOwner(void) const { return m_Owner; }
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
|
@ -0,0 +1,290 @@
|
||||||
|
|
||||||
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
|
#include "MobSpawnerEntity.h"
|
||||||
|
|
||||||
|
#include "../World.h"
|
||||||
|
#include "../FastRandom.h"
|
||||||
|
#include "../MobSpawner.h"
|
||||||
|
#include "../Items/ItemSpawnEgg.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cMobSpawnerEntity::cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
|
||||||
|
: super(E_BLOCK_MOB_SPAWNER, a_BlockX, a_BlockY, a_BlockZ, a_World)
|
||||||
|
, m_Entity(mtPig)
|
||||||
|
, m_SpawnDelay(100)
|
||||||
|
, m_IsActive(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobSpawnerEntity::SendTo(cClientHandle & a_Client)
|
||||||
|
{
|
||||||
|
a_Client.SendUpdateBlockEntity(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobSpawnerEntity::UsedBy(cPlayer * a_Player)
|
||||||
|
{
|
||||||
|
if (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SPAWN_EGG)
|
||||||
|
{
|
||||||
|
eMonsterType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Player->GetEquippedItem().m_ItemDamage);
|
||||||
|
if (MonsterType == eMonsterType::mtInvalidType)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Entity = MonsterType;
|
||||||
|
ResetTimer();
|
||||||
|
if (!a_Player->IsGameModeCreative())
|
||||||
|
{
|
||||||
|
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||||
|
}
|
||||||
|
LOGD("Changed monster spawner at {%d, %d, %d} to type %s.", GetPosX(), GetPosY(), GetPosZ(), cMonster::MobTypeToString(MonsterType).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobSpawnerEntity::UpdateActiveState(void)
|
||||||
|
{
|
||||||
|
if (GetNearbyPlayersNum() > 0)
|
||||||
|
{
|
||||||
|
m_IsActive = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_IsActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cMobSpawnerEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
|
{
|
||||||
|
// Update the active flag every 5 seconds
|
||||||
|
if ((m_World->GetWorldAge() % 100) == 0)
|
||||||
|
{
|
||||||
|
UpdateActiveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_IsActive)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_SpawnDelay <= 0)
|
||||||
|
{
|
||||||
|
SpawnEntity();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_SpawnDelay--;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobSpawnerEntity::ResetTimer(void)
|
||||||
|
{
|
||||||
|
m_SpawnDelay = static_cast<short>(200 + m_World->GetTickRandomNumber(600));
|
||||||
|
m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cMobSpawnerEntity::SpawnEntity(void)
|
||||||
|
{
|
||||||
|
int NearbyEntities = GetNearbyMonsterNum(m_Entity);
|
||||||
|
if (NearbyEntities >= 6)
|
||||||
|
{
|
||||||
|
ResetTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
class cCallback : public cChunkCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cCallback(int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, int a_NearbyEntitiesNum) :
|
||||||
|
m_RelX(a_RelX),
|
||||||
|
m_RelY(a_RelY),
|
||||||
|
m_RelZ(a_RelZ),
|
||||||
|
m_MobType(a_MobType),
|
||||||
|
m_NearbyEntitiesNum(a_NearbyEntitiesNum)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Item(cChunk * a_Chunk)
|
||||||
|
{
|
||||||
|
cFastRandom Random;
|
||||||
|
|
||||||
|
bool EntitiesSpawned = false;
|
||||||
|
for (size_t i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (m_NearbyEntitiesNum >= 6)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RelX = (int) (m_RelX + (double)(Random.NextFloat() - Random.NextFloat()) * 4.0);
|
||||||
|
int RelY = m_RelY + Random.NextInt(3) - 1;
|
||||||
|
int RelZ = (int) (m_RelZ + (double)(Random.NextFloat() - Random.NextFloat()) * 4.0);
|
||||||
|
|
||||||
|
cChunk * Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(RelX, RelZ);
|
||||||
|
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EMCSBiome Biome = Chunk->GetBiomeAt(RelX, RelZ);
|
||||||
|
|
||||||
|
if (cMobSpawner::CanSpawnHere(Chunk, RelX, RelY, RelZ, m_MobType, Biome))
|
||||||
|
{
|
||||||
|
double PosX = Chunk->GetPosX() * cChunkDef::Width + RelX;
|
||||||
|
double PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ;
|
||||||
|
|
||||||
|
cMonster * Monster = cMonster::NewMonsterFromType(m_MobType);
|
||||||
|
if (Monster == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Monster->SetPosition(PosX, RelY, PosZ);
|
||||||
|
Monster->SetYaw(Random.NextFloat() * 360.0f);
|
||||||
|
if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != mtInvalidType)
|
||||||
|
{
|
||||||
|
EntitiesSpawned = true;
|
||||||
|
Chunk->BroadcastSoundParticleEffect(2004, (int)(PosX * 8.0), (int)(RelY * 8.0), (int)(PosZ * 8.0), 0);
|
||||||
|
m_NearbyEntitiesNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EntitiesSpawned;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
int m_RelX, m_RelY, m_RelZ;
|
||||||
|
eMonsterType m_MobType;
|
||||||
|
int m_NearbyEntitiesNum;
|
||||||
|
} Callback(m_RelX, m_PosY, m_RelZ, m_Entity, NearbyEntities);
|
||||||
|
|
||||||
|
if (m_World->DoWithChunk(GetChunkX(), GetChunkZ(), Callback))
|
||||||
|
{
|
||||||
|
ResetTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int cMobSpawnerEntity::GetNearbyPlayersNum(void)
|
||||||
|
{
|
||||||
|
Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5);
|
||||||
|
int NumPlayers = 0;
|
||||||
|
|
||||||
|
class cCallback : public cChunkDataCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cCallback(Vector3d a_SpawnerPos, int & a_NumPlayers) :
|
||||||
|
m_SpawnerPos(a_SpawnerPos),
|
||||||
|
m_NumPlayers(a_NumPlayers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Entity(cEntity * a_Entity) override
|
||||||
|
{
|
||||||
|
if (!a_Entity->IsPlayer())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_SpawnerPos - a_Entity->GetPosition()).Length() <= 16)
|
||||||
|
{
|
||||||
|
m_NumPlayers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vector3d m_SpawnerPos;
|
||||||
|
int & m_NumPlayers;
|
||||||
|
} Callback(SpawnerPos, NumPlayers);
|
||||||
|
|
||||||
|
int ChunkX = GetChunkX();
|
||||||
|
int ChunkZ = GetChunkZ();
|
||||||
|
m_World->ForEachChunkInRect(ChunkX - 1, ChunkX + 1, ChunkZ - 1, ChunkZ + 1, Callback);
|
||||||
|
|
||||||
|
return NumPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int cMobSpawnerEntity::GetNearbyMonsterNum(eMonsterType a_EntityType)
|
||||||
|
{
|
||||||
|
Vector3d SpawnerPos(m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5);
|
||||||
|
int NumEntities = 0;
|
||||||
|
|
||||||
|
class cCallback : public cChunkDataCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cCallback(Vector3d a_SpawnerPos, eMonsterType a_EntityType, int & a_NumEntities) :
|
||||||
|
m_SpawnerPos(a_SpawnerPos),
|
||||||
|
m_EntityType(a_EntityType),
|
||||||
|
m_NumEntities(a_NumEntities)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Entity(cEntity * a_Entity) override
|
||||||
|
{
|
||||||
|
if (!a_Entity->IsMob())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cMonster * Mob = (cMonster *)a_Entity;
|
||||||
|
if (Mob->GetMobType() != m_EntityType)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Diff(m_SpawnerPos.x, a_Entity->GetPosX()) <= 8.0) && (Diff(m_SpawnerPos.y, a_Entity->GetPosY()) <= 4.0) && (Diff(m_SpawnerPos.z, a_Entity->GetPosZ()) <= 8.0))
|
||||||
|
{
|
||||||
|
m_NumEntities++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vector3d m_SpawnerPos;
|
||||||
|
eMonsterType m_EntityType;
|
||||||
|
int & m_NumEntities;
|
||||||
|
} Callback(SpawnerPos, a_EntityType, NumEntities);
|
||||||
|
|
||||||
|
int ChunkX = GetChunkX();
|
||||||
|
int ChunkZ = GetChunkZ();
|
||||||
|
m_World->ForEachChunkInRect(ChunkX - 1, ChunkX + 1, ChunkZ - 1, ChunkZ + 1, Callback);
|
||||||
|
|
||||||
|
return NumEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
// MobSpawnerEntity.h
|
||||||
|
|
||||||
|
// Declares the cMobSpawnerEntity class representing a single mob spawner in the world
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BlockEntity.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
class cMobSpawnerEntity :
|
||||||
|
public cBlockEntity
|
||||||
|
{
|
||||||
|
typedef cBlockEntity super;
|
||||||
|
public:
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||||
|
|
||||||
|
virtual void SendTo(cClientHandle & a_Client) override;
|
||||||
|
virtual void UsedBy(cPlayer * a_Player) override;
|
||||||
|
virtual bool Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
|
|
||||||
|
/** Upate the active flag from the mob spawner. This function will called every 5 seconds from the Tick() function. */
|
||||||
|
void UpdateActiveState(void);
|
||||||
|
|
||||||
|
/** Sets the spawn delay to a new random value. */
|
||||||
|
void ResetTimer(void);
|
||||||
|
|
||||||
|
/** Spawns the entity. This function automaticly change the spawn delay! */
|
||||||
|
void SpawnEntity(void);
|
||||||
|
|
||||||
|
/** Returns the entity type that will be spawn by this mob spawner. */
|
||||||
|
eMonsterType GetEntity(void) const { return m_Entity; }
|
||||||
|
|
||||||
|
/** Sets the entity type who will be spawn by this mob spawner. */
|
||||||
|
void SetEntity(eMonsterType a_EntityType) { m_Entity = a_EntityType; }
|
||||||
|
|
||||||
|
/** Returns the spawn delay. This is the tick delay that is needed to spawn new monsters. */
|
||||||
|
short GetSpawnDelay(void) const { return m_SpawnDelay; }
|
||||||
|
|
||||||
|
/** Sets the spawn delay. */
|
||||||
|
void SetSpawnDelay(short a_Delay) { m_SpawnDelay = a_Delay; }
|
||||||
|
|
||||||
|
/** Returns the amount of the nearby players in a 16-block radius. */
|
||||||
|
int GetNearbyPlayersNum(void);
|
||||||
|
|
||||||
|
/** Returns the amount of this monster type in a 8-block radius (Y: 4-block radius). */
|
||||||
|
int GetNearbyMonsterNum(eMonsterType a_EntityType);
|
||||||
|
|
||||||
|
// tolua_end
|
||||||
|
|
||||||
|
static const char * GetClassStatic(void) { return "cMobSpawnerEntity"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** The entity to spawn. */
|
||||||
|
eMonsterType m_Entity;
|
||||||
|
|
||||||
|
short m_SpawnDelay;
|
||||||
|
|
||||||
|
bool m_IsActive;
|
||||||
|
} ; // tolua_end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,6 @@
|
||||||
#include "RedstonePoweredEntity.h"
|
#include "RedstonePoweredEntity.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +34,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cNoteEntity);
|
BLOCKENTITY_PROTODEF(cNoteEntity)
|
||||||
|
|
||||||
/// Creates a new note entity. a_World may be nullptr
|
/// Creates a new note entity. a_World may be nullptr
|
||||||
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);
|
||||||
|
|
|
@ -14,15 +14,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Json
|
|
||||||
{
|
|
||||||
class Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
class cSignEntity :
|
class cSignEntity :
|
||||||
|
@ -34,7 +25,7 @@ public:
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
BLOCKENTITY_PROTODEF(cSignEntity);
|
BLOCKENTITY_PROTODEF(cSignEntity)
|
||||||
|
|
||||||
/// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr
|
/// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr
|
||||||
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);
|
||||||
|
|
|
@ -200,7 +200,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BLOCKTYPE BlockStringToType(const AString & a_BlockTypeString)
|
int BlockStringToType(const AString & a_BlockTypeString)
|
||||||
{
|
{
|
||||||
int res = atoi(a_BlockTypeString.c_str());
|
int res = atoi(a_BlockTypeString.c_str());
|
||||||
if ((res != 0) || (a_BlockTypeString.compare("0") == 0))
|
if ((res != 0) || (a_BlockTypeString.compare("0") == 0))
|
||||||
|
|
|
@ -1096,7 +1096,7 @@ class cIniFile;
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
/// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure.
|
/// Translates a blocktype string into blocktype. Takes either a number or an items.ini alias as input. Returns -1 on failure.
|
||||||
extern BLOCKTYPE BlockStringToType(const AString & a_BlockTypeString);
|
extern int BlockStringToType(const AString & a_BlockTypeString);
|
||||||
|
|
||||||
/// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful.
|
/// Translates an itemtype string into an item. Takes either a number, number^number, number:number or an items.ini alias as input. Returns true if successful.
|
||||||
extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item);
|
extern bool StringToItem(const AString & a_ItemTypeString, cItem & a_Item);
|
||||||
|
|
|
@ -19,6 +19,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
|
||||||
|
{
|
||||||
|
a_ChunkInterface.UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool IsUseable() override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||||
{
|
{
|
||||||
// No pickups
|
// No pickups
|
||||||
|
|
|
@ -104,7 +104,6 @@ SET (HDRS
|
||||||
Inventory.h
|
Inventory.h
|
||||||
Item.h
|
Item.h
|
||||||
ItemGrid.h
|
ItemGrid.h
|
||||||
LeakFinder.h
|
|
||||||
LightingThread.h
|
LightingThread.h
|
||||||
LineBlockTracer.h
|
LineBlockTracer.h
|
||||||
LinearInterpolation.h
|
LinearInterpolation.h
|
||||||
|
@ -114,7 +113,6 @@ SET (HDRS
|
||||||
Map.h
|
Map.h
|
||||||
MapManager.h
|
MapManager.h
|
||||||
Matrix4.h
|
Matrix4.h
|
||||||
MemoryLeak.h
|
|
||||||
MobCensus.h
|
MobCensus.h
|
||||||
MobFamilyCollecter.h
|
MobFamilyCollecter.h
|
||||||
MobProximityCounter.h
|
MobProximityCounter.h
|
||||||
|
@ -127,7 +125,6 @@ SET (HDRS
|
||||||
Scoreboard.h
|
Scoreboard.h
|
||||||
Server.h
|
Server.h
|
||||||
SetChunkData.h
|
SetChunkData.h
|
||||||
StackWalker.h
|
|
||||||
Statistics.h
|
Statistics.h
|
||||||
StringCompression.h
|
StringCompression.h
|
||||||
StringUtils.h
|
StringUtils.h
|
||||||
|
@ -175,6 +172,10 @@ if (NOT MSVC)
|
||||||
else ()
|
else ()
|
||||||
# MSVC-specific handling: Put all files into one project, separate by the folders:
|
# MSVC-specific handling: Put all files into one project, separate by the folders:
|
||||||
|
|
||||||
|
# Add the MSVC-specific LeakFinder sources:
|
||||||
|
list (APPEND SRCS LeakFinder.cpp StackWalker.cpp)
|
||||||
|
list (APPEND HDRS LeakFinder.h StackWalker.h MemoryLeak.h)
|
||||||
|
|
||||||
source_group(Bindings FILES "Bindings/Bindings.cpp" "Bindings/Bindings.h")
|
source_group(Bindings FILES "Bindings/Bindings.cpp" "Bindings/Bindings.h")
|
||||||
|
|
||||||
# Add all subfolders as solution-folders:
|
# Add all subfolders as solution-folders:
|
||||||
|
@ -224,7 +225,7 @@ else ()
|
||||||
Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS "/Yc\"string.h\" /Fp\"$(IntDir)/Bindings.pch\""
|
Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS "/Yc\"string.h\" /Fp\"$(IntDir)/Bindings.pch\""
|
||||||
)
|
)
|
||||||
SET_SOURCE_FILES_PROPERTIES(
|
SET_SOURCE_FILES_PROPERTIES(
|
||||||
"StackWalker.cpp LeakFinder.h" PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\""
|
"StackWalker.cpp LeakFinder.cpp" PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\""
|
||||||
)
|
)
|
||||||
list(APPEND SOURCE "Resources/MCServer.rc")
|
list(APPEND SOURCE "Resources/MCServer.rc")
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
#include "BlockEntities/ChestEntity.h"
|
#include "BlockEntities/ChestEntity.h"
|
||||||
#include "BlockEntities/DispenserEntity.h"
|
#include "BlockEntities/DispenserEntity.h"
|
||||||
#include "BlockEntities/DropperEntity.h"
|
#include "BlockEntities/DropperEntity.h"
|
||||||
|
#include "BlockEntities/FlowerPotEntity.h"
|
||||||
#include "BlockEntities/FurnaceEntity.h"
|
#include "BlockEntities/FurnaceEntity.h"
|
||||||
#include "BlockEntities/HopperEntity.h"
|
#include "BlockEntities/HopperEntity.h"
|
||||||
#include "BlockEntities/JukeboxEntity.h"
|
#include "BlockEntities/JukeboxEntity.h"
|
||||||
|
#include "BlockEntities/MobHeadEntity.h"
|
||||||
|
#include "BlockEntities/MobSpawnerEntity.h"
|
||||||
#include "BlockEntities/NoteEntity.h"
|
#include "BlockEntities/NoteEntity.h"
|
||||||
#include "BlockEntities/SignEntity.h"
|
#include "BlockEntities/SignEntity.h"
|
||||||
#include "BlockEntities/MobHeadEntity.h"
|
|
||||||
#include "BlockEntities/FlowerPotEntity.h"
|
|
||||||
#include "Entities/Pickup.h"
|
#include "Entities/Pickup.h"
|
||||||
#include "Item.h"
|
#include "Item.h"
|
||||||
#include "Noise/Noise.h"
|
#include "Noise/Noise.h"
|
||||||
|
@ -1347,6 +1348,7 @@ void cChunk::CreateBlockEntities(void)
|
||||||
case E_BLOCK_NOTE_BLOCK:
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
case E_BLOCK_JUKEBOX:
|
case E_BLOCK_JUKEBOX:
|
||||||
case E_BLOCK_FLOWER_POT:
|
case E_BLOCK_FLOWER_POT:
|
||||||
|
case E_BLOCK_MOB_SPAWNER:
|
||||||
{
|
{
|
||||||
if (!HasBlockEntityAt(x + m_PosX * Width, y, z + m_PosZ * Width))
|
if (!HasBlockEntityAt(x + m_PosX * Width, y, z + m_PosZ * Width))
|
||||||
{
|
{
|
||||||
|
@ -1478,6 +1480,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
|
||||||
case E_BLOCK_NOTE_BLOCK:
|
case E_BLOCK_NOTE_BLOCK:
|
||||||
case E_BLOCK_JUKEBOX:
|
case E_BLOCK_JUKEBOX:
|
||||||
case E_BLOCK_FLOWER_POT:
|
case E_BLOCK_FLOWER_POT:
|
||||||
|
case E_BLOCK_MOB_SPAWNER:
|
||||||
{
|
{
|
||||||
AddBlockEntity(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
AddBlockEntity(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||||
break;
|
break;
|
||||||
|
@ -1868,18 +1871,18 @@ bool cChunk::AddClient(cClientHandle * a_Client)
|
||||||
|
|
||||||
void cChunk::RemoveClient(cClientHandle * a_Client)
|
void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
for (cClientHandleList::iterator itrC = m_LoadedByClient.begin(); itrC != m_LoadedByClient.end(); ++itrC)
|
||||||
{
|
{
|
||||||
if (*itr != a_Client)
|
if (*itrC != a_Client)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LoadedByClient.erase(itr);
|
m_LoadedByClient.erase(itrC);
|
||||||
|
|
||||||
if (!a_Client->IsDestroyed())
|
if (!a_Client->IsDestroyed())
|
||||||
{
|
{
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
for (cEntityList::iterator itrE = m_Entities.begin(); itrE != m_Entities.end(); ++itrE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
// DEBUG:
|
// DEBUG:
|
||||||
|
@ -1888,7 +1891,7 @@ void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||||
(*itr)->GetUniqueID(), a_Client->GetUsername().c_str()
|
(*itr)->GetUniqueID(), a_Client->GetUsername().c_str()
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
a_Client->SendDestroyEntity(*(*itr));
|
a_Client->SendDestroyEntity(*(*itrE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1220,12 +1220,18 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||||
{
|
{
|
||||||
// TODO: Rewrite this function
|
// TODO: Rewrite this function
|
||||||
|
|
||||||
LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s",
|
// Distance from the block's center to the player's eye height
|
||||||
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str()
|
double dist = (Vector3d(a_BlockX, a_BlockY, a_BlockZ) + Vector3d(0.5, 0.5, 0.5) - m_Player->GetEyePosition()).Length();
|
||||||
|
LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s; dist: %.02f",
|
||||||
|
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str(), dist
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Check the reach distance:
|
||||||
|
// _X 2014-11-25: I've maxed at 5.26 with a Survival client and 5.78 with a Creative client in my tests
|
||||||
|
double maxDist = m_Player->IsGameModeCreative() ? 5.78 : 5.26;
|
||||||
|
bool AreRealCoords = (dist <= maxDist);
|
||||||
|
|
||||||
cWorld * World = m_Player->GetWorld();
|
cWorld * World = m_Player->GetWorld();
|
||||||
bool AreRealCoords = (Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block
|
(a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block
|
||||||
|
|
|
@ -289,7 +289,7 @@ void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingG
|
||||||
}
|
}
|
||||||
|
|
||||||
// Built-in recipes:
|
// Built-in recipes:
|
||||||
std::auto_ptr<cRecipe> Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight()));
|
std::unique_ptr<cRecipe> Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight()));
|
||||||
a_Recipe.Clear();
|
a_Recipe.Clear();
|
||||||
if (Recipe.get() == nullptr)
|
if (Recipe.get() == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +377,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::auto_ptr<cCraftingRecipes::cRecipe> Recipe(new cCraftingRecipes::cRecipe);
|
std::unique_ptr<cCraftingRecipes::cRecipe> Recipe(new cCraftingRecipes::cRecipe);
|
||||||
|
|
||||||
// Parse the result:
|
// Parse the result:
|
||||||
AStringVector ResultSplit = StringSplit(Sides[0], ",");
|
AStringVector ResultSplit = StringSplit(Sides[0], ",");
|
||||||
|
@ -758,7 +758,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti
|
||||||
} // for y, for x
|
} // for y, for x
|
||||||
|
|
||||||
// The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid:
|
// The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid:
|
||||||
std::auto_ptr<cRecipe> Recipe(new cRecipe);
|
std::unique_ptr<cRecipe> Recipe(new cRecipe);
|
||||||
Recipe->m_Result = a_Recipe->m_Result;
|
Recipe->m_Result = a_Recipe->m_Result;
|
||||||
Recipe->m_Width = a_Recipe->m_Width;
|
Recipe->m_Width = a_Recipe->m_Width;
|
||||||
Recipe->m_Height = a_Recipe->m_Height;
|
Recipe->m_Height = a_Recipe->m_Height;
|
||||||
|
|
|
@ -128,7 +128,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
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(static_cast<int>(a_Idx), a_Item); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cItemGrid m_Contents;
|
cItemGrid m_Contents;
|
||||||
|
|
|
@ -117,6 +117,11 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) :
|
||||||
{
|
{
|
||||||
m_CanFly = true;
|
m_CanFly = true;
|
||||||
}
|
}
|
||||||
|
if (World->IsGameModeSpectator()) // Otherwise Player will fall out of the world on join
|
||||||
|
{
|
||||||
|
m_CanFly = true;
|
||||||
|
m_IsFlying = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cRoot::Get()->GetServer()->PlayerCreated(this);
|
cRoot::Get()->GetServer()->PlayerCreated(this);
|
||||||
|
@ -1068,7 +1073,7 @@ bool cPlayer::IsGameModeAdventure(void) const
|
||||||
bool cPlayer::IsGameModeSpectator(void) const
|
bool cPlayer::IsGameModeSpectator(void) const
|
||||||
{
|
{
|
||||||
return (m_GameMode == gmSpectator) || // Either the player is explicitly in Spectator
|
return (m_GameMode == gmSpectator) || // Either the player is explicitly in Spectator
|
||||||
((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Adventure
|
((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Spectator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1887,8 +1892,8 @@ void cPlayer::UseEquippedItem(int a_Amount)
|
||||||
|
|
||||||
void cPlayer::TickBurning(cChunk & a_Chunk)
|
void cPlayer::TickBurning(cChunk & a_Chunk)
|
||||||
{
|
{
|
||||||
// Don't burn in creative and stop burning in creative if necessary
|
// Don't burn in creative or spectator and stop burning in creative if necessary
|
||||||
if (!IsGameModeCreative())
|
if (!IsGameModeCreative() && !IsGameModeSpectator())
|
||||||
{
|
{
|
||||||
super::TickBurning(a_Chunk);
|
super::TickBurning(a_Chunk);
|
||||||
}
|
}
|
||||||
|
@ -1907,9 +1912,9 @@ void cPlayer::HandleFood(void)
|
||||||
{
|
{
|
||||||
// Ref.: http://www.minecraftwiki.net/wiki/Hunger
|
// Ref.: http://www.minecraftwiki.net/wiki/Hunger
|
||||||
|
|
||||||
if (IsGameModeCreative())
|
if (IsGameModeCreative() || IsGameModeSpectator())
|
||||||
{
|
{
|
||||||
// Hunger is disabled for Creative
|
// Hunger is disabled for Creative and Spectator
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2074,7 +2079,7 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos)
|
||||||
|
|
||||||
void cPlayer::ApplyFoodExhaustionFromMovement()
|
void cPlayer::ApplyFoodExhaustionFromMovement()
|
||||||
{
|
{
|
||||||
if (IsGameModeCreative())
|
if (IsGameModeCreative() || IsGameModeSpectator())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_Line
|
||||||
Line.erase(Line.begin()); // Remove the beginning "!"
|
Line.erase(Line.begin()); // Remove the beginning "!"
|
||||||
Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
|
Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
|
||||||
|
|
||||||
std::auto_ptr<cItem> Item(new cItem);
|
std::unique_ptr<cItem> Item(new cItem);
|
||||||
int BurnTime;
|
int BurnTime;
|
||||||
|
|
||||||
const AStringVector & Sides = StringSplit(Line, "=");
|
const AStringVector & Sides = StringSplit(Line, "=");
|
||||||
|
@ -157,8 +157,8 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li
|
||||||
Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
|
Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
|
||||||
|
|
||||||
int CookTime = 200;
|
int CookTime = 200;
|
||||||
std::auto_ptr<cItem> InputItem(new cItem());
|
std::unique_ptr<cItem> InputItem(new cItem());
|
||||||
std::auto_ptr<cItem> OutputItem(new cItem());
|
std::unique_ptr<cItem> OutputItem(new cItem());
|
||||||
|
|
||||||
const AStringVector & Sides = StringSplit(Line, "=");
|
const AStringVector & Sides = StringSplit(Line, "=");
|
||||||
if (Sides.size() != 2)
|
if (Sides.size() != 2)
|
||||||
|
|
|
@ -191,13 +191,13 @@ EMCSBiome cChunkGenerator::GetBiomeAt(int a_BlockX, int a_BlockZ)
|
||||||
BLOCKTYPE cChunkGenerator::GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default)
|
BLOCKTYPE cChunkGenerator::GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default)
|
||||||
{
|
{
|
||||||
AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default);
|
AString BlockType = a_IniFile.GetValueSet(a_SectionName, a_ValueName, a_Default);
|
||||||
BLOCKTYPE Block = BlockStringToType(BlockType);
|
int Block = BlockStringToType(BlockType);
|
||||||
if (Block < 0)
|
if (Block < 0)
|
||||||
{
|
{
|
||||||
LOGWARN("[%s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(), a_Default.c_str());
|
LOGWARN("[%s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(), a_Default.c_str());
|
||||||
return BlockStringToType(a_Default);
|
return static_cast<BLOCKTYPE>(BlockStringToType(a_Default));
|
||||||
}
|
}
|
||||||
return Block;
|
return static_cast<BLOCKTYPE>(Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -290,17 +290,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:
|
||||||
BLOCKTYPE Block = E_BLOCK_AIR;
|
BLOCKTYPE Block = E_BLOCK_AIR;
|
||||||
if (Val < m_Threshold) // Don't calculate if the block should be Netherrack or Soulsand when it's already decided that it's air.
|
if (Val < m_Threshold) // Don't calculate if the block should be Netherrack or Soulsand when it's already decided that it's air.
|
||||||
{
|
{
|
||||||
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(BaseX + x)) / 8;
|
Block = E_BLOCK_NETHERRACK;
|
||||||
NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(BaseZ + z)) / 8;
|
|
||||||
NOISE_DATATYPE CompBlock = m_Noise1.CubicNoise3D(NoiseX, (float) (y + Segment) / 2, NoiseY);
|
|
||||||
if (CompBlock < -0.5)
|
|
||||||
{
|
|
||||||
Block = E_BLOCK_SOULSAND;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Block = E_BLOCK_NETHERRACK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
a_ChunkDesc.SetBlockType(x, y + Segment, z, Block);
|
a_ChunkDesc.SetBlockType(x, y + Segment, z, Block);
|
||||||
}
|
}
|
||||||
|
@ -324,7 +314,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:
|
||||||
CeilingDisguise = -CeilingDisguise;
|
CeilingDisguise = -CeilingDisguise;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CeilingDisguiseHeight = Height - 2 - (int)CeilingDisguise * 3;
|
int CeilingDisguiseHeight = Height - 2 - FloorC(CeilingDisguise * 3);
|
||||||
|
|
||||||
for (int y = Height - 1; y > CeilingDisguiseHeight; y--)
|
for (int y = Height - 1; y > CeilingDisguiseHeight; y--)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
|
|
||||||
// Fill the rest with stone:
|
// Fill the rest with stone:
|
||||||
static BlockInfo Stone = {E_BLOCK_STONE, 0};
|
static BlockInfo Stone = {E_BLOCK_STONE, 0};
|
||||||
for (size_t i = a_Count; i < cChunkDef::Height; i++)
|
for (int i = static_cast<int>(a_Count); i < cChunkDef::Height; i++)
|
||||||
{
|
{
|
||||||
m_Pattern[i] = Stone;
|
m_Pattern[i] = Stone;
|
||||||
}
|
}
|
||||||
|
|
|
@ -570,6 +570,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||||
GridSize, MaxOffset
|
GridSize, MaxOffset
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
else if (NoCaseCompare(*itr, "SoulsandRims") == 0)
|
||||||
|
{
|
||||||
|
m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSoulsandRims(Seed)));
|
||||||
|
}
|
||||||
else if (NoCaseCompare(*itr, "Snow") == 0)
|
else if (NoCaseCompare(*itr, "Snow") == 0)
|
||||||
{
|
{
|
||||||
m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow));
|
m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow));
|
||||||
|
|
|
@ -122,6 +122,8 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
|
||||||
cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr 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_CurChunkX(0x7fffffff), // Set impossible coords for the chunk so that it's always considered stale
|
||||||
|
m_CurChunkZ(0x7fffffff),
|
||||||
m_BiomeGen(a_BiomeGen),
|
m_BiomeGen(a_BiomeGen),
|
||||||
m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)),
|
m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)),
|
||||||
m_HeightGen(m_UnderlyingHeiGen, 64),
|
m_HeightGen(m_UnderlyingHeiGen, 64),
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "DungeonRoomsFinisher.h"
|
#include "DungeonRoomsFinisher.h"
|
||||||
#include "../FastRandom.h"
|
#include "../FastRandom.h"
|
||||||
#include "../BlockEntities/ChestEntity.h"
|
#include "../BlockEntities/ChestEntity.h"
|
||||||
|
#include "../BlockEntities/MobSpawnerEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +58,22 @@ public:
|
||||||
int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions;
|
int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions;
|
||||||
m_Chest1 = DecodeChestCoords(FirstChestPos, SizeX, SizeZ);
|
m_Chest1 = DecodeChestCoords(FirstChestPos, SizeX, SizeZ);
|
||||||
m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ);
|
m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ);
|
||||||
|
|
||||||
|
// Choose what the mobspawner will spawn.
|
||||||
|
// 25% chance for a spider, 25% for a skeleton and 50% chance to get a zombie spawer.
|
||||||
|
int MobType = (a_Noise.IntNoise3DInt(a_OriginX, m_FloorHeight, a_OriginZ) / 7) % 100;
|
||||||
|
if (MobType <= 25)
|
||||||
|
{
|
||||||
|
m_MonsterType = mtSkeleton;
|
||||||
|
}
|
||||||
|
else if (MobType <= 50)
|
||||||
|
{
|
||||||
|
m_MonsterType = mtSpider;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_MonsterType = mtZombie;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -76,6 +93,8 @@ protected:
|
||||||
/** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */
|
/** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */
|
||||||
Vector3i m_Chest2;
|
Vector3i m_Chest2;
|
||||||
|
|
||||||
|
/** The monster type for the mobspawner entity. */
|
||||||
|
eMonsterType m_MonsterType;
|
||||||
|
|
||||||
|
|
||||||
/** Decodes the position index along the room walls into a proper 2D position for a chest.
|
/** Decodes the position index along the room walls into a proper 2D position for a chest.
|
||||||
|
@ -246,7 +265,9 @@ protected:
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0);
|
a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0);
|
||||||
// TODO: Set the spawned mob
|
cMobSpawnerEntity * MobSpawner = static_cast<cMobSpawnerEntity *>(a_ChunkDesc.GetBlockEntity(CenterX, b, CenterZ));
|
||||||
|
ASSERT((MobSpawner != nullptr) && (MobSpawner->GetBlockType() == E_BLOCK_MOB_SPAWNER));
|
||||||
|
MobSpawner->SetEntity(m_MonsterType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
|
|
@ -65,7 +65,7 @@ void cFinishGenNetherClumpFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose what block to use.
|
// Choose what block to use.
|
||||||
NOISE_DATATYPE BlockType = m_Noise.IntNoise3D((int) ChunkX, y, (int) ChunkZ);
|
NOISE_DATATYPE BlockType = m_Noise.IntNoise3D((int) ChunkX, y, (int) ChunkZ);
|
||||||
if (BlockType < -0.7)
|
if (BlockType < -0.7)
|
||||||
|
@ -195,10 +195,10 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the top block + 1. This is the place where the grass would finaly be placed:
|
// Get the top block + 1. This is the place where the grass would finaly be placed:
|
||||||
int y = a_ChunkDesc.GetHeight(x, z) + 1;
|
int y = a_ChunkDesc.GetHeight(x, z) + 1;
|
||||||
|
|
||||||
if (y >= 255)
|
if (y >= 255)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -281,7 +281,7 @@ bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All conditions met, place a sugarcane here:
|
// All conditions met, place a sugarcane here:
|
||||||
a_ChunkDesc.SetBlockType(a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE);
|
a_ChunkDesc.SetBlockType(a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE);
|
||||||
return true;
|
return true;
|
||||||
|
@ -294,7 +294,7 @@ bool cFinishGenSprinkleFoliage::TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_
|
||||||
void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
|
void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
{
|
{
|
||||||
// Generate small foliage (1-block):
|
// Generate small foliage (1-block):
|
||||||
|
|
||||||
// TODO: Update heightmap with 1-block-tall foliage
|
// TODO: Update heightmap with 1-block-tall foliage
|
||||||
for (int z = 0; z < cChunkDef::Width; z++)
|
for (int z = 0; z < cChunkDef::Width; z++)
|
||||||
{
|
{
|
||||||
|
@ -319,7 +319,7 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
// WEIRD, since we're using heightmap, so there should NOT be anything above it
|
// WEIRD, since we're using heightmap, so there should NOT be anything above it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float xx = (float)BlockX;
|
const float xx = (float)BlockX;
|
||||||
float val1 = m_Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f);
|
float val1 = m_Noise.CubicNoise2D(xx * 0.1f, zz * 0.1f);
|
||||||
float val2 = m_Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f);
|
float val2 = m_Noise.CubicNoise2D(xx * 0.01f, zz * 0.01f);
|
||||||
|
@ -359,7 +359,7 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} // case E_BLOCK_GRASS
|
} // case E_BLOCK_GRASS
|
||||||
|
|
||||||
case E_BLOCK_SAND:
|
case E_BLOCK_SAND:
|
||||||
{
|
{
|
||||||
int y = Top + 1;
|
int y = Top + 1;
|
||||||
|
@ -391,6 +391,58 @@ void cFinishGenSprinkleFoliage::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cFinishGenSoulsandRims
|
||||||
|
|
||||||
|
void cFinishGenSoulsandRims::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
|
{
|
||||||
|
int ChunkX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
||||||
|
int ChunkZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
|
||||||
|
HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight();
|
||||||
|
|
||||||
|
for (int x = 0; x < 16; x++)
|
||||||
|
{
|
||||||
|
int xx = ChunkX + x;
|
||||||
|
for (int z = 0; z < 16; z++)
|
||||||
|
{
|
||||||
|
int zz = ChunkZ + z;
|
||||||
|
|
||||||
|
// Place soulsand rims when netherrack gets thin
|
||||||
|
for (int y = 2; y < MaxHeight - 2; y++)
|
||||||
|
{
|
||||||
|
// The current block is air. Let's bail ut.
|
||||||
|
BLOCKTYPE Block = a_ChunkDesc.GetBlockType(x, y, z);
|
||||||
|
if (Block == E_BLOCK_AIR)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
((a_ChunkDesc.GetBlockType(x, y + 1, z) != E_BLOCK_AIR) &&
|
||||||
|
( a_ChunkDesc.GetBlockType(x, y + 2, z) != E_BLOCK_AIR)) ||
|
||||||
|
((a_ChunkDesc.GetBlockType(x, y - 1, z) != E_BLOCK_AIR) &&
|
||||||
|
( a_ChunkDesc.GetBlockType(x, y - 2, z) != E_BLOCK_AIR))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(xx)) / 32;
|
||||||
|
NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(zz)) / 32;
|
||||||
|
NOISE_DATATYPE CompBlock = m_Noise.CubicNoise3D(NoiseX, (float) (y) / 4, NoiseY);
|
||||||
|
if (CompBlock < 0)
|
||||||
|
{
|
||||||
|
a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SOULSAND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cFinishGenSnow:
|
// cFinishGenSnow:
|
||||||
|
|
||||||
|
@ -516,7 +568,7 @@ void cFinishGenSingleTopBlock::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
int Height = a_ChunkDesc.GetHeight(x, z);
|
int Height = a_ChunkDesc.GetHeight(x, z);
|
||||||
if (Height >= cChunkDef::Height)
|
if (Height >= cChunkDef::Height - 1)
|
||||||
{
|
{
|
||||||
// Too high up
|
// Too high up
|
||||||
continue;
|
continue;
|
||||||
|
@ -716,7 +768,7 @@ void cFinishGenPreSimulator::StationarizeFluid(
|
||||||
} // for y
|
} // for y
|
||||||
} // for x
|
} // for x
|
||||||
} // for z
|
} // for z
|
||||||
|
|
||||||
// Turn fluid at the chunk edges into non-stationary fluid:
|
// Turn fluid at the chunk edges into non-stationary fluid:
|
||||||
for (int y = 0; y < cChunkDef::Height; y++)
|
for (int y = 0; y < cChunkDef::Height; y++)
|
||||||
{
|
{
|
||||||
|
@ -808,12 +860,12 @@ void cFinishGenFluidSprings::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||||
// Not in this chunk
|
// Not in this chunk
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the height at which to try:
|
// Get the height at which to try:
|
||||||
int Height = m_Noise.IntNoise3DInt(128 * a_ChunkDesc.GetChunkX(), 1024, 256 * a_ChunkDesc.GetChunkZ()) / 11;
|
int Height = m_Noise.IntNoise3DInt(128 * a_ChunkDesc.GetChunkX(), 1024, 256 * a_ChunkDesc.GetChunkZ()) / 11;
|
||||||
Height %= m_HeightDistribution.GetSum();
|
Height %= m_HeightDistribution.GetSum();
|
||||||
Height = m_HeightDistribution.MapValue(Height);
|
Height = m_HeightDistribution.MapValue(Height);
|
||||||
|
|
||||||
// Try adding the spring at the height, if unsuccessful, move lower:
|
// Try adding the spring at the height, if unsuccessful, move lower:
|
||||||
for (int y = Height; y > 1; y--)
|
for (int y = Height; y > 1; y--)
|
||||||
{
|
{
|
||||||
|
@ -851,7 +903,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
|
@ -882,7 +934,7 @@ bool cFinishGenFluidSprings::TryPlaceSpring(cChunkDesc & a_ChunkDesc, int x, int
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has exactly one air neighbor, place a spring:
|
// Has exactly one air neighbor, place a spring:
|
||||||
a_ChunkDesc.SetBlockTypeMeta(x, y, z, m_Fluid, 0);
|
a_ChunkDesc.SetBlockTypeMeta(x, y, z, m_Fluid, 0);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -117,19 +117,38 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cFinishGenSoulsandRims :
|
||||||
|
public cFinishGen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cFinishGenSoulsandRims(int a_Seed) :
|
||||||
|
m_Noise(a_Seed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cNoise m_Noise;
|
||||||
|
|
||||||
|
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cFinishGenSprinkleFoliage :
|
class cFinishGenSprinkleFoliage :
|
||||||
public cFinishGen
|
public cFinishGen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFinishGenSprinkleFoliage(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {}
|
cFinishGenSprinkleFoliage(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cNoise m_Noise;
|
cNoise m_Noise;
|
||||||
int m_Seed;
|
int m_Seed;
|
||||||
|
|
||||||
/// Tries to place sugarcane at the coords specified, returns true if successful
|
/// Tries to place sugarcane at the coords specified, returns true if successful
|
||||||
bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ);
|
bool TryAddSugarcane(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelY, int a_RelZ);
|
||||||
|
|
||||||
// cFinishGen override:
|
// cFinishGen override:
|
||||||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
||||||
} ;
|
} ;
|
||||||
|
@ -167,31 +186,31 @@ public:
|
||||||
{
|
{
|
||||||
m_IsAllowedBelow[idx] = false;
|
m_IsAllowedBelow[idx] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the allowed blocks into m_IsAllowedBelow
|
// Load the allowed blocks into m_IsAllowedBelow
|
||||||
for (BlockList::iterator itr = a_AllowedBelow.begin(); itr != a_AllowedBelow.end(); ++itr)
|
for (BlockList::iterator itr = a_AllowedBelow.begin(); itr != a_AllowedBelow.end(); ++itr)
|
||||||
{
|
{
|
||||||
m_IsAllowedBelow[*itr] = true;
|
m_IsAllowedBelow[*itr] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize all the biome types.
|
// Initialize all the biome types.
|
||||||
for (size_t idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx)
|
for (size_t idx = 0; idx < ARRAYCOUNT(m_IsBiomeAllowed); ++idx)
|
||||||
{
|
{
|
||||||
m_IsBiomeAllowed[idx] = false;
|
m_IsBiomeAllowed[idx] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the allowed biomes into m_IsBiomeAllowed
|
// Load the allowed biomes into m_IsBiomeAllowed
|
||||||
for (BiomeList::iterator itr = a_Biomes.begin(); itr != a_Biomes.end(); ++itr)
|
for (BiomeList::iterator itr = a_Biomes.begin(); itr != a_Biomes.end(); ++itr)
|
||||||
{
|
{
|
||||||
m_IsBiomeAllowed[*itr] = true;
|
m_IsBiomeAllowed[*itr] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cNoise m_Noise;
|
cNoise m_Noise;
|
||||||
BLOCKTYPE m_BlockType;
|
BLOCKTYPE m_BlockType;
|
||||||
int m_Amount; ///< Relative amount of blocks to try adding. 1 = one block per 256 biome columns.
|
int m_Amount; ///< Relative amount of blocks to try adding. 1 = one block per 256 biome columns.
|
||||||
|
|
||||||
int GetNumToGen(const cChunkDef::BiomeMap & a_BiomeMap);
|
int GetNumToGen(const cChunkDef::BiomeMap & a_BiomeMap);
|
||||||
|
|
||||||
// Returns true if the given biome is a biome that is allowed.
|
// Returns true if the given biome is a biome that is allowed.
|
||||||
|
@ -206,7 +225,7 @@ protected:
|
||||||
return m_IsAllowedBelow[a_BlockBelow];
|
return m_IsAllowedBelow[a_BlockBelow];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// cFinishGen override:
|
// cFinishGen override:
|
||||||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
||||||
} ;
|
} ;
|
||||||
|
@ -223,11 +242,11 @@ public:
|
||||||
m_Level(a_Level)
|
m_Level(a_Level)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetLevel(void) const { return m_Level; }
|
int GetLevel(void) const { return m_Level; }
|
||||||
protected:
|
protected:
|
||||||
int m_Level;
|
int m_Level;
|
||||||
|
|
||||||
// cFinishGen override:
|
// cFinishGen override:
|
||||||
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
|
||||||
} ;
|
} ;
|
||||||
|
@ -241,7 +260,7 @@ class cFinishGenPreSimulator :
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFinishGenPreSimulator(bool a_PreSimulateFallingBlocks, bool a_PreSimulateWater, bool a_PreSimulateLava);
|
cFinishGenPreSimulator(bool a_PreSimulateFallingBlocks, bool a_PreSimulateWater, bool a_PreSimulateLava);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool m_PreSimulateFallingBlocks;
|
bool m_PreSimulateFallingBlocks;
|
||||||
|
@ -253,7 +272,7 @@ protected:
|
||||||
cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
|
cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
|
||||||
cChunkDef::HeightMap & a_HeightMap // Height map to update by the current data
|
cChunkDef::HeightMap & a_HeightMap // Height map to update by the current data
|
||||||
);
|
);
|
||||||
|
|
||||||
/** For each fluid block:
|
/** For each fluid block:
|
||||||
- if all surroundings are of the same fluid, makes it stationary; otherwise makes it flowing (excl. top)
|
- if all surroundings are of the same fluid, makes it stationary; otherwise makes it flowing (excl. top)
|
||||||
- all fluid on the chunk's edge is made flowing
|
- all fluid on the chunk's edge is made flowing
|
||||||
|
@ -278,7 +297,7 @@ class cFinishGenFluidSprings :
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, eDimension a_Dimension);
|
cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, eDimension a_Dimension);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
cNoise m_Noise;
|
cNoise m_Noise;
|
||||||
|
|
|
@ -20,6 +20,7 @@ in a depth-first processing. Each of the descendants will branch randomly, if no
|
||||||
#include "MineShafts.h"
|
#include "MineShafts.h"
|
||||||
#include "../Cuboid.h"
|
#include "../Cuboid.h"
|
||||||
#include "../BlockEntities/ChestEntity.h"
|
#include "../BlockEntities/ChestEntity.h"
|
||||||
|
#include "../BlockEntities/MobSpawnerEntity.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -875,7 +876,9 @@ void cMineShaftCorridor::PlaceSpawner(cChunkDesc & a_ChunkDesc)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
a_ChunkDesc.SetBlockTypeMeta(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ, E_BLOCK_MOB_SPAWNER, 0);
|
a_ChunkDesc.SetBlockTypeMeta(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ, E_BLOCK_MOB_SPAWNER, 0);
|
||||||
// TODO: The spawner needs its accompanying cMobSpawnerEntity, when implemented
|
cMobSpawnerEntity * MobSpawner = static_cast<cMobSpawnerEntity *>(a_ChunkDesc.GetBlockEntity(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ));
|
||||||
|
ASSERT((MobSpawner != nullptr) && (MobSpawner->GetBlockType() == E_BLOCK_MOB_SPAWNER));
|
||||||
|
MobSpawner->SetEntity(mtCaveSpider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -528,7 +528,9 @@ cBiomalNoise3DComposable::cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_Bi
|
||||||
m_DensityNoiseA(a_Seed + 1),
|
m_DensityNoiseA(a_Seed + 1),
|
||||||
m_DensityNoiseB(a_Seed + 2),
|
m_DensityNoiseB(a_Seed + 2),
|
||||||
m_BaseNoise(a_Seed + 3),
|
m_BaseNoise(a_Seed + 3),
|
||||||
m_BiomeGen(a_BiomeGen)
|
m_BiomeGen(a_BiomeGen),
|
||||||
|
m_LastChunkX(0x7fffffff), // Set impossible coords for the chunk so that it's always considered stale
|
||||||
|
m_LastChunkZ(0x7fffffff)
|
||||||
{
|
{
|
||||||
// Generate the weight distribution for summing up neighboring biomes:
|
// Generate the weight distribution for summing up neighboring biomes:
|
||||||
m_WeightSum = 0;
|
m_WeightSum = 0;
|
||||||
|
|
|
@ -263,6 +263,7 @@ template class SizeChecker<UInt16, 2>;
|
||||||
#include "OSSupport/Event.h"
|
#include "OSSupport/Event.h"
|
||||||
#include "OSSupport/File.h"
|
#include "OSSupport/File.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "OSSupport/StackTrace.h"
|
||||||
#else
|
#else
|
||||||
// Logging functions
|
// Logging functions
|
||||||
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);
|
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);
|
||||||
|
@ -348,14 +349,14 @@ void inline LOGD(const char* a_Format, ...)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), assert(0), 0))
|
#define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), PrintStackTrace(), assert(0), 0))
|
||||||
#else
|
#else
|
||||||
#define ASSERT(x) ((void)(x))
|
#define ASSERT(x) ((void)(x))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Pretty much the same as ASSERT() but stays in Release builds
|
// Pretty much the same as ASSERT() but stays in Release builds
|
||||||
#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0))
|
#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), PrintStackTrace(), exit(1), 0))
|
||||||
|
|
||||||
// Same as assert but in all Self test builds
|
// Same as assert but in all Self test builds
|
||||||
#ifdef SELF_TEST
|
#ifdef SELF_TEST
|
||||||
|
|
|
@ -126,8 +126,9 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
|
||||||
|
|
||||||
bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome)
|
bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome)
|
||||||
{
|
{
|
||||||
|
cFastRandom Random;
|
||||||
BLOCKTYPE TargetBlock = E_BLOCK_AIR;
|
BLOCKTYPE TargetBlock = E_BLOCK_AIR;
|
||||||
if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock))
|
if (a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock))
|
||||||
{
|
{
|
||||||
if ((a_RelY + 1 > cChunkDef::Height) || (a_RelY - 1 < 0))
|
if ((a_RelY + 1 > cChunkDef::Height) || (a_RelY - 1 < 0))
|
||||||
{
|
{
|
||||||
|
@ -177,7 +178,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
|
||||||
(BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) || (BlockBelow == E_BLOCK_NEW_LEAVES)
|
(BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) || (BlockBelow == E_BLOCK_NEW_LEAVES)
|
||||||
) &&
|
) &&
|
||||||
(a_RelY >= 62) &&
|
(a_RelY >= 62) &&
|
||||||
(m_Random.NextInt(3, a_Biome) != 0)
|
(Random.NextInt(3, a_Biome) != 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +239,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
|
||||||
(!cBlockInfo::IsTransparent(BlockBelow)) &&
|
(!cBlockInfo::IsTransparent(BlockBelow)) &&
|
||||||
(SkyLight <= 7) &&
|
(SkyLight <= 7) &&
|
||||||
(BlockLight <= 7) &&
|
(BlockLight <= 7) &&
|
||||||
(m_Random.NextInt(2, a_Biome) == 0)
|
(Random.NextInt(2, a_Biome) == 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +263,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
|
||||||
(TargetBlock == E_BLOCK_AIR) &&
|
(TargetBlock == E_BLOCK_AIR) &&
|
||||||
(BlockAbove == E_BLOCK_AIR) &&
|
(BlockAbove == E_BLOCK_AIR) &&
|
||||||
(!cBlockInfo::IsTransparent(BlockBelow)) &&
|
(!cBlockInfo::IsTransparent(BlockBelow)) &&
|
||||||
(m_Random.NextInt(20, a_Biome) == 0)
|
(Random.NextInt(20, a_Biome) == 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +285,19 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case mtMooshroom:
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(TargetBlock == E_BLOCK_AIR) &&
|
||||||
|
(BlockAbove == E_BLOCK_AIR) &&
|
||||||
|
(BlockBelow == E_BLOCK_MYCELIUM) &&
|
||||||
|
(
|
||||||
|
(a_Biome == biMushroomShore) ||
|
||||||
|
(a_Biome == biMushroomIsland)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -322,8 +336,8 @@ cMonster* cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY,
|
||||||
|
|
||||||
// Make sure we are looking at the right chunk to spawn in
|
// Make sure we are looking at the right chunk to spawn in
|
||||||
a_Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ);
|
a_Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ);
|
||||||
|
|
||||||
if (CanSpawnHere(a_Chunk, a_RelX, a_RelY, a_RelZ, m_MobType, a_Biome))
|
if ((m_AllowedTypes.find(m_MobType) != m_AllowedTypes.end()) && CanSpawnHere(a_Chunk, a_RelX, a_RelY, a_RelZ, m_MobType, a_Biome))
|
||||||
{
|
{
|
||||||
cMonster * newMob = cMonster::NewMonsterFromType(m_MobType);
|
cMonster * newMob = cMonster::NewMonsterFromType(m_MobType);
|
||||||
if (newMob)
|
if (newMob)
|
||||||
|
|
|
@ -51,10 +51,10 @@ public :
|
||||||
typedef const std::set<cMonster *> tSpawnedContainer;
|
typedef const std::set<cMonster *> tSpawnedContainer;
|
||||||
tSpawnedContainer & getSpawned(void);
|
tSpawnedContainer & getSpawned(void);
|
||||||
|
|
||||||
protected :
|
/** Returns true if specified type of mob can spawn on specified block */
|
||||||
// return true if specified type of mob can spawn on specified block
|
static bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome);
|
||||||
bool CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, eMonsterType a_MobType, EMCSBiome a_Biome);
|
|
||||||
|
|
||||||
|
protected :
|
||||||
// return a random type that can spawn on specified biome.
|
// return a random type that can spawn on specified biome.
|
||||||
// returns E_ENTITY_TYPE_DONOTUSE if none is possible
|
// returns E_ENTITY_TYPE_DONOTUSE if none is possible
|
||||||
eMonsterType ChooseMobType(EMCSBiome a_Biome);
|
eMonsterType ChooseMobType(EMCSBiome a_Biome);
|
||||||
|
@ -62,7 +62,6 @@ protected :
|
||||||
// add toAdd inside toAddIn, if toAdd is in m_AllowedTypes
|
// add toAdd inside toAddIn, if toAdd is in m_AllowedTypes
|
||||||
void addIfAllowed(eMonsterType toAdd, std::set<eMonsterType> & toAddIn);
|
void addIfAllowed(eMonsterType toAdd, std::set<eMonsterType> & toAddIn);
|
||||||
|
|
||||||
protected :
|
|
||||||
cMonster::eFamily m_MonsterFamily;
|
cMonster::eFamily m_MonsterFamily;
|
||||||
std::set<eMonsterType> m_AllowedTypes;
|
std::set<eMonsterType> m_AllowedTypes;
|
||||||
bool m_NewPack;
|
bool m_NewPack;
|
||||||
|
|
|
@ -20,57 +20,49 @@
|
||||||
/** Map for eType <-> string
|
/** Map for eType <-> string
|
||||||
Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType()
|
Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType()
|
||||||
The strings need to be lowercase (for more efficient comparisons in StringToMobType())
|
The strings need to be lowercase (for more efficient comparisons in StringToMobType())
|
||||||
|
m_VanillaName is the name that vanilla use for this mob.
|
||||||
*/
|
*/
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
eMonsterType m_Type;
|
eMonsterType m_Type;
|
||||||
const char * m_lcName;
|
const char * m_lcName;
|
||||||
|
const char * m_VanillaName;
|
||||||
} g_MobTypeNames[] =
|
} g_MobTypeNames[] =
|
||||||
{
|
{
|
||||||
{mtBat, "bat"},
|
{mtBat, "bat", "Bat"},
|
||||||
{mtBlaze, "blaze"},
|
{mtBlaze, "blaze", "Blaze"},
|
||||||
{mtCaveSpider, "cavespider"},
|
{mtCaveSpider, "cavespider", "CaveSpider"},
|
||||||
{mtChicken, "chicken"},
|
{mtChicken, "chicken", "Chicken"},
|
||||||
{mtCow, "cow"},
|
{mtCow, "cow", "Cow"},
|
||||||
{mtCreeper, "creeper"},
|
{mtCreeper, "creeper", "Creeper"},
|
||||||
{mtEnderman, "enderman"},
|
{mtEnderman, "enderman", "Enderman"},
|
||||||
{mtEnderDragon, "enderdragon"},
|
{mtEnderDragon, "enderdragon", "EnderDragon"},
|
||||||
{mtGhast, "ghast"},
|
{mtGhast, "ghast", "Ghast"},
|
||||||
{mtHorse, "horse"},
|
{mtHorse, "horse", "EntityHorse"},
|
||||||
{mtIronGolem, "irongolem"},
|
{mtIronGolem, "irongolem", "VillagerGolem"},
|
||||||
{mtMagmaCube, "magmacube"},
|
{mtMagmaCube, "magmacube", "LavaSlime"},
|
||||||
{mtMooshroom, "mooshroom"},
|
{mtMooshroom, "mooshroom", "MushroomCow"},
|
||||||
{mtOcelot, "ocelot"},
|
{mtOcelot, "ocelot", "Ozelot"},
|
||||||
{mtPig, "pig"},
|
{mtPig, "pig", "Pig"},
|
||||||
{mtSheep, "sheep"},
|
{mtSheep, "sheep", "Sheep"},
|
||||||
{mtSilverfish, "silverfish"},
|
{mtSilverfish, "silverfish", "Silverfish"},
|
||||||
{mtSkeleton, "skeleton"},
|
{mtSkeleton, "skeleton", "Skeleton"},
|
||||||
{mtSlime, "slime"},
|
{mtSlime, "slime", "Slime"},
|
||||||
{mtSnowGolem, "snowgolem"},
|
{mtSnowGolem, "snowgolem", "SnowMan"},
|
||||||
{mtSpider, "spider"},
|
{mtSpider, "spider", "Spider"},
|
||||||
{mtSquid, "squid"},
|
{mtSquid, "squid", "Squid"},
|
||||||
{mtVillager, "villager"},
|
{mtVillager, "villager", "Villager"},
|
||||||
{mtWitch, "witch"},
|
{mtWitch, "witch", "Witch"},
|
||||||
{mtWither, "wither"},
|
{mtWither, "wither", "WitherBoss"},
|
||||||
{mtWolf, "wolf"},
|
{mtWolf, "wolf", "Wolf"},
|
||||||
{mtZombie, "zombie"},
|
{mtZombie, "zombie", "Zombie"},
|
||||||
{mtZombiePigman, "zombiepigman"},
|
{mtZombiePigman, "zombiepigman", "PigZombie"},
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
eMonsterType StringToMobType(const AString & a_MobString)
|
|
||||||
{
|
|
||||||
LOGWARNING("%s: Function is obsolete, use cMonster::StringToMobType() instead", __FUNCTION__);
|
|
||||||
return cMonster::StringToMobType(a_MobString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cMonster:
|
// cMonster:
|
||||||
|
|
||||||
|
@ -783,39 +775,47 @@ AString cMonster::MobTypeToString(eMonsterType a_MobType)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AString cMonster::MobTypeToVanillaName(eMonsterType a_MobType)
|
||||||
|
{
|
||||||
|
// Mob types aren't sorted, so we need to search linearly:
|
||||||
|
for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++)
|
||||||
|
{
|
||||||
|
if (g_MobTypeNames[i].m_Type == a_MobType)
|
||||||
|
{
|
||||||
|
return g_MobTypeNames[i].m_VanillaName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
eMonsterType cMonster::StringToMobType(const AString & a_Name)
|
eMonsterType cMonster::StringToMobType(const AString & a_Name)
|
||||||
{
|
{
|
||||||
AString lcName = StrToLower(a_Name);
|
AString lcName = StrToLower(a_Name);
|
||||||
|
|
||||||
// Binary-search for the lowercase name:
|
// Search MCServer name:
|
||||||
int lo = 0, hi = ARRAYCOUNT(g_MobTypeNames) - 1;
|
for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++)
|
||||||
while (hi - lo > 1)
|
|
||||||
{
|
{
|
||||||
int mid = (lo + hi) / 2;
|
if (strcmp(g_MobTypeNames[i].m_lcName, lcName.c_str()) == 0)
|
||||||
int res = strcmp(g_MobTypeNames[mid].m_lcName, lcName.c_str());
|
|
||||||
if (res == 0)
|
|
||||||
{
|
{
|
||||||
return g_MobTypeNames[mid].m_Type;
|
return g_MobTypeNames[i].m_Type;
|
||||||
}
|
|
||||||
if (res < 0)
|
|
||||||
{
|
|
||||||
lo = mid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hi = mid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Range has collapsed to at most two elements, compare each:
|
|
||||||
if (strcmp(g_MobTypeNames[lo].m_lcName, lcName.c_str()) == 0)
|
// Not found. Search Vanilla name:
|
||||||
|
for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++)
|
||||||
{
|
{
|
||||||
return g_MobTypeNames[lo].m_Type;
|
if (strcmp(StrToLower(g_MobTypeNames[i].m_VanillaName).c_str(), lcName.c_str()) == 0)
|
||||||
|
{
|
||||||
|
return g_MobTypeNames[i].m_Type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((lo != hi) && (strcmp(g_MobTypeNames[hi].m_lcName, lcName.c_str()) == 0))
|
|
||||||
{
|
|
||||||
return g_MobTypeNames[hi].m_Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found:
|
// Not found:
|
||||||
return mtInvalidType;
|
return mtInvalidType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
virtual bool ReachedDestination(void);
|
virtual bool ReachedDestination(void);
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
eMonsterType GetMobType(void) const {return m_MobType; }
|
eMonsterType GetMobType(void) const { return m_MobType; }
|
||||||
eFamily GetMobFamily(void) const;
|
eFamily GetMobFamily(void) const;
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
@ -133,16 +133,19 @@ public:
|
||||||
If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name. */
|
If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name. */
|
||||||
void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible);
|
void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible);
|
||||||
|
|
||||||
/// Translates MobType enum to a string, empty string if unknown
|
/** Translates MobType enum to a string, empty string if unknown */
|
||||||
static AString MobTypeToString(eMonsterType a_MobType);
|
static AString MobTypeToString(eMonsterType a_MobType);
|
||||||
|
|
||||||
/// Translates MobType string to the enum, mtInvalidType if not recognized
|
/** Translates MobType enum to the vanilla name of the mob, empty string if unknown. */
|
||||||
|
static AString MobTypeToVanillaName(eMonsterType a_MobType);
|
||||||
|
|
||||||
|
/** Translates MobType string to the enum, mtInvalidType if not recognized */
|
||||||
static eMonsterType StringToMobType(const AString & a_MobTypeName);
|
static eMonsterType StringToMobType(const AString & a_MobTypeName);
|
||||||
|
|
||||||
/// Returns the mob family based on the type
|
/** Returns the mob family based on the type */
|
||||||
static eFamily FamilyFromType(eMonsterType a_MobType);
|
static eFamily FamilyFromType(eMonsterType a_MobType);
|
||||||
|
|
||||||
/// Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family
|
/** Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family */
|
||||||
static int GetSpawnDelay(cMonster::eFamily a_MobFamily);
|
static int GetSpawnDelay(cMonster::eFamily a_MobFamily);
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/// This identifies individual monster type, as well as their network type-ID
|
/// This identifies individual monster type, as well as their network type-ID
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
enum eMonsterType
|
enum eMonsterType
|
||||||
{
|
{
|
||||||
|
@ -38,15 +39,6 @@ enum eMonsterType
|
||||||
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
|
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Translates a mob string ("ocelot") to mobtype (mtOcelot).
|
|
||||||
OBSOLETE, use cMonster::StringToMobType() instead.
|
|
||||||
Implemented in Monster.cpp. */
|
|
||||||
extern eMonsterType StringToMobType(const AString & a_MobString);
|
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,17 +49,17 @@ void cPig::OnRightClicked(cPlayer & a_Player)
|
||||||
a_Player.Detach();
|
a_Player.Detach();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Attachee->IsPlayer())
|
if (m_Attachee->IsPlayer())
|
||||||
{
|
{
|
||||||
// Another player is already sitting in here, cannot attach
|
// Another player is already sitting in here, cannot attach
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach whatever is sitting in this pig now:
|
// Detach whatever is sitting in this pig now:
|
||||||
m_Attachee->Detach();
|
m_Attachee->Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach the player to this pig
|
// Attach the player to this pig
|
||||||
a_Player.AttachTo(this);
|
a_Player.AttachTo(this);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ void cPig::Tick(float a_Dt, cChunk & a_Chunk)
|
||||||
|
|
||||||
|
|
||||||
bool cPig::DoTakeDamage(TakeDamageInfo & a_TDI)
|
bool cPig::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||||
{
|
{
|
||||||
if (!super::DoTakeDamage(a_TDI))
|
if (!super::DoTakeDamage(a_TDI))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -66,17 +66,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the first octave directly into array:
|
// Generate the first octave directly into array:
|
||||||
const cOctave & FirstOctave = m_Octaves.front();
|
|
||||||
int ArrayCount = a_SizeX * a_SizeY;
|
int ArrayCount = a_SizeX * a_SizeY;
|
||||||
FirstOctave.m_Noise.Generate2D(
|
|
||||||
a_Workspace, a_SizeX, a_SizeY,
|
|
||||||
a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
|
|
||||||
a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
|
|
||||||
);
|
|
||||||
NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
|
|
||||||
for (int i = 0; i < ArrayCount; i++)
|
|
||||||
{
|
{
|
||||||
a_Array[i] = a_Workspace[i] * Amplitude;
|
const cOctave & FirstOctave = m_Octaves.front();
|
||||||
|
FirstOctave.m_Noise.Generate2D(
|
||||||
|
a_Workspace, a_SizeX, a_SizeY,
|
||||||
|
a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
|
||||||
|
a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
|
||||||
|
);
|
||||||
|
NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
|
||||||
|
for (int i = 0; i < ArrayCount; i++)
|
||||||
|
{
|
||||||
|
a_Array[i] = a_Workspace[i] * Amplitude;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add each octave:
|
// Add each octave:
|
||||||
|
@ -124,18 +126,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the first octave directly into array:
|
// Generate the first octave directly into array:
|
||||||
const cOctave & FirstOctave = m_Octaves.front();
|
|
||||||
int ArrayCount = a_SizeX * a_SizeY * a_SizeZ;
|
int ArrayCount = a_SizeX * a_SizeY * a_SizeZ;
|
||||||
FirstOctave.m_Noise.Generate3D(
|
|
||||||
a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
|
|
||||||
a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
|
|
||||||
a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
|
|
||||||
a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
|
|
||||||
);
|
|
||||||
NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
|
|
||||||
for (int i = 0; i < ArrayCount; i++)
|
|
||||||
{
|
{
|
||||||
a_Array[i] = a_Workspace[i] * Amplitude;
|
const cOctave & FirstOctave = m_Octaves.front();
|
||||||
|
FirstOctave.m_Noise.Generate3D(
|
||||||
|
a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
|
||||||
|
a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
|
||||||
|
a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
|
||||||
|
a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
|
||||||
|
);
|
||||||
|
NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
|
||||||
|
for (int i = 0; i < ArrayCount; i++)
|
||||||
|
{
|
||||||
|
a_Array[i] = a_Workspace[i] * Amplitude;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add each octave:
|
// Add each octave:
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
);
|
);
|
||||||
for (int i = 0; i < ArrayCount; i++)
|
for (int i = 0; i < ArrayCount; i++)
|
||||||
{
|
{
|
||||||
a_Array[i] = fabs(a_Array[i]);
|
a_Array[i] = std::abs(a_Array[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
);
|
);
|
||||||
for (int i = 0; i < ArrayCount; i++)
|
for (int i = 0; i < ArrayCount; i++)
|
||||||
{
|
{
|
||||||
a_Array[i] = fabs(a_Array[i]);
|
a_Array[i] = std::abs(a_Array[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ SET (SRCS
|
||||||
Semaphore.cpp
|
Semaphore.cpp
|
||||||
Socket.cpp
|
Socket.cpp
|
||||||
SocketThreads.cpp
|
SocketThreads.cpp
|
||||||
|
StackTrace.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET (HDRS
|
SET (HDRS
|
||||||
|
@ -29,6 +30,7 @@ SET (HDRS
|
||||||
Semaphore.h
|
Semaphore.h
|
||||||
Socket.h
|
Socket.h
|
||||||
SocketThreads.h
|
SocketThreads.h
|
||||||
|
StackTrace.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
// StackTrace.cpp
|
||||||
|
|
||||||
|
// Implements the functions to print current stack traces
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "StackTrace.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "../StackWalker.h"
|
||||||
|
#else
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void PrintStackTrace(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Reuse the StackWalker from the LeakFinder project already bound to MCS
|
||||||
|
// Define a subclass of the StackWalker that outputs everything to stdout
|
||||||
|
class PrintingStackWalker :
|
||||||
|
public StackWalker
|
||||||
|
{
|
||||||
|
virtual void OnOutput(LPCSTR szText) override
|
||||||
|
{
|
||||||
|
puts(szText);
|
||||||
|
}
|
||||||
|
} sw;
|
||||||
|
sw.ShowCallstack();
|
||||||
|
#else
|
||||||
|
// Use the backtrace() function to get and output the stackTrace:
|
||||||
|
// Code adapted from http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes
|
||||||
|
void * stackTrace[30];
|
||||||
|
size_t numItems = backtrace(stackTrace, ARRAYCOUNT(stackTrace));
|
||||||
|
backtrace_symbols_fd(stackTrace, numItems, STDERR_FILENO);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
// StackTrace.h
|
||||||
|
|
||||||
|
// Declares the functions to print current stack trace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Prints the stacktrace for the current thread. */
|
||||||
|
extern void PrintStackTrace(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ Implements the 1.7.x protocol classes:
|
||||||
#include "../BlockEntities/BeaconEntity.h"
|
#include "../BlockEntities/BeaconEntity.h"
|
||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../BlockEntities/MobHeadEntity.h"
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
#include "../BlockEntities/MobSpawnerEntity.h"
|
||||||
#include "../BlockEntities/FlowerPotEntity.h"
|
#include "../BlockEntities/FlowerPotEntity.h"
|
||||||
#include "Bindings/PluginManager.h"
|
#include "Bindings/PluginManager.h"
|
||||||
|
|
||||||
|
@ -2662,6 +2663,18 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
|
||||||
Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
|
Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case E_BLOCK_MOB_SPAWNER:
|
||||||
|
{
|
||||||
|
cMobSpawnerEntity & MobSpawnerEntity = (cMobSpawnerEntity &)a_BlockEntity;
|
||||||
|
|
||||||
|
Writer.AddInt("x", MobSpawnerEntity.GetPosX());
|
||||||
|
Writer.AddInt("y", MobSpawnerEntity.GetPosY());
|
||||||
|
Writer.AddInt("z", MobSpawnerEntity.GetPosZ());
|
||||||
|
Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity()));
|
||||||
|
Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay());
|
||||||
|
Writer.AddString("id", "MobSpawner");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3134,4 +3147,3 @@ void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ Implements the 1.8.x protocol classes:
|
||||||
#include "../BlockEntities/BeaconEntity.h"
|
#include "../BlockEntities/BeaconEntity.h"
|
||||||
#include "../BlockEntities/CommandBlockEntity.h"
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../BlockEntities/MobHeadEntity.h"
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
#include "../BlockEntities/MobSpawnerEntity.h"
|
||||||
#include "../BlockEntities/FlowerPotEntity.h"
|
#include "../BlockEntities/FlowerPotEntity.h"
|
||||||
#include "Bindings/PluginManager.h"
|
#include "Bindings/PluginManager.h"
|
||||||
|
|
||||||
|
@ -2972,6 +2973,18 @@ void cProtocol180::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
|
||||||
Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
|
Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case E_BLOCK_MOB_SPAWNER:
|
||||||
|
{
|
||||||
|
cMobSpawnerEntity & MobSpawnerEntity = (cMobSpawnerEntity &)a_BlockEntity;
|
||||||
|
|
||||||
|
Writer.AddInt("x", MobSpawnerEntity.GetPosX());
|
||||||
|
Writer.AddInt("y", MobSpawnerEntity.GetPosY());
|
||||||
|
Writer.AddInt("z", MobSpawnerEntity.GetPosZ());
|
||||||
|
Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity()));
|
||||||
|
Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay());
|
||||||
|
Writer.AddString("id", "MobSpawner");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ void cRoot::Start(void)
|
||||||
m_WebAdmin->Init();
|
m_WebAdmin->Init();
|
||||||
|
|
||||||
LOGD("Loading settings...");
|
LOGD("Loading settings...");
|
||||||
m_RankManager = new cRankManager();
|
m_RankManager.reset(new cRankManager());
|
||||||
m_RankManager->Initialize(m_MojangAPI);
|
m_RankManager->Initialize(m_MojangAPI);
|
||||||
m_CraftingRecipes = new cCraftingRecipes;
|
m_CraftingRecipes = new cCraftingRecipes;
|
||||||
m_FurnaceRecipe = new cFurnaceRecipe();
|
m_FurnaceRecipe = new cFurnaceRecipe();
|
||||||
|
|
|
@ -87,7 +87,7 @@ public:
|
||||||
cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export
|
cPluginManager * GetPluginManager (void) { return m_PluginManager; } // tolua_export
|
||||||
cAuthenticator & GetAuthenticator (void) { return m_Authenticator; }
|
cAuthenticator & GetAuthenticator (void) { return m_Authenticator; }
|
||||||
cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; }
|
cMojangAPI & GetMojangAPI (void) { return m_MojangAPI; }
|
||||||
cRankManager * GetRankManager (void) { return m_RankManager; }
|
cRankManager * GetRankManager (void) { return m_RankManager.get(); }
|
||||||
|
|
||||||
/** Queues a console command for execution through the cServer class.
|
/** Queues a console command for execution through the cServer class.
|
||||||
The command will be executed in the tick thread
|
The command will be executed in the tick thread
|
||||||
|
@ -189,7 +189,9 @@ private:
|
||||||
cPluginManager * m_PluginManager;
|
cPluginManager * m_PluginManager;
|
||||||
cAuthenticator m_Authenticator;
|
cAuthenticator m_Authenticator;
|
||||||
cMojangAPI m_MojangAPI;
|
cMojangAPI m_MojangAPI;
|
||||||
cRankManager * m_RankManager;
|
|
||||||
|
std::unique_ptr<cRankManager> m_RankManager;
|
||||||
|
|
||||||
cHTTPServer m_HTTPServer;
|
cHTTPServer m_HTTPServer;
|
||||||
|
|
||||||
bool m_bStop;
|
bool m_bStop;
|
||||||
|
|
|
@ -157,6 +157,8 @@ protected:
|
||||||
if (m_NumPrepared >= m_MaxIdx)
|
if (m_NumPrepared >= m_MaxIdx)
|
||||||
{
|
{
|
||||||
m_EvtFinished.Set();
|
m_EvtFinished.Set();
|
||||||
|
// Must return here, because "this" may have gotten deleted by the previous line
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue another chunk, if appropriate:
|
// Queue another chunk, if appropriate:
|
||||||
|
@ -602,7 +604,7 @@ void cWorld::Start(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the enum-backed variables into their respective bounds:
|
// Adjust the enum-backed variables into their respective bounds:
|
||||||
m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmAdventure);
|
m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmSpectator);
|
||||||
m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll);
|
m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll);
|
||||||
m_Weather = (eWeather) Clamp(Weather, (int)wSunny, (int)wStorm);
|
m_Weather = (eWeather) Clamp(Weather, (int)wSunny, (int)wStorm);
|
||||||
|
|
||||||
|
@ -747,7 +749,7 @@ void cWorld::InitialiseGeneratorDefaults(cIniFile & a_IniFile)
|
||||||
a_IniFile.GetValueSet("Generator", "HeightGen", "Flat");
|
a_IniFile.GetValueSet("Generator", "HeightGen", "Flat");
|
||||||
a_IniFile.GetValueSet("Generator", "FlatHeight", "128");
|
a_IniFile.GetValueSet("Generator", "FlatHeight", "128");
|
||||||
a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether");
|
a_IniFile.GetValueSet("Generator", "CompositionGen", "Nether");
|
||||||
a_IniFile.GetValueSet("Generator", "Finishers", "WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator");
|
a_IniFile.GetValueSet("Generator", "Finishers", "SoulsandRims, WormNestCaves, BottomLava, LavaSprings, NetherClumpFoliage, NetherForts, PreSimulator");
|
||||||
a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30");
|
a_IniFile.GetValueSet("Generator", "BottomLavaHeight", "30");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2668,7 +2670,7 @@ bool cWorld::ForEachPlayer(cPlayerListCallback & a_Callback)
|
||||||
|
|
||||||
bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback)
|
||||||
{
|
{
|
||||||
// Calls the callback for each player in the list
|
// Calls the callback for the specified player in the list
|
||||||
cCSLock Lock(m_CSPlayers);
|
cCSLock Lock(m_CSPlayers);
|
||||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -315,7 +315,8 @@ public:
|
||||||
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
|
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
|
||||||
virtual bool ForEachPlayer(cPlayerListCallback & a_Callback) override; // >> EXPORTED IN MANUALBINDINGS <<
|
virtual bool ForEachPlayer(cPlayerListCallback & a_Callback) override; // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found. Callback return ignored */
|
/** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found.
|
||||||
|
Callback return value is ignored. If there are multiple players of the same name, only (random) one is processed by the callback. */
|
||||||
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||||
|
|
||||||
/** Finds a player from a partial or complete player name and calls the callback - case-insensitive */
|
/** Finds a player from a partial or complete player name and calls the callback - case-insensitive */
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
#include "../BlockEntities/HopperEntity.h"
|
#include "../BlockEntities/HopperEntity.h"
|
||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
|
#include "../BlockEntities/MobSpawnerEntity.h"
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
#include "../BlockEntities/SignEntity.h"
|
#include "../BlockEntities/SignEntity.h"
|
||||||
#include "../BlockEntities/MobHeadEntity.h"
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
@ -290,6 +291,20 @@ void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cNBTChunkSerializer::AddMobSpawnerEntity(cMobSpawnerEntity * a_MobSpawner)
|
||||||
|
{
|
||||||
|
m_Writer.BeginCompound("");
|
||||||
|
AddBasicTileEntity(a_MobSpawner, "MobSpawner");
|
||||||
|
m_Writer.AddShort("Entity", static_cast<short>(a_MobSpawner->GetEntity()));
|
||||||
|
m_Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(a_MobSpawner->GetEntity()));
|
||||||
|
m_Writer.AddShort("Delay", a_MobSpawner->GetSpawnDelay());
|
||||||
|
m_Writer.EndCompound();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note)
|
void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note)
|
||||||
{
|
{
|
||||||
m_Writer.BeginCompound("");
|
m_Writer.BeginCompound("");
|
||||||
|
@ -914,6 +929,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
|
||||||
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
|
||||||
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
||||||
case E_BLOCK_LIT_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
|
case E_BLOCK_LIT_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
|
||||||
|
case E_BLOCK_MOB_SPAWNER: AddMobSpawnerEntity ((cMobSpawnerEntity *) a_Entity); break;
|
||||||
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
||||||
case E_BLOCK_SIGN_POST: AddSignEntity ((cSignEntity *) a_Entity); break;
|
case E_BLOCK_SIGN_POST: AddSignEntity ((cSignEntity *) a_Entity); break;
|
||||||
case E_BLOCK_TRAPPED_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break;
|
case E_BLOCK_TRAPPED_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break;
|
||||||
|
|
|
@ -32,6 +32,7 @@ class cJukeboxEntity;
|
||||||
class cNoteEntity;
|
class cNoteEntity;
|
||||||
class cSignEntity;
|
class cSignEntity;
|
||||||
class cMobHeadEntity;
|
class cMobHeadEntity;
|
||||||
|
class cMobSpawnerEntity;
|
||||||
class cFlowerPotEntity;
|
class cFlowerPotEntity;
|
||||||
class cFallingBlock;
|
class cFallingBlock;
|
||||||
class cMinecart;
|
class cMinecart;
|
||||||
|
@ -94,19 +95,20 @@ protected:
|
||||||
void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0);
|
void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0);
|
||||||
|
|
||||||
// Block entities:
|
// Block entities:
|
||||||
void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
void AddBasicTileEntity (cBlockEntity * a_Entity, const char * a_EntityTypeID);
|
||||||
void AddBeaconEntity (cBeaconEntity * a_Entity);
|
void AddBeaconEntity (cBeaconEntity * a_Entity);
|
||||||
void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType);
|
void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType);
|
||||||
void AddDispenserEntity(cDispenserEntity * a_Entity);
|
void AddDispenserEntity (cDispenserEntity * a_Entity);
|
||||||
void AddDropperEntity (cDropperEntity * a_Entity);
|
void AddDropperEntity (cDropperEntity * a_Entity);
|
||||||
void AddFurnaceEntity (cFurnaceEntity * a_Furnace);
|
void AddFurnaceEntity (cFurnaceEntity * a_Furnace);
|
||||||
void AddHopperEntity (cHopperEntity * a_Entity);
|
void AddHopperEntity (cHopperEntity * a_Entity);
|
||||||
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
|
void AddJukeboxEntity (cJukeboxEntity * a_Jukebox);
|
||||||
void AddNoteEntity (cNoteEntity * a_Note);
|
void AddMobSpawnerEntity (cMobSpawnerEntity * a_MobSpawner);
|
||||||
void AddSignEntity (cSignEntity * a_Sign);
|
void AddNoteEntity (cNoteEntity * a_Note);
|
||||||
void AddMobHeadEntity (cMobHeadEntity * a_MobHead);
|
void AddSignEntity (cSignEntity * a_Sign);
|
||||||
|
void AddMobHeadEntity (cMobHeadEntity * a_MobHead);
|
||||||
void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
|
void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock);
|
||||||
void AddFlowerPotEntity(cFlowerPotEntity * a_FlowerPot);
|
void AddFlowerPotEntity (cFlowerPotEntity * a_FlowerPot);
|
||||||
|
|
||||||
// Entities:
|
// Entities:
|
||||||
void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName);
|
void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "../BlockEntities/NoteEntity.h"
|
#include "../BlockEntities/NoteEntity.h"
|
||||||
#include "../BlockEntities/SignEntity.h"
|
#include "../BlockEntities/SignEntity.h"
|
||||||
#include "../BlockEntities/MobHeadEntity.h"
|
#include "../BlockEntities/MobHeadEntity.h"
|
||||||
|
#include "../BlockEntities/MobSpawnerEntity.h"
|
||||||
#include "../BlockEntities/FlowerPotEntity.h"
|
#include "../BlockEntities/FlowerPotEntity.h"
|
||||||
|
|
||||||
#include "../Mobs/Monster.h"
|
#include "../Mobs/Monster.h"
|
||||||
|
@ -664,6 +665,7 @@ cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a
|
||||||
case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta);
|
case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta);
|
||||||
|
case E_BLOCK_MOB_SPAWNER: return LoadMobSpawnerFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ);
|
||||||
case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST);
|
case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST);
|
||||||
case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST);
|
case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST);
|
||||||
|
@ -1085,6 +1087,54 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
|
{
|
||||||
|
// Check if the data has a proper type:
|
||||||
|
if (!CheckBlockEntityType(a_NBT, a_TagIdx, "MobSpawner"))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<cMobSpawnerEntity> MobSpawner(new cMobSpawnerEntity(a_BlockX, a_BlockY, a_BlockZ, m_World));
|
||||||
|
|
||||||
|
// Load entity (MCServer worlds):
|
||||||
|
int Type = a_NBT.FindChildByName(a_TagIdx, "Entity");
|
||||||
|
if ((Type >= 0) && (a_NBT.GetType(Type) == TAG_Short))
|
||||||
|
{
|
||||||
|
short MonsterType = a_NBT.GetShort(Type);
|
||||||
|
if ((MonsterType >= 50) && (MonsterType <= 120))
|
||||||
|
{
|
||||||
|
MobSpawner->SetEntity(static_cast<eMonsterType>(MonsterType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Load entity (vanilla worlds):
|
||||||
|
Type = a_NBT.FindChildByName(a_TagIdx, "EntityId");
|
||||||
|
if ((Type >= 0) && (a_NBT.GetType(Type) == TAG_String))
|
||||||
|
{
|
||||||
|
eMonsterType MonsterType = cMonster::StringToMobType(a_NBT.GetString(Type));
|
||||||
|
if (MonsterType != eMonsterType::mtInvalidType)
|
||||||
|
{
|
||||||
|
MobSpawner->SetEntity(MonsterType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load delay:
|
||||||
|
int Delay = a_NBT.FindChildByName(a_TagIdx, "Delay");
|
||||||
|
if ((Delay >= 0) && (a_NBT.GetType(Delay) == TAG_Short))
|
||||||
|
{
|
||||||
|
MobSpawner->SetSpawnDelay(a_NBT.GetShort(Delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MobSpawner.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
{
|
{
|
||||||
// Check if the data has a proper type:
|
// Check if the data has a proper type:
|
||||||
|
@ -1807,9 +1857,10 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||||
int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile");
|
int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile");
|
||||||
if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0))
|
if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0))
|
||||||
{
|
{
|
||||||
if (a_NBT.GetType(InBlockXIdx) == a_NBT.GetType(InBlockYIdx) == a_NBT.GetType(InBlockZIdx))
|
eTagType typeX = a_NBT.GetType(InBlockXIdx);
|
||||||
|
if ((typeX == a_NBT.GetType(InBlockYIdx)) && (typeX == a_NBT.GetType(InBlockZIdx)))
|
||||||
{
|
{
|
||||||
switch (a_NBT.GetType(InBlockXIdx))
|
switch (typeX)
|
||||||
{
|
{
|
||||||
case TAG_Int:
|
case TAG_Int:
|
||||||
{
|
{
|
||||||
|
@ -1823,6 +1874,11 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
|
||||||
Arrow->SetBlockHit(Vector3i((int)a_NBT.GetShort(InBlockXIdx), (int)a_NBT.GetShort(InBlockYIdx), (int)a_NBT.GetShort(InBlockZIdx)));
|
Arrow->SetBlockHit(Vector3i((int)a_NBT.GetShort(InBlockXIdx), (int)a_NBT.GetShort(InBlockYIdx), (int)a_NBT.GetShort(InBlockZIdx)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// No hit block, the arrow is still flying?
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ protected:
|
||||||
cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||||
|
cBlockEntity * LoadMobSpawnerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
|
@ -61,6 +61,7 @@ void NonCtrlHandler(int a_Signal)
|
||||||
std::signal(SIGSEGV, SIG_DFL);
|
std::signal(SIGSEGV, SIG_DFL);
|
||||||
LOGERROR(" D: | MCServer has encountered an error and needs to close");
|
LOGERROR(" D: | MCServer has encountered an error and needs to close");
|
||||||
LOGERROR("Details | SIGSEGV: Segmentation fault");
|
LOGERROR("Details | SIGSEGV: Segmentation fault");
|
||||||
|
PrintStackTrace();
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
|
@ -71,6 +72,7 @@ void NonCtrlHandler(int a_Signal)
|
||||||
std::signal(a_Signal, SIG_DFL);
|
std::signal(a_Signal, SIG_DFL);
|
||||||
LOGERROR(" D: | MCServer has encountered an error and needs to close");
|
LOGERROR(" D: | MCServer has encountered an error and needs to close");
|
||||||
LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault");
|
LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault");
|
||||||
|
PrintStackTrace();
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
|
@ -137,6 +139,9 @@ LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_Except
|
||||||
g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : nullptr, nullptr, nullptr);
|
g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : nullptr, nullptr, nullptr);
|
||||||
CloseHandle(dumpFile);
|
CloseHandle(dumpFile);
|
||||||
|
|
||||||
|
// Print the stack trace for the basic debugging:
|
||||||
|
PrintStackTrace();
|
||||||
|
|
||||||
// Revert to old stack:
|
// Revert to old stack:
|
||||||
_asm
|
_asm
|
||||||
{
|
{
|
||||||
|
@ -182,7 +187,7 @@ int main( int argc, char **argv)
|
||||||
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
||||||
InitLeakFinder();
|
InitLeakFinder();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Magic code to produce dump-files on Windows if the server crashes:
|
// Magic code to produce dump-files on Windows if the server crashes:
|
||||||
#if defined(_WIN32) && !defined(_WIN64) && defined(_MSC_VER)
|
#if defined(_WIN32) && !defined(_WIN64) && defined(_MSC_VER)
|
||||||
HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL");
|
HINSTANCE hDbgHelp = LoadLibrary("DBGHELP.DLL");
|
||||||
|
|
Loading…
Reference in New Issue