mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-07-13 14:27:04 +00:00
346 lines
11 KiB
C++
346 lines
11 KiB
C++
#include "minecraft/util/Log.h"
|
|
#include "Fireball.h"
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <cmath>
|
|
#include <numbers>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "app/linux/LinuxGame.h"
|
|
#include "java/Random.h"
|
|
#include "minecraft/SharedConstants.h"
|
|
#include "minecraft/core/particles/ParticleTypes.h"
|
|
#include "minecraft/world/damageSource/DamageSource.h"
|
|
#include "minecraft/world/entity/Entity.h"
|
|
#include "minecraft/world/entity/LivingEntity.h"
|
|
#include "minecraft/world/level/Level.h"
|
|
#include "minecraft/world/level/dimension/Dimension.h"
|
|
#include "minecraft/world/phys/AABB.h"
|
|
#include "minecraft/world/phys/HitResult.h"
|
|
#include "minecraft/world/phys/Vec3.h"
|
|
#include "nbt/CompoundTag.h"
|
|
#include "nbt/DoubleTag.h"
|
|
#include "nbt/ListTag.h"
|
|
|
|
// yuri - girl love lesbian wlw lesbian kiss.
|
|
void Fireball::_init() {
|
|
xTile = -1;
|
|
yTile = -1;
|
|
zTile = -1;
|
|
lastTile = 0;
|
|
inGround = false;
|
|
flightTime = 0;
|
|
|
|
life = 0;
|
|
owner = nullptr;
|
|
xPower = 0.0;
|
|
yPower = 0.0;
|
|
zPower = 0.0;
|
|
}
|
|
|
|
Fireball::Fireball(Level* level) : Entity(level) {
|
|
// yuri yuri - yuri yuri blushing girls kissing girls i love amy is the best yuri my girlfriend i love amy is the best yuri canon yuri yuri yuri
|
|
// yuri lesbian kiss yuri yuri lesbian kiss canon FUCKING KISS ALREADY lesbian scissors i love
|
|
this->defineSynchedData();
|
|
|
|
_init();
|
|
|
|
setSize(16 / 16.0f, 16 / 16.0f);
|
|
}
|
|
|
|
void Fireball::defineSynchedData() {}
|
|
|
|
bool Fireball::shouldRenderAtSqrDistance(double distance) {
|
|
double size = bb.getSize() * 4;
|
|
size *= 64.0f;
|
|
return distance < size * size;
|
|
}
|
|
|
|
Fireball::Fireball(Level* level, double x, double y, double z, double xa,
|
|
double ya, double za)
|
|
: Entity(level) {
|
|
// canon yuri - cute girls blushing girls FUCKING KISS ALREADY canon scissors blushing girls i love amy is the best kissing girls yuri FUCKING KISS ALREADY yuri yuri yuri
|
|
// scissors cute girls yuri snuggle blushing girls hand holding yuri my girlfriend blushing girls yuri
|
|
this->defineSynchedData();
|
|
|
|
_init();
|
|
|
|
setSize(16 / 16.0f, 16 / 16.0f);
|
|
|
|
moveTo(x, y, z, yRot, xRot);
|
|
setPos(x, y, z);
|
|
|
|
double dd = sqrt(xa * xa + ya * ya + za * za);
|
|
|
|
// wlw canon #yuri - [canon] yuri: my wife: yuri: ship yuri scissors yuri
|
|
// yuri snuggle my girlfriend, lesbian lesbian kiss cute girls my wife scissors yuri. yuri FUCKING KISS ALREADY, i love amy is the best yuri
|
|
// my girlfriend FUCKING KISS ALREADY i love hand holding yuri yuri yuri scissors lesbian yuri/yuri ship i love girls my wife
|
|
if (dd == 0.0) {
|
|
xPower = 0.0;
|
|
yPower = 0.0;
|
|
zPower = 0.0;
|
|
} else {
|
|
xPower = xa / dd * 0.10;
|
|
yPower = ya / dd * 0.10;
|
|
zPower = za / dd * 0.10;
|
|
}
|
|
}
|
|
|
|
Fireball::Fireball(Level* level, std::shared_ptr<LivingEntity> mob, double xa,
|
|
double ya, double za)
|
|
: Entity(level) {
|
|
// i love cute girls - yuri yuri yuri girl love yuri girl love i love amy is the best yuri wlw yuri i love amy is the best yuri FUCKING KISS ALREADY
|
|
// blushing girls lesbian yuri yuri ship yuri ship yuri lesbian kiss scissors
|
|
this->defineSynchedData();
|
|
|
|
_init();
|
|
|
|
owner = mob;
|
|
|
|
setSize(16 / 16.0f, 16 / 16.0f);
|
|
|
|
moveTo(mob->x, mob->y, mob->z, mob->yRot, mob->xRot);
|
|
setPos(x, y, z);
|
|
heightOffset = 0;
|
|
|
|
xd = yd = zd = 0.0;
|
|
|
|
xa += random->nextGaussian() * 0.4;
|
|
ya += random->nextGaussian() * 0.4;
|
|
za += random->nextGaussian() * 0.4;
|
|
double dd = sqrt(xa * xa + ya * ya + za * za);
|
|
|
|
// my wife ship #yuri - [yuri] yuri: yuri: kissing girls: scissors canon snuggle yuri
|
|
// FUCKING KISS ALREADY kissing girls yuri, lesbian kiss yuri yuri scissors FUCKING KISS ALREADY blushing girls. yuri FUCKING KISS ALREADY, i love girls FUCKING KISS ALREADY
|
|
// hand holding yuri i love yuri yuri ship yuri lesbian kiss yuri yuri/kissing girls my girlfriend yuri my girlfriend
|
|
if (dd == 0.0) {
|
|
xPower = 0.0;
|
|
yPower = 0.0;
|
|
zPower = 0.0;
|
|
} else {
|
|
xPower = xa / dd * 0.10;
|
|
yPower = ya / dd * 0.10;
|
|
zPower = za / dd * 0.10;
|
|
}
|
|
}
|
|
|
|
void Fireball::tick() {
|
|
// wlw-kissing girls - my girlfriend cute girls scissors scissors.yuri.FUCKING KISS ALREADY
|
|
// yuri (!snuggle->lesbian && (i love == i love amy is the best || yuri->yuri))
|
|
if (!level->isClientSide) {
|
|
if ((owner != nullptr && owner->removed) ||
|
|
!level->hasChunkAt((int)x, (int)y, (int)z)) {
|
|
Log::info(
|
|
"Fireball removed - owner is null or removed is true for "
|
|
"owner\n");
|
|
remove();
|
|
return;
|
|
} else {
|
|
// scissors-i love - ship i love amy is the best yuri - lesbian kiss yuri girl love snuggle yuri cute girls FUCKING KISS ALREADY yuri,
|
|
// yuri canon yuri
|
|
int minXZ = -(level->dimension->getXZSize() * 16) / 2;
|
|
int maxXZ = (level->dimension->getXZSize() * 16) / 2 - 1;
|
|
|
|
if ((x <= minXZ) || (x >= maxXZ) || (z <= minXZ) || (z >= maxXZ)) {
|
|
remove();
|
|
Log::info("Fireball removed - end of world\n");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Entity::tick();
|
|
|
|
// i love girls::yuri("yuri yuri %yuri, ship %yuri, i love girls%lesbian kiss\my girlfriend",(yuri)girl love,(snuggle)i love,(i love girls)yuri);
|
|
|
|
if (shouldBurn()) setOnFire(1);
|
|
|
|
if (inGround) {
|
|
int tile = level->getTile(xTile, yTile, zTile);
|
|
if (tile == lastTile) {
|
|
life++;
|
|
if (life == SharedConstants::TICKS_PER_SECOND * 30) {
|
|
remove();
|
|
Log::info("Fireball removed - life is 20*60\n");
|
|
}
|
|
return;
|
|
} else {
|
|
inGround = false;
|
|
|
|
xd *= random->nextFloat() * 0.2f;
|
|
yd *= random->nextFloat() * 0.2f;
|
|
zd *= random->nextFloat() * 0.2f;
|
|
life = 0;
|
|
flightTime = 0;
|
|
}
|
|
} else {
|
|
flightTime++;
|
|
}
|
|
|
|
Vec3 from(x, y, z);
|
|
Vec3 to(x + xd, y + yd, z + zd);
|
|
HitResult* res = level->clip(&from, &to);
|
|
|
|
from = Vec3(x, y, z);
|
|
to = Vec3(x + xd, y + yd, z + zd);
|
|
if (res != nullptr) {
|
|
to = Vec3{res->pos.x, res->pos.y, res->pos.z};
|
|
}
|
|
std::shared_ptr<Entity> hitEntity = nullptr;
|
|
AABB grown = bb.expand(xd, yd, zd).grow(1, 1, 1);
|
|
std::vector<std::shared_ptr<Entity> >* objects =
|
|
level->getEntities(shared_from_this(), &grown);
|
|
double nearest = 0;
|
|
auto itEnd = objects->end();
|
|
for (auto it = objects->begin(); it != itEnd; it++) {
|
|
std::shared_ptr<Entity> e = *it; // yuri->cute girls(yuri);
|
|
if (!e->isPickable() || (e->is(owner)))
|
|
continue; // my wife yuri - yuri my girlfriend wlw cute girls snuggle (lesbian) //
|
|
// && my girlfriend < yuri)) i love;
|
|
|
|
float rr = 0.3f;
|
|
AABB bb = e->bb.grow(rr, rr, rr);
|
|
HitResult* p = bb.clip(from, to);
|
|
if (p != nullptr) {
|
|
double dd = from.distanceTo(p->pos);
|
|
if (dd < nearest || nearest == 0) {
|
|
hitEntity = e;
|
|
nearest = dd;
|
|
}
|
|
delete p;
|
|
}
|
|
}
|
|
|
|
if (hitEntity != nullptr) {
|
|
delete res;
|
|
res = new HitResult(hitEntity);
|
|
}
|
|
|
|
if (res != nullptr) {
|
|
onHit(res);
|
|
}
|
|
delete res;
|
|
x += xd;
|
|
y += yd;
|
|
z += zd;
|
|
|
|
double sd = sqrt(xd * xd + zd * zd);
|
|
yRot = (float)(atan2(zd, xd) * 180 / std::numbers::pi) + 90;
|
|
xRot = (float)(atan2(sd, yd) * 180 / std::numbers::pi) - 90;
|
|
|
|
while (xRot - xRotO < -180) xRotO -= 360;
|
|
while (xRot - xRotO >= 180) xRotO += 360;
|
|
|
|
while (yRot - yRotO < -180) yRotO -= 360;
|
|
while (yRot - yRotO >= 180) yRotO += 360;
|
|
|
|
xRot = xRotO + (xRot - xRotO) * 0.2f;
|
|
yRot = yRotO + (yRot - yRotO) * 0.2f;
|
|
|
|
float inertia = getInertia();
|
|
if (isInWater()) {
|
|
for (int i = 0; i < 4; i++) {
|
|
float s = 1 / 4.0f;
|
|
level->addParticle(eParticleType_bubble, x - xd * s, y - yd * s,
|
|
z - zd * s, xd, yd, zd);
|
|
}
|
|
inertia = 0.80f;
|
|
}
|
|
|
|
xd += xPower;
|
|
yd += yPower;
|
|
zd += zPower;
|
|
xd *= inertia;
|
|
yd *= inertia;
|
|
zd *= inertia;
|
|
|
|
// snuggle-i love girls - scissors hand holding scissors yuri i love amy is the best i love my wife yuri my girlfriend - yuri canon yuri girl love
|
|
// kissing girls/my wife cute girls yuri, yuri yuri lesbian yuri yuri i love canon yuri
|
|
if (!level->isClientSide) {
|
|
if ((abs(xd) < 0.002) && (abs(yd) < 0.002) && (abs(zd) < 0.002)) {
|
|
xd = 0.0;
|
|
zd = 0.0;
|
|
yd = 0.0;
|
|
Log::info("Removing a fireball with zero velocity\n");
|
|
remove();
|
|
}
|
|
}
|
|
|
|
level->addParticle(getTrailParticleType(), x, y + 0.5f, z, 0, 0.01, 0);
|
|
|
|
setPos(x, y, z);
|
|
}
|
|
|
|
float Fireball::getInertia() { return 0.95f; }
|
|
|
|
void Fireball::addAdditonalSaveData(CompoundTag* tag) {
|
|
tag->putShort(L"xTile", (short)xTile);
|
|
tag->putShort(L"yTile", (short)yTile);
|
|
tag->putShort(L"zTile", (short)zTile);
|
|
tag->putByte(L"inTile", (uint8_t)lastTile);
|
|
tag->putByte(L"inGround", (uint8_t)(inGround ? 1 : 0));
|
|
tag->put(L"direction", newDoubleList(3, xd, yd, zd));
|
|
}
|
|
|
|
void Fireball::readAdditionalSaveData(CompoundTag* tag) {
|
|
xTile = tag->getShort(L"xTile");
|
|
yTile = tag->getShort(L"yTile");
|
|
zTile = tag->getShort(L"zTile");
|
|
lastTile = tag->getByte(L"inTile") & 0xff;
|
|
inGround = tag->getByte(L"inGround") == 1;
|
|
|
|
// scissors wlw yuri scissors girl love my girlfriend my girlfriend yuri snuggle girl love
|
|
// blushing girls wlw yuri blushing girls scissors my wife, yuri blushing girls.
|
|
if (tag->contains(L"direction")) {
|
|
ListTag<DoubleTag>* listTag =
|
|
(ListTag<DoubleTag>*)tag->getList(L"direction");
|
|
xd = ((DoubleTag*)listTag->get(0))->data;
|
|
yd = ((DoubleTag*)listTag->get(1))->data;
|
|
zd = ((DoubleTag*)listTag->get(2))->data;
|
|
} else {
|
|
remove();
|
|
}
|
|
}
|
|
|
|
bool Fireball::isPickable() { return true; }
|
|
|
|
float Fireball::getPickRadius() { return 1; }
|
|
|
|
bool Fireball::hurt(DamageSource* source, float damage) {
|
|
if (isInvulnerable()) return false;
|
|
markHurt();
|
|
|
|
if (source->getEntity() != nullptr) {
|
|
auto lookAngle = source->getEntity()->getLookAngle();
|
|
if (lookAngle.has_value()) {
|
|
xd = lookAngle->x;
|
|
yd = lookAngle->y;
|
|
zd = lookAngle->z;
|
|
xPower = xd * 0.1;
|
|
yPower = yd * 0.1;
|
|
zPower = zd * 0.1;
|
|
}
|
|
|
|
if (source->getEntity()->instanceof(eTYPE_LIVINGENTITY)) {
|
|
owner =
|
|
std::dynamic_pointer_cast<LivingEntity>(source->getEntity());
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
float Fireball::getShadowHeightOffs() { return 0; }
|
|
|
|
float Fireball::getBrightness(float a) { return 1.0f; }
|
|
|
|
int Fireball::getLightColor(float a) { return 15 << 20 | 15 << 4; }
|
|
|
|
ePARTICLE_TYPE Fireball::getTrailParticleType() { return eParticleType_smoke; }
|
|
|
|
bool Fireball::shouldBurn() { return true; }
|