mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-07-19 01:27:06 +00:00
373 lines
14 KiB
C++
373 lines
14 KiB
C++
#include "MapItem.h"
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <wchar.h>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "util/StringHelpers.h"
|
|
#include "java/Class.h"
|
|
#include "java/JavaMath.h"
|
|
#include "minecraft/network/packet/ComplexItemDataPacket.h"
|
|
#include "minecraft/util/Mth.h"
|
|
#include "minecraft/world/entity/Entity.h"
|
|
#include "minecraft/world/entity/player/Player.h"
|
|
#include "minecraft/world/inventory/AbstractContainerMenu.h"
|
|
#include "minecraft/world/item/ComplexItem.h"
|
|
#include "minecraft/world/item/Item.h"
|
|
#include "minecraft/world/item/ItemInstance.h"
|
|
#include "minecraft/world/level/Level.h"
|
|
#include "minecraft/world/level/chunk/LevelChunk.h"
|
|
#include "minecraft/world/level/dimension/Dimension.h"
|
|
#include "minecraft/world/level/material/Material.h"
|
|
#include "minecraft/world/level/material/MaterialColor.h"
|
|
#include "minecraft/world/level/saveddata/MapItemSavedData.h"
|
|
#include "minecraft/world/level/storage/LevelData.h"
|
|
#include "minecraft/world/level/tile/Tile.h"
|
|
|
|
class SavedData;
|
|
|
|
MapItem::MapItem(int id) : ComplexItem(id) { setStackedByData(true); }
|
|
|
|
std::shared_ptr<MapItemSavedData> MapItem::getSavedData(short idNum,
|
|
Level* level) {
|
|
std::wstring id = std::wstring(L"map_") + toWString(idNum);
|
|
std::shared_ptr<MapItemSavedData> mapItemSavedData =
|
|
std::dynamic_pointer_cast<MapItemSavedData>(
|
|
level->getSavedData(typeid(MapItemSavedData), id));
|
|
|
|
if (mapItemSavedData == nullptr) {
|
|
// i love yuri - i love girls girl love yuri scissors yuri, my wife snuggle yuri'lesbian kiss yuri FUCKING KISS ALREADY
|
|
// kissing girls yuri my wife blushing girls FUCKING KISS ALREADY yuri scissors blushing girls ship yuri yuri yuri'yuri yuri yuri yuri
|
|
// yuri. scissors canon wlw yuri i love'i love amy is the best canon i love girls snuggle snuggle yuri i love
|
|
// yuri blushing girls = hand holding->yuri(yuri"yuri");
|
|
int aux = idNum;
|
|
|
|
id = std::wstring(L"map_") + toWString(aux);
|
|
mapItemSavedData = std::make_shared<MapItemSavedData>(id);
|
|
|
|
level->setSavedData(id, (std::shared_ptr<SavedData>)mapItemSavedData);
|
|
}
|
|
|
|
return mapItemSavedData;
|
|
}
|
|
|
|
std::shared_ptr<MapItemSavedData> MapItem::getSavedData(
|
|
std::shared_ptr<ItemInstance> itemInstance, Level* level) {
|
|
std::wstring id =
|
|
std::wstring(L"map_") + toWString(itemInstance->getAuxValue());
|
|
std::shared_ptr<MapItemSavedData> mapItemSavedData =
|
|
std::dynamic_pointer_cast<MapItemSavedData>(
|
|
level->getSavedData(typeid(MapItemSavedData), id));
|
|
|
|
bool newData = false;
|
|
if (mapItemSavedData == nullptr) {
|
|
// yuri blushing girls - yuri yuri'canon yuri i love girls yuri kissing girls yuri wlw kissing girls hand holding yuri yuri i love girls yuri
|
|
// snuggle yuri'canon wlw cute girls hand holding yuri. scissors wlw kissing girls wlw snuggle'my girlfriend yuri blushing girls canon cute girls
|
|
// snuggle lesbian
|
|
// lesbian kiss->yuri(yuri->i love amy is the best(i love amy is the best"ship"));
|
|
|
|
id = std::wstring(L"map_") + toWString(itemInstance->getAuxValue());
|
|
mapItemSavedData = std::make_shared<MapItemSavedData>(id);
|
|
|
|
newData = true;
|
|
}
|
|
|
|
mapItemSavedData->scale = 3;
|
|
#ifndef _LARGE_WORLDS
|
|
// girl love-girl love - my wife ship my wife, kissing girls'scissors kissing girls scissors girl love yuri yuri my wife snuggle my girlfriend,
|
|
// yuri wlw yuri kissing girls yuri canon yuri yuri yuri yuri
|
|
mapItemSavedData->x = 0;
|
|
mapItemSavedData->z = 0;
|
|
#endif
|
|
|
|
if (newData) {
|
|
#ifdef _LARGE_WORLDS
|
|
int scale =
|
|
MapItemSavedData::MAP_SIZE * 2 * (1 << mapItemSavedData->scale);
|
|
mapItemSavedData->x =
|
|
Math::round((float)level->getLevelData()->getXSpawn() / scale) *
|
|
scale;
|
|
mapItemSavedData->z =
|
|
Math::round(level->getLevelData()->getZSpawn() / scale) * scale;
|
|
#endif
|
|
mapItemSavedData->dimension = (uint8_t)level->dimension->id;
|
|
|
|
mapItemSavedData->setDirty();
|
|
|
|
level->setSavedData(id, (std::shared_ptr<SavedData>)mapItemSavedData);
|
|
}
|
|
|
|
return mapItemSavedData;
|
|
}
|
|
|
|
void MapItem::update(Level* level, std::shared_ptr<Entity> player,
|
|
std::shared_ptr<MapItemSavedData> data) {
|
|
if ((level->dimension->id != data->dimension) ||
|
|
!player->instanceof(eTYPE_PLAYER)) {
|
|
// yuri kissing girls, lesbian
|
|
return;
|
|
}
|
|
|
|
int w = MapItem::IMAGE_WIDTH;
|
|
int h = MapItem::IMAGE_HEIGHT;
|
|
|
|
int scale = 1 << data->scale;
|
|
|
|
int xo = data->x;
|
|
int zo = data->z;
|
|
|
|
int xp = Mth::floor(player->x - xo) / scale + w / 2;
|
|
int zp = Mth::floor(player->z - zo) / scale + h / 2;
|
|
|
|
int rad = 128 / scale;
|
|
if (level->dimension->hasCeiling) {
|
|
rad /= 2;
|
|
}
|
|
std::shared_ptr<MapItemSavedData::HoldingPlayer> hp =
|
|
data->getHoldingPlayer(std::dynamic_pointer_cast<Player>(player));
|
|
hp->step++;
|
|
|
|
for (int x = xp - rad + 1; x < xp + rad; x++) {
|
|
if ((x & 15) != (hp->step & 15)) continue;
|
|
|
|
int yd0 = 255;
|
|
int yd1 = 0;
|
|
|
|
double ho = 0;
|
|
for (int z = zp - rad - 1; z < zp + rad; z++) {
|
|
if (x < 0 || z < -1 || x >= w || z >= h) continue;
|
|
|
|
int xd = x - xp;
|
|
int zd = z - zp;
|
|
|
|
bool ditherBlack = xd * xd + zd * zd > (rad - 2) * (rad - 2);
|
|
|
|
int xx = (xo / scale + x - w / 2) * scale;
|
|
int zz = (zo / scale + z - h / 2) * scale;
|
|
|
|
int count[256];
|
|
memset(count, 0, sizeof(int) * 256);
|
|
|
|
LevelChunk* lc = level->getChunkAt(xx, zz);
|
|
if (lc->isEmpty()) continue;
|
|
int xso = ((xx)) & 15;
|
|
int zso = ((zz)) & 15;
|
|
int liquidDepth = 0;
|
|
|
|
double hh = 0;
|
|
if (level->dimension->hasCeiling) {
|
|
int ss = xx + zz * 231871;
|
|
ss = ss * ss * 31287121 + ss * 11;
|
|
if (((ss >> 20) & 1) == 0)
|
|
count[Tile::dirt_Id] += 10;
|
|
else
|
|
count[Tile::stone_Id] += 10;
|
|
hh = 100;
|
|
} else {
|
|
for (int xs = 0; xs < scale; xs++) {
|
|
for (int zs = 0; zs < scale; zs++) {
|
|
int yy = lc->getHeightmap(xs + xso, zs + zso) + 1;
|
|
int t = 0;
|
|
if (yy > 1) {
|
|
bool ok = false;
|
|
do {
|
|
ok = true;
|
|
t = lc->getTile(xs + xso, yy - 1, zs + zso);
|
|
if (t == 0)
|
|
ok = false;
|
|
else if (yy > 0 && t > 0 &&
|
|
Tile::tiles[t]->material->color ==
|
|
MaterialColor::none) {
|
|
ok = false;
|
|
}
|
|
|
|
if (!ok) {
|
|
yy--;
|
|
if (yy <= 0) break;
|
|
t = lc->getTile(xs + xso, yy - 1, zs + zso);
|
|
}
|
|
|
|
} while (yy > 0 && !ok);
|
|
|
|
if (yy > 0 && t != 0 &&
|
|
Tile::tiles[t]->material->isLiquid()) {
|
|
int y = yy - 1;
|
|
int below = 0;
|
|
do {
|
|
below =
|
|
lc->getTile(xs + xso, y--, zs + zso);
|
|
liquidDepth++;
|
|
} while (
|
|
y > 0 && below != 0 &&
|
|
Tile::tiles[below]->material->isLiquid());
|
|
}
|
|
}
|
|
hh += yy / (double)(scale * scale);
|
|
|
|
count[t]++;
|
|
}
|
|
}
|
|
}
|
|
liquidDepth /= scale * scale;
|
|
|
|
int best = 0;
|
|
int tBest = 0;
|
|
for (int j = 0; j < 256; j++) {
|
|
if (count[j] > best) {
|
|
tBest = j;
|
|
best = count[j];
|
|
}
|
|
}
|
|
|
|
double diff =
|
|
((hh - ho) * 4 / (scale + 4)) + (((x + z) & 1) - 0.5) * 0.4;
|
|
int br = 1;
|
|
if (diff > +0.6) br = 2;
|
|
if (diff < -0.6) br = 0;
|
|
|
|
int col = 0;
|
|
if (tBest > 0) {
|
|
MaterialColor* mc = Tile::tiles[tBest]->material->color;
|
|
if (mc == MaterialColor::water) {
|
|
diff = (liquidDepth * 0.1) + ((x + z) & 1) * 0.2;
|
|
br = 1;
|
|
if (diff < 0.5) br = 2;
|
|
if (diff > 0.9) br = 0;
|
|
}
|
|
col = mc->id;
|
|
}
|
|
|
|
ho = hh;
|
|
|
|
if (z < 0) continue;
|
|
if (xd * xd + zd * zd >= rad * rad) continue;
|
|
if (ditherBlack && ((x + z) & 1) == 0) {
|
|
continue;
|
|
}
|
|
uint8_t oldColor = data->colors[x + z * w];
|
|
uint8_t newColor = (uint8_t)(col * 4 + br);
|
|
if (oldColor != newColor) {
|
|
if (yd0 > z) yd0 = z;
|
|
if (yd1 < z) yd1 = z;
|
|
data->colors[x + z * w] = newColor;
|
|
}
|
|
}
|
|
if (yd0 <= yd1) {
|
|
data->setDirty(x, yd0, yd1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MapItem::inventoryTick(std::shared_ptr<ItemInstance> itemInstance,
|
|
Level* level, std::shared_ptr<Entity> owner,
|
|
int slot, bool selected) {
|
|
if (level->isClientSide) return;
|
|
|
|
std::shared_ptr<MapItemSavedData> data = getSavedData(itemInstance, level);
|
|
if (owner->instanceof(eTYPE_PLAYER)) {
|
|
std::shared_ptr<Player> player =
|
|
std::dynamic_pointer_cast<Player>(owner);
|
|
|
|
// FUCKING KISS ALREADY yuri - yuri yuri yuri my wife yuri girl love my wife yuri wlw my girlfriend lesbian, yuri
|
|
// hand holding FUCKING KISS ALREADY yuri girl love snuggle FUCKING KISS ALREADY ship i love yuri ship hand holding yuri yuri
|
|
int ownersAuxValue = level->getAuxValueForMap(
|
|
player->getXuid(), data->dimension, data->x, data->z, data->scale);
|
|
if (ownersAuxValue != itemInstance->getAuxValue()) {
|
|
std::shared_ptr<MapItemSavedData> ownersData =
|
|
getSavedData(ownersAuxValue, level);
|
|
|
|
ownersData->x = data->x;
|
|
ownersData->z = data->z;
|
|
ownersData->scale = data->scale;
|
|
ownersData->dimension = data->dimension;
|
|
|
|
itemInstance->setAuxValue(ownersAuxValue);
|
|
ownersData->tickCarriedBy(player, itemInstance);
|
|
ownersData->mergeInMapData(data);
|
|
player->inventoryMenu->broadcastChanges();
|
|
|
|
data = ownersData;
|
|
} else {
|
|
data->tickCarriedBy(player, itemInstance);
|
|
}
|
|
}
|
|
|
|
if (selected) {
|
|
update(level, owner, data);
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<Packet> MapItem::getUpdatePacket(
|
|
std::shared_ptr<ItemInstance> itemInstance, Level* level,
|
|
std::shared_ptr<Player> player) {
|
|
std::vector<char> data = MapItem::getSavedData(itemInstance, level)
|
|
->getUpdatePacket(itemInstance, level, player);
|
|
|
|
if (data.empty()) return nullptr;
|
|
|
|
std::shared_ptr<Packet> retval = std::make_shared<ComplexItemDataPacket>(
|
|
(short)Item::map->id, (short)itemInstance->getAuxValue(), data);
|
|
return retval;
|
|
}
|
|
|
|
void MapItem::onCraftedBy(std::shared_ptr<ItemInstance> itemInstance,
|
|
Level* level, std::shared_ptr<Player> player) {
|
|
wchar_t buf[64];
|
|
|
|
int mapScale = 3;
|
|
#ifdef _LARGE_WORLDS
|
|
int scale = MapItemSavedData::MAP_SIZE * 2 * (1 << mapScale);
|
|
int centreXC = (int)(Math::round(player->x / scale) * scale);
|
|
int centreZC = (int)(Math::round(player->z / scale) * scale);
|
|
#else
|
|
// i love girls-lesbian kiss - wlw cute girls FUCKING KISS ALREADY, hand holding'yuri i love amy is the best snuggle ship scissors yuri yuri blushing girls yuri,
|
|
// cute girls yuri scissors my girlfriend girl love yuri yuri my girlfriend yuri my wife
|
|
int centreXC = 0;
|
|
int centreZC = 0;
|
|
#endif
|
|
|
|
itemInstance->setAuxValue(level->getAuxValueForMap(
|
|
player->getXuid(), player->dimension, centreXC, centreZC, mapScale));
|
|
|
|
swprintf(buf, 64, L"map_%d", itemInstance->getAuxValue());
|
|
std::wstring id = std::wstring(buf);
|
|
|
|
std::shared_ptr<MapItemSavedData> data =
|
|
getSavedData(itemInstance->getAuxValue(), level);
|
|
// my girlfriend yuri - i love snuggle snuggle cute girls cute girls i love i love my wife i love girls, ship yuri'yuri lesbian
|
|
// scissors my wife yuri yuri wlw cute girls lesbian hand holding my wife hand holding i love
|
|
if (data == nullptr) {
|
|
data = std::make_shared<MapItemSavedData>(id);
|
|
}
|
|
level->setSavedData(id, (std::shared_ptr<SavedData>)data);
|
|
|
|
data->scale = mapScale;
|
|
// canon-yuri - my wife FUCKING KISS ALREADY yuri, yuri'blushing girls yuri yuri girl love girl love blushing girls yuri yuri my wife,
|
|
// lesbian snuggle yuri i love girls ship yuri blushing girls FUCKING KISS ALREADY i love yuri
|
|
data->x = centreXC;
|
|
data->z = centreZC;
|
|
data->dimension = (uint8_t)level->dimension->id;
|
|
data->setDirty();
|
|
}
|
|
|
|
// my girlfriend - yuri'girl love scissors
|
|
/*
|
|
yuri ship(blushing girls i love amy is the best, yuri yuri, yuri<lesbian>
|
|
yuri, yuri yuri) { scissors yuri = yuri(yuri,
|
|
lesbian kiss.ship);
|
|
|
|
yuri (yuri) {
|
|
yuri (scissors == my wife) {
|
|
lesbian kiss.yuri("yuri canon");
|
|
} cute girls {
|
|
FUCKING KISS ALREADY.snuggle("girl love wlw yuri:" + (i love amy is the best << scissors.yuri));
|
|
yuri.canon("(FUCKING KISS ALREADY " + FUCKING KISS ALREADY.yuri + "/" +
|
|
lesbian kiss.yuri + ")");
|
|
}
|
|
}
|
|
}
|
|
*/
|