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.phys.h"
3#include "net.minecraft.world.entity.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.level.tile.h"
6#include "com.mojang.nbt.h"
7#include "Throwable.h"
8
9
10
11void Throwable::_throwableInit()
12{
13 xTile = -1;
14 yTile = -1;
15 zTile = -1;
16 lastTile = 0;
17 inGround = false;
18 shakeTime = 0;
19 owner = nullptr;
20 life = 0;
21 flightTime = 0;
22 ownerName = L"";
23}
24
25Throwable::Throwable(Level *level) : Entity(level)
26{
27 _throwableInit();
28 setSize(0.25f, 0.25f);
29}
30
31void Throwable::defineSynchedData()
32{
33}
34
35bool Throwable::shouldRenderAtSqrDistance(double distance)
36{
37 double size = bb->getSize() * 4;
38 size *= 64.0f;
39 return distance < size * size;
40}
41
42Throwable::Throwable(Level *level, shared_ptr<LivingEntity> mob) : Entity(level)
43{
44 _throwableInit();
45 owner = mob;
46
47 setSize(4 / 16.0f, 4 / 16.0f);
48
49 moveTo(mob->x, mob->y + mob->getHeadHeight(), mob->z, mob->yRot, mob->xRot);
50
51
52 x -= cos(yRot / 180 * PI) * 0.16f;
53 y -= 0.1f;
54 z -= sin(yRot / 180 * PI) * 0.16f;
55 setPos(x, y, z);
56 heightOffset = 0;
57
58
59 float speed = 0.4f;
60 xd = (-sin(yRot / 180 * PI) * cos(xRot / 180 * PI)) * speed;
61 zd = (cos(yRot / 180 * PI) * cos(xRot / 180 * PI)) * speed;
62 yd = (-sin((xRot + getThrowUpAngleOffset()) / 180 * PI)) * speed;
63
64 shoot(xd, yd, zd, getThrowPower(), 1);
65}
66
67Throwable::Throwable(Level *level, double x, double y, double z) : Entity(level)
68{
69 _throwableInit();
70 life = 0;
71
72 setSize(4 / 16.0f, 4 / 16.0f);
73
74 setPos(x, y, z);
75 heightOffset = 0;
76}
77
78
79float Throwable::getThrowPower()
80{
81 return 1.5f;
82}
83
84float Throwable::getThrowUpAngleOffset()
85{
86 return 0;
87}
88
89void Throwable::shoot(double xd, double yd, double zd, float pow, float uncertainty)
90{
91 float dist = sqrt(xd * xd + yd * yd + zd * zd);
92
93 xd /= dist;
94 yd /= dist;
95 zd /= dist;
96
97 xd += (random->nextGaussian()) * 0.0075f * uncertainty;
98 yd += (random->nextGaussian()) * 0.0075f * uncertainty;
99 zd += (random->nextGaussian()) * 0.0075f * uncertainty;
100
101 xd *= pow;
102 yd *= pow;
103 zd *= pow;
104
105 this->xd = xd;
106 this->yd = yd;
107 this->zd = zd;
108
109 float sd = (float) sqrt(xd * xd + zd * zd);
110
111 yRotO = yRot = (float) (atan2(xd, zd) * 180 / PI);
112 xRotO = xRot = (float) (atan2(yd, (double)sd) * 180 / PI);
113 life = 0;
114}
115
116void Throwable::lerpMotion(double xd, double yd, double zd)
117{
118 this->xd = xd;
119 this->yd = yd;
120 this->zd = zd;
121 if (xRotO == 0 && yRotO == 0)
122 {
123 float sd = (float) sqrt(xd * xd + zd * zd);
124 yRotO = yRot = (float) (atan2(xd, zd) * 180 / PI);
125 xRotO = xRot = (float) (atan2(yd, (double)sd) * 180 / PI);
126 }
127}
128
129void Throwable::tick()
130{
131 xOld = x;
132 yOld = y;
133 zOld = z;
134 Entity::tick();
135
136 if (shakeTime > 0) shakeTime--;
137
138 if (inGround)
139 {
140 int tile = level->getTile(xTile, yTile, zTile);
141 if (tile == lastTile)
142 {
143 life++;
144 if (life == 20 * 60) remove();
145 return;
146 }
147 else
148 {
149 inGround = false;
150
151 xd *= random->nextFloat() * 0.2f;
152 yd *= random->nextFloat() * 0.2f;
153 zd *= random->nextFloat() * 0.2f;
154 life = 0;
155 flightTime = 0;
156 }
157 }
158 else
159 {
160 flightTime++;
161 }
162
163 Vec3 *from = Vec3::newTemp(x, y, z);
164 Vec3 *to = Vec3::newTemp(x + xd, y + yd, z + zd);
165 HitResult *res = level->clip(from, to);
166
167 from = Vec3::newTemp(x, y, z);
168 to = Vec3::newTemp(x + xd, y + yd, z + zd);
169 if (res != NULL)
170 {
171 to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z);
172 }
173
174 if (!level->isClientSide)
175 {
176 shared_ptr<Entity> hitEntity = nullptr;
177 vector<shared_ptr<Entity> > *objects = level->getEntities(shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1));
178 double nearest = 0;
179 shared_ptr<LivingEntity> owner = getOwner();
180 for (int i = 0; i < objects->size(); i++)
181 {
182 shared_ptr<Entity> e = objects->at(i);
183 if (!e->isPickable() || (e == owner && flightTime < 5)) continue;
184
185 float rr = 0.3f;
186 AABB *bb = e->bb->grow(rr, rr, rr);
187 HitResult *p = bb->clip(from, to);
188 if (p != NULL)
189 {
190 double dd = from->distanceTo(p->pos);
191 delete p;
192 if (dd < nearest || nearest == 0)
193 {
194 hitEntity = e;
195 nearest = dd;
196 }
197 }
198 }
199
200 if (hitEntity != NULL)
201 {
202 if(res != NULL) delete res;
203 res = new HitResult(hitEntity);
204 }
205 }
206
207 if (res != NULL)
208 {
209 if ( (res->type == HitResult::TILE) && (level->getTile(res->x, res->y, res->z) == Tile::portalTile_Id) )
210 {
211 handleInsidePortal();
212 }
213 else
214 {
215 onHit(res);
216 }
217 delete res;
218 }
219 x += xd;
220 y += yd;
221 z += zd;
222
223 float sd = (float) sqrt(xd * xd + zd * zd);
224 yRot = (float) (atan2(xd, zd) * 180 / PI);
225 xRot = (float) (atan2(yd, (double)sd) * 180 / PI);
226
227 while (xRot - xRotO < -180)
228 xRotO -= 360;
229 while (xRot - xRotO >= 180)
230 xRotO += 360;
231
232 while (yRot - yRotO < -180)
233 yRotO -= 360;
234 while (yRot - yRotO >= 180)
235 yRotO += 360;
236
237 xRot = xRotO + (xRot - xRotO) * 0.2f;
238 yRot = yRotO + (yRot - yRotO) * 0.2f;
239
240
241 float inertia = 0.99f;
242 float gravity = getGravity();
243
244 if (isInWater())
245 {
246 for (int i = 0; i < 4; i++)
247 {
248 float s = 1 / 4.0f;
249 level->addParticle(eParticleType_bubble, x - xd * s, y - yd * s, z - zd * s, xd, yd, zd);
250 }
251 inertia = 0.80f;
252 }
253
254 xd *= inertia;
255 yd *= inertia;
256 zd *= inertia;
257 yd -= gravity;
258
259 setPos(x, y, z);
260}
261
262float Throwable::getGravity()
263{
264 return 0.03f;
265}
266
267
268void Throwable::addAdditonalSaveData(CompoundTag *tag)
269{
270 tag->putShort(L"xTile", (short) xTile);
271 tag->putShort(L"yTile", (short) yTile);
272 tag->putShort(L"zTile", (short) zTile);
273 tag->putByte(L"inTile", (byte) lastTile);
274 tag->putByte(L"shake", (byte) shakeTime);
275 tag->putByte(L"inGround", (byte) (inGround ? 1 : 0));
276
277 if (ownerName.empty() && (owner != NULL) && owner->instanceof(eTYPE_PLAYER) )
278 {
279 ownerName = owner->getAName();
280 }
281
282 tag->putString(L"ownerName", ownerName.empty() ? L"" : ownerName);
283}
284
285void Throwable::readAdditionalSaveData(CompoundTag *tag)
286{
287 xTile = tag->getShort(L"xTile");
288 yTile = tag->getShort(L"yTile");
289 zTile = tag->getShort(L"zTile");
290 lastTile = tag->getByte(L"inTile") & 0xff;
291 shakeTime = tag->getByte(L"shake") & 0xff;
292 inGround = tag->getByte(L"inGround") == 1;
293 ownerName = tag->getString(L"ownerName");
294 if (ownerName.empty() ) ownerName = L"";
295}
296
297float Throwable::getShadowHeightOffs()
298{
299 return 0;
300}
301
302shared_ptr<LivingEntity> Throwable::getOwner()
303{
304 if (owner == NULL && !ownerName.empty() )
305 {
306 owner = level->getPlayerByName(ownerName);
307 }
308 return owner;
309}