the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 281 lines 6.2 kB view raw
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}