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 "JavaMath.h"
3#include "net.minecraft.stats.h"
4#include "net.minecraft.world.entity.h"
5#include "net.minecraft.world.level.h"
6#include "net.minecraft.world.level.tile.h"
7#include "net.minecraft.world.phys.h"
8#include "net.minecraft.world.item.h"
9#include "net.minecraft.world.entity.player.h"
10#include "net.minecraft.world.level.material.h"
11#include "net.minecraft.world.damagesource.h"
12#include "com.mojang.nbt.h"
13#include "ItemEntity.h"
14#include "SoundTypes.h"
15
16
17
18void ItemEntity::_init()
19{
20 age = 0;
21 throwTime = 0;
22 health = 5;
23 bobOffs = (float) (Math::random() * PI * 2);
24
25 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
26 // the derived version of the function is called
27 this->defineSynchedData();
28
29 setSize(0.25f, 0.25f);
30 heightOffset = bbHeight / 2.0f;
31}
32
33void ItemEntity::_init(Level *level, double x, double y, double z)
34{
35 _init();
36
37 setPos(x, y, z);
38
39 yRot = (float) (Math::random() * 360);
40
41 xd = (float) (Math::random() * 0.2f - 0.1f);
42 yd = +0.2f;
43 zd = (float) (Math::random() * 0.2f - 0.1f);
44}
45
46ItemEntity::ItemEntity(Level *level, double x, double y, double z) : Entity(level)
47{
48 _init(level,x,y,z);
49}
50
51ItemEntity::ItemEntity(Level *level, double x, double y, double z, shared_ptr<ItemInstance> item) : Entity( level )
52{
53 _init(level,x,y,z);
54 setItem(item);
55}
56
57bool ItemEntity::makeStepSound()
58{
59 return false;
60}
61
62ItemEntity::ItemEntity(Level *level) : Entity( level )
63{
64 _init();
65}
66
67void ItemEntity::defineSynchedData()
68{
69 getEntityData()->defineNULL(DATA_ITEM, NULL);
70}
71
72void ItemEntity::tick()
73{
74 Entity::tick();
75
76 if (throwTime > 0) throwTime--;
77 xo = x;
78 yo = y;
79 zo = z;
80
81 yd -= 0.04f;
82 noPhysics = checkInTile(x, (bb->y0 + bb->y1) / 2, z);
83
84 // 4J - added parameter here so that these don't care about colliding with other entities
85 move(xd, yd, zd, true);
86
87 bool moved = (int) xo != (int) x || (int) yo != (int) y || (int) zo != (int) z;
88
89 if (moved || tickCount % 25 == 0)
90 {
91 if (level->getMaterial( Mth::floor(x), Mth::floor(y), Mth::floor(z)) == Material::lava)
92 {
93 yd = 0.2f;
94 xd = (random->nextFloat() - random->nextFloat()) * 0.2f;
95 zd = (random->nextFloat() - random->nextFloat()) * 0.2f;
96 MemSect(31);
97 playSound(eSoundType_RANDOM_FIZZ, 0.4f, 2.0f + random->nextFloat() * 0.4f);
98 MemSect(0);
99 }
100
101 if (!level->isClientSide)
102 {
103 mergeWithNeighbours();
104 }
105 }
106
107 float friction = 0.98f;
108 if (onGround)
109 {
110 friction = 0.6f * 0.98f;
111 int t = level->getTile( Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z) );
112 if (t > 0)
113 {
114 friction = Tile::tiles[t]->friction * 0.98f;
115 }
116 }
117
118 xd *= friction;
119 yd *= 0.98f;
120 zd *= friction;
121
122 if (onGround)
123 {
124 yd *= -0.5f;
125 }
126
127 tickCount++;
128 age++;
129 if (!level->isClientSide && age >= LIFETIME)
130 {
131 remove();
132 }
133}
134
135void ItemEntity::mergeWithNeighbours()
136{
137 vector<shared_ptr<Entity> > *neighbours = level->getEntitiesOfClass(typeid(*this), bb->grow(0.5, 0, 0.5));
138 for(AUTO_VAR(it, neighbours->begin()); it != neighbours->end(); ++it)
139 {
140 shared_ptr<ItemEntity> entity = dynamic_pointer_cast<ItemEntity>(*it);
141 merge(entity);
142 }
143 delete neighbours;
144}
145
146bool ItemEntity::merge(shared_ptr<ItemEntity> target)
147{
148 if (target == shared_from_this()) return false;
149 if (!target->isAlive() || !this->isAlive()) return false;
150 shared_ptr<ItemInstance> myItem = this->getItem();
151 shared_ptr<ItemInstance> targetItem = target->getItem();
152
153 if (targetItem->getItem() != myItem->getItem()) return false;
154 if (targetItem->hasTag() ^ myItem->hasTag()) return false;
155 if (targetItem->hasTag() && !targetItem->getTag()->equals(myItem->getTag())) return false;
156 if (targetItem->getItem()->isStackedByData() && targetItem->getAuxValue() != myItem->getAuxValue()) return false;
157 if (targetItem->count < myItem->count) return target->merge(dynamic_pointer_cast<ItemEntity>(shared_from_this()));
158 if (targetItem->count + myItem->count > targetItem->getMaxStackSize()) return false;
159
160 targetItem->count += myItem->count;
161 target->throwTime = max(target->throwTime, this->throwTime);
162 target->age = min(target->age, this->age);
163 target->setItem(targetItem);
164 remove();
165
166 return true;
167}
168
169void ItemEntity::setShortLifeTime()
170{
171 // reduce lifetime to one minute
172 age = LIFETIME - (60 * SharedConstants::TICKS_PER_SECOND);
173}
174
175bool ItemEntity::updateInWaterState()
176{
177 return level->checkAndHandleWater(bb, Material::water, shared_from_this());
178}
179
180
181void ItemEntity::burn(int dmg)
182{
183 hurt(DamageSource::inFire, dmg);
184}
185
186
187bool ItemEntity::hurt(DamageSource *source, float damage)
188{
189 // 4J - added next line: found whilst debugging an issue with item entities getting into a bad state when being created by a cactus, since entities insides cactuses get hurt
190 // and therefore depending on the timing of things they could get removed from the client when they weren't supposed to be. Are there really any cases were we would want
191 // an itemEntity to be locally hurt?
192 if (level->isClientSide ) return false;
193
194 if (isInvulnerable()) return false;
195 if (getItem() != NULL && getItem()->id == Item::netherStar_Id && source->isExplosion()) return false;
196 markHurt();
197 health -= damage;
198 if (health <= 0)
199 {
200 remove();
201 }
202 return false;
203}
204
205void ItemEntity::addAdditonalSaveData(CompoundTag *entityTag)
206{
207 entityTag->putShort(L"Health", (byte) health);
208 entityTag->putShort(L"Age", (short) age);
209 if (getItem() != NULL) entityTag->putCompound(L"Item", getItem()->save(new CompoundTag()));
210}
211
212void ItemEntity::readAdditionalSaveData(CompoundTag *tag)
213{
214 health = tag->getShort(L"Health") & 0xff;
215 age = tag->getShort(L"Age");
216 CompoundTag *itemTag = tag->getCompound(L"Item");
217 setItem(ItemInstance::fromTag(itemTag));
218 if (getItem() == NULL) remove();
219}
220
221void ItemEntity::playerTouch(shared_ptr<Player> player)
222{
223 if (level->isClientSide) return;
224
225 shared_ptr<ItemInstance> item = getItem();
226
227 // 4J Stu - Fix for duplication glitch
228 if(item->count <= 0)
229 {
230 remove();
231 return;
232 }
233
234 int orgCount = item->count;
235 if (throwTime == 0 && player->inventory->add(item))
236 {
237 //if (item.id == Tile.treeTrunk.id) player.awardStat(Achievements.mineWood);
238 //if (item.id == Item.leather.id) player.awardStat(Achievements.killCow);
239 //if (item.id == Item.diamond.id) player.awardStat(Achievements.diamonds);
240 //if (item.id == Item.blazeRod.id) player.awardStat(Achievements.blazeRod);
241 if (item->id == Item::diamond_Id)
242 {
243 player->awardStat(GenericStats::diamonds(), GenericStats::param_diamonds());
244
245#ifdef _EXTENDED_ACHIEVEMENTS
246 if ( getItem()->getItem()->id )
247 {
248 shared_ptr<Player> pThrower = level->getPlayerByName(getThrower());
249 if ( (pThrower != nullptr) && (pThrower != player) )
250 {
251 pThrower->awardStat(GenericStats::diamondsToYou(), GenericStats::param_diamondsToYou());
252 }
253 }
254#endif
255 }
256 if (item->id == Item::blazeRod_Id)
257 player->awardStat(GenericStats::blazeRod(), GenericStats::param_blazeRod());
258
259 playSound(eSoundType_RANDOM_POP, 0.2f, ((random->nextFloat() - random->nextFloat()) * 0.7f + 1.0f) * 2.0f);
260 player->take(shared_from_this(), orgCount);
261 // System.out.println(item.count + ", " + orgCount);
262 if (item->count <= 0) remove();
263 }
264}
265
266wstring ItemEntity::getAName()
267{
268 return L"";//L"item." + getItem()->getDescriptionId();
269 //return I18n.get("item." + item.getDescriptionId());
270}
271
272void ItemEntity::changeDimension(int i)
273{
274 Entity::changeDimension(i);
275
276 if (!level->isClientSide) mergeWithNeighbours();
277}
278
279shared_ptr<ItemInstance> ItemEntity::getItem()
280{
281 shared_ptr<ItemInstance> result = getEntityData()->getItemInstance(DATA_ITEM);
282
283 if (result == NULL)
284 {
285 if (level != NULL)
286 {
287 app.DebugPrintf("Item entity %d has no item?!\n", entityId);
288 //level.getLogger().severe("Item entity " + entityId + " has no item?!");
289 }
290 return shared_ptr<ItemInstance>(new ItemInstance(Tile::stone));
291 }
292
293 return result;
294}
295
296void ItemEntity::setItem(shared_ptr<ItemInstance> item)
297{
298 getEntityData()->set(DATA_ITEM, item);
299 getEntityData()->markDirty(DATA_ITEM);
300}
301
302bool ItemEntity::isAttackable()
303{
304 return false;
305}
306
307void ItemEntity::setThrower(const wstring &thrower)
308{
309 this->thrower = thrower;
310}
311
312wstring ItemEntity::getThrower()
313{
314 return this->thrower;
315}