the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.entity.h"
3#include "net.minecraft.world.level.tile.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.damagesource.h"
6#include "com.mojang.nbt.h"
7#include "FallingTile.h"
8
9
10
11// 4J - added for common ctor code
12void FallingTile::_init()
13{
14 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
15 // the derived version of the function is called
16 this->defineSynchedData();
17
18 tile = 0;
19 data = 0;
20 time = 0;
21 dropItem = true;
22
23 cancelDrop = false;
24 hurtEntities = false;
25 fallDamageMax = 40;
26 fallDamageAmount = 2;
27 tileData = NULL;
28
29 // 4J Added so that client-side falling tiles can fall through blocks
30 // This fixes a bug on the host where the tile update from the server comes in before the client-side falling tile
31 // has reached that level, causing it to stop at one block higher.
32 m_ignoreVerticalCollisions = level->isClientSide;
33}
34
35FallingTile::FallingTile(Level *level) :
36 Entity( level )
37{
38 _init();
39}
40
41FallingTile::FallingTile(Level *level, double x, double y, double z, int tile, int data) : Entity( level )
42{
43 _init();
44
45 this->tile = tile;
46 this->data = data;
47 blocksBuilding = true;
48 setSize(0.98f, 0.98f);
49 heightOffset = bbHeight / 2.0f;
50 setPos(x, y, z);
51
52 xd = 0;
53 yd = 0;
54 zd = 0;
55
56 xo = x;
57 yo = y;
58 zo = z;
59
60 // 4J added - without this newly created falling tiles weren't interpolating their render positions correctly
61 xOld = x;
62 yOld = y;
63 zOld = z;
64}
65
66FallingTile::~FallingTile()
67{
68 delete tileData;
69}
70
71bool FallingTile::makeStepSound()
72{
73 return false;
74}
75
76void FallingTile::defineSynchedData()
77{
78}
79
80bool FallingTile::isPickable()
81{
82 return !removed;
83}
84
85void FallingTile::tick()
86{
87 if (tile == 0)
88 {
89 remove();
90 return;
91 }
92
93 xo = x;
94 yo = y;
95 zo = z;
96 time++;
97
98 yd -= 0.04f;
99 move(xd, yd, zd);
100 xd *= 0.98f;
101 yd *= 0.98f;
102 zd *= 0.98f;
103
104 if(!level->isClientSide)
105 {
106
107 int xt = Mth::floor(x);
108 int yt = Mth::floor(y);
109 int zt = Mth::floor(z);
110 if(time == 1)
111 {
112 if (level->getTile(xt, yt, zt) == tile)
113 {
114 level->removeTile(xt, yt, zt);
115 }
116 else
117 {
118 remove();
119 return;
120 }
121 }
122
123 if (onGround)
124 {
125 xd *= 0.7f;
126 zd *= 0.7f;
127 yd *= -0.5f;
128
129 if (level->getTile(xt, yt, zt) != Tile::pistonMovingPiece_Id)
130 {
131 remove();
132 if (!cancelDrop && level->mayPlace(tile, xt, yt, zt, true, 1, nullptr, nullptr) && !HeavyTile::isFree(level, xt, yt - 1, zt) && level->setTileAndData(xt, yt, zt, tile, data, Tile::UPDATE_ALL))
133 {
134 HeavyTile *hv = dynamic_cast<HeavyTile *>(Tile::tiles[tile]);
135 if (hv)
136 {
137 hv->onLand(level, xt, yt, zt, data);
138 }
139 if (tileData != NULL && Tile::tiles[tile]->isEntityTile())
140 {
141 shared_ptr<TileEntity> tileEntity = level->getTileEntity(xt, yt, zt);
142
143 if (tileEntity != NULL)
144 {
145 CompoundTag *swap = new CompoundTag();
146 tileEntity->save(swap);
147 vector<Tag *> *allTags = tileData->getAllTags();
148 for(AUTO_VAR(it, allTags->begin()); it != allTags->end(); ++it)
149 {
150 Tag *tag = *it;
151 if (tag->getName().compare(L"x") == 0 || tag->getName().compare(L"y") == 0 || tag->getName().compare(L"z") == 0) continue;
152 swap->put(tag->getName(), tag->copy());
153 }
154 delete allTags;
155 tileEntity->load(swap);
156 tileEntity->setChanged();
157 }
158 }
159 }
160 else
161 {
162 if(dropItem && !cancelDrop) spawnAtLocation( shared_ptr<ItemInstance>(new ItemInstance(tile, 1, Tile::tiles[tile]->getSpawnResourcesAuxValue(data))), 0);
163 }
164 }
165 }
166 else if ( (time > 20 * 5 && !level->isClientSide && (yt < 1 || yt > Level::maxBuildHeight)) || (time > 20 * 30))
167 {
168 if(dropItem) spawnAtLocation( shared_ptr<ItemInstance>( new ItemInstance(tile, 1, Tile::tiles[tile]->getSpawnResourcesAuxValue(data) )), 0);
169 remove();
170 }
171 }
172}
173
174void FallingTile::causeFallDamage(float distance)
175{
176 if (hurtEntities)
177 {
178 int dmg = Mth::ceil(distance - 1);
179 if (dmg > 0)
180 {
181 // 4J: Copy vector since it might be modified when we hurt the entities (invalidating our iterator)
182 vector<shared_ptr<Entity> > *entities = new vector<shared_ptr<Entity> >(*level->getEntities(shared_from_this(), bb));
183 DamageSource *source = tile == Tile::anvil_Id ? DamageSource::anvil : DamageSource::fallingBlock;
184 //for (Entity entity : entities)
185 for(AUTO_VAR(it, entities->begin()); it != entities->end(); ++it)
186 {
187 (*it)->hurt(source, min(Mth::floor(dmg * fallDamageAmount), fallDamageMax));
188 }
189 delete entities;
190
191 if (tile == Tile::anvil_Id && random->nextFloat() < 0.05f + (dmg * 0.05))
192 {
193 int damage = data >> 2;
194 int dir = data & 3;
195
196 if (++damage > 2)
197 {
198 cancelDrop = true;
199 }
200 else
201 {
202 data = dir | (damage << 2);
203 }
204 }
205 }
206 }
207}
208
209void FallingTile::addAdditonalSaveData(CompoundTag *tag)
210{
211 tag->putByte(L"Tile", (byte) tile);
212 tag->putInt(L"TileID", tile);
213 tag->putByte(L"Data", (byte) data);
214 tag->putByte(L"Time", (byte) time);
215 tag->putBoolean(L"DropItem", dropItem);
216 tag->putBoolean(L"HurtEntities", hurtEntities);
217 tag->putFloat(L"FallHurtAmount", fallDamageAmount);
218 tag->putInt(L"FallHurtMax", fallDamageMax);
219 if (tileData != NULL) tag->putCompound(L"TileEntityData", tileData);
220}
221
222void FallingTile::readAdditionalSaveData(CompoundTag *tag)
223{
224 if (tag->contains(L"TileID"))
225 {
226 tile = tag->getInt(L"TileID");
227 }
228 else
229 {
230 tile = tag->getByte(L"Tile") & 0xff;
231 }
232 data = tag->getByte(L"Data") & 0xff;
233 time = tag->getByte(L"Time") & 0xff;
234
235 if (tag->contains(L"HurtEntities"))
236 {
237 hurtEntities = tag->getBoolean(L"HurtEntities");
238 fallDamageAmount = tag->getFloat(L"FallHurtAmount");
239 fallDamageMax = tag->getInt(L"FallHurtMax");
240 }
241 else if (tile == Tile::anvil_Id)
242 {
243 hurtEntities = true;
244 }
245
246 if (tag->contains(L"DropItem"))
247 {
248 dropItem = tag->getBoolean(L"DropItem");
249 }
250
251 if (tag->contains(L"TileEntityData"))
252 {
253 tileData = tag->getCompound(L"TileEntityData");
254 }
255
256 if (tile == 0)
257 {
258 tile = Tile::sand_Id;
259 }
260}
261
262
263float FallingTile::getShadowHeightOffs()
264{
265 return 0;
266}
267
268Level *FallingTile::getLevel()
269{
270 return level;
271}
272
273void FallingTile::setHurtsEntities(bool value)
274{
275 this->hurtEntities = value;
276}
277
278bool FallingTile::displayFireAnimation()
279{
280 return false;
281}