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.stats.h"
3#include "net.minecraft.world.level.h"
4#include "net.minecraft.world.level.tile.h"
5#include "net.minecraft.world.phys.h"
6#include "net.minecraft.world.entity.player.h"
7#include "net.minecraft.world.item.h"
8#include "net.minecraft.world.entity.item.h"
9#include "net.minecraft.world.entity.h"
10#include "net.minecraft.world.damagesource.h"
11#include "com.mojang.nbt.h"
12#include "FishingHook.h"
13#include "SoundTypes.h"
14
15
16
17// 4J - added common ctor code.
18void FishingHook::_init()
19{
20 // 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
21 // the derived version of the function is called
22 this->defineSynchedData();
23
24 xTile = -1;
25 yTile = -1;
26 zTile = -1;
27 lastTile = 0;
28 inGround = false;
29 shakeTime = 0;
30 flightTime = 0;
31 nibble = 0;
32 hookedIn = nullptr;
33
34 lSteps = 0;
35 lx = 0.0;
36 ly = 0.0;
37 lz = 0.0;
38 lyr = 0.0;
39 lxr = 0.0;
40 lxd = 0.0;
41 lyd = 0.0;
42 lzd = 0.0;
43 owner = nullptr;
44 life = 0;
45
46 setSize(0.25f, 0.25f);
47 noCulling = true;
48}
49
50FishingHook::FishingHook(Level *level) : Entity( level )
51{
52 _init();
53}
54
55FishingHook::FishingHook(Level *level, double x, double y, double z, shared_ptr<Player> owner) : Entity( level )
56{
57 _init();
58
59 this->owner = owner;
60 // 4J Stu - Moved this outside the ctor
61 //owner->fishing = dynamic_pointer_cast<FishingHook>( shared_from_this() );
62
63 setPos(x, y, z);
64}
65
66FishingHook::FishingHook(Level *level, shared_ptr<Player> mob) : Entity( level )
67{
68 _init();
69
70 owner = mob;
71 // 4J Stu - Moved this outside the ctor
72 //owner->fishing = dynamic_pointer_cast<FishingHook>( shared_from_this() );
73
74 moveTo(mob->x, mob->y + 1.62 - mob->heightOffset, mob->z, mob->yRot, mob->xRot);
75
76
77 x -= Mth::cos(yRot / 180 * PI) * 0.16f;
78 y -= 0.1f;
79 z -= Mth::sin(yRot / 180 * PI) * 0.16f;
80 setPos(x, y, z);
81 heightOffset = 0;
82
83
84 float speed = 0.4f;
85 xd = (-Mth::sin(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI)) * speed;
86 zd = (Mth::cos(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI)) * speed;
87 yd = (-Mth::sin(xRot / 180 * PI)) * speed;
88
89 shoot(xd, yd, zd, 1.5f, 1);
90}
91
92void FishingHook::defineSynchedData()
93{
94}
95
96bool FishingHook::shouldRenderAtSqrDistance(double distance)
97{
98 double size = bb->getSize() * 4;
99 size *= 64.0f;
100 return distance < size * size;
101}
102
103void FishingHook::shoot(double xd, double yd, double zd, float pow, float uncertainty)
104{
105 float dist = (float) sqrt(xd * xd + yd * yd + zd * zd);
106
107 xd /= dist;
108 yd /= dist;
109 zd /= dist;
110
111 xd += (random->nextGaussian()) * 0.0075f * uncertainty;
112 yd += (random->nextGaussian()) * 0.0075f * uncertainty;
113 zd += (random->nextGaussian()) * 0.0075f * uncertainty;
114
115 xd *= pow;
116 yd *= pow;
117 zd *= pow;
118
119 this->xd = xd;
120 this->yd = yd;
121 this->zd = zd;
122
123 double sd = sqrt(xd * xd + zd * zd);
124
125 yRotO = yRot = (float) (atan2(xd, zd) * 180 / PI);
126 xRotO = xRot = (float) (atan2(yd, sd) * 180 / PI);
127 life = 0;
128}
129
130void FishingHook::lerpTo(double x, double y, double z, float yRot, float xRot, int steps)
131{
132 lx = x;
133 ly = y;
134 lz = z;
135 lyr = yRot;
136 lxr = xRot;
137
138 lSteps = steps;
139
140 xd = lxd;
141 yd = lyd;
142 zd = lzd;
143}
144
145void FishingHook::lerpMotion(double xd, double yd, double zd)
146{
147 lxd = this->xd = xd;
148 lyd = this->yd = yd;
149 lzd = this->zd = zd;
150}
151
152void FishingHook::tick()
153{
154 Entity::tick();
155
156 if (lSteps > 0)
157 {
158 double xt = x + (lx - x) / lSteps;
159 double yt = y + (ly - y) / lSteps;
160 double zt = z + (lz - z) / lSteps;
161
162 double yrd = Mth::wrapDegrees(lyr - yRot);
163
164 yRot += (float) ( (yrd) / lSteps );
165 xRot += (float) ( (lxr - xRot) / lSteps );
166
167 lSteps--;
168 setPos(xt, yt, zt);
169 setRot(yRot, xRot);
170 return;
171 }
172
173 if (!level->isClientSide)
174 {
175 shared_ptr<ItemInstance> selectedItem = owner->getSelectedItem();
176 if (owner->removed || !owner->isAlive() || selectedItem == NULL || selectedItem->getItem() != Item::fishingRod || distanceToSqr(owner) > 32 * 32)
177 {
178 remove();
179 owner->fishing = nullptr;
180 return;
181 }
182
183 if (hookedIn != NULL)
184 {
185 if (hookedIn->removed) hookedIn = nullptr;
186 else
187 {
188 x = hookedIn->x;
189 y = hookedIn->bb->y0 + hookedIn->bbHeight * 0.8;
190 z = hookedIn->z;
191 return;
192 }
193 }
194 }
195
196 if (shakeTime > 0) shakeTime--;
197
198 if (inGround)
199 {
200 int tile = level->getTile(xTile, yTile, zTile);
201 if (tile != lastTile)
202 {
203 life++;
204 if (life == 20 * 60) remove();
205 return;
206 }
207 else
208 {
209 inGround = false;
210
211 xd *= random->nextFloat() * 0.2f;
212 yd *= random->nextFloat() * 0.2f;
213 zd *= random->nextFloat() * 0.2f;
214 life = 0;
215 flightTime = 0;
216 }
217 }
218 else
219 {
220 flightTime++;
221 }
222
223 Vec3 *from = Vec3::newTemp(x, y, z);
224 Vec3 *to = Vec3::newTemp(x + xd, y + yd, z + zd);
225 HitResult *res = level->clip(from, to);
226
227 from = Vec3::newTemp(x, y, z);
228 to = Vec3::newTemp(x + xd, y + yd, z + zd);
229 if (res != NULL)
230 {
231 to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z);
232 }
233 shared_ptr<Entity> hitEntity = nullptr;
234 vector<shared_ptr<Entity> > *objects = level->getEntities(shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1));
235 double nearest = 0;
236 AUTO_VAR(itEnd, objects->end());
237 for (AUTO_VAR(it, objects->begin()); it != itEnd; it++)
238 {
239 shared_ptr<Entity> e = *it; // objects->at(i);
240 if (!e->isPickable() || (e == owner && flightTime < 5)) continue;
241
242 float rr = 0.3f;
243 AABB *bb = e->bb->grow(rr, rr, rr);
244 HitResult *p = bb->clip(from, to);
245 if (p != NULL)
246 {
247 double dd = from->distanceTo(p->pos);
248 if (dd < nearest || nearest == 0)
249 {
250 hitEntity = e;
251 nearest = dd;
252 }
253 delete p;
254 }
255 }
256
257 if (hitEntity != NULL)
258 {
259 delete res;
260 res = new HitResult(hitEntity);
261 }
262
263 if (res != NULL)
264 {
265 if (res->entity != NULL)
266 {
267 // 4J Stu Move fix for : fix for #48587 - CRASH: Code: Gameplay: Hitting another player with the fishing bobber crashes the game. [Fishing pole, line]
268 // Incorrect dynamic_pointer_cast used around the shared_from_this()
269 DamageSource *damageSource = DamageSource::thrown(shared_from_this(), owner);
270 if (res->entity->hurt(damageSource, 0))
271 {
272 hookedIn = res->entity;
273 }
274 delete damageSource;
275 }
276 else
277 {
278 inGround = true;
279 }
280 }
281 delete res;
282
283 if (inGround) return;
284
285 move(xd, yd, zd);
286
287 double sd = sqrt(xd * xd + zd * zd);
288 yRot = (float) (atan2(xd, zd) * 180 / PI);
289 xRot = (float) (atan2(yd, sd) * 180 / PI);
290
291 while (xRot - xRotO < -180)
292 xRotO -= 360;
293 while (xRot - xRotO >= 180)
294 xRotO += 360;
295
296 while (yRot - yRotO < -180)
297 yRotO -= 360;
298 while (yRot - yRotO >= 180)
299 yRotO += 360;
300
301 xRot = xRotO + (xRot - xRotO) * 0.2f;
302 yRot = yRotO + (yRot - yRotO) * 0.2f;
303
304
305 float inertia = 0.92f;
306
307 if (onGround || horizontalCollision)
308 {
309 inertia = 0.5f;
310 }
311
312 int steps = 5;
313 double waterPercentage = 0;
314 for (int i = 0; i < steps; i++)
315 {
316 double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f + 2 / 16.0f;
317 double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f + 2 / 16.0f;
318 AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1);
319 if (level->containsLiquid(bb2, Material::water))
320 {
321 waterPercentage += 1.0 / steps;
322 }
323 }
324
325 if (waterPercentage > 0)
326 {
327 if (nibble > 0)
328 {
329 nibble--;
330 }
331 else
332 {
333 int nibbleOdds = 500;
334 if (level->isRainingAt( Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z))) nibbleOdds = 300;
335
336 if (random->nextInt(nibbleOdds) == 0)
337 {
338 nibble = random->nextInt(30) + 10;
339 yd -= 0.2f;
340 playSound(eSoundType_RANDOM_SPLASH, 0.25f, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f);
341 float yt = (float) Mth::floor(bb->y0);
342 for (int i = 0; i < 1 + bbWidth * 20; i++)
343 {
344 float xo = (random->nextFloat() * 2 - 1) * bbWidth;
345 float zo = (random->nextFloat() * 2 - 1) * bbWidth;
346 level->addParticle(eParticleType_bubble, x + xo, yt + 1, z + zo, xd, yd - random->nextFloat() * 0.2f, zd);
347 }
348 for (int i = 0; i < 1 + bbWidth * 20; i++)
349 {
350 float xo = (random->nextFloat() * 2 - 1) * bbWidth;
351 float zo = (random->nextFloat() * 2 - 1) * bbWidth;
352 level->addParticle(eParticleType_splash, x + xo, yt + 1, z + zo, xd, yd, zd);
353 }
354 }
355 }
356
357 }
358
359 if (nibble > 0)
360 {
361 yd -= random->nextFloat() * random->nextFloat() * random->nextFloat() * 0.2;
362 }
363
364 double bob = waterPercentage * 2 - 1;
365 yd += 0.04f * bob;
366 if (waterPercentage > 0)
367 {
368 inertia *= 0.9;
369 yd *= 0.8;
370 }
371
372 xd *= inertia;
373 yd *= inertia;
374 zd *= inertia;
375
376 setPos(x, y, z);
377}
378
379void FishingHook::addAdditonalSaveData(CompoundTag *tag)
380{
381 tag->putShort(L"xTile", (short) xTile);
382 tag->putShort(L"yTile", (short) yTile);
383 tag->putShort(L"zTile", (short) zTile);
384 tag->putByte(L"inTile", (byte) lastTile);
385 tag->putByte(L"shake", (byte) shakeTime);
386 tag->putByte(L"inGround", (byte) (inGround ? 1 : 0));
387}
388
389void FishingHook::readAdditionalSaveData(CompoundTag *tag)
390{
391 xTile = tag->getShort(L"xTile");
392 yTile = tag->getShort(L"yTile");
393 zTile = tag->getShort(L"zTile");
394 lastTile = tag->getByte(L"inTile") & 0xff;
395 shakeTime = tag->getByte(L"shake") & 0xff;
396 inGround = tag->getByte(L"inGround") == 1;
397}
398
399float FishingHook::getShadowHeightOffs()
400{
401 return 0;
402}
403
404int FishingHook::retrieve()
405{
406 if (level->isClientSide) return 0;
407
408 int dmg = 0;
409 if (hookedIn != NULL)
410 {
411 double xa = owner->x - x;
412 double ya = owner->y - y;
413 double za = owner->z - z;
414
415 double dist = sqrt(xa * xa + ya * ya + za * za);
416 double speed = 0.1;
417 hookedIn->xd += xa * speed;
418 hookedIn->yd += ya * speed + sqrt(dist) * 0.08;
419 hookedIn->zd += za * speed;
420 dmg = 3;
421 }
422 else if (nibble > 0)
423 {
424 shared_ptr<ItemEntity> ie = shared_ptr<ItemEntity>( new ItemEntity(this->Entity::level, x, y, z, shared_ptr<ItemInstance>( new ItemInstance(Item::fish_raw) ) ) );
425 double xa = owner->x - x;
426 double ya = owner->y - y;
427 double za = owner->z - z;
428
429 double dist = sqrt(xa * xa + ya * ya + za * za);
430 double speed = 0.1;
431 ie->Entity::xd = xa * speed;
432 ie->Entity::yd = ya * speed + sqrt(dist) * 0.08;
433 ie->Entity::zd = za * speed;
434 level->addEntity(ie);
435 owner->level->addEntity( shared_ptr<ExperienceOrb>( new ExperienceOrb(owner->level, owner->x, owner->y + 0.5f, owner->z + 0.5f, random->nextInt(6) + 1) ) ); // 4J Stu brought forward from 1.4
436 dmg = 1;
437 }
438 if (inGround) dmg = 2;
439
440 remove();
441 owner->fishing = nullptr;
442 return dmg;
443}
444
445// 4J Stu - Brought forward from 1.4
446void FishingHook::remove()
447{
448 Entity::remove();
449 if (owner != NULL) owner->fishing = nullptr;
450}