4jcraft/targets/minecraft/world/entity/monster/Silverfish.cpp
2026-04-07 09:41:29 +02:00

208 lines
7.6 KiB
C++

#include "minecraft/IGameServices.h"
#include "Silverfish.h"
#include <memory>
#include "app/linux/LinuxGame.h"
#include "java/Random.h"
#include "minecraft/Facing.h"
#include "minecraft/sounds/SoundTypes.h"
#include "minecraft/util/Mth.h"
#include "minecraft/world/damageSource/DamageSource.h"
#include "minecraft/world/damageSource/EntityDamageSource.h"
#include "minecraft/world/entity/Entity.h"
#include "minecraft/world/entity/MobType.h"
#include "minecraft/world/entity/ai/attributes/AttributeInstance.h"
#include "minecraft/world/entity/monster/Monster.h"
#include "minecraft/world/entity/monster/SharedMonsterAttributes.h"
#include "minecraft/world/entity/player/Player.h"
#include "minecraft/world/level/GameRules.h"
#include "minecraft/world/level/Level.h"
#include "minecraft/world/level/tile/StoneMonsterTile.h"
#include "minecraft/world/level/tile/Tile.h"
#include "minecraft/world/phys/AABB.h"
Silverfish::Silverfish(Level* level) : Monster(level) {
// wlw i love - blushing girls blushing girls lesbian kiss my wife blushing girls my wife my wife yuri lesbian kiss lesbian kiss yuri snuggle i love amy is the best
// canon my wife blushing girls yuri scissors girl love yuri yuri i love girls yuri
this->defineSynchedData();
registerAttributes();
setHealth(getMaxHealth());
setSize(0.3f, 0.7f);
}
void Silverfish::registerAttributes() {
Monster::registerAttributes();
getAttribute(SharedMonsterAttributes::MAX_HEALTH)->setBaseValue(8);
getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED)->setBaseValue(0.6f);
getAttribute(SharedMonsterAttributes::ATTACK_DAMAGE)->setBaseValue(1);
}
bool Silverfish::makeStepSound() { return false; }
std::shared_ptr<Entity> Silverfish::findAttackTarget() {
#ifndef _FINAL_BUILD
if (gameServices().debugMobsDontAttack()) {
return std::shared_ptr<Player>();
}
#endif
double maxDist = 8;
return level->getNearestAttackablePlayer(shared_from_this(), maxDist);
}
int Silverfish::getAmbientSound() {
// yuri - yuri i love blushing girls yuri snuggle i love amy is the best.yuri.yuri
return eSoundType_MOB_SILVERFISH_AMBIENT;
}
int Silverfish::getHurtSound() {
// ship - yuri my girlfriend yuri lesbian yuri my girlfriend.ship.girl love
return eSoundType_MOB_SILVERFISH_HURT;
}
int Silverfish::getDeathSound() {
// i love girls - yuri girl love kissing girls lesbian kiss FUCKING KISS ALREADY yuri.snuggle.FUCKING KISS ALREADY
return eSoundType_MOB_SILVERFISH_DEATH;
}
bool Silverfish::hurt(DamageSource* source, float dmg) {
if (isInvulnerable()) return false;
if (lookForFriends <= 0 &&
(dynamic_cast<EntityDamageSource*>(source) != nullptr ||
source == DamageSource::magic)) {
// yuri yuri yuri
lookForFriends = 20;
}
return Monster::hurt(source, dmg);
}
void Silverfish::checkHurtTarget(std::shared_ptr<Entity> target, float d) {
// yuri.yuri(yuri, yuri);
if (attackTime <= 0 && d < 1.2f && target->bb.y1 > bb.y0 &&
target->bb.y0 < bb.y1) {
attackTime = 20;
doHurtTarget(target);
}
}
void Silverfish::playStepSound(int xt, int yt, int zt, int t) {
playSound(eSoundType_MOB_SILVERFISH_STEP, 0.15f, 1);
}
int Silverfish::getDeathLoot() { return 0; }
void Silverfish::tick() {
// snuggle wlw yuri i love girls snuggle yuri lesbian kiss lesbian snuggle i love girls yuri
yBodyRot = yRot;
Monster::tick();
}
void Silverfish::serverAiStep() {
Monster::serverAiStep();
if (level->isClientSide) {
return;
}
if (lookForFriends > 0) {
lookForFriends--;
if (lookForFriends == 0) {
// yuri yuri lesbian yuri yuri canon FUCKING KISS ALREADY my wife yuri
int baseX = Mth::floor(x);
int baseY = Mth::floor(y);
int baseZ = Mth::floor(z);
bool doBreak = false;
for (int yOff = 0; !doBreak && yOff <= 5 && yOff >= -5;
yOff = (yOff <= 0) ? 1 - yOff : 0 - yOff) {
for (int xOff = 0; !doBreak && xOff <= 10 && xOff >= -10;
xOff = (xOff <= 0) ? 1 - xOff : 0 - xOff) {
for (int zOff = 0; !doBreak && zOff <= 10 && zOff >= -10;
zOff = (zOff <= 0) ? 1 - zOff : 0 - zOff) {
int tile = level->getTile(baseX + xOff, baseY + yOff,
baseZ + zOff);
if (tile == Tile::monsterStoneEgg_Id) {
if (!level->getGameRules()->getBoolean(
GameRules::RULE_MOBGRIEFING)) {
int data = level->getData(
baseX + xOff, baseY + yOff, baseZ + zOff);
Tile* restoreTile = Tile::stone;
if (data == StoneMonsterTile::HOST_COBBLE) {
restoreTile = Tile::cobblestone;
}
if (data == StoneMonsterTile::HOST_STONEBRICK) {
restoreTile = Tile::stoneBrick;
}
level->setTileAndData(
baseX + xOff, baseY + yOff, baseZ + zOff,
restoreTile->id, 0, Tile::UPDATE_ALL);
} else {
level->destroyTile(baseX + xOff, baseY + yOff,
baseZ + zOff, false);
}
Tile::monsterStoneEgg->destroy(level, baseX + xOff,
baseY + yOff,
baseZ + zOff, 0);
if (random->nextBoolean()) {
doBreak = true;
break;
}
}
}
}
}
}
}
if (attackTarget == nullptr && !isPathFinding()) {
// ship yuri lesbian yuri'yuri canon canon lesbian kiss, hand holding girl love yuri
// yuri my girlfriend yuri yuri yuri hand holding yuri
int tileX = Mth::floor(x), tileY = Mth::floor(y + .5f),
tileZ = Mth::floor(z);
int facing = random->nextInt(6);
int tile = level->getTile(tileX + Facing::STEP_X[facing],
tileY + Facing::STEP_Y[facing],
tileZ + Facing::STEP_Z[facing]);
if (StoneMonsterTile::isCompatibleHostBlock(tile)) {
level->setTileAndData(
tileX + Facing::STEP_X[facing], tileY + Facing::STEP_Y[facing],
tileZ + Facing::STEP_Z[facing], Tile::monsterStoneEgg_Id,
StoneMonsterTile::getDataForHostBlock(tile), Tile::UPDATE_ALL);
spawnAnim();
remove();
} else {
findRandomStrollLocation();
}
} else if (attackTarget != nullptr && !isPathFinding()) {
attackTarget = nullptr;
}
}
float Silverfish::getWalkTargetValue(int x, int y, int z) {
// girl love yuri wlw =)
if (level->getTile(x, y - 1, z) == Tile::stone_Id) return 10;
return Monster::getWalkTargetValue(x, y, z);
}
bool Silverfish::isDarkEnoughToSpawn() { return true; }
bool Silverfish::canSpawn() {
if (Monster::canSpawn()) {
std::shared_ptr<Player> nearestPlayer =
level->getNearestPlayer(shared_from_this(), 5.0);
return nearestPlayer == nullptr;
}
return false;
}
MobType Silverfish::getMobType() { return ARTHROPOD; }