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.tile.h"
4#include "net.minecraft.world.entity.player.h"
5#include "net.minecraft.world.phys.h"
6#include "net.minecraft.world.item.h"
7#include "net.minecraft.world.damagesource.h"
8#include "com.mojang.nbt.h"
9#include "Fireball.h"
10#include "net.minecraft.world.level.dimension.h"
11#include "SharedConstants.h"
12
13
14// 4J - added common ctor code.
15void Fireball::_init()
16{
17 xTile = -1;
18 yTile = -1;
19 zTile = -1;
20 lastTile = 0;
21 inGround = false;
22 flightTime = 0;
23
24 life = 0;
25 owner = nullptr;
26 xPower = 0.0;
27 yPower = 0.0;
28 zPower = 0.0;
29}
30
31Fireball::Fireball(Level *level) : Entity( level )
32{
33 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
34 // the derived version of the function is called
35 this->defineSynchedData();
36
37 _init();
38
39 setSize(16 / 16.0f, 16 / 16.0f);
40
41}
42
43void Fireball::defineSynchedData()
44{
45
46}
47
48bool Fireball::shouldRenderAtSqrDistance(double distance)
49{
50 double size = bb->getSize() * 4;
51 size *= 64.0f;
52 return distance < size * size;
53}
54
55
56Fireball::Fireball(Level *level, double x, double y, double z, double xa, double ya, double za) : Entity( level )
57{
58 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
59 // the derived version of the function is called
60 this->defineSynchedData();
61
62 _init();
63
64 setSize(16 / 16.0f, 16 / 16.0f);
65
66 moveTo(x, y, z, yRot, xRot);
67 setPos(x, y, z);
68
69 double dd = sqrt(xa * xa + ya * ya + za * za);
70
71 // Fix for #69150 - [CRASH] TU8: Code: Gameplay: Nether portal mechanics can become permanently broken, causing a hard lock upon usage.
72 // IF xa, ya and za are 0 then dd is 0 and the xa/dd etc return NAN
73 if(dd == 0.0)
74 {
75 xPower = 0.0;
76 yPower = 0.0;
77 zPower = 0.0;
78 }
79 else
80 {
81 xPower = xa / dd * 0.10;
82 yPower = ya / dd * 0.10;
83 zPower = za / dd * 0.10;
84 }
85}
86
87Fireball::Fireball(Level *level, shared_ptr<LivingEntity> mob, double xa, double ya, double za) : Entity ( level )
88{
89 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
90 // the derived version of the function is called
91 this->defineSynchedData();
92
93 _init();
94
95 owner = mob;
96
97 setSize(16 / 16.0f, 16 / 16.0f);
98
99 moveTo(mob->x, mob->y, mob->z, mob->yRot, mob->xRot);
100 setPos(x, y, z);
101 heightOffset = 0;
102
103
104 xd = yd = zd = 0.0;
105
106 xa += random->nextGaussian() * 0.4;
107 ya += random->nextGaussian() * 0.4;
108 za += random->nextGaussian() * 0.4;
109 double dd = sqrt(xa * xa + ya * ya + za * za);
110
111 // Fix for #69150 - [CRASH] TU8: Code: Gameplay: Nether portal mechanics can become permanently broken, causing a hard lock upon usage.
112 // IF xa, ya and za are 0 then dd is 0 and the xa/dd etc return NAN
113 if(dd == 0.0)
114 {
115 xPower = 0.0;
116 yPower = 0.0;
117 zPower = 0.0;
118 }
119 else
120 {
121 xPower = xa / dd * 0.10;
122 yPower = ya / dd * 0.10;
123 zPower = za / dd * 0.10;
124 }
125}
126
127void Fireball::tick()
128{
129 // 4J-PB - Moved forward from 1.2.3
130 //if (!level->isClientSide && (owner == NULL || owner->removed))
131 if (!level->isClientSide)
132 {
133 if((owner != NULL && owner->removed) || !level->hasChunkAt((int) x, (int) y, (int) z))
134 {
135 app.DebugPrintf("Fireball removed - owner is null or removed is true for owner\n");
136 remove();
137 return;
138 }
139 else
140 {
141 // 4J-PB - TU9 bug fix - fireballs can hit the edge of the world, and stay there
142 int minXZ = - (level->dimension->getXZSize() * 16 ) / 2;
143 int maxXZ = (level->dimension->getXZSize() * 16 ) / 2 - 1;
144
145 if ((x<=minXZ) || (x>=maxXZ) || (z<=minXZ) || (z>=maxXZ))
146 {
147 remove();
148 app.DebugPrintf("Fireball removed - end of world\n");
149 return;
150 }
151 }
152 }
153
154 Entity::tick();
155
156 //app.DebugPrintf("Fireball x %d, y %d, z%d\n",(int)x,(int)y,(int)z);
157
158 if(shouldBurn()) setOnFire(1);
159
160 if (inGround)
161 {
162 int tile = level->getTile(xTile, yTile, zTile);
163 if (tile == lastTile)
164 {
165 life++;
166 if (life == SharedConstants::TICKS_PER_SECOND * 30)
167 {
168 remove();
169 app.DebugPrintf("Fireball removed - life is 20*60\n");
170 }
171 return;
172 }
173 else
174 {
175 inGround = false;
176
177 xd *= random->nextFloat() * 0.2f;
178 yd *= random->nextFloat() * 0.2f;
179 zd *= random->nextFloat() * 0.2f;
180 life = 0;
181 flightTime = 0;
182 }
183 }
184 else
185 {
186 flightTime++;
187 }
188
189 MemSect(41);
190 Vec3 *from = Vec3::newTemp(x, y, z);
191 Vec3 *to = Vec3::newTemp(x + xd, y + yd, z + zd);
192 HitResult *res = level->clip(from, to);
193
194 from = Vec3::newTemp(x, y, z);
195 to = Vec3::newTemp(x + xd, y + yd, z + zd);
196 if (res != NULL)
197 {
198 to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z);
199 }
200 shared_ptr<Entity> hitEntity = nullptr;
201 vector<shared_ptr<Entity> > *objects = level->getEntities(shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1));
202 double nearest = 0;
203 AUTO_VAR(itEnd, objects->end());
204 for (AUTO_VAR(it, objects->begin()); it != itEnd; it++)
205 {
206 shared_ptr<Entity> e = *it; //objects->at(i);
207 if (!e->isPickable() || (e->is(owner) )) continue; //4J Stu - Never collide with the owner (Enderdragon) // && flightTime < 25)) continue;
208
209 float rr = 0.3f;
210 AABB *bb = e->bb->grow(rr, rr, rr);
211 HitResult *p = bb->clip(from, to);
212 if (p != NULL)
213 {
214 double dd = from->distanceTo(p->pos);
215 if (dd < nearest || nearest == 0)
216 {
217 hitEntity = e;
218 nearest = dd;
219 }
220 delete p;
221 }
222
223 }
224
225 if (hitEntity != NULL)
226 {
227 delete res;
228 res = new HitResult(hitEntity);
229 }
230 MemSect(0);
231
232 if (res != NULL)
233 {
234 onHit(res);
235 }
236 delete res;
237 x += xd;
238 y += yd;
239 z += zd;
240
241 double sd = sqrt(xd * xd + zd * zd);
242 yRot = (float) (atan2(zd, xd) * 180 / PI) + 90;
243 xRot = (float) (atan2(sd, yd) * 180 / PI) - 90;
244
245 while (xRot - xRotO < -180)
246 xRotO -= 360;
247 while (xRot - xRotO >= 180)
248 xRotO += 360;
249
250 while (yRot - yRotO < -180)
251 yRotO -= 360;
252 while (yRot - yRotO >= 180)
253 yRotO += 360;
254
255 xRot = xRotO + (xRot - xRotO) * 0.2f;
256 yRot = yRotO + (yRot - yRotO) * 0.2f;
257
258
259 float inertia = getInertia();
260 if (isInWater())
261 {
262 for (int i = 0; i < 4; i++)
263 {
264 float s = 1 / 4.0f;
265 level->addParticle(eParticleType_bubble, x - xd * s, y - yd * s, z - zd * s, xd, yd, zd);
266 }
267 inertia = 0.80f;
268 }
269
270 xd += xPower;
271 yd += yPower;
272 zd += zPower;
273 xd *= inertia;
274 yd *= inertia;
275 zd *= inertia;
276
277 // 4J-PB - bug fix for the fireballs in a saved game - they are saved with no/very small velocity, so end up hanging around in the air
278 if (!level->isClientSide)
279 {
280 if((abs(xd)<0.002) && (abs(yd)<0.002) && (abs(zd)<0.002))
281 {
282 xd=0.0;
283 zd=0.0;
284 yd=0.0;
285 app.DebugPrintf("Removing a fireball with zero velocity\n");
286 remove();
287 }
288 }
289
290 level->addParticle(getTrailParticleType(), x, y + 0.5f, z, 0, 0.01, 0);
291
292 setPos(x, y, z);
293}
294
295float Fireball::getInertia()
296{
297 return 0.95f;
298}
299
300void Fireball::addAdditonalSaveData(CompoundTag *tag)
301{
302 tag->putShort(L"xTile", (short) xTile);
303 tag->putShort(L"yTile", (short) yTile);
304 tag->putShort(L"zTile", (short) zTile);
305 tag->putByte(L"inTile", (byte) lastTile);
306 tag->putByte(L"inGround", (byte) (inGround ? 1 : 0));
307 tag->put(L"direction", newDoubleList(3, xd, yd, zd));
308}
309
310void Fireball::readAdditionalSaveData(CompoundTag *tag)
311{
312 xTile = tag->getShort(L"xTile");
313 yTile = tag->getShort(L"yTile");
314 zTile = tag->getShort(L"zTile");
315 lastTile = tag->getByte(L"inTile") & 0xff;
316 inGround = tag->getByte(L"inGround") == 1;
317
318 // Load the stored direction and apply it to the fireball
319 // if it has no stored direction, remove it.
320 if (tag->contains(L"direction"))
321 {
322 ListTag<DoubleTag> *listTag = (ListTag<DoubleTag> *)tag->getList(L"direction");
323 xd = ((DoubleTag *) listTag->get(0))->data;
324 yd = ((DoubleTag *) listTag->get(1))->data;
325 zd = ((DoubleTag *) listTag->get(2))->data;
326 }
327 else
328 {
329 remove();
330 }
331}
332
333bool Fireball::isPickable()
334{
335 return true;
336}
337
338float Fireball::getPickRadius()
339{
340 return 1;
341}
342
343bool Fireball::hurt(DamageSource *source, float damage)
344{
345 if (isInvulnerable()) return false;
346 markHurt();
347
348 if (source->getEntity() != NULL)
349 {
350 Vec3 *lookAngle = source->getEntity()->getLookAngle();
351 if (lookAngle != NULL)
352 {
353 xd = lookAngle->x;
354 yd = lookAngle->y;
355 zd = lookAngle->z;
356 xPower = xd * 0.1;
357 yPower = yd * 0.1;
358 zPower = zd * 0.1;
359 }
360 if ( source->getEntity()->instanceof(eTYPE_LIVINGENTITY) )
361 {
362 owner = dynamic_pointer_cast<LivingEntity>( source->getEntity() );
363 }
364 return true;
365 }
366 return false;
367}
368
369float Fireball::getShadowHeightOffs()
370{
371 return 0;
372}
373
374float Fireball::getBrightness(float a)
375{
376 return 1.0f;
377}
378
379int Fireball::getLightColor(float a)
380{
381 return 15 << 20 | 15 << 4;
382}
383
384ePARTICLE_TYPE Fireball::getTrailParticleType()
385{
386 return eParticleType_smoke;
387}
388
389bool Fireball::shouldBurn()
390{
391 return true;
392}