1
0

Merge branch 'master' into MobSpawner

Conflicts:
	src/MobSpawner.h
	src/Mobs/Monster.h
This commit is contained in:
Howaner 2014-09-26 23:56:20 +02:00
commit 033d16babb
186 changed files with 10593 additions and 4070 deletions

View File

@ -1634,6 +1634,11 @@ a_Player:OpenWindow(Window);
]],
Functions =
{
HasCustomName = { Params = "", Return = "bool", Notes = "Returns true if the monster has a custom name." },
GetCustomName = { Params = "", Return = "string", Notes = "Gets the custom name of the monster. If no custom name is set, the function returns 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." },
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)" },
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)" },
@ -1759,6 +1764,7 @@ a_Player:OpenWindow(Window);
ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." },
GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." },
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player's messages (based on their rank). Prefix player messages with this code." },
GetPlayerListName = { Return = "string", Notes = "Returns the name that is used in the playerlist." },
GetCurrentXp = { Params = "", Return = "number", Notes = "Returns the current amount of XP" },
GetEffectiveGameMode = { Params = "", Return = "{{Globals#GameMode|GameMode}}", Notes = "(OBSOLETE) Returns the current resolved game mode of the player. If the player is set to inherit the world's gamemode, returns that instead. See also GetGameMode() and IsGameModeXXX() functions. Note that this function is the same as GetGameMode(), use that function instead." },
GetEquippedItem = { Params = "", Return = "{{cItem}}", Notes = "Returns the item that the player is currently holding; empty item if holding nothing." },
@ -1809,6 +1815,9 @@ a_Player:OpenWindow(Window);
SendMessagePrivateMsg = { Params = "Message, SenderName", Return = "", Notes = "Prepends Light Blue [MSG: *SenderName*] / prepends SenderName and colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For private messaging." },
SendMessageSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Success notification." },
SendMessageWarning = { Params = "Message, Sender", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Denotes that something concerning, such as plugin reload, is about to happen." },
HasCustomName = { Params = "", Return = "bool", Notes = "Returns true if the player has a custom name." },
GetCustomName = { Params = "", Return = "string", Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string." },
SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of this player. If you want to disable the custom name, simply set an empty string. The custom name will be used in the tab-list, in the player nametag and in the tab-completion." },
SetCanFly = { Params = "CanFly", Notes = "Sets if the player can fly or not." },
SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." },
SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." },

View File

@ -6,8 +6,9 @@ return
DefaultFnName = "OnSpawningEntity", -- also used as pagename
Desc = [[
This hook is called before the server spawns an {{cEntity|entity}}. The plugin can either modify the
entity before it is spawned, or disable the spawning altogether. If the entity spawning is a
monster, the {{OnSpawningMonster|HOOK_SPAWNING_MONSTER}} hook is called before this hook.</p>
entity before it is spawned, or disable the spawning altogether. You can't disable the spawning if the
entity is a player. If the entity spawning is a monster, the {{OnSpawningMonster|HOOK_SPAWNING_MONSTER}}
hook is called before this hook.</p>
<p>
See also the {{OnSpawnedEntity|HOOK_SPAWNED_ENTITY}} hook for a similar hook called after the
entity is spawned.

View File

@ -38,6 +38,7 @@ function Initialize(Plugin)
-- _X: Disabled so that the normal operation doesn't interfere with anything
-- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
PM:BindCommand("/nick", "debuggers", HandleNickCmd, "- Gives you a custom name");
PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities");
PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities");
PM:BindCommand("/wool", "debuggers", HandleWoolCmd, "- Sets all your armor to blue wool");
@ -770,6 +771,21 @@ end
function HandleNickCmd(Split, Player)
if (Split[2] == nil) then
Player:SendMessage("Usage: /nick [CustomName]");
return true;
end
Player:SetCustomName(Split[2]);
Player:SendMessageSuccess("Custom name setted to " .. Player:GetCustomName() .. "!")
return true
end
function HandleListEntitiesCmd(Split, Player)
local NumEntities = 0;

View File

@ -348,6 +348,7 @@ Emerald, 9 = EmeraldBlock, *
RedstoneDust, 9 = RedstoneBlock, *
Coal, 9 = CoalBlock, *
Clay, 4 = ClayBlock, *
SlimeBall, 9 = SlimeBlock, *
Painting = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Wool, 2:2
ItemFrame = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Leather, 2:2

View File

@ -1,5 +1,6 @@
[Items]
air=0
stone=1
rock=1
granite=1:1
polishedgranite=1:2
@ -7,7 +8,6 @@ diorite=1:3
polisheddiorite=1:4
andesite=1:5
polishedandesite=1:6
stone=1
grass=2
dirt=3
coarseddirt=3:1
@ -410,7 +410,7 @@ lightgraystainedclay=159:8
lightgreystainedclay=159:8
ltgraystainedclay=159:8
ltgreystainedclay=159:8
silvertsainedclay=159:8
silverstainedclay=159:8
cyanstainedclay=159:9
purplestainedclay=159:10
violetstainedclay=159:10
@ -471,6 +471,7 @@ darkoakwoodstairs=164
bigoakwoodstiars=164
roofedoakwoodstairs=164
slimeblock=165
barrier=166
irontrapdoor=167
prismarine=168
prismarinebricks=168:1
@ -525,7 +526,8 @@ redsandstone=179
chiseledredsandstone=179:1
smoothredsandstone=179:2
redsandstonestairs=180
redsandstoneslab=182
newstoneslab=182
redsandstoneslab=182:0
sprucefencegate=183
coniferfencegate=183
pinefencegate=183
@ -698,7 +700,11 @@ lightdust=348
glowdust=348
fish=349
rawfish=349
rawsalmon=349:1
clownfish=349:2
pufferfish=349:3
cookedfish=350
cookedsalmon=350:1
dye=351
inksac=351:0
blackdye=351:0

603
MCServer/lang/items_de.ini Normal file
View File

@ -0,0 +1,603 @@
[Items]
luft=0
stein=1
granit=1:1
poliertergranit=1:2
diorit=1:3
polierterdiorit=1:4
andesit=1:5
polierterandesit=1:6
grasblock=2
erde=3
grobeerde=3:1
podsol=3:2
bruchstein=4
holzbretter=5
eichenholzbretter=5:0
fichtenholzbretter=5:1
birkenholzbretter=5:2
tropenholzbretter=5:3
akazienholzbretter=5:4
schwarzeichenholzbretter=5:5
setzling=6
eichensetzling=6:0
fichtensetzling=6:1
birkensetzling=6:2
tropensetzling=6:3
akaziensetzling=6:4
schwarzeichensetzling=6:5
grundgestein=7
wasser=8
fliessendeswasser=8
stehendeswasser=9
stilleswasser=9
swasser=9
lava=10
fliessendelava=10
stehendelava=11
stillelava=11
slava=11
sand=12
rotersand=12:1
kies=13
golderz=14
eisenerz=15
kohleerz=16
stamm=17
eichenholz=17:0
fichtenholz=17:1
birkenholz=17:2
tropenholz=17:3
laub=18
eichenlaub=18:0
fichtenlaub=18:1
birkenlaub=18:2
tropenlaub=18:3
schwamm=19
nasserschwamm=19:1
glas=20
lapislazulierz=21
lapislazuliblock=22
werfer=23
sandstein=24
normalersandstein=24:0
gemeisseltersandstein=24:1
glattersandstein=24:2
notenblock=25
bettblock=26
antriebsschiene=27
sensorschiene=28
klebrigerkolben=29
spinnenweben=30
gras=31
gras=31:1
farn=31:2
toterbusch=32
kolben=33
kolbenkopf=34
wolle=35
weissewolle=35:0
orangenewolle=35:1
magentawolle=35:2
hellblauewolle=35:3
gelbewolle=35:4
hellgruene=35:5
rosawolle=35:6
grauwool=35:7
greywool=35:7
grauewolle=35:7
hellgrauewolle=35:8
tuerkisewolle=35:9
violettewolle=35:10
blauewolle=35:11
braunewolle=35:12
gruenewolle=35:13
rotewolle=35:14
schwarzewolle=35:15
loewenzahn=37
blume=38
mohn=38:0
blaueorchidee=38:1
sternlauch=38:2
porzellansternchen=38:3
rotetulpe=38:4
orangenetulpe=38:5
weissetulpe=38:6
rosatulpe=38:7
margerite=38:8
braunerpilz=39
roterpilz=40
goldblock=41
eisenblock=42
doppelstufe=43
doppelsteinstufe=43:0
doppelsandsteinstufe=43:1
doppelholzstufe=43:2
doppelbruchsteinstufe=43:3
doppelziegelstufe=43:4
doppelsteinziegelstufe=43:5
doppelnetherziegelstufe=43:6
doppelquarzstufe=43:7
stufe=44
steinstufe=44:0
sandsteinstufe=44:1
holzstufe=44:2
bruchsteinstufe=44:3
ziegelstufe=44:4
steinziegelstufe=44:5
netherziegelstufe=44:6
quarzstufe=44:7
ziegelsteine=45
tnt=46
buecherregal=47
bemoosterbruchstein=48
obsidian=49
fackel=50
feuer=51
monsterspawner=52
eichenholztreppe=53
kiste=54
rotstonekabel=55
diamanterz=56
diamantblock=57
werkbank=58
ernte=59
farmland=60
ofen=61
brennenderofen=62
schildblock=63
holztuerblock=64
leiter=65
schiene=66
bruchsteintreppe=67
wandschild=68
schalter=69
steindruckplatte=70
eisentuerblock=71
holzdruckplatte=72
rotstoneerz=73
leuchtendesrotstoneerz=74
erloschenerotstonefackel=75
rotstonefackel=76
setinknopf=77
schnee=78
eis=79
schneeblock=80
kaktus=81
ton=82
zuckerrohrblock=83
plattenspieler=84
eichenholzzaun=85
kuerbis=86
netherstein=87
selensand=88
leuchtstein=89
portal=90
kürbislaterne=91
kuchenlock=92
weissesglas=95
orangenesglas=95:1
magentaglas=95:2
hellblauesglas=95:3
gelbesglas=95:4
hellgruenesglas=95:5
rosagerfaerbtglas=95:6
grauesglas=95:7
hellgrauesglas=95:8
tuerkisesglas=95:9
violettesglas=95:10
blauesglas=95:11
braunesglas=95:12
gruenesglas=95:13
rotesglas=95:14
schwarzesglas=95:15
falltuer=96
silberfischblock=97
steinziegel=98
bemoostesteinziegel=98:1
rissigesteinziegel=98:2
gemeisseltesteinziegel=98:3
braunerpilzblock=99
roterpilzblock=100
eisengitter=101
glasscheibe=102
melone=103
kuerbispflanze=104
melonenpflanze=105
ranken=106
eichenholzzauntor=107
ziegeltreppe=108
steinziegeltreppe=109
myzel=110
seerosenblatt=111
netherziegel=112
netherziegelzaun=113
netherziegeltreppe=114
netherwarzenblock=115
zaubertisch=116
braustandblock=117
kesselblock=118
endportal=119
endportalrahmen=120
endstein=121
drachenei=122
redstonelampe=123
erlosscheneredstonelampe=124
doppelholzstufe=125
doppeleichenholzstufe=125:0
doppelfichtenholzstufe=125:1
doppelbirkenholzstufe=125:2
doppeltropenholzstufe=125:3
doppelakazienholzstufe=125:4
doppelschwarzeichenstufe=125:5
holzstufe=126
eichenholzstufe=126:0
fichtenholzstufe=126:1
birkenholzstufe=126:2
tropenholzstufe=126:3
akazienholzstufe=126:4
schwarzeichenholzstufe=126:5
kakaobohnen=127
sandsteintreppe=128
smaragderz=129
endertruhe=130
haken=131
stolperdraht=132
smaragdblock=133
fichtenholztreppe=134
birkenholztreppe=135
tropenholztreppe=136
kommandoblock=137
leuchtfeuer=138
bruchsteinmauer=139
bemoostebruchsteinmauer=139:1
blumentopfblock=140
karottenpflanze=141
kartoffelpflanze=142
knopf=143
skelettschaedel=144
witherskelettschaedel=144:1
zombieschaedel=144:2
schaedel=144:3
creeperschaedel=144:4
amboss=145
redstonetruhe=146
waegeplatteniedrigegewichte=147 # WTF, that names are so stupid...
waegeplattehohegewichte=148
inaktiverkomparator=149
aktiverkomparator=150
tageslichtsensor=151
redstoneblock=152
netherquarzerz=153
trichter=154
quarzblock=155
gemeisselterquarzblock=155:1
quarzsaeule=155:2
quarztreppe=156
aktivierungsschiene=157
spender=158
weissgerfaerbterton=159
orangegerfaerbterton=159:1
magentagerfaerbterton=159:2
hellblaugerfaerbterton=159:3
gelbgerfaerbterton=159:4
hellgruengerfaerbterton=159:5
rosagerfaerbterton=159:6
graugerfaerbterton=159:7
hellgraugefaerbterton=159:8
tuerkisgerfaerbterton=159:9
purplegerfaerbterton=159:10
violettegerfaerbterton=159:10
blaugerfaerbterton=159:11
braungerfaerbterton=159:12
gruengerfaerbterton=159:13
rotgerfaerbterton=159:14
schwarzgerfaerbterton=159:15
weisseglasscheibe=160
orangeneglasscheibe=160:1
magentaglasscheibe=160:2
hellblaueglasscheibe=160:3
gelbeglasscheibe=160:4
hellgrueneglasscheibe=160:5
rosaglasscheibe=160:6
graueglasscheibe=160:7
hellgraueglasscheibe=160:8
tuerkiseglasscheibe=160:9
violetteglasscheibe=160:10
blaueglasscheibe=160:11
brauneglasscheibe=160:12
grueneglasscheibe=160:13
roteglasscheibe=160:14
schwarzeglasscheibe=160:15
neueslaub=161
akazienlaub=161:0
schwarzeichenlaub=161:1
neuestaemme=162
akazienholz=162:0
schwarzeichenholz=162:1
akazientreppe=163
schwarzeichentreppe=164
schleimblock=165
bartriere=166
eisenfalltür=167
prismarin=168
prismarinziegel=168:1
dunklerprismarin=168:2
seelaterne=169
strohballen=170
teppich=171
weisserteppich=171:0
orangenerteppich=171:1
magentateppich=171:2
hellblauerteppich=171:3
gelberteppich=171:4
hellgruenerteppich=171:5
rosateppich=171:6
grauerteppich=171:7
hellgrauerteppich=171:8
tuerkiserteppich=171:9
violetterteppich=171:10
blauerteppich=171:11
braunerteppich=171:12
gruenerteppich=171:13
roterteppich=171:14
schwarzerteppich=171:15
gebrannterton=172
kohleblock=173
packeis=174
doppelpflanze=175
sonnenblume=175:0
Flieder=175:1
hohesgras=175:2
grosserfarn=175:3
rosenstrauch=175:4
pfingstrose=175:5
rotersandstein=179
gemeisselterrotersandstein=179:1
glatterrotersandstein=179:2
rotesandsteintreppe=180
neuesteinstufe=182
rotesandsteinstufe=182:0
fichtenzauntor=183
birkenzauntor=184
tropenzauntor=185
schwarzeichenzauntor=186
akazienzauntor=187
fichtenzaun=188
birkenzaun=189
tropenzaun=190
schwarzeichenzaun=191
akazienzaun=192
eisenschaufel=256
eisenspitzhacke=257
eisenaxt=258
feuerzeug=259
apfel=260
bogen=261
pfeil=262
kohle=263
holzkohle=263:1
diamant=264
eisenbarren=265
goldbarren=266
eisenschwert=267
holzschwert=268
holzschaufel=269
holzspitzhacke=270
holzaxt=271
steinschwert=272
steinschaufel=273
steinspitzhacke=274
steinaxt=275
diamantschwert=276
diamantschaufel=277
diamantspitzhacke=278
diamantaxt=279
stock=280
schuessel=281
pilzsuppe=282
goldschwert=283
goldschaufel=284
goldspitzhacke=285
goldaxt=286
faden=287
feder=288
schwarzpulver=289
holzhacke=290
steinhacke=291
eisenhacke=292
diamanthacke=293
goldhacke=294
samen=295
weizen=296
brot=297
lederkappe=298
lederjacke=299
lederhose=300
lederstiefel=301
kettenhaube=302
kettenhemd=303
kettenhose=304
kettenstiefel=305
eisenhelm=306
eisenbrustplatte=307
eisenbeinschutz=308
eisenstiefel=309
diamanthelm=310
diamantbrustplatte=311
diamantbeinschutz=312
diamantstiefel=313
goldhelm=314
goldharnisch=315
goldbeinschutz=316
goldstiefel=317
goldboots=317
feuerstein=318
rohesschweinefleisch=319
gebratenesschweinefleisch=320
gemaelde=321
goldenerapfel=322
goldenerapfel=322:1
schild=323
eichenholztuer=324
eimer=325
wassereimer=326
lavaeimer=327
lore=328
sattel=329
eisentuer=330
redstone=331
schneeballl=332
boot=333
leder=334
milcht=335
ziegel=336
ton=337
zuckercane=338
papier=339
buch=340
schleimball=341
gueterlore=342
angetriebenelore=343
ei=344
kompass=345
angel=346
uhr=347
glowstonestaub=348
fisch=349
roherfisch=349
roherlachs=349:1
clownfisch=349:2
kugelfisch=349:3
gebratenerfisch=350
gebratenerlachs=350:1
farbe=351
tintenbeutel=351:0
rosenrot=351:1
kaktusgruen=351:2
kakaobohnen=351:3
lapislazuli=351:4
violetterfarbstoff=351:5
tuerkiserfarbstoff=351:6
hellgrauerfarbstoff=351:7
grauerfarbstoff=351:8
rosafarbstoff=351:9
hellgruenerfarbstoff=351:10
gelberfarbstoff=351:11
hellblauerfarbstoff=351:12
magentafarbstoff=351:13
orangenerfarbstoff=351:14
knochenmehl=351:15
knochen=352
zucker=353
kuchen=354
bett=355
redstoneverstaerker=356
keks=357
karte=358
schere=359
melone=360
kürbiskerne=361
melonenkerne=362
rohesrindfleisch=363
steak=364
roheshühnchen=365
gebrateneshühnchen=366
verrottetesfleisch=367
enderperle=368
lohenrute=369
ghasttraene=370
goldnugget=371
netherwarze=372
trank=373
glasflasche=374
spinnenauge=375
fermentiertesspinnenauge=376
lohenstaub=377
magmacreme=378
braustand=379
kessel=380
enderauge=381
glitzerndemelone=382
spawnei=383
erfahrungsfläschchen=384
feuerkugel=385
buchundfeder=386
beschriebenesbuch=387
smaragd=388
rahmen=389
blumentopf=390
karotte=391
kartoffel=392
ofenkartoffel=393
giftigekartoffel=394
leerekarte=395
goldenekarotte=396
skelettschaedel=397
witherschaedel=397:1
zombieschaedel=397:2
kopf=397:3
creeperschaedel=397:4
karottenrute=398
netherstern=399
kuerbiskuchen=400
feuerwerksrakete=401
feuerwerksstern=402
verzauberungsbuch=403
redstonekomparator=404
netherziegelitem=405
netherquarz=406
tntlore=407
trichterlore=408
prismarinscherbe=409
prismarinkristalle=410
roheskaninchen=411
gebrateneskaninchen=412
kaninchenragout=413
hasenpfote=414
kaninchenfell=415
ruestungsstaender=416
eisernepferderuestung=417
goldenepferderuestung=418
diamantenepferderuestung=419
leine=420
namensschild=421
kommandoblocklore=422
roheshammelfleisch=423
gebrateneshammelfleisch=424
banner=425
schwarzesbanner=415:0
rotesbanner=415:1
gruenesbanner=415:2
braunbanner=415:3
blauesbanner=415:4
violettesbanner=415:5
tuerkisesbanner=415:6
hellgrauesbanner=415:7
grauesbanner=415:8
rosabanner=415:9
hellgruenesbanner=415:10
gelbesbanner=415:11
hellblauesbanner=415:12
magentabanner=415:13
orangenesbanner=415:14
weissesbanner=415:15
fichtenholztuer=427
birkenholztuer=428
tropentuer=429
akazientuer=430
schwarzeichentuer=431
goldeneschallplatte=2256
grueneschallplatte=2257
blocksschallplatte=2258
chirpschallplatte=2259
farschallplatte=2260
mallschallplatte=2261
mellohischallplatte=2262
stalschallplatte=2263
stradschallplatte=2264
wardschallplatte=2265
11schallplatte=2266

View File

@ -5,7 +5,7 @@ MCServer is a Minecraft server that is written in C++ and designed to be efficie
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis.
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.7.10.
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.8.
Installation
------------

View File

@ -1,6 +1,6 @@
#include "Globals.h"
#include "BiomeView.h"
#include "Chunk.h"
#include "QtChunk.h"
#include <QPainter>
#include <QResizeEvent>

View File

@ -1,7 +1,9 @@
#include "Globals.h"
#include "ChunkSource.h"
#include <QThread>
#include "Generating/BioGen.h"
#include "src/Generating/BioGen.h"
#include "src/StringCompression.h"
#include "src/WorldStorage/FastNBT.h"
#include "inifile/iniFile.h"
@ -140,8 +142,8 @@ static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image
////////////////////////////////////////////////////////////////////////////////
// BioGenSource:
BioGenSource::BioGenSource(QString a_WorldIniPath) :
m_WorldIniPath(a_WorldIniPath),
BioGenSource::BioGenSource(cIniFilePtr a_IniFile) :
m_IniFile(a_IniFile),
m_Mtx(QMutex::Recursive)
{
reload();
@ -169,16 +171,251 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu
void BioGenSource::reload()
{
cIniFile ini;
ini.ReadFile(m_WorldIniPath.toStdString());
int seed = ini.GetValueSetI("Seed", "Seed", 0);
int seed = m_IniFile->GetValueSetI("Generator", "Seed", 0);
bool unused = false;
QMutexLocker lock(&m_Mtx);
m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(ini, seed, unused));
lock.unlock();
ini.WriteFile(m_WorldIniPath.toStdString());
m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused));
}
////////////////////////////////////////////////////////////////////////////////
// AnvilSource::AnvilFile
class AnvilSource::AnvilFile
{
public:
/** Coordinates of the region file. */
int m_RegionX, m_RegionZ;
/** True iff the file contains proper data. */
bool m_IsValid;
/** Creates a new instance with the specified region coords. Reads the file header. */
AnvilFile(int a_RegionX, int a_RegionZ, const AString & a_WorldPath) :
m_RegionX(a_RegionX),
m_RegionZ(a_RegionZ),
m_IsValid(false)
{
readFile(Printf("%s/r.%d.%d.mca", a_WorldPath.c_str(), a_RegionX, a_RegionZ));
}
/** Returns the compressed data of the specified chunk.
Returns an empty string when chunk not present. */
AString getChunkData(int a_ChunkX, int a_ChunkZ)
{
if (!m_IsValid)
{
return "";
}
// Translate to local coords:
int RelChunkX = a_ChunkX - m_RegionX * 32;
int RelChunkZ = a_ChunkZ - m_RegionZ * 32;
ASSERT((RelChunkX >= 0) && (RelChunkX < 32));
ASSERT((RelChunkZ >= 0) && (RelChunkZ < 32));
// Get the chunk data location:
UInt32 chunkOffset = m_Header[RelChunkX + 32 * RelChunkZ] >> 8;
UInt32 numChunkSectors = m_Header[RelChunkX + 32 * RelChunkZ] & 0xff;
if ((chunkOffset < 2) || (numChunkSectors == 0))
{
return "";
}
// Get the real data size:
const char * chunkData = m_FileData.data() + chunkOffset * 4096;
UInt32 chunkSize = GetBEInt(chunkData);
if ((chunkSize < 2) || (chunkSize / 4096 > numChunkSectors))
{
// Bad data, bail out
return "";
}
// Check the compression method:
if (chunkData[4] != 2)
{
// Chunk is in an unknown compression
return "";
}
chunkSize--;
// Read the chunk data:
return m_FileData.substr(chunkOffset * 4096 + 5, chunkSize);
}
protected:
AString m_FileData;
UInt32 m_Header[2048];
/** Reads the whole specified file contents and parses the header. */
void readFile(const AString & a_FileName)
{
// Read the entire file:
m_FileData = cFile::ReadWholeFile(a_FileName);
if (m_FileData.size() < sizeof(m_Header))
{
return;
}
// Parse the header - change endianness:
const char * hdr = m_FileData.data();
for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++)
{
m_Header[i] = GetBEInt(hdr + 4 * i);
}
m_IsValid = true;
}
};
////////////////////////////////////////////////////////////////////////////////
// AnvilSource:
AnvilSource::AnvilSource(QString a_WorldRegionFolder) :
m_WorldRegionFolder(a_WorldRegionFolder)
{
}
void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk)
{
// Load the compressed data:
AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ);
if (compressedChunkData.empty())
{
return;
}
// Uncompress the chunk data:
AString uncompressed;
int res = InflateString(compressedChunkData.data(), compressedChunkData.size(), uncompressed);
if (res != Z_OK)
{
return;
}
// Parse the NBT data:
cParsedNBT nbt(uncompressed.data(), uncompressed.size());
if (!nbt.IsValid())
{
return;
}
// Get the biomes out of the NBT:
int Level = nbt.FindChildByName(0, "Level");
if (Level < 0)
{
return;
}
cChunkDef::BiomeMap biomeMap;
int mcsBiomes = nbt.FindChildByName(Level, "MCSBiomes");
if ((mcsBiomes >= 0) && (nbt.GetDataLength(mcsBiomes) == sizeof(biomeMap)))
{
// Convert the biomes from BigEndian to platform native numbers:
const char * beBiomes = nbt.GetData(mcsBiomes);
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
{
biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i);
}
// Render the biomes:
Chunk::Image img;
biomesToImage(biomeMap, img);
a_DestChunk->setImage(img);
return;
}
// MCS biomes not found, load Vanilla biomes instead:
int biomes = nbt.FindChildByName(Level, "Biomes");
if ((biomes < 0) || (nbt.GetDataLength(biomes) != ARRAYCOUNT(biomeMap)))
{
return;
}
// Convert the biomes from Vanilla to EMCSBiome:
const char * vanillaBiomes = nbt.GetData(biomes);
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
{
biomeMap[i] = EMCSBiome(vanillaBiomes[i]);
}
// Render the biomes:
Chunk::Image img;
biomesToImage(biomeMap, img);
a_DestChunk->setImage(img);
}
void AnvilSource::reload()
{
// Remove all files from the cache:
QMutexLocker lock(&m_Mtx);
m_Files.clear();
}
void AnvilSource::chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ)
{
a_RegionX = a_ChunkX >> 5;
a_RegionZ = a_ChunkZ >> 5;
}
AString AnvilSource::getCompressedChunkData(int a_ChunkX, int a_ChunkZ)
{
return getAnvilFile(a_ChunkX, a_ChunkZ)->getChunkData(a_ChunkX, a_ChunkZ);
}
AnvilSource::AnvilFilePtr AnvilSource::getAnvilFile(int a_ChunkX, int a_ChunkZ)
{
int RegionX, RegionZ;
chunkToRegion(a_ChunkX, a_ChunkZ, RegionX, RegionZ);
// Search the cache for the file:
QMutexLocker lock(&m_Mtx);
for (auto itr = m_Files.cbegin(), end = m_Files.cend(); itr != end; ++itr)
{
if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ))
{
// Found the file in the cache, move it to front and return it:
AnvilFilePtr file(*itr);
m_Files.erase(itr);
m_Files.push_front(file);
return file;
}
}
// File not in cache, create it:
AnvilFilePtr file(new AnvilFile(RegionX, RegionZ, m_WorldRegionFolder.toStdString()));
m_Files.push_front(file);
return file;
}

View File

@ -1,7 +1,8 @@
#pragma once
#include "Globals.h"
#include <QString>
#include <QMutex>
#include "Chunk.h"
#include "QtChunk.h"
@ -11,6 +12,7 @@
class cBiomeGen;
typedef std::shared_ptr<cBiomeGen> cBiomeGenPtr;
class cIniFile;
typedef std::shared_ptr<cIniFile> cIniFilePtr;
@ -40,15 +42,15 @@ class BioGenSource :
{
public:
/** Constructs a new BioGenSource based on the biome generator that is defined in the specified world.ini file. */
BioGenSource(QString a_WorldIniPath);
BioGenSource(cIniFilePtr a_IniFile);
// ChunkSource overrides:
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
virtual void reload(void) override;
protected:
/** Path to the world.ini file from which the m_WorldIni is regenerated on reload requests. */
QString m_WorldIniPath;
/** The world.ini contents from which the generator is created and re-created on reload(). */
cIniFilePtr m_IniFile;
/** The generator used for generating biomes. */
std::unique_ptr<cBiomeGen> m_BiomeGen;
@ -64,11 +66,40 @@ class AnvilSource :
public ChunkSource
{
public:
// TODO
/** Constructs a new AnvilSource based on the world path. */
AnvilSource(QString a_WorldRegionFolder);
// ChunkSource overrides:
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
virtual void reload() override {}
virtual void reload() override;
protected:
class AnvilFile;
typedef std::shared_ptr<AnvilFile> AnvilFilePtr;
/** Folder where the individual Anvil Region files are located. */
QString m_WorldRegionFolder;
/** List of currently loaded files. Acts as a cache so that a file is not opened and closed over and over again.
Protected against multithreaded access by m_Mtx. */
std::list<AnvilFilePtr> m_Files;
/** Guards m_Files agains multithreaded access. */
QMutex m_Mtx;
/** Converts chunk coords to region coords. */
void chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ);
/** Returns the compressed data of the specified chunk.
Returns an empty string if the chunk is not available. */
AString getCompressedChunkData(int a_ChunkX, int a_ChunkZ);
/** Returns the file object that contains the specified chunk.
The file is taken from the cache if available there, otherwise it is created anew. */
AnvilFilePtr getAnvilFile(int a_ChunkX, int a_ChunkZ);
};

View File

@ -0,0 +1,159 @@
#include "Globals.h"
#include "GeneratorSetup.h"
#include <QLabel>
#include <QLineEdit>
#include "src/Generating/BioGen.h"
#include "inifile/iniFile.h"
static const QString s_GeneratorNames[] =
{
QString("Checkerboard"),
QString("Constant"),
QString("DistortedVoronoi"),
QString("MultiStepMap"),
QString("TwoLevel"),
QString("Voronoi"),
};
GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent) :
super(a_Parent),
m_IniFile(new cIniFile())
{
// The seed and generator name is in a separate form layout at the top, always present:
m_eSeed = new QLineEdit();
m_eSeed->setValidator(new QIntValidator());
m_eSeed->setText("0");
m_eSeed->setProperty("INI.ItemName", QVariant("Seed"));
m_cbGenerator = new QComboBox();
m_cbGenerator->setMinimumWidth(120);
for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++)
{
m_cbGenerator->addItem(s_GeneratorNames[i]);
}
QFormLayout * baseLayout = new QFormLayout();
baseLayout->addRow(new QLabel(tr("Seed")), m_eSeed);
baseLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator);
// The rest of the controls are in a dynamically created form layout:
m_FormLayout = new QFormLayout();
// The main layout joins these two vertically:
m_MainLayout = new QVBoxLayout();
m_MainLayout->addLayout(baseLayout);
m_MainLayout->addLayout(m_FormLayout);
m_MainLayout->addStretch();
setLayout(m_MainLayout);
// Load the INI file, if specified, otherwise set defaults:
if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName))
{
m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen")));
m_eSeed->setText(QString::number(m_IniFile->GetValueI("Generator", "Seed")));
}
else
{
m_IniFile->SetValue("Generator", "Generator", "Composable");
m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString());
bool dummy;
delete cBiomeGen::CreateBiomeGen(*m_IniFile, 0, dummy);
}
updateFromIni();
// Connect the change events only after the data has been loaded:
connect(m_cbGenerator, SIGNAL(currentIndexChanged(QString)), this, SLOT(generatorChanged(QString)));
connect(m_eSeed, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString)));
}
void GeneratorSetup::generatorChanged(const QString & a_NewName)
{
// Clear the current contents of the form layout by assigning it to a stack temporary:
{
m_MainLayout->takeAt(1);
QWidget().setLayout(m_FormLayout);
}
// Re-create the layout:
m_FormLayout = new QFormLayout();
m_MainLayout->insertLayout(1, m_FormLayout);
// Recreate the INI file:
m_IniFile->Clear();
m_IniFile->SetValue("Generator", "Generator", "Composable");
m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString());
// Create a dummy biome gen from the INI file, this will create the defaults in the INI file:
bool dummy;
delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy);
// Read all values from the INI file and put them into the form layout:
updateFromIni();
// Notify of the changes:
emit generatorUpdated();
}
void GeneratorSetup::editChanged(const QString & a_NewValue)
{
QString itemName = sender()->property("INI.ItemName").toString();
m_IniFile->SetValue("Generator", itemName.toStdString(), a_NewValue.toStdString());
emit generatorUpdated();
}
void GeneratorSetup::updateFromIni()
{
int keyID = m_IniFile->FindKey("Generator");
if (keyID <= -1)
{
return;
}
int numItems = m_IniFile->GetNumValues(keyID);
AString generatorName = m_IniFile->GetValue("Generator", "BiomeGen");
size_t generatorNameLen = generatorName.length();
for (int i = 0; i < numItems; i++)
{
AString itemName = m_IniFile->GetValueName(keyID, i);
if ((itemName == "Generator") || (itemName == "BiomeGen"))
{
// These special cases are not to be added
continue;
}
AString itemValue = m_IniFile->GetValue(keyID, i);
QLineEdit * edit = new QLineEdit();
edit->setText(QString::fromStdString(itemValue));
edit->setProperty("INI.ItemName", QVariant(QString::fromStdString(itemName)));
// Remove the generator name prefix from the item name, for clarity purposes:
if (NoCaseCompare(itemName.substr(0, generatorNameLen), generatorName) == 0)
{
itemName.erase(0, generatorNameLen);
}
connect(edit, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString)));
m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit);
} // for i - INI values[]
}

View File

@ -0,0 +1,64 @@
#pragma once
#include <memory>
#include <QDialog>
#include <QComboBox>
#include <QVBoxLayout>
#include <QFormLayout>
class cIniFile;
typedef std::shared_ptr<cIniFile> cIniFilePtr;
class GeneratorSetup :
public QWidget
{
typedef QWidget super;
Q_OBJECT
public:
/** Creates the widget and loads the contents of the INI file, if not empty. */
explicit GeneratorSetup(const std::string & a_IniFileName, QWidget * parent = nullptr);
/** Returns the cIniFile instance that is being edited by this widget. */
cIniFilePtr getIniFile() { return m_IniFile; }
signals:
/** Emitted when the generator parameters have changed. */
void generatorUpdated();
public slots:
/** Called when the user selects a different generator from the top combobox.
Re-creates m_IniFile and updates the form layout. */
void generatorChanged(const QString & a_NewName);
protected slots:
/** Called when any of the edit widgets are changed. */
void editChanged(const QString & a_NewValue);
protected:
QComboBox * m_cbGenerator;
QLineEdit * m_eSeed;
QVBoxLayout * m_MainLayout;
QFormLayout * m_FormLayout;
cIniFilePtr m_IniFile;
int m_Seed;
/** Updates the form layout with the values from m_IniFile. */
void updateFromIni();
};

View File

@ -238,14 +238,14 @@ template class SizeChecker<UInt16, 2>;
#ifndef TEST_GLOBALS
// Common headers (part 1, without macros):
#include "StringUtils.h"
#include "OSSupport/Sleep.h"
#include "OSSupport/CriticalSection.h"
#include "OSSupport/Semaphore.h"
#include "OSSupport/Event.h"
#include "OSSupport/Thread.h"
#include "OSSupport/File.h"
#include "Logger.h"
#include "src/StringUtils.h"
#include "src/OSSupport/Sleep.h"
#include "src/OSSupport/CriticalSection.h"
#include "src/OSSupport/Semaphore.h"
#include "src/OSSupport/Event.h"
#include "src/OSSupport/Thread.h"
#include "src/OSSupport/File.h"
#include "src/Logger.h"
#else
// Logging functions
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);
@ -375,10 +375,10 @@ T Clamp(T a_Value, T a_Min, T a_Max)
// Common headers (part 2, with macros):
#include "ChunkDef.h"
#include "BiomeDef.h"
#include "BlockID.h"
#include "BlockInfo.h"
#include "src/ChunkDef.h"
#include "src/BiomeDef.h"
#include "src/BlockID.h"
#include "src/BlockInfo.h"

View File

@ -5,19 +5,34 @@
#include <QMenuBar>
#include <QApplication>
#include <QFileDialog>
#include <QSettings>
#include <QDirIterator>
#include "inifile/iniFile.h"
#include "ChunkSource.h"
#include "Generating/BioGen.h"
#include "src/Generating/BioGen.h"
#include "src/StringCompression.h"
#include "src/WorldStorage/FastNBT.h"
#include "GeneratorSetup.h"
MainWindow::MainWindow(QWidget * parent) :
QMainWindow(parent)
QMainWindow(parent),
m_GeneratorSetup(nullptr),
m_LineSeparator(nullptr)
{
m_BiomeView = new BiomeView(this);
setCentralWidget(m_BiomeView);
initMinecraftPath();
m_BiomeView = new BiomeView();
m_MainLayout = new QHBoxLayout();
m_MainLayout->addWidget(m_BiomeView, 1);
m_MainLayout->setMenuBar(menuBar());
m_MainLayout->setMargin(0);
QWidget * central = new QWidget();
central->setLayout(m_MainLayout);
setCentralWidget(central);
createActions();
createMenus();
@ -36,10 +51,14 @@ MainWindow::~MainWindow()
void MainWindow::generate()
void MainWindow::newGenerator()
{
QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)"));
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(worldIni)));
// (Re-)open the generator setup dialog with empty settings:
openGeneratorSetup("");
// Set the chunk source:
cIniFilePtr iniFile = m_GeneratorSetup->getIniFile();
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(iniFile)));
m_BiomeView->redraw();
}
@ -47,9 +66,79 @@ void MainWindow::generate()
void MainWindow::open()
void MainWindow::openGenerator()
{
// TODO
// Let the user specify the world.ini file:
QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)"));
if (worldIni.isEmpty())
{
return;
}
// (Re-)open the generator setup dialog:
openGeneratorSetup(worldIni.toStdString());
// Set the chunk source:
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(m_GeneratorSetup->getIniFile())));
m_BiomeView->redraw();
}
void MainWindow::openWorld()
{
// Let the user specify the world:
QString regionFolder = QFileDialog::getExistingDirectory(this, tr("Select the region folder"), QString());
if (regionFolder.isEmpty())
{
return;
}
// Remove the generator setup dialog, if open:
closeGeneratorSetup();
// Set the chunk source:
m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(regionFolder)));
m_BiomeView->redraw();
}
void MainWindow::openVanillaWorld()
{
// The world is stored in the sender action's data, retrieve it:
QAction * action = qobject_cast<QAction *>(sender());
if (action == nullptr)
{
return;
}
// Remove the generator setup dialog, if open:
closeGeneratorSetup();
// Set the chunk source:
m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(action->data().toString())));
m_BiomeView->redraw();
}
void MainWindow::initMinecraftPath()
{
#ifdef Q_OS_MAC
m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/Library/Application Support/minecraft");
#elif defined Q_OS_WIN32
QSettings ini(QSettings::IniFormat, QSettings::UserScope, ".minecraft", "minecraft1");
m_MinecraftPath = QFileInfo(ini.fileName()).absolutePath();
#else
m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/.minecraft");
#endif
}
@ -58,19 +147,26 @@ void MainWindow::open()
void MainWindow::createActions()
{
m_actGen = new QAction(tr("&Generate..."), this);
m_actGen->setShortcut(tr("Ctrl+N"));
m_actGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
connect(m_actGen, SIGNAL(triggered()), this, SLOT(generate()));
createWorldActions();
m_actOpen = new QAction(tr("&Open world..."), this);
m_actOpen->setShortcut(tr("Ctrl+O"));
m_actOpen->setStatusTip(tr("Open an existing world and display its biomes"));
connect(m_actOpen, SIGNAL(triggered()), this, SLOT(open()));
m_actNewGen = new QAction(tr("&New generator"), this);
m_actNewGen->setShortcut(tr("Ctrl+N"));
m_actNewGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
connect(m_actNewGen, SIGNAL(triggered()), this, SLOT(newGenerator()));
m_actOpenGen = new QAction(tr("&Open generator..."), this);
m_actOpenGen->setShortcut(tr("Ctrl+G"));
m_actOpenGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
connect(m_actOpenGen, SIGNAL(triggered()), this, SLOT(openGenerator()));
m_actOpenWorld = new QAction(tr("&Open world..."), this);
m_actOpenWorld->setShortcut(tr("Ctrl+O"));
m_actOpenWorld->setStatusTip(tr("Open an existing world and display its biomes"));
connect(m_actOpenWorld, SIGNAL(triggered()), this, SLOT(openWorld()));
m_actReload = new QAction(tr("&Reload"), this);
m_actReload->setShortcut(tr("F5"));
m_actReload->setStatusTip(tr("Open an existing world and display its biomes"));
m_actReload->setStatusTip(tr("Clear the view cache and force a reload of all the data"));
connect(m_actReload, SIGNAL(triggered()), m_BiomeView, SLOT(reload()));
m_actExit = new QAction(tr("E&xit"), this);
@ -83,15 +179,130 @@ void MainWindow::createActions()
void MainWindow::createMenus()
void MainWindow::createWorldActions()
{
QMenu * mFile = menuBar()->addMenu(tr("&World"));
mFile->addAction(m_actGen);
mFile->addAction(m_actOpen);
mFile->addSeparator();
mFile->addAction(m_actReload);
mFile->addSeparator();
mFile->addAction(m_actExit);
QDir mc(m_MinecraftPath);
if (!mc.cd("saves"))
{
return;
}
QDirIterator it(mc);
int key = 1;
while (it.hasNext())
{
it.next();
if (!it.fileInfo().isDir())
{
continue;
}
QString name = getWorldName(it.filePath().toStdString());
if (name.isEmpty())
{
continue;
}
QAction * w = new QAction(this);
w->setText(name);
w->setData(it.filePath() + "/region");
if (key < 10)
{
w->setShortcut("Ctrl+" + QString::number(key));
key++;
}
connect(w, SIGNAL(triggered()), this, SLOT(openVanillaWorld()));
m_WorldActions.append(w);
}
}
void MainWindow::createMenus()
{
QMenu * file = menuBar()->addMenu(tr("&Map"));
file->addAction(m_actNewGen);
file->addAction(m_actOpenGen);
file->addSeparator();
QMenu * worlds = file->addMenu(tr("Open existing"));
worlds->addActions(m_WorldActions);
if (m_WorldActions.empty())
{
worlds->setEnabled(false);
}
file->addAction(m_actOpenWorld);
file->addSeparator();
file->addAction(m_actReload);
file->addSeparator();
file->addAction(m_actExit);
}
QString MainWindow::getWorldName(const AString & a_Path)
{
AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat");
if (levelData.empty())
{
// No such file / no data
return QString();
}
AString uncompressed;
if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK)
{
return QString();
}
cParsedNBT nbt(uncompressed.data(), uncompressed.size());
if (!nbt.IsValid())
{
return QString();
}
AString name = nbt.GetName(1);
int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName");
if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String))
{
return QString();
}
return QString::fromStdString(nbt.GetString(levelNameTag));
}
void MainWindow::openGeneratorSetup(const AString & a_IniFileName)
{
// Close any previous editor:
closeGeneratorSetup();
// Open up a new editor:
m_GeneratorSetup = new GeneratorSetup(a_IniFileName);
m_LineSeparator = new QWidget();
m_LineSeparator->setFixedWidth(2);
m_LineSeparator->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
m_LineSeparator->setStyleSheet(QString("background-color: #c0c0c0;"));
m_MainLayout->addWidget(m_LineSeparator);
m_MainLayout->addWidget(m_GeneratorSetup);
// Connect the signals from the setup pane:
connect(m_GeneratorSetup, SIGNAL(generatorUpdated()), m_BiomeView, SLOT(reload()));
}
void MainWindow::closeGeneratorSetup()
{
delete m_MainLayout->takeAt(2);
delete m_MainLayout->takeAt(1);
delete m_GeneratorSetup;
delete m_LineSeparator;
m_GeneratorSetup = nullptr;
m_LineSeparator = nullptr;
}

View File

@ -1,43 +1,92 @@
#pragma once
#include <memory>
#include <QList>
#include <QMainWindow>
#include <QHBoxLayout>
#include "BiomeView.h"
// fwd:
class GeneratorSetup;
class MainWindow :
public QMainWindow
{
Q_OBJECT
BiomeView * m_BiomeView;
public:
MainWindow(QWidget *parent = 0);
MainWindow(QWidget * parent = nullptr);
~MainWindow();
private slots:
/** Creates a generator definition from scratch, lets user modify generator params in realtime. */
void newGenerator();
/** Opens a generator definition and generates the biomes based on that. */
void generate();
void openGenerator();
/** Opens an existing world and displays the loaded biomes. */
void open();
void openWorld();
/** Opens a vanilla world that is specified by the calling action. */
void openVanillaWorld();
protected:
// Actions:
QAction * m_actGen;
QAction * m_actOpen;
QAction * m_actNewGen;
QAction * m_actOpenGen;
QAction * m_actOpenWorld;
QAction * m_actReload;
QAction * m_actExit;
/** List of actions that open the specific vanilla world. */
QList<QAction *> m_WorldActions;
/** Path to the vanilla folder. */
QString m_MinecraftPath;
/** The pane for setting up the generator, available when visualising a generator. */
GeneratorSetup * m_GeneratorSetup;
/** The main biome display widget. */
BiomeView * m_BiomeView;
/** The layout for the window. */
QHBoxLayout * m_MainLayout;
/** The separator line between biome view and generator setup. */
QWidget * m_LineSeparator;
/** Initializes the m_MinecraftPath based on the proper MC path */
void initMinecraftPath();
/** Creates the actions that the UI supports. */
void createActions();
/** Creates the actions that open a specific vanilla world. Iterates over the minecraft saves folder. */
void createWorldActions();
/** Creates the menu bar and connects its events. */
void createMenus();
/** Returns the name of the vanilla world in the specified path.
Reads the level.dat file for the name. Returns an empty string on failure. */
QString getWorldName(const AString & a_Path);
/** Opens the generator setup pane, if not already open, and loads the specified INI file to it. */
void openGeneratorSetup(const AString & a_IniFileName);
/** Closes and destroys the generator setup pane, if there is one. */
void closeGeneratorSetup();
};

View File

@ -12,7 +12,7 @@ TARGET = QtBiomeVisualiser
TEMPLATE = app
SOURCES += main.cpp\
SOURCES +=\
MainWindow.cpp \
BiomeView.cpp \
../../src/Generating/BioGen.cpp \
@ -27,9 +27,28 @@ SOURCES += main.cpp\
../../src/OSSupport/IsThread.cpp \
../../src/BiomeDef.cpp \
ChunkCache.cpp \
Chunk.cpp \
ChunkSource.cpp \
ChunkLoader.cpp
ChunkLoader.cpp \
../../src/StringCompression.cpp \
../../src/WorldStorage/FastNBT.cpp \
../../lib/zlib/adler32.c \
../../lib/zlib/compress.c \
../../lib/zlib/crc32.c \
../../lib/zlib/deflate.c \
../../lib/zlib/gzclose.c \
../../lib/zlib/gzlib.c \
../../lib/zlib/gzread.c \
../../lib/zlib/gzwrite.c \
../../lib/zlib/infback.c \
../../lib/zlib/inffast.c \
../../lib/zlib/inflate.c \
../../lib/zlib/inftrees.c \
../../lib/zlib/trees.c \
../../lib/zlib/uncompr.c \
../../lib/zlib/zutil.c \
GeneratorSetup.cpp \
QtBiomeVisualiser.cpp \
QtChunk.cpp
HEADERS += MainWindow.h \
Globals.h \
@ -46,15 +65,36 @@ HEADERS += MainWindow.h \
../../src/OSSupport/IsThread.h \
../../src/BiomeDef.h \
ChunkCache.h \
Chunk.h \
ChunkSource.h \
ChunkLoader.h
ChunkLoader.h \
../../src/StringCompression.h \
../../src/WorldStorage/FastNBT.h \
../../lib/zlib/crc32.h \
../../lib/zlib/deflate.h \
../../lib/zlib/gzguts.h \
../../lib/zlib/inffast.h \
../../lib/zlib/inffixed.h \
../../lib/zlib/inflate.h \
../../lib/zlib/inftrees.h \
../../lib/zlib/trees.h \
../../lib/zlib/zconf.h \
../../lib/zlib/zlib.h \
../../lib/zlib/zutil.h \
GeneratorSetup.h \
QtChunk.h
INCLUDEPATH += $$_PRO_FILE_PWD_ \
$$_PRO_FILE_PWD_/../../src \
$$_PRO_FILE_PWD_/../../lib
$$_PRO_FILE_PWD_/../../lib \
$$_PRO_FILE_PWD_/../../lib/jsoncpp/include \
$$_PRO_FILE_PWD_/../../lib/polarssl/include \
$$_PRO_FILE_PWD_/../../lib/sqlite \
$$_PRO_FILE_PWD_/../../lib/SQLiteCpp/include \
$$_PRO_FILE_PWD_/../../
CONFIG += C++11
OTHER_FILES +=

View File

@ -1,6 +1,5 @@
#include "Globals.h"
#include "Globals.h"
#include "Chunk.h"
#include "QtChunk.h"

View File

@ -129,6 +129,8 @@ set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPER
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE)
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/LuaState_Call.inc PROPERTIES GENERATED TRUE)
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES COMPILE_FLAGS -Wno-error)
if(NOT MSVC)
add_library(Bindings ${SRCS} ${HDRS})

View File

@ -5,11 +5,6 @@
#undef TOLUA_TEMPLATE_BIND
#include "tolua++/include/tolua++.h"
#include "Plugin.h"
#include "PluginLua.h"
#include "PluginManager.h"
#include "LuaWindow.h"
#include "LuaChunkStay.h"
#include "../BlockInfo.h"

View File

@ -6,7 +6,6 @@
#include "Globals.h"
#include "LuaChunkStay.h"
#include "PluginLua.h"
#include "../World.h"

View File

@ -18,6 +18,7 @@
// fwd:
class cPluginLua;
class cChunkMap;

View File

@ -56,7 +56,6 @@ struct HTTPRequest;
class cWebAdmin;
struct HTTPTemplateRequest;
class cTNTEntity;
class cCreeper;
class cHopperEntity;
class cBlockEntity;
class cBoundingBox;

View File

@ -6,7 +6,6 @@
#include "LuaWindow.h"
#include "../UI/SlotArea.h"
#include "PluginLua.h"
#include "../Entities/Player.h"
#include "lua/src/lauxlib.h" // Needed for LUA_REFNIL

View File

@ -5,7 +5,6 @@
#undef TOLUA_TEMPLATE_BIND
#include "tolua++/include/tolua++.h"
#include "polarssl/md5.h"
#include "Plugin.h"
#include "PluginLua.h"
#include "PluginManager.h"
#include "LuaWindow.h"
@ -27,7 +26,6 @@
#include "../BlockEntities/MobHeadEntity.h"
#include "../BlockEntities/FlowerPotEntity.h"
#include "../LineBlockTracer.h"
#include "../Protocol/Authenticator.h"
#include "../WorldStorage/SchematicFileSerializer.h"
#include "../CompositeChat.h"

View File

@ -1,23 +1,25 @@
#pragma once
#include "PluginManager.h"
#include "Defines.h"
class cCommandOutputCallback;
class cItems;
class cHopperEntity;
class cBlockEntityWithItems;
class cClientHandle;
class cPlayer;
class cPickup;
class cItem;
class cPlayer;
class cProjectileEntity;
class cEntity;
class cMonster;
class cWorld;
class cChunkDesc;
struct TakeDamageInfo;
// fwd: cPlayer.h
class cPlayer;
// fwd: CraftingRecipes.h
class cCraftingGrid;

View File

@ -12,10 +12,12 @@
#endif
#include "PluginLua.h"
#include "../CommandOutput.h"
#include "PluginManager.h"
#include "../Item.h"
extern "C"
{
#include "lua/src/lualib.h"
#include "lua/src/lauxlib.h"
}
#undef TOLUA_TEMPLATE_BIND

View File

@ -4,12 +4,10 @@
#include "PluginManager.h"
#include "Plugin.h"
#include "PluginLua.h"
#include "../WebAdmin.h"
#include "../Item.h"
#include "../Root.h"
#include "../Server.h"
#include "../CommandOutput.h"
#include "../ChatColor.h"
#include "inifile/iniFile.h"
#include "../Entities/Player.h"

View File

@ -1,9 +1,8 @@
#pragma once
#include "../Item.h"
#include "Defines.h"
@ -36,7 +35,6 @@ class cPickup;
// fwd: Pawn.h
struct TakeDamageInfo;
class cPawn;
// fwd: CommandOutput.h
class cCommandOutputCallback;
@ -49,6 +47,8 @@ class cBlockEntityWithItems;
class cItems;
// tolua_begin

View File

@ -3,7 +3,6 @@
#include "WebPlugin.h"
#include "../WebAdmin.h"
#include "../Server.h"
#include "../Root.h"

View File

@ -1,7 +1,6 @@
#pragma once
struct lua_State;
struct HTTPRequest;

View File

@ -1,8 +1,6 @@
#pragma once
#include "../ClientHandle.h"
#include "../World.h"
@ -13,8 +11,9 @@ namespace Json
class Value;
};
class cChunk;
class cPlayer;
class cPacket;
class cWorld;

View File

@ -12,6 +12,7 @@
#include "BlockEntity.h"
#include "../ItemGrid.h"
#include "../UI/WindowOwner.h"
#include "World.h"

View File

@ -5,7 +5,6 @@
#include "../Item.h"
#include "../Entities/Player.h"
#include "../UI/Window.h"
#include "json/json.h"

View File

@ -13,8 +13,6 @@ namespace Json
};
class cClientHandle;
class cServer;
class cNBTData;

View File

@ -4,16 +4,14 @@
// Implements the cCommandBlockEntity class representing a single command block in the world
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "json/json.h"
#include "CommandBlockEntity.h"
#include "../Entities/Player.h"
#include "../WorldStorage/FastNBT.h"
#include "../CommandOutput.h"
#include "../Root.h"
#include "../Server.h" // ExecuteConsoleCommand()
#include "../Chunk.h"
#include "../ChatColor.h"
#include "../World.h"
#include "../ClientHandle.h"

View File

@ -10,7 +10,7 @@
#pragma once
#include "BlockEntity.h"
#include "RedstonePoweredEntity.h"
@ -27,7 +27,8 @@ namespace Json
// tolua_begin
class cCommandBlockEntity :
public cBlockEntity
public cBlockEntity,
public cRedstonePoweredEntity
{
typedef cBlockEntity super;
@ -52,7 +53,7 @@ public:
// tolua_begin
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
void SetRedstonePower(bool a_IsPowered);
virtual void SetRedstonePower(bool a_IsPowered) override;
/// Sets the command block to execute a command in the next tick
void Activate(void);

View File

@ -2,13 +2,10 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "DispenserEntity.h"
#include "../Entities/Player.h"
#include "../Simulator/FluidSimulator.h"
#include "../Chunk.h"
#include "../World.h"
#include "../Entities/ArrowEntity.h"
#include "../Entities/FireChargeEntity.h"
#include "../Entities/ProjectileEntity.h"
@ -109,7 +106,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
{
double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width);
double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
if (m_World->SpawnMob(MobX, DispY, MobZ, (cMonster::eType)m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0)
if (m_World->SpawnMob(MobX, DispY, MobZ, (eMonsterType)m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0)
{
m_Contents.ChangeSlotCount(a_SlotNum, -1);
}
@ -203,7 +200,7 @@ void cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY,
Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta)
{
switch (a_Meta)
switch (a_Meta & 0x7)
{
case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0);
case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0);

View File

@ -8,7 +8,6 @@
#include "DropSpenserEntity.h"
#include "../Entities/Player.h"
#include "../Chunk.h"
#include "json/json.h"

View File

@ -22,7 +22,6 @@ namespace Json
}
class cClientHandle;
class cServer;

View File

@ -5,8 +5,6 @@
#include "Globals.h"
#include "DropperEntity.h"
#include "../Entities/Player.h"
#include "../Simulator/FluidSimulator.h"

View File

@ -5,7 +5,6 @@
#include "../Item.h"
#include "../Entities/Player.h"
#include "../UI/Window.h"
#include "json/json.h"

View File

@ -3,7 +3,6 @@
#include "BlockEntity.h"
#include "UI/WindowOwner.h"
#include "json/json.h"

View File

@ -4,7 +4,6 @@
// Implements the cFlowerPotEntity class representing a single flower pot in the world
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "json/json.h"
#include "FlowerPotEntity.h"
#include "../Entities/Player.h"
#include "../Item.h"

View File

@ -9,8 +9,8 @@
#pragma once
#include "BlockEntity.h"
#include "Item.h"
class cItem;

View File

@ -5,8 +5,6 @@
#include "../UI/Window.h"
#include "../Entities/Player.h"
#include "../Root.h"
#include "../Chunk.h"
#include "json/json.h"

View File

@ -14,7 +14,6 @@ namespace Json
}
class cClientHandle;
class cServer;

View File

@ -10,10 +10,7 @@
#include "../Entities/Pickup.h"
#include "../Bindings/PluginManager.h"
#include "ChestEntity.h"
#include "DropSpenserEntity.h"
#include "FurnaceEntity.h"
#include "../BoundingBox.h"
#include "json/json.h"

View File

@ -3,8 +3,8 @@
#include "JukeboxEntity.h"
#include "../World.h"
#include "json/json.h"
#include "json/value.h"
#include "Entities/Player.h"

View File

@ -2,7 +2,6 @@
#pragma once
#include "BlockEntity.h"
#include "../Entities/Player.h"

View File

@ -4,7 +4,6 @@
// Implements the cMobHeadEntity class representing a single skull/head in the world
#include "Globals.h"
#include "json/json.h"
#include "MobHeadEntity.h"
#include "../Entities/Player.h"

View File

@ -9,7 +9,7 @@
#pragma once
#include "BlockEntity.h"
#include "Defines.h"

View File

@ -3,7 +3,7 @@
#include "NoteEntity.h"
#include "../World.h"
#include "json/json.h"
#include "json/value.h"

View File

@ -6,7 +6,7 @@ class cRedstonePoweredEntity
{
public:
virtual ~cRedstonePoweredEntity() {};
virtual ~cRedstonePoweredEntity() {}
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
virtual void SetRedstonePower(bool a_IsPowered) = 0;

View File

@ -4,9 +4,9 @@
// Implements the cSignEntity class representing a single sign in the world
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "json/json.h"
#include "json/value.h"
#include "SignEntity.h"
#include "../Entities/Player.h"
#include "../ClientHandle.h"

View File

@ -261,34 +261,34 @@ int StringToMobType(const AString & a_MobString)
const char * m_String;
} MobMap [] =
{
{cMonster::mtCreeper, "Creeper"},
{cMonster::mtSkeleton, "Skeleton"},
{cMonster::mtSpider, "Spider"},
{cMonster::mtGiant, "Giant"},
{cMonster::mtZombie, "Zombie"},
{cMonster::mtSlime, "Slime"},
{cMonster::mtGhast, "Ghast"},
{cMonster::mtZombiePigman, "ZombiePigman"},
{cMonster::mtEnderman, "Enderman"},
{cMonster::mtCaveSpider, "CaveSpider"},
{cMonster::mtSilverfish, "SilverFish"},
{cMonster::mtBlaze, "Blaze"},
{cMonster::mtMagmaCube, "MagmaCube"},
{cMonster::mtEnderDragon, "EnderDragon"},
{cMonster::mtWither, "Wither"},
{cMonster::mtBat, "Bat"},
{cMonster::mtWitch, "Witch"},
{cMonster::mtPig, "Pig"},
{cMonster::mtSheep, "Sheep"},
{cMonster::mtCow, "Cow"},
{cMonster::mtChicken, "Chicken"},
{cMonster::mtSquid, "Squid"},
{cMonster::mtWolf, "Wolf"},
{cMonster::mtMooshroom, "Mooshroom"},
{cMonster::mtSnowGolem, "SnowGolem"},
{cMonster::mtOcelot, "Ocelot"},
{cMonster::mtIronGolem, "IronGolem"},
{cMonster::mtVillager, "Villager"},
{mtCreeper, "Creeper"},
{mtSkeleton, "Skeleton"},
{mtSpider, "Spider"},
{mtGiant, "Giant"},
{mtZombie, "Zombie"},
{mtSlime, "Slime"},
{mtGhast, "Ghast"},
{mtZombiePigman, "ZombiePigman"},
{mtEnderman, "Enderman"},
{mtCaveSpider, "CaveSpider"},
{mtSilverfish, "SilverFish"},
{mtBlaze, "Blaze"},
{mtMagmaCube, "MagmaCube"},
{mtEnderDragon, "EnderDragon"},
{mtWither, "Wither"},
{mtBat, "Bat"},
{mtWitch, "Witch"},
{mtPig, "Pig"},
{mtSheep, "Sheep"},
{mtCow, "Cow"},
{mtChicken, "Chicken"},
{mtSquid, "Squid"},
{mtWolf, "Wolf"},
{mtMooshroom, "Mooshroom"},
{mtSnowGolem, "SnowGolem"},
{mtOcelot, "Ocelot"},
{mtIronGolem, "IronGolem"},
{mtVillager, "Villager"},
};
for (size_t i = 0; i < ARRAYCOUNT(MobMap); i++)
{

View File

@ -175,12 +175,36 @@ enum ENUM_BLOCK_ID
E_BLOCK_NEW_LOG = 162,
E_BLOCK_ACACIA_WOOD_STAIRS = 163,
E_BLOCK_DARK_OAK_WOOD_STAIRS = 164,
E_BLOCK_SLIME_BLOCK = 165,
E_BLOCK_BARRIER = 166,
E_BLOCK_IRON_TRAPDOOR = 167,
E_BLOCK_PRISMARINE_BLOCK = 168,
E_BLOCK_SEA_LANTERN = 169,
E_BLOCK_HAY_BALE = 170,
E_BLOCK_CARPET = 171,
E_BLOCK_HARDENED_CLAY = 172,
E_BLOCK_BLOCK_OF_COAL = 173,
E_BLOCK_PACKED_ICE = 174,
E_BLOCK_BIG_FLOWER = 175,
E_BLOCK_RED_SANDSTONE = 179,
E_BLOCK_RED_SANDSTONE_STAIRS = 180,
E_BLOCK_DOUBLE_NEW_STONE_SLAB= 181,
E_BLOCK_NEW_STONE_SLAB = 182,
E_BLOCK_SPRUCE_FENCE_GATE = 183,
E_BLOCK_BIRCH_FENCE_GATE = 184,
E_BLOCK_JUNGLE_FENCE_GATE = 185,
E_BLOCK_DARK_OAK_FENCE_GATE = 186,
E_BLOCK_ACACIA_FENCE_GATE = 187,
E_BLOCK_SPRUCE_FENCE = 188,
E_BLOCK_BIRCH_FENCE = 189,
E_BLOCK_JUNGLE_FENCE = 190,
E_BLOCK_DARK_OAK_FENCE = 191,
E_BLOCK_ACACIA_FENCE = 192,
E_BLOCK_SPRUCE_DOOR = 193,
E_BLOCK_BIRCH_DOOR = 194,
E_BLOCK_JUNGLE_DOOR = 195,
E_BLOCK_ACACIA_DOOR = 196,
E_BLOCK_DARK_OAK_DOOR = 197,
// Keep these two as the last values, without a number - they will get their correct number assigned automagically by C++
// IsValidBlock() depends on this
@ -356,6 +380,14 @@ enum ENUM_ITEM_ID
E_ITEM_NETHER_QUARTZ = 406,
E_ITEM_MINECART_WITH_TNT = 407,
E_ITEM_MINECART_WITH_HOPPER = 408,
E_ITEM_PRISMARINE_SHARD = 409,
E_ITEM_PRISMARINE_CRYSTALS = 410,
E_ITEM_RAW_RABBIT = 411,
E_ITEM_COOKED_RABBIT = 412,
E_ITEM_RABBIT_STEW = 413,
E_ITEM_RABBITS_FOOT = 414,
E_ITEM_RABBIT_HIDE = 415,
E_ITEM_ARMOR_STAND = 416,
E_ITEM_IRON_HORSE_ARMOR = 417,
E_ITEM_GOLD_HORSE_ARMOR = 418,
E_ITEM_DIAMOND_HORSE_ARMOR = 419,
@ -363,7 +395,13 @@ enum ENUM_ITEM_ID
E_ITEM_NAME_TAG = 421,
E_ITEM_MINECART_WITH_COMMAND_BLOCK = 422,
E_ITEM_RAW_MUTTON = 423,
E_ITEM_MUTTON = 424,
E_ITEM_COOKED_MUTTON = 424,
E_ITEM_BANNER = 425,
E_ITEM_SPRUCE_DOOR = 427,
E_ITEM_BIRCH_DOOR = 428,
E_ITEM_JUNGLE_DOOR = 429,
E_ITEM_ACACIA_DOOR = 430,
E_ITEM_DARK_OAK_DOOR = 431,
// Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++
// IsValidItem() depends on this!

View File

@ -6,26 +6,6 @@
cBlockInfo::cBlockInfo()
: m_LightValue(0x00)
, m_SpreadLightFalloff(0x0f)
, m_Transparent(false)
, m_OneHitDig(false)
, m_PistonBreakable(false)
, m_IsSnowable(false)
, m_IsSolid(true)
, m_FullyOccupiesVoxel(false)
, m_CanBeTerraformed(false)
, m_PlaceSound("")
, m_Handler(NULL)
{}
cBlockInfo::~cBlockInfo()
{
delete m_Handler;
@ -33,28 +13,6 @@ cBlockInfo::~cBlockInfo()
}
/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once.
It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable.
It works only if it is called for the first time before the app spawns other threads. */
cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
{
static cBlockInfo ms_Info[256];
static bool IsBlockInfoInitialized = false;
if (!IsBlockInfoInitialized)
{
cBlockInfo::Initialize(ms_Info);
IsBlockInfoInitialized = true;
}
return ms_Info[a_Type];
}
void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
{
for (unsigned int i = 0; i < 256; ++i)
@ -84,18 +42,26 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9;
a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9;
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7;
a_Info[E_BLOCK_SEA_LANTERN ].m_LightValue = 15;
a_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15;
a_Info[E_BLOCK_TORCH ].m_LightValue = 14;
// Spread blocks
a_Info[E_BLOCK_ACACIA_DOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_ACACIA_FENCE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_ANVIL ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BARRIER ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BEACON ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BED ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BIG_FLOWER ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BIRCH_DOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BIRCH_FENCE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_BREWING_STAND ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_CACTUS ].m_SpreadLightFalloff = 1;
@ -109,6 +75,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DANDELION ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DARK_OAK_DOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DARK_OAK_FENCE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DEAD_BUSH ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_DETECTOR_RAIL ].m_SpreadLightFalloff = 1;
@ -132,6 +101,10 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_IRON_TRAPDOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_JUNGLE_DOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_JUNGLE_FENCE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_LADDER ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_LEVER ].m_SpreadLightFalloff = 1;
@ -142,6 +115,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_NETHER_PORTAL ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_NETHER_WART ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_NEW_STONE_SLAB ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_PISTON ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_PISTON_EXTENSION ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_SpreadLightFalloff = 1;
@ -158,6 +132,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_SAPLING ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_SNOW ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_SPRUCE_DOOR ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_SPRUCE_FENCE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_STAINED_GLASS ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_SpreadLightFalloff = 1;
a_Info[E_BLOCK_STICKY_PISTON ].m_SpreadLightFalloff = 1;
@ -186,13 +163,20 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
// Transparent blocks
a_Info[E_BLOCK_ACACIA_DOOR ].m_Transparent = true;
a_Info[E_BLOCK_ACACIA_FENCE ].m_Transparent = true;
a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_Transparent = true;
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_Transparent = true;
a_Info[E_BLOCK_AIR ].m_Transparent = true;
a_Info[E_BLOCK_ANVIL ].m_Transparent = true;
a_Info[E_BLOCK_BARRIER ].m_Transparent = true;
a_Info[E_BLOCK_BEACON ].m_Transparent = true;
a_Info[E_BLOCK_BED ].m_Transparent = true;
a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
a_Info[E_BLOCK_BIRCH_DOOR ].m_Transparent = true;
a_Info[E_BLOCK_BIRCH_FENCE ].m_Transparent = true;
a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_Transparent = true;
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
a_Info[E_BLOCK_BREWING_STAND ].m_Transparent = true;
a_Info[E_BLOCK_CACTUS ].m_Transparent = true;
@ -206,6 +190,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_COBWEB ].m_Transparent = true;
a_Info[E_BLOCK_CROPS ].m_Transparent = true;
a_Info[E_BLOCK_DANDELION ].m_Transparent = true;
a_Info[E_BLOCK_DARK_OAK_DOOR ].m_Transparent = true;
a_Info[E_BLOCK_DARK_OAK_FENCE ].m_Transparent = true;
a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_Transparent = true;
a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_Transparent = true;
a_Info[E_BLOCK_DEAD_BUSH ].m_Transparent = true;
a_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true;
@ -229,6 +216,10 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_Transparent = true;
a_Info[E_BLOCK_IRON_BARS ].m_Transparent = true;
a_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
a_Info[E_BLOCK_IRON_TRAPDOOR ].m_Transparent = true;
a_Info[E_BLOCK_JUNGLE_DOOR ].m_Transparent = true;
a_Info[E_BLOCK_JUNGLE_FENCE ].m_Transparent = true;
a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_Transparent = true;
a_Info[E_BLOCK_LADDER ].m_Transparent = true;
a_Info[E_BLOCK_LAVA ].m_Transparent = true;
a_Info[E_BLOCK_LEAVES ].m_Transparent = true;
@ -241,6 +232,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_NETHER_PORTAL ].m_Transparent = true;
a_Info[E_BLOCK_NETHER_WART ].m_Transparent = true;
a_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true;
a_Info[E_BLOCK_NEW_STONE_SLAB ].m_Transparent = true;
a_Info[E_BLOCK_PISTON ].m_Transparent = true;
a_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true;
a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_Transparent = true;
@ -257,6 +249,9 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_SAPLING ].m_Transparent = true;
a_Info[E_BLOCK_SIGN_POST ].m_Transparent = true;
a_Info[E_BLOCK_SNOW ].m_Transparent = true;
a_Info[E_BLOCK_SPRUCE_DOOR ].m_Transparent = true;
a_Info[E_BLOCK_SPRUCE_FENCE ].m_Transparent = true;
a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_Transparent = true;
a_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true;
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true;
a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true;
@ -388,6 +383,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_DIAMOND_ORE ].m_IsSnowable = true;
a_Info[E_BLOCK_DIRT ].m_IsSnowable = true;
a_Info[E_BLOCK_DISPENSER ].m_IsSnowable = true;
a_Info[E_BLOCK_DOUBLE_NEW_STONE_SLAB].m_IsSnowable = true;
a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_IsSnowable = true;
a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_IsSnowable = true;
a_Info[E_BLOCK_DROPPER ].m_IsSnowable = true;
@ -424,14 +420,17 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_NOTE_BLOCK ].m_IsSnowable = true;
a_Info[E_BLOCK_OBSIDIAN ].m_IsSnowable = true;
a_Info[E_BLOCK_PLANKS ].m_IsSnowable = true;
a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_IsSnowable = true;
a_Info[E_BLOCK_PUMPKIN ].m_IsSnowable = true;
a_Info[E_BLOCK_QUARTZ_BLOCK ].m_IsSnowable = true;
a_Info[E_BLOCK_RED_SANDSTONE ].m_IsSnowable = true;
a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_IsSnowable = true;
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_IsSnowable = true;
a_Info[E_BLOCK_REDSTONE_ORE ].m_IsSnowable = true;
a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_IsSnowable = true;
a_Info[E_BLOCK_SAND ].m_IsSnowable = true;
a_Info[E_BLOCK_SANDSTONE ].m_IsSnowable = true;
a_Info[E_BLOCK_SEA_LANTERN ].m_IsSnowable = true;
a_Info[E_BLOCK_SILVERFISH_EGG ].m_IsSnowable = true;
a_Info[E_BLOCK_SNOW_BLOCK ].m_IsSnowable = true;
a_Info[E_BLOCK_SOULSAND ].m_IsSnowable = true;
@ -488,7 +487,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
// Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things:
a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_BARRIER ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true;
@ -533,12 +532,15 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_RED_SANDSTONE ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true;
a_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true;
@ -732,12 +734,35 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // I hope it is named slime, it's definetly a new sound type though...
a_Info[E_BLOCK_BARRIER ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PlaceSound = "dig.metal";
a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_SEA_LANTERN ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_HAY_BALE ].m_PlaceSound = "dig.grass";
a_Info[E_BLOCK_CARPET ].m_PlaceSound = "dig.cloth";
a_Info[E_BLOCK_HARDENED_CLAY ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass";
a_Info[E_BLOCK_RED_SANDSTONE ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_RED_SANDSTONE_STAIRS ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_NEW_STONE_SLAB ].m_PlaceSound = "dig.stone";
a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_SPRUCE_FENCE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_BIRCH_FENCE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_JUNGLE_FENCE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_DARK_OAK_FENCE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_ACACIA_FENCE ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_SPRUCE_DOOR ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_BIRCH_DOOR ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_JUNGLE_DOOR ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_ACACIA_DOOR ].m_PlaceSound = "dig.wood";
a_Info[E_BLOCK_DARK_OAK_DOOR ].m_PlaceSound = "dig.wood";
}

View File

@ -11,14 +11,27 @@ class cBlockHandler;
// tolua_begin
class cBlockInfo
{
public:
/** Returns the associated BlockInfo structure for the specified block type. */
static cBlockInfo & Get(BLOCKTYPE a_Type);
/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once.
It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable.
It works only if it is called for the first time before the app spawns other threads. */
static cBlockInfo & Get(BLOCKTYPE a_Type)
{
static cBlockInfo ms_Info[256];
static bool IsBlockInfoInitialized = false;
if (!IsBlockInfoInitialized)
{
cBlockInfo::Initialize(ms_Info);
IsBlockInfoInitialized = true;
}
return ms_Info[a_Type];
}
/** How much light do the blocks emit on their own? */
@ -78,7 +91,19 @@ protected:
typedef cBlockInfo cBlockInfoArray[256];
/** Creates a default BlockInfo structure, initializes all values to their defaults */
cBlockInfo();
cBlockInfo()
: m_LightValue(0x00)
, m_SpreadLightFalloff(0x0f)
, m_Transparent(false)
, m_OneHitDig(false)
, m_PistonBreakable(false)
, m_IsSnowable(false)
, m_IsSolid(true)
, m_FullyOccupiesVoxel(false)
, m_CanBeTerraformed(false)
, m_PlaceSound("")
, m_Handler(NULL)
{}
/** Cleans up the stored values */
~cBlockInfo();

View File

@ -4,6 +4,15 @@
#include "BroadcastInterface.h"
#include "ChunkInterface.h"
#include "Entities/../World.h"
#include "Entities/Player.h"
#include "WorldInterface.h"
void cBlockBedHandler::OnPlacedByPlayer(
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player,

View File

@ -2,12 +2,14 @@
#pragma once
#include "BlockHandler.h"
#include "ChunkInterface.h"
#include "WorldInterface.h"
#include "MetaRotator.h"
#include "../Entities/Player.h"
#include "Item.h"
class cChunkInterface;
class cPlayer;
class cWorldInterface;

View File

@ -2,7 +2,7 @@
#pragma once
#include "BlockHandler.h"
#include "ChunkInterface.h"

View File

@ -3,8 +3,8 @@
#include "BlockHandler.h"
#include "../FastRandom.h"
#include "Root.h"
#include "Bindings/PluginManager.h"

View File

@ -1,7 +1,6 @@
#include "Globals.h"
#include "BlockDoor.h"
#include "../Item.h"
#include "../Entities/Player.h"

View File

@ -5,6 +5,7 @@
#include "../Entities/Player.h"
#include "Chunk.h"
#include "MetaRotator.h"
#include "ChunkInterface.h"

View File

@ -3,8 +3,6 @@
#include "BlockHandler.h"
#include "../Item.h"
#include "../World.h"
#include "../Root.h"
#include "../Bindings/PluginManager.h"
#include "../Chunk.h"
#include "BlockAnvil.h"
#include "BlockBed.h"
@ -68,6 +66,7 @@
#include "BlockTripwireHook.h"
#include "BlockSand.h"
#include "BlockSapling.h"
#include "BlockSeaLantern.h"
#include "BlockSideways.h"
#include "BlockSignPost.h"
#include "BlockSlab.h"
@ -84,6 +83,8 @@
#include "BlockWorkbench.h"
#include "BlockPluginInterface.h"
@ -177,12 +178,16 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
switch (a_BlockType)
{
// Block handlers, alphabetically sorted:
case E_BLOCK_ACACIA_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_ACACIA_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType);
case E_BLOCK_BEACON: return new cBlockEntityHandler (a_BlockType);
case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType);
case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType);
case E_BLOCK_BIRCH_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_BIRCH_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType);
case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
@ -200,12 +205,15 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_COBBLESTONE_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_COBWEB: return new cBlockCobWebHandler (a_BlockType);
case E_BLOCK_CROPS: return new cBlockCropsHandler (a_BlockType);
case E_BLOCK_DARK_OAK_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_DARK_OAK_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_DARK_OAK_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_DEAD_BUSH: return new cBlockDeadBushHandler (a_BlockType);
case E_BLOCK_DETECTOR_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_DIAMOND_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_DIRT: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_DISPENSER: return new cBlockDropSpenserHandler (a_BlockType);
case E_BLOCK_DOUBLE_NEW_STONE_SLAB: return new cBlockDoubleSlabHandler (a_BlockType);
case E_BLOCK_DOUBLE_STONE_SLAB: return new cBlockDoubleSlabHandler (a_BlockType);
case E_BLOCK_DOUBLE_WOODEN_SLAB: return new cBlockDoubleSlabHandler (a_BlockType);
case E_BLOCK_DROPPER: return new cBlockDropSpenserHandler (a_BlockType);
@ -231,8 +239,11 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
case E_BLOCK_IRON_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_IRON_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_IRON_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
case E_BLOCK_JACK_O_LANTERN: return new cBlockPumpkinHandler (a_BlockType);
case E_BLOCK_JUKEBOX: return new cBlockEntityHandler (a_BlockType);
case E_BLOCK_JUNGLE_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_JUNGLE_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType);
case E_BLOCK_JUNGLE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_LADDER: return new cBlockLadderHandler (a_BlockType);
case E_BLOCK_LEVER: return new cBlockLeverHandler (a_BlockType);
@ -253,6 +264,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_NEW_LEAVES: return new cBlockLeavesHandler (a_BlockType);
case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_NEW_STONE_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_NOTE_BLOCK: return new cBlockEntityHandler (a_BlockType);
case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler;
@ -264,6 +276,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType);
case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_RED_SANDSTONE_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType);
case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType);
@ -277,8 +290,10 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType);
case E_BLOCK_SANDSTONE_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_SAPLING: return new cBlockSaplingHandler (a_BlockType);
case E_BLOCK_SEA_LANTERN: return new cBlockSeaLanternHandler (a_BlockType);
case E_BLOCK_SIGN_POST: return new cBlockSignPostHandler (a_BlockType);
case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType);
case E_BLOCK_SPRUCE_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);

View File

@ -2,10 +2,6 @@
#pragma once
#include "../Defines.h"
#include "../Item.h"
#include "WorldInterface.h"
#include "ChunkInterface.h"
#include "BlockPluginInterface.h"
@ -14,6 +10,10 @@
// fwd:
class cPlayer;
class cChunk;
class cBlockPluginInterface;
class cChunkInterface;
class cWorldInterface;
class cItems;

View File

@ -151,7 +151,7 @@ public:
a_ChunkInterface.SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the wither:
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtWither);
// Award Achievement
a_WorldInterface.ForEachPlayer(PlayerCallback);
@ -181,7 +181,7 @@ public:
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
// Spawn the wither:
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtWither);
// Award Achievement
a_WorldInterface.ForEachPlayer(PlayerCallback);

View File

@ -5,6 +5,7 @@
#include "../World.h"
#include "../Entities/Player.h"
#include "BlockInServerPluginInterface.h"
#include "ChunkInterface.h"

View File

@ -4,7 +4,7 @@
#include "BlockHandler.h"
class cWorld;
class cBlockPistonHandler :
@ -94,6 +94,7 @@ private:
switch (a_BlockType)
{
case E_BLOCK_ANVIL:
case E_BLOCK_BARRIER:
case E_BLOCK_BEACON:
case E_BLOCK_BEDROCK:
case E_BLOCK_BREWING_STAND:

View File

@ -50,7 +50,7 @@ public:
int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX;
int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ;
a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman);
a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, mtZombiePigman);
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override

View File

@ -36,7 +36,7 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0);
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtSnowGolem);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtSnowGolem);
return;
}
@ -61,7 +61,7 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the golem:
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtIronGolem);
}
else if (
(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) == E_BLOCK_IRON_BLOCK) &&
@ -76,7 +76,7 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the golem:
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtIronGolem);
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, mtIronGolem);
}
}

View File

@ -4,7 +4,7 @@
#include "BlockHandler.h"
#include "Chunk.h"
#include "MetaRotator.h"
#include "ChunkInterface.h"

View File

@ -0,0 +1,30 @@
#pragma once
#include "BlockHandler.h"
class cBlockSeaLanternHandler :
public cBlockHandler
{
public:
cBlockSeaLanternHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
// Reset meta to 0
cFastRandom Random;
a_Pickups.push_back(cItem(E_ITEM_PRISMARINE_CRYSTALS, (char)(2 + Random.NextInt(2)), 0));
}
} ;

View File

@ -12,6 +12,7 @@
#include "BlockHandler.h"
#include "../Items/ItemHandler.h"
#include "Root.h"
#include "ChunkInterface.h"
@ -96,7 +97,7 @@ public:
/// Returns true if the specified blocktype is one of the slabs handled by this handler
static bool IsAnySlabType(BLOCKTYPE a_BlockType)
{
return ((a_BlockType == E_BLOCK_WOODEN_SLAB) || (a_BlockType == E_BLOCK_STONE_SLAB));
return ((a_BlockType == E_BLOCK_WOODEN_SLAB) || (a_BlockType == E_BLOCK_STONE_SLAB) || (a_BlockType == E_BLOCK_NEW_STONE_SLAB));
}
@ -119,6 +120,7 @@ public:
{
case E_BLOCK_STONE_SLAB: return E_BLOCK_DOUBLE_STONE_SLAB;
case E_BLOCK_WOODEN_SLAB: return E_BLOCK_DOUBLE_WOODEN_SLAB;
case E_BLOCK_NEW_STONE_SLAB: return E_BLOCK_DOUBLE_NEW_STONE_SLAB;
}
ASSERT(!"Unhandled slab type!");
return E_BLOCK_AIR;
@ -158,6 +160,7 @@ public:
{
case E_BLOCK_DOUBLE_STONE_SLAB: return E_BLOCK_STONE_SLAB;
case E_BLOCK_DOUBLE_WOODEN_SLAB: return E_BLOCK_WOODEN_SLAB;
case E_BLOCK_DOUBLE_NEW_STONE_SLAB: return E_BLOCK_NEW_STONE_SLAB;
}
ASSERT(!"Unhandled double slab type!");
return a_BlockType;

View File

@ -2,7 +2,7 @@
#include "BlockHandler.h"
#include "MetaRotator.h"
#include "Bindings/PluginManager.h"

View File

@ -2,7 +2,139 @@
#include "Globals.h"
#include "ChunkInterface.h"
#include "ChunkMap.h"
#include "BlockHandler.h"
#include "WorldInterface.h"
BLOCKTYPE cChunkInterface::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return m_ChunkMap->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
}
BLOCKTYPE cChunkInterface::GetBlock(const Vector3i & a_Pos)
{
return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z);
}
NIBBLETYPE cChunkInterface::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
}
bool cChunkInterface::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
{
return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
/** Sets the block at the specified coords to the specified value.
Full processing, incl. updating neighbors, is performed.
*/
void cChunkInterface::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
void cChunkInterface::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData)
{
m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData);
}
void cChunkInterface::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface)
{
m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_WorldInterface.GetWorldAge() + a_TickDelay, a_PreviousBlockType);
}
/** Sets the block at the specified coords to the specified value.
The replacement doesn't trigger block updates.
The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block)
*/
void cChunkInterface::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
void cChunkInterface::FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta);
}
void cChunkInterface::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
bool cChunkInterface::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback)
{
return m_ChunkMap->ForEachChunkInRect(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ, a_Callback);
}
bool cChunkInterface::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
}
bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z)
{
@ -10,3 +142,4 @@ bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int
Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z);
return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);
}

View File

@ -1,13 +1,13 @@
#pragma once
#include "../ChunkMap.h"
#include "../ForEachChunkProvider.h"
#include "WorldInterface.h"
class cChunkMap;
class cWorldInterface;
class cPlayer;
class cChunkInterface:
public cForEachChunkProvider
@ -16,70 +16,34 @@ public:
cChunkInterface(cChunkMap * a_ChunkMap) : m_ChunkMap(a_ChunkMap) {}
BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return m_ChunkMap->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
}
BLOCKTYPE GetBlock(const Vector3i & a_Pos)
{
return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z);
}
NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
}
BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
BLOCKTYPE GetBlock(const Vector3i & a_Pos);
NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ);
bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
{
return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
/** Sets the block at the specified coords to the specified value.
Full processing, incl. updating neighbors, is performed.
*/
void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData)
{
m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData);
}
void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData);
void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface)
{
m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_WorldInterface.GetWorldAge() + a_TickDelay, a_PreviousBlockType);
}
void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay, BLOCKTYPE a_PreviousBlockType, cWorldInterface & a_WorldInterface);
/** Sets the block at the specified coords to the specified value.
The replacement doesn't trigger block updates.
The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block)
*/
void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
}
void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta);
}
void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
{
m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ);
}
void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ);
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override
{
return m_ChunkMap->ForEachChunkInRect(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ, a_Callback);
}
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override;
virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override
{
return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
}
virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override;
bool DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z);

View File

@ -0,0 +1,91 @@
#pragma once
class cBlockTorchHandler;
class cBlockLeverHandler;
class cBlockButtonHandler;
class cBlockTripwireHookHandler;
class cBlockDoorHandler;
class cBlockPistonHandler;
template<BLOCKTYPE T>
class GetHandlerCompileTime;
template<>
class GetHandlerCompileTime<E_BLOCK_TORCH>
{
public:
typedef cBlockTorchHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_LEVER>
{
public:
typedef cBlockLeverHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_STONE_BUTTON>
{
public:
typedef cBlockButtonHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_TRIPWIRE_HOOK>
{
public:
typedef cBlockTripwireHookHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_WOODEN_DOOR>
{
public:
typedef cBlockDoorHandler type;
};
template<>
class GetHandlerCompileTime<E_BLOCK_PISTON>
{
public:
typedef cBlockPistonHandler type;
};

View File

@ -2,14 +2,15 @@
#pragma once
#include "BroadcastInterface.h"
#include "../Mobs/Monster.h"
#include "../Mobs/MonsterTypes.h"
class cItems;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
class cMonster;
class cPlayer;
class cWorldInterface
@ -33,7 +34,7 @@ public:
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) = 0;
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) = 0;
/** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */
virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0;

View File

@ -267,7 +267,7 @@ size_t cByteBuffer::GetReadableSpace(void) const
}
// Single readable space partition:
ASSERT(m_WritePos >= m_ReadPos);
return m_WritePos - m_ReadPos ;
return m_WritePos - m_ReadPos;
}
@ -489,6 +489,30 @@ bool cByteBuffer::ReadLEInt(int & a_Value)
bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
{
Int64 Value;
if (!ReadBEInt64(Value))
{
return false;
}
// Convert the 64 received bits into 3 coords:
UInt32 BlockXRaw = (Value >> 38) & 0x03ffffff; // Top 26 bits
UInt32 BlockYRaw = (Value >> 26) & 0x0fff; // Middle 12 bits
UInt32 BlockZRaw = (Value & 0x03ffffff); // Bottom 26 bits
// If the highest bit in the number's range is set, convert the number into negative:
a_BlockX = ((BlockXRaw & 0x02000000) == 0) ? BlockXRaw : -(0x04000000 - (int)BlockXRaw);
a_BlockY = ((BlockYRaw & 0x0800) == 0) ? BlockYRaw : -(0x0800 - (int)BlockYRaw);
a_BlockZ = ((BlockZRaw & 0x02000000) == 0) ? BlockZRaw : -(0x04000000 - (int)BlockZRaw);
return true;
}
bool cByteBuffer::WriteChar(char a_Value)
{
CHECK_THREAD;
@ -526,6 +550,19 @@ bool cByteBuffer::WriteBEShort(short a_Value)
bool cByteBuffer::WriteBEUShort(unsigned short a_Value)
{
CHECK_THREAD;
CheckValid();
PUTBYTES(2);
u_short Converted = htons((u_short)a_Value);
return WriteBuf(&Converted, 2);
}
bool cByteBuffer::WriteBEInt(int a_Value)
{
CHECK_THREAD;
@ -661,6 +698,15 @@ bool cByteBuffer::WriteLEInt(int a_Value)
bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return WriteBEInt64(((Int64)a_BlockX & 0x3FFFFFF) << 38 | ((Int64)a_BlockY & 0xFFF) << 26 | ((Int64)a_BlockZ & 0x3FFFFFF));
}
bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count)
{
CHECK_THREAD;

View File

@ -64,6 +64,7 @@ public:
bool ReadVarInt (UInt32 & a_Value);
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
bool ReadLEInt (int & a_Value);
bool ReadPosition (int & a_BlockX, int & a_BlockY, int & a_BlockZ);
/** Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...) */
template <typename T> bool ReadVarInt(T & a_Value)
@ -81,6 +82,7 @@ public:
bool WriteChar (char a_Value);
bool WriteByte (unsigned char a_Value);
bool WriteBEShort (short a_Value);
bool WriteBEUShort (unsigned short a_Value);
bool WriteBEInt (int a_Value);
bool WriteBEInt64 (Int64 a_Value);
bool WriteBEFloat (float a_Value);
@ -90,6 +92,7 @@ public:
bool WriteVarInt (UInt32 a_Value);
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
bool WriteLEInt (int a_Value);
bool WritePosition (int a_BlockX, int a_BlockY, int a_BlockZ);
/** Reads a_Count bytes into a_Buffer; returns true if successful */
bool ReadBuf(void * a_Buffer, size_t a_Count);

View File

@ -39,6 +39,7 @@
#include "BlockInServerPluginInterface.h"
#include "SetChunkData.h"
#include "BoundingBox.h"
#include "Blocks/ChunkInterface.h"
#include "json/json.h"
@ -92,6 +93,7 @@ cChunk::cChunk(
m_NeighborZP(a_NeighborZP),
m_WaterSimulatorData(a_World->GetWaterSimulator()->CreateChunkData()),
m_LavaSimulatorData (a_World->GetLavaSimulator ()->CreateChunkData()),
m_RedstoneSimulatorData(NULL),
m_AlwaysTicked(0)
{
if (a_NeighborXM != NULL)
@ -160,6 +162,8 @@ cChunk::~cChunk()
m_WaterSimulatorData = NULL;
delete m_LavaSimulatorData;
m_LavaSimulatorData = NULL;
delete m_RedstoneSimulatorData;
m_RedstoneSimulatorData = NULL;
}
@ -1368,9 +1372,9 @@ void cChunk::CreateBlockEntities(void)
void cChunk::WakeUpSimulators(void)
{
cSimulator * WaterSimulator = m_World->GetWaterSimulator();
cSimulator * LavaSimulator = m_World->GetLavaSimulator();
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
cSimulator<cChunk, cWorld> * WaterSimulator = m_World->GetWaterSimulator();
cSimulator<cChunk, cWorld> * LavaSimulator = m_World->GetLavaSimulator();
cSimulator<cChunk, cWorld> * RedstoneSimulator = m_World->GetRedstoneSimulator();
int BaseX = m_PosX * cChunkDef::Width;
int BaseZ = m_PosZ * cChunkDef::Width;
for (int x = 0; x < Width; x++)
@ -3046,7 +3050,7 @@ void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation
void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude)
void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude)
{
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{
@ -3054,7 +3058,7 @@ void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src
{
continue;
}
(*itr)->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount);
(*itr)->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount);
} // for itr - LoadedByClient[]
}

View File

@ -9,7 +9,9 @@
#include "Simulator/SandSimulator.h"
#include "Simulator/IncrementalRedstoneSimulator.h"
#include "Blocks/GetHandlerCompileTimeTemplate.h"
#include "ChunkMap.h"
@ -29,7 +31,10 @@ class MTRand;
class cPlayer;
class cChunkMap;
class cBeaconEntity;
class cBoundingBox;
class cChestEntity;
class cCHunkDataCallback;
class cCommandBlockEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cNoteEntity;
@ -44,6 +49,7 @@ class cFluidSimulatorData;
class cMobCensus;
class cMobSpawner;
class cRedstonePoweredEntity;
class cSetChunkData;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback;
@ -326,7 +332,7 @@ public:
void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL);
void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL);
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL);
@ -414,12 +420,7 @@ public:
cFluidSimulatorData * GetLavaSimulatorData (void) { return m_LavaSimulatorData; }
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; }
cRedstoneSimulatorChunkData * GetRedstoneSimulatorQueuedData(void) { return &m_RedstoneSimulatorQueuedData; }
cIncrementalRedstoneSimulator::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; }
cIncrementalRedstoneSimulator::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; }
cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; }
cIncrementalRedstoneSimulator::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; }
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return m_RedstoneSimulatorData; }
bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; }
void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; }
@ -504,12 +505,8 @@ private:
cFluidSimulatorData * m_LavaSimulatorData;
cSandSimulatorChunkData m_SandSimulatorData;
cRedstoneSimulatorChunkData m_RedstoneSimulatorData;
cRedstoneSimulatorChunkData m_RedstoneSimulatorQueuedData;
cIncrementalRedstoneSimulator::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList;
cIncrementalRedstoneSimulator::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList;
cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList;
cIncrementalRedstoneSimulator::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList;
cRedstoneSimulatorChunkData * m_RedstoneSimulatorData;
/** Indicates if simulate-once blocks should be updated by the redstone simulator */
bool m_IsRedstoneDirty;

View File

@ -17,7 +17,7 @@
#include "MobSpawner.h"
#include "BoundingBox.h"
#include "SetChunkData.h"
#include "Blocks/ChunkInterface.h"
#include "Entities/Pickup.h"
#ifndef _WIN32
@ -617,7 +617,7 @@ void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animat
void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude)
void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
@ -629,7 +629,7 @@ void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
Chunk->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount, a_Exclude);
Chunk->BroadcastParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount, a_Exclude);
}

View File

@ -87,7 +87,7 @@ public:
void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL);
void BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude = NULL);
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL);

View File

@ -12,6 +12,7 @@
#include "World.h"
#include "BlockEntities/BlockEntity.h"
#include "Protocol/ChunkDataSerializer.h"
#include "ClientHandle.h"

View File

@ -124,13 +124,14 @@ cClientHandle::~cClientHandle()
if (m_Player != NULL)
{
cWorld * World = m_Player->GetWorld();
if (!m_Username.empty() && (World != NULL))
{
// Send the Offline PlayerList packet:
World->BroadcastPlayerListItem(*m_Player, false, this);
}
if (World != NULL)
{
if (!m_Username.empty())
{
// Send the Offline PlayerList packet:
World->BroadcastPlayerListRemovePlayer(*m_Player, this);
}
World->RemovePlayer(m_Player, true); // Must be called before cPlayer::Destroy() as otherwise cChunk tries to delete the player, and then we do it again
m_Player->Destroy();
}
@ -370,7 +371,12 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
// Send experience
m_Player->SendExperience();
// Send player list items
SendPlayerListAddPlayer(*m_Player);
World->BroadcastPlayerListAddPlayer(*m_Player);
World->SendPlayerList(m_Player);
m_Player->Initialize(*World);
m_State = csAuthenticated;
@ -1206,50 +1212,61 @@ void cClientHandle::FinishDigAnimation()
void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem)
{
// TODO: Rewrite this function
LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s",
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str()
);
cWorld * World = m_Player->GetWorld();
bool AreRealCoords = (Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5;
if (
(a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block
(
(Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || // The block is too far away
(Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
(Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)
)
IsValidBlock(a_HeldItem.m_ItemType) &&
!AreRealCoords
)
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
if (a_BlockY < cChunkDef::Height - 1)
if ((a_BlockX != -1) && (a_BlockY >= 0) && (a_BlockZ != -1))
{
World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
}
if (a_BlockY > 0)
{
World->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, m_Player); // 2 block high things
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
if (a_BlockY < cChunkDef::Height - 1)
{
World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
}
if (a_BlockY > 0)
{
World->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, m_Player); // 2 block high things
}
}
m_Player->GetInventory().SendEquippedSlot();
return;
}
if (!AreRealCoords)
{
a_BlockFace = BLOCK_FACE_NONE;
}
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
{
// A plugin doesn't agree with the action, replace the block on the client and quit:
cChunkInterface ChunkInterface(World->GetChunkMap());
BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
if (a_BlockFace != BLOCK_FACE_NONE)
if (AreRealCoords)
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
m_Player->GetInventory().SendEquippedSlot();
cChunkInterface ChunkInterface(World->GetChunkMap());
BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
if (a_BlockFace != BLOCK_FACE_NONE)
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
m_Player->GetInventory().SendEquippedSlot();
}
}
return;
}
@ -1282,22 +1299,25 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
return;
}
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
if (BlockHandler->IsUseable() && !m_Player->IsCrouched())
if (AreRealCoords)
{
if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
if (BlockHandler->IsUseable() && !m_Player->IsCrouched())
{
// A plugin doesn't agree with using the block, abort
if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
{
// A plugin doesn't agree with using the block, abort
return;
}
cChunkInterface ChunkInterface(World->GetChunkMap());
BlockHandler->OnUse(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
return;
}
cChunkInterface ChunkInterface(World->GetChunkMap());
BlockHandler->OnUse(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
return;
}
short EquippedDamage = Equipped.m_ItemDamage;
@ -2326,18 +2346,18 @@ void cClientHandle::SendInventorySlot(char a_WindowID, short a_SlotNum, const cI
void cClientHandle::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length)
void cClientHandle::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale)
{
m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length);
m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length, m_Scale);
}
void cClientHandle::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
void cClientHandle::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale)
{
m_Protocol->SendMapDecorators(a_ID, a_Decorators);
m_Protocol->SendMapDecorators(a_ID, a_Decorators, m_Scale);
}
@ -2353,9 +2373,9 @@ void cClientHandle::SendMapInfo(int a_ID, unsigned int a_Scale)
void cClientHandle::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount)
void cClientHandle::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount)
{
m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount);
m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount);
}
@ -2397,9 +2417,45 @@ void cClientHandle::SendPlayerAbilities()
void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline)
void cClientHandle::SendPlayerListAddPlayer(const cPlayer & a_Player)
{
m_Protocol->SendPlayerListItem(a_Player, a_IsOnline);
m_Protocol->SendPlayerListAddPlayer(a_Player);
}
void cClientHandle::SendPlayerListRemovePlayer(const cPlayer & a_Player)
{
m_Protocol->SendPlayerListRemovePlayer(a_Player);
}
void cClientHandle::SendPlayerListUpdateGameMode(const cPlayer & a_Player)
{
m_Protocol->SendPlayerListUpdateGameMode(a_Player);
}
void cClientHandle::SendPlayerListUpdatePing(const cPlayer & a_Player)
{
m_Protocol->SendPlayerListUpdatePing(a_Player);
}
void cClientHandle::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName)
{
m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_CustomName);
}

View File

@ -134,73 +134,77 @@ public:
// The following functions send the various packets:
// (Please keep these alpha-sorted)
void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType);
void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export
void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes);
void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
void SendChat (const cCompositeChat & a_Message);
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player);
void SendDestroyEntity (const cEntity & a_Entity);
void SendDisconnect (const AString & a_Reason);
void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration);
void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item);
void SendEntityHeadLook (const cEntity & a_Entity);
void SendEntityLook (const cEntity & a_Entity);
void SendEntityMetadata (const cEntity & a_Entity);
void SendEntityProperties (const cEntity & a_Entity);
void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityStatus (const cEntity & a_Entity, char a_Status);
void SendEntityVelocity (const cEntity & a_Entity);
void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion);
void SendGameMode (eGameMode a_GameMode);
void SendHealth (void);
void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item);
void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length);
void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators);
void SendMapInfo (int a_ID, unsigned int a_Scale);
void SendPaintingSpawn (const cPainting & a_Painting);
void SendPickupSpawn (const cPickup & a_Pickup);
void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export
void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount);
void SendPlayerAbilities (void);
void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline);
void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+)
void SendPlayerMoveLook (void);
void SendPlayerPosition (void);
void SendPlayerSpawn (const cPlayer & a_Player);
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false);
void SendExperience (void);
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode);
void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display);
void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export
void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data);
void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock);
void SendSpawnMob (const cMonster & a_Mob);
void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch);
void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType = 0);
void SendStatistics (const cStatManager & a_Manager);
void SendTabCompletionResults(const AStringVector & a_Results);
void SendTeleportEntity (const cEntity & a_Entity);
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export
void SendUnloadChunk (int a_ChunkX, int a_ChunkZ);
void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity);
void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ);
void SendWeather (eWeather a_Weather);
void SendWholeInventory (const cWindow & a_Window);
void SendWindowClose (const cWindow & a_Window);
void SendWindowOpen (const cWindow & a_Window);
void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value);
void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType);
void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export
void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes);
void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
void SendChat (const cCompositeChat & a_Message);
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player);
void SendDestroyEntity (const cEntity & a_Entity);
void SendDisconnect (const AString & a_Reason);
void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration);
void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item);
void SendEntityHeadLook (const cEntity & a_Entity);
void SendEntityLook (const cEntity & a_Entity);
void SendEntityMetadata (const cEntity & a_Entity);
void SendEntityProperties (const cEntity & a_Entity);
void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityStatus (const cEntity & a_Entity, char a_Status);
void SendEntityVelocity (const cEntity & a_Entity);
void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion);
void SendGameMode (eGameMode a_GameMode);
void SendHealth (void);
void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item);
void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale);
void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale);
void SendMapInfo (int a_ID, unsigned int a_Scale);
void SendPaintingSpawn (const cPainting & a_Painting);
void SendPickupSpawn (const cPickup & a_Pickup);
void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export
void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount);
void SendPlayerAbilities (void);
void SendPlayerListAddPlayer (const cPlayer & a_Player);
void SendPlayerListRemovePlayer (const cPlayer & a_Player);
void SendPlayerListUpdateGameMode (const cPlayer & a_Player);
void SendPlayerListUpdatePing (const cPlayer & a_Player);
void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName);
void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+)
void SendPlayerMoveLook (void);
void SendPlayerPosition (void);
void SendPlayerSpawn (const cPlayer & a_Player);
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false);
void SendExperience (void);
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode);
void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display);
void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export
void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data);
void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock);
void SendSpawnMob (const cMonster & a_Mob);
void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch);
void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType = 0);
void SendStatistics (const cStatManager & a_Manager);
void SendTabCompletionResults (const AStringVector & a_Results);
void SendTeleportEntity (const cEntity & a_Entity);
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export
void SendUnloadChunk (int a_ChunkX, int a_ChunkZ);
void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity);
void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ);
void SendWeather (eWeather a_Weather);
void SendWholeInventory (const cWindow & a_Window);
void SendWindowClose (const cWindow & a_Window);
void SendWindowOpen (const cWindow & a_Window);
void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value);
// tolua_begin
const AString & GetUsername(void) const;

View File

@ -5,6 +5,7 @@
#include "Globals.h"
#include "CompositeChat.h"
#include "ClientHandle.h"
@ -399,6 +400,183 @@ void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle)
AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const
{
Json::Value msg;
msg["text"] = cClientHandle::FormatMessageType(a_ShouldUseChatPrefixes, GetMessageType(), GetAdditionalMessageTypeData()); // The client crashes without this field being present
const cCompositeChat::cParts & Parts = GetParts();
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
{
Json::Value Part;
switch ((*itr)->m_PartType)
{
case cCompositeChat::ptText:
{
Part["text"] = (*itr)->m_Text;
AddChatPartStyle(Part, (*itr)->m_Style);
break;
}
case cCompositeChat::ptClientTranslated:
{
const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
Part["translate"] = p.m_Text;
Json::Value With;
for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
{
With.append(*itrW);
}
if (!p.m_Parameters.empty())
{
Part["with"] = With;
}
AddChatPartStyle(Part, p.m_Style);
break;
}
case cCompositeChat::ptUrl:
{
const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
Part["text"] = p.m_Text;
Json::Value Url;
Url["action"] = "open_url";
Url["value"] = p.m_Url;
Part["clickEvent"] = Url;
AddChatPartStyle(Part, p.m_Style);
break;
}
case cCompositeChat::ptSuggestCommand:
case cCompositeChat::ptRunCommand:
{
const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
Part["text"] = p.m_Text;
Json::Value Cmd;
Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
Cmd["value"] = p.m_Command;
Part["clickEvent"] = Cmd;
AddChatPartStyle(Part, p.m_Style);
break;
}
case cCompositeChat::ptShowAchievement:
{
const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
Part["translate"] = "chat.type.achievement";
Json::Value Ach;
Ach["action"] = "show_achievement";
Ach["value"] = p.m_Text;
Json::Value AchColourAndName;
AchColourAndName["color"] = "green";
AchColourAndName["translate"] = p.m_Text;
AchColourAndName["hoverEvent"] = Ach;
Json::Value Extra;
Extra.append(AchColourAndName);
Json::Value Name;
Name["text"] = p.m_PlayerName;
Json::Value With;
With.append(Name);
With.append(Extra);
Part["with"] = With;
AddChatPartStyle(Part, p.m_Style);
break;
}
}
msg["extra"].append(Part);
} // for itr - Parts[]
return msg.toStyledString();
}
void cCompositeChat::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const
{
size_t len = a_PartStyle.length();
for (size_t i = 0; i < len; i++)
{
switch (a_PartStyle[i])
{
case 'b':
{
// bold
a_Value["bold"] = Json::Value(true);
break;
}
case 'i':
{
// italic
a_Value["italic"] = Json::Value(true);
break;
}
case 'u':
{
// Underlined
a_Value["underlined"] = Json::Value(true);
break;
}
case 's':
{
// strikethrough
a_Value["strikethrough"] = Json::Value(true);
break;
}
case 'o':
{
// obfuscated
a_Value["obfuscated"] = Json::Value(true);
break;
}
case '@':
{
// Color, specified by the next char:
i++;
if (i >= len)
{
// String too short, didn't contain a color
break;
}
switch (a_PartStyle[i])
{
case '0': a_Value["color"] = Json::Value("black"); break;
case '1': a_Value["color"] = Json::Value("dark_blue"); break;
case '2': a_Value["color"] = Json::Value("dark_green"); break;
case '3': a_Value["color"] = Json::Value("dark_aqua"); break;
case '4': a_Value["color"] = Json::Value("dark_red"); break;
case '5': a_Value["color"] = Json::Value("dark_purple"); break;
case '6': a_Value["color"] = Json::Value("gold"); break;
case '7': a_Value["color"] = Json::Value("gray"); break;
case '8': a_Value["color"] = Json::Value("dark_gray"); break;
case '9': a_Value["color"] = Json::Value("blue"); break;
case 'a': a_Value["color"] = Json::Value("green"); break;
case 'b': a_Value["color"] = Json::Value("aqua"); break;
case 'c': a_Value["color"] = Json::Value("red"); break;
case 'd': a_Value["color"] = Json::Value("light_purple"); break;
case 'e': a_Value["color"] = Json::Value("yellow"); break;
case 'f': a_Value["color"] = Json::Value("white"); break;
} // switch (color)
} // case '@'
} // switch (Style[i])
} // for i - a_PartStyle[]
}
////////////////////////////////////////////////////////////////////////////////
// cCompositeChat::cBasePart:

View File

@ -4,6 +4,7 @@
// Declares the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd)
#include "Defines.h"
#include "json/json.h"
@ -189,6 +190,8 @@ public:
Used for older protocols that don't support composite chat
and for console-logging. */
AString ExtractText(void) const;
AString CreateJsonString(bool a_ShouldUseChatPrefixes = true) const;
// tolua_end
@ -197,6 +200,9 @@ public:
/** Converts the MessageType to a LogLevel value.
Used by the logging bindings when logging a cCompositeChat object. */
static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType);
/** Adds the chat part's style (represented by the part's stylestring) into the Json object. */
void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const;
protected:
/** All the parts that */

View File

@ -3,7 +3,6 @@
#include "Player.h"
#include "ArrowEntity.h"
#include "../Chunk.h"
#include "FastRandom.h"

View File

@ -62,6 +62,8 @@ bool cBoat::DoTakeDamage(TakeDamageInfo & TDI)
void cBoat::OnRightClicked(cPlayer & a_Player)
{
super::OnRightClicked(a_Player);
if (m_Attachee != NULL)
{
if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID())

View File

@ -3,8 +3,8 @@
#include "EnderCrystal.h"
#include "ClientHandle.h"
#include "Player.h"
#include "../Chunk.h"
#include "../World.h"

View File

@ -3,7 +3,6 @@
#include "Entity.h"
#include "../World.h"
#include "../Server.h"
#include "../Root.h"
#include "../Matrix4.h"
#include "../ClientHandle.h"
@ -135,7 +134,7 @@ const char * cEntity::GetParentClass(void) const
bool cEntity::Initialize(cWorld & a_World)
{
if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this))
if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this) && !IsPlayer())
{
return false;
}
@ -260,7 +259,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
void cEntity::SetYawFromSpeed(void)
{
const double EPS = 0.0000001;
if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS))
if ((std::abs(m_Speed.x) < EPS) && (std::abs(m_Speed.z) < EPS))
{
// atan2() may overflow or is undefined, pick any number
SetYaw(0);
@ -277,7 +276,7 @@ void cEntity::SetPitchFromSpeed(void)
{
const double EPS = 0.0000001;
double xz = sqrt(m_Speed.x * m_Speed.x + m_Speed.z * m_Speed.z); // Speed XZ-plane component
if ((abs(xz) < EPS) && (abs(m_Speed.y) < EPS))
if ((std::abs(xz) < EPS) && (std::abs(m_Speed.y) < EPS))
{
// atan2() may overflow or is undefined, pick any number
SetPitch(0);
@ -334,14 +333,15 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
cMonster * Monster = (cMonster *)this;
switch (Monster->GetMobType())
{
case cMonster::mtSkeleton:
case cMonster::mtZombie:
case cMonster::mtWither:
case cMonster::mtZombiePigman:
case mtSkeleton:
case mtZombie:
case mtWither:
case mtZombiePigman:
{
a_TDI.FinalDamage += (int)ceil(2.5 * SmiteLevel);
break;
}
default: break;
}
}
}
@ -352,9 +352,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
cMonster * Monster = (cMonster *)this;
switch (Monster->GetMobType())
{
case cMonster::mtSpider:
case cMonster::mtCaveSpider:
case cMonster::mtSilverfish:
case mtSpider:
case mtCaveSpider:
case mtSilverfish:
{
a_TDI.RawDamage += (int)ceil(2.5 * BaneOfArthropodsLevel);
// TODO: Add slowness effect
@ -384,9 +384,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
cMonster * Monster = (cMonster *)this;
switch (Monster->GetMobType())
{
case cMonster::mtGhast:
case cMonster::mtZombiePigman:
case cMonster::mtMagmaCube:
case mtGhast:
case mtZombiePigman:
case mtMagmaCube:
{
break;
};
@ -1015,7 +1015,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f;
if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f;
if (Tracer.HitNormal.y == 1) // Hit BLOCK_FACE_YP, we are on the ground
if (Tracer.HitNormal.y == 1.f) // Hit BLOCK_FACE_YP, we are on the ground
{
m_bOnGround = true;
}
@ -1960,7 +1960,7 @@ void cEntity::SteerVehicle(float a_Forward, float a_Sideways)
{
return;
}
if ((a_Forward != 0) || (a_Sideways != 0))
if ((a_Forward != 0.f) || (a_Sideways != 0.f))
{
m_AttachedTo->HandleSpeedFromAttachee(a_Forward, a_Sideways);
}

View File

@ -447,7 +447,7 @@ public:
// tolua_end
/// Called when the specified player right-clicks this entity
virtual void OnRightClicked(cPlayer &) {}
virtual void OnRightClicked(cPlayer & a_Player) {}
/// Returns the list of drops for this pawn when it is killed. May check a_Killer for special handling (sword of looting etc.). Called from KilledBy().
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL)

View File

@ -96,6 +96,7 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage)
base = 1800;
break;
}
default: break;
}
// If potion is level II, half the duration. If not, stays the same
@ -435,8 +436,8 @@ void cEntityEffectPoison::OnTick(cPawn & a_Target)
// Doesn't effect undead mobs, spiders
if (
Target.IsUndead() ||
(Target.GetMobType() == cMonster::mtSpider) ||
(Target.GetMobType() == cMonster::mtCaveSpider)
(Target.GetMobType() == mtSpider) ||
(Target.GetMobType() == mtCaveSpider)
)
{
return;

View File

@ -18,10 +18,27 @@ cExpBottleEntity::cExpBottleEntity(cEntity * a_Creator, double a_X, double a_Y,
void cExpBottleEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
Break(a_HitPos);
}
void cExpBottleEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
{
Break(a_HitPos);
}
void cExpBottleEntity::Break(const Vector3d &a_HitPos)
{
// Spawn an experience orb with a reward between 3 and 11.
m_World->BroadcastSoundParticleEffect(2002, POSX_TOINT, POSY_TOINT, POSZ_TOINT, 0);
m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), 3 + m_World->GetTickRandomNumber(8));
Destroy();
}

View File

@ -29,5 +29,10 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
/** Breaks the bottle, fires its particle effects and sounds
@param a_HitPos The position where the bottle will break */
void Break(const Vector3d &a_HitPos);
}; // tolua_export

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