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.level.h"
3#include "net.minecraft.world.level.material.h"
4#include "net.minecraft.world.phys.h"
5#include "net.minecraft.world.level.tile.h"
6#include "net.minecraft.world.damagesource.h"
7#include "com.mojang.nbt.h"
8#include "JavaMath.h"
9#include "SharedConstants.h"
10#include "ExperienceOrb.h"
11#include "SoundTypes.h"
12
13
14
15const int ExperienceOrb::LIFETIME = 5 * 60 * SharedConstants::TICKS_PER_SECOND; // Five minutes!
16
17void ExperienceOrb::_init()
18{
19 tickCount = 0;
20 age = 0;
21
22 throwTime = 0;
23
24 health = 5;
25 value = 0;
26 followingPlayer = nullptr;
27 followingTime = 0;
28}
29
30ExperienceOrb::ExperienceOrb(Level *level, double x, double y, double z, int count) : Entity(level)
31{
32 _init();
33
34 setSize(0.5f, 0.5f);
35 heightOffset = bbHeight / 2.0f;
36 setPos(x, y, z);
37
38 yRot = (float) (Math::random() * 360);
39
40 xd = (float) (Math::random() * 0.2f - 0.1f) * 2;
41 yd = (float) (Math::random() * 0.2) * 2;
42 zd = (float) (Math::random() * 0.2f - 0.1f) * 2;
43
44 value = count;
45}
46
47bool ExperienceOrb::makeStepSound()
48{
49 return false;
50}
51
52ExperienceOrb::ExperienceOrb(Level *level) : Entity( level )
53{
54 _init();
55
56 setSize(0.25f, 0.25f);
57 heightOffset = bbHeight / 2.0f;
58}
59
60void ExperienceOrb::defineSynchedData()
61{
62}
63
64int ExperienceOrb::getLightColor(float a)
65{
66 float l = 0.5f;
67 if (l < 0) l = 0;
68 if (l > 1) l = 1;
69 int br = Entity::getLightColor(a);
70
71 int br1 = (br) & 0xff;
72 int br2 = (br >> 16) & 0xff;
73 br1 += (int) (l * 15 * 16);
74 if (br1 > 15 * 16) br1 = 15 * 16;
75 // br2 = 15*16;
76 return br1 | br2 << 16;
77}
78
79void ExperienceOrb::tick()
80{
81 Entity::tick();
82 if (throwTime > 0) throwTime--;
83 xo = x;
84 yo = y;
85 zo = z;
86
87 yd -= 0.03f;
88 if (level->getMaterial(Mth::floor(x), Mth::floor(y), Mth::floor(z)) == Material::lava)
89 {
90 yd = 0.2f;
91 xd = (random->nextFloat() - random->nextFloat()) * 0.2f;
92 zd = (random->nextFloat() - random->nextFloat()) * 0.2f;
93 playSound(eSoundType_RANDOM_FIZZ, 0.4f, 2.0f + random->nextFloat() * 0.4f);
94 }
95 checkInTile(x, (bb->y0 + bb->y1) / 2, z);
96
97 double maxDist = 8;
98 // 4J - PC Comment
99 // Usually exp orbs will get created at the same time so smoothen the lagspikes
100 if (followingTime < tickCount - SharedConstants::TICKS_PER_SECOND + (entityId % 100))
101 {
102 if (followingPlayer == NULL || followingPlayer->distanceToSqr(shared_from_this()) > maxDist * maxDist)
103 {
104 followingPlayer = level->getNearestPlayer(shared_from_this(), maxDist);
105 }
106 followingTime = tickCount;
107 }
108 if (followingPlayer != NULL)
109 {
110 double xdd = (followingPlayer->x - x) / maxDist;
111 double ydd = (followingPlayer->y + followingPlayer->getHeadHeight() - y) / maxDist;
112 double zdd = (followingPlayer->z - z) / maxDist;
113 double dd = sqrt(xdd * xdd + ydd * ydd + zdd * zdd);
114 double power = 1 - dd;
115 if (power > 0)
116 {
117 power = power * power;
118 xd += xdd / dd * power * 0.1;
119 yd += ydd / dd * power * 0.1;
120 zd += zdd / dd * power * 0.1;
121 }
122 }
123
124 move(xd, yd, zd);
125
126 float friction = 0.98f;
127 if (onGround)
128 {
129 friction = 0.6f * 0.98f;
130 int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z));
131 if (t > 0)
132 {
133 friction = Tile::tiles[t]->friction * 0.98f;
134 }
135 }
136
137 xd *= friction;
138 yd *= 0.98f;
139 zd *= friction;
140
141 if (onGround)
142 {
143 yd *= -0.9f;
144 }
145
146 tickCount++;
147
148 age++;
149 if (age >= LIFETIME)
150 {
151 remove();
152 }
153}
154
155bool ExperienceOrb::updateInWaterState()
156{
157 return level->checkAndHandleWater(bb, Material::water, shared_from_this());
158}
159
160void ExperienceOrb::burn(int dmg)
161{
162 hurt(DamageSource::inFire, dmg);
163}
164
165bool ExperienceOrb::hurt(DamageSource *source, float damage)
166{
167 if (isInvulnerable()) return false;
168 markHurt();
169 health -= damage;
170 if (health <= 0)
171 {
172 remove();
173 }
174 return false;
175}
176
177void ExperienceOrb::addAdditonalSaveData(CompoundTag *entityTag)
178{
179 entityTag->putShort(L"Health", (byte) health);
180 entityTag->putShort(L"Age", (short) age);
181 entityTag->putShort(L"Value", (short) value);
182}
183
184void ExperienceOrb::readAdditionalSaveData(CompoundTag *tag)
185{
186 health = tag->getShort(L"Health") & 0xff;
187 age = tag->getShort(L"Age");
188 value = tag->getShort(L"Value");
189}
190
191void ExperienceOrb::playerTouch(shared_ptr<Player> player)
192{
193 if (level->isClientSide) return;
194
195 if (throwTime == 0 && player->takeXpDelay == 0)
196 {
197 player->takeXpDelay = 2;
198 // 4J - sound change brought forward from 1.2.3
199 playSound(eSoundType_RANDOM_ORB, 0.1f, 0.5f * ((random->nextFloat() - random->nextFloat()) * 0.7f + 1.8f));
200 player->take(shared_from_this(), 1);
201 player->increaseXp(value);
202 remove();
203 }
204}
205
206int ExperienceOrb::getValue()
207{
208 return value;
209}
210
211int ExperienceOrb::getIcon()
212{
213
214 if (value >= 2477)
215 {
216 return 10;
217 }
218 else if (value >= 1237)
219 {
220 return 9;
221 }
222 else if (value >= 617)
223 {
224 return 8;
225 }
226 else if (value >= 307)
227 {
228 return 7;
229 }
230 else if (value >= 149)
231 {
232 return 6;
233 }
234 else if (value >= 73)
235 {
236 return 5;
237 }
238 else if (value >= 37)
239 {
240 return 4;
241 }
242 else if (value >= 17)
243 {
244 return 3;
245 }
246 else if (value >= 7)
247 {
248 return 2;
249 }
250 else if (value >= 3)
251 {
252 return 1;
253 }
254
255 return 0;
256}
257
258/**
259* Fetches the biggest possible experience orb value based on a maximum
260* value. The current algorithm is next prime which is at least twice more
261* than the previous one.
262*
263* @param maxValue
264* @return
265*/
266int ExperienceOrb::getExperienceValue(int maxValue)
267{
268
269 if (maxValue >= 2477)
270 {
271 return 2477;
272 }
273 else if (maxValue >= 1237)
274 {
275 return 1237;
276 }
277 else if (maxValue >= 617)
278 {
279 return 617;
280 }
281 else if (maxValue >= 307)
282 {
283 return 307;
284 }
285 else if (maxValue >= 149)
286 {
287 return 149;
288 }
289 else if (maxValue >= 73)
290 {
291 return 73;
292 }
293 else if (maxValue >= 37)
294 {
295 return 37;
296 }
297 else if (maxValue >= 17)
298 {
299 return 17;
300 }
301 else if (maxValue >= 7)
302 {
303 return 7;
304 }
305 else if (maxValue >= 3)
306 {
307 return 3;
308 }
309
310 return 1;
311}
312
313bool ExperienceOrb::isAttackable()
314{
315 return false;
316}
317
318// 4J added
319bool ExperienceOrb::shouldRender(Vec3 *c)
320{
321 double xd = x - c->x;
322 double yd = y - c->y;
323 double zd = z - c->z;
324 double distance = xd * xd + yd * yd + zd * zd;
325
326 // 4J - don't render experience orbs that are less than 2 metres away, to try and avoid large particles that are causing us problems with photosensitivity testing - issues when you go
327 // near a large pile of experience orbs that all rush towards the near clip plane
328 if( distance < 4 ) return false;
329
330 return Entity::shouldRender(c);
331}