123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- #include "FluidBlock.h"
- #include "Game.h"
- FluidBlock::FluidBlock(int typeId,
- Framework::Vec3<int> pos,
- int dimensionId,
- Vec3<float> lightWeights)
- : Block(typeId, 0, pos, dimensionId, 0),
- lightWeights(lightWeights),
- neighborChanged(1),
- nextFlow(0),
- maxFlowDistance(8)
- {
- transparent = 1;
- passable = 1;
- hp = 1;
- maxHP = 1;
- hardness = -1.f;
- speedModifier = 0.5f;
- tickSource = 1;
- interactable = 0;
- flowOptions = 0;
- distanceToSource = 0;
- }
- FluidBlock::~FluidBlock() {}
- bool FluidBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
- {
- if (neighborChanged)
- {
- nextFlow -= numTicks;
- if (nextFlow <= 0)
- {
- const FluidBlockType* zType
- = dynamic_cast<const FluidBlockType*>(zBlockType());
- if (zType)
- {
- nextFlow = zType->getTicktsToFlow();
- }
- else
- {
- nextFlow = 0;
- }
- neighborChanged = 0;
- doFlow();
- }
- return true;
- }
- return false;
- }
- void FluidBlock::onPostTick() {}
- void FluidBlock::setNeighbourType(Direction dir, int type)
- {
- Block::setNeighbourType(dir, type);
- neighborChanged = 1;
- }
- void FluidBlock::sendModelInfo(NetworkMessage* zMessage)
- {
- zMessage->addressBlock(this);
- char* msg = new char[3];
- msg[0] = 2; // fluid amount change
- *(msg + 1) = flowOptions;
- *(msg + 2) = distanceToSource;
- zMessage->setMessage(msg, 3);
- }
- void FluidBlock::broadcastFlow()
- {
- NetworkMessage* changeMsg = new NetworkMessage();
- sendModelInfo(changeMsg);
- Game::INSTANCE->broadcastMessage(changeMsg);
- }
- void FluidBlock::doFlow()
- {
- bool changed = false;
- for (int i = 0; i < 6; i++)
- {
- Direction dir = getDirectionFromIndex(i);
- if (dir & Direction::TOP) continue;
- if (neighbourTypes[i] == BlockTypeEnum::AIR)
- {
- Game::INSTANCE->doLater([this, dir, i]() {
- if (neighbourTypes[i] == BlockTypeEnum::AIR)
- {
- Block* belowBlock = zBlockType()->createBlockAt(
- getPos() + getDirection(dir), getDimensionId(), 0);
- FluidBlock* fluidBlock
- = dynamic_cast<FluidBlock*>(belowBlock);
- if (fluidBlock)
- {
- fluidBlock->distanceToSource
- = dir & Direction::BOTTOM
- ? 1
- : distanceToSource + 1;
- fluidBlock->flowOptions = (char)dir;
- Game::INSTANCE->zDimension(getDimensionId())
- ->placeBlock(
- getPos() + getDirection(dir), belowBlock);
- }
- else
- {
- std::cout
- << "ERROR: created flow fuild block is not an "
- "instance of FluidBlock\n";
- belowBlock->release();
- }
- }
- });
- }
- else if (zNeighbours[i] && zNeighbours[i]->zBlockType() == zBlockType())
- {
- if (dir & Direction::BOTTOM) continue;
- FluidBlock* neighbour = dynamic_cast<FluidBlock*>(zNeighbours[i]);
- if (neighbour)
- {
- if (distanceToSource > neighbour->distanceToSource + 1)
- {
- distanceToSource = neighbour->distanceToSource + 1;
- flowOptions = (char)getOppositeDirection(dir);
- changed = true;
- }
- else if (distanceToSource == neighbour->distanceToSource + 1)
- {
- char tmp = flowOptions;
- flowOptions |= (char)getOppositeDirection(dir);
- changed |= tmp != flowOptions;
- }
- }
- }
- }
- if (changed)
- {
- broadcastFlow();
- neighborChanged = 1;
- for (int i = 0; i < 6; i++)
- {
- Direction dir = getDirectionFromIndex(i);
- if (dir & (Direction::TOP | Direction::BOTTOM)) continue;
- if (zNeighbours[i] && zNeighbours[i]->zBlockType() == zBlockType())
- {
- FluidBlock* neighbour
- = dynamic_cast<FluidBlock*>(zNeighbours[i]);
- if (neighbour)
- {
- neighbour->neighborChanged = 1;
- }
- }
- }
- }
- }
- void FluidBlock::filterPassingLight(unsigned char rgb[3]) const
- {
- rgb[0] = (unsigned char)(rgb[0] * lightWeights.x);
- rgb[1] = (unsigned char)(rgb[1] * lightWeights.y);
- rgb[2] = (unsigned char)(rgb[2] * lightWeights.z);
- }
- char FluidBlock::getDistanceToSource() const
- {
- return distanceToSource;
- }
- char FluidBlock::getFlowOptions() const
- {
- return flowOptions;
- }
- FluidBlockType::FluidBlockType(int id,
- ModelInfo model,
- const char* name,
- int mapColor,
- Vec3<float> lightWeights,
- int ticktsToFlow,
- char flowDistance)
- : BlockType(id, 0, model, 1, 10, 0, name, true, mapColor),
- lightWeights(lightWeights),
- ticktsToFlow(ticktsToFlow),
- flowDistance(flowDistance)
- {}
- void FluidBlockType::loadSuperBlock(
- Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
- {
- FluidBlock* block = dynamic_cast<FluidBlock*>(zBlock);
- zReader->lese(&block->flowOptions, 1);
- zReader->lese(&block->distanceToSource, 1);
- block->nextFlow = ticktsToFlow;
- block->maxFlowDistance = flowDistance;
- BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
- }
- void FluidBlockType::saveSuperBlock(
- Block* zBlock, Framework::StreamWriter* zWriter) const
- {
- FluidBlock* block = dynamic_cast<FluidBlock*>(zBlock);
- zWriter->schreibe(&block->flowOptions, 1);
- zWriter->schreibe(&block->distanceToSource, 1);
- BlockType::saveSuperBlock(zBlock, zWriter);
- }
- Item* FluidBlockType::createItem() const
- {
- return 0;
- }
- Block* FluidBlockType::createBlock(
- Framework::Vec3<int> position, int dimensionId) const
- {
- FluidBlock* result
- = new FluidBlock(getId(), position, dimensionId, lightWeights);
- result->nextFlow = ticktsToFlow;
- result->maxFlowDistance = flowDistance;
- return result;
- }
- bool FluidBlockType::isFluid() const
- {
- return true;
- }
- int FluidBlockType::getTicktsToFlow() const
- {
- return ticktsToFlow;
- }
- char FluidBlockType::getFlowDistance() const
- {
- return flowDistance;
- }
|