Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void Chunk::deserialize(od::StreamReader& data, const SaveParams& params)
- {
- enum {
- FlagFluidType,
- FlagFluid,
- FlagFront2,
- FlagBack2,
- FlagPalFront,
- FlagPalBack
- };
- od::bitfield<8> header;
- if(params.version >= 45) {
- uint8_t header_bits;
- data >> header_bits;
- header = od::bitfield<8>(header_bits);
- } else {
- header = od::bitfield<8>(0xFF);
- }
- decorations.clear();
- _tiles.resize(width * width);
- decorations.resize(width * width);
- unsigned size;
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::front, 0xFFFF, data, size);
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::back, 0xFFFF, data, size);
- if(params.version >= 30)
- {
- if(header[FlagFront2]) {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::front2, 0xFFFF, data, size);
- }
- if(header[FlagBack2]) {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::back2, 0xFFFF, data, size);
- }
- }
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::slope_front, 0xFF, data, size);
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::slope_back, 0xFF, data, size);
- if(params.version >= 17)
- {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::pflags, 0xFF, data, size);
- // remove old volatile flags
- if(params.version <= 39) {
- for(Tile& t: _tiles) {
- t.pflags &= 7;
- }
- }
- }
- if(params.version < 16) // load corrupted data ...
- {
- _fluids.resize(width * width);
- data >> size;
- runLengthEncodingDecompressNoCheck(
- _fluids.begin(), _fluids.end(),
- &FluidCell::fluid, 0xFF, data, size);
- data >> size;
- runLengthEncodingDecompressNoCheck(
- _fluids.begin(), _fluids.end(),
- &FluidCell::flags, 0xFF, data, size);
- // prevent corrupted fluid data
- for(FluidCell& cell: _fluids) {
- if(cell.fluid > FluidCell::MaxFluid)
- cell.fluid = FluidCell::MaxFluid;
- }
- }
- else if(params.version <= 37)
- {
- std::cout << "Import old fluids" << std::endl;
- // Convert old fluid system to new fluid system
- // 1. Import old fluids
- std::vector<FluidCell> fluids(_tiles.size());
- data >> size;
- od::runLengthEncodingDecompress(
- fluids.begin(), fluids.end(),
- &FluidCell::fluid, 0xFF, data, size);
- data >> size;
- od::runLengthEncodingDecompress(
- fluids.begin(), fluids.end(),
- &FluidCell::flags, 0xFF, data, size);
- // 2. Convert fluid using the new system (tiles attributes)
- for(unsigned i=0; i<fluids.size(); ++i)
- {
- _tiles[i].fluid = fluids[i].fluid;
- if(fluids[i].flags == FluidCell::Water) {
- _tiles[i].fluid_type = Tile::FluidWater;
- }
- else if(fluids[i].flags == FluidCell::Lava) {
- _tiles[i].fluid_type = Tile::FluidLava;
- }
- else {
- _tiles[i].fluid_type = Tile::FluidEmpty;
- }
- }
- // 3. fix corrupted fluids
- for(Tile& t: tiles())
- {
- if(t.fluid > Tile::MaxFluid) {
- t.fluid = 0;
- t.fluid_type = Tile::FluidEmpty;
- }
- }
- }
- else
- {
- if(header[FlagFluidType]) {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::fluid_type, 0xFF, data, size);
- }
- if(header[FlagFluid]) {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::fluid, 0xFF, data, size);
- }
- }
- // Import colors
- if(params.version >= 45)
- {
- if(header[FlagPalFront]) {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::pal_front, 0xFF, data, size);
- }
- if(header[FlagPalBack]) {
- data >> size;
- od::runLengthEncodingDecompress(
- _tiles.begin(), _tiles.end(),
- &Tile::pal_back, 0xFF, data, size);
- }
- }
- /// @todo ne devrait pas être ici, mais bon, on est plus a ça pres...
- // update la vie des tiles en fonction du type de block (vu que la vie n'a pas été save)
- for(auto& tile: _tiles)
- {
- if(tile.front != 0) {
- tile.life = BlockInfo::get(tile.front).life();
- } else {
- tile.life = BlockInfo::get(tile.back).life();
- }
- }
- // generate invincible flags
- if(params.version < 17) // < 3-3-2017 (0.6.15)
- {
- static const std::set<int> invincible_blocks = {
- itemIndexFromEntry("pc_brick_monk1").ind,
- itemIndexFromEntry("pc_brick_monk2").ind,
- itemIndexFromEntry("pc_brick_monk3").ind,
- itemIndexFromEntry("pc_brick_monk4").ind,
- itemIndexFromEntry("pc_brick_monk5").ind,
- itemIndexFromEntry("pc_brick_monk6").ind,
- itemIndexFromEntry("pc_brick_monk7").ind,
- itemIndexFromEntry("pc_brick_monk8").ind,
- itemIndexFromEntry("pc_brick_monk9").ind,
- itemIndexFromEntry("pc_brick_monk10").ind,
- itemIndexFromEntry("pc_brick_monk11").ind,
- itemIndexFromEntry("pc_brick_donjon1").ind,
- itemIndexFromEntry("pc_brick_donjon2").ind,
- itemIndexFromEntry("pc_brick_donjon3").ind,
- itemIndexFromEntry("pc_brick_donjon4").ind,
- itemIndexFromEntry("pc_brick_donjon_speed_right").ind,
- itemIndexFromEntry("pc_brick_donjon_speed_left").ind,
- itemIndexFromEntry("pc_brick_donjon_speed_up").ind,
- itemIndexFromEntry("pc_brick_donjon_speed_down").ind,
- itemIndexFromEntry("pc_brick_donjon_speed_h").ind,
- itemIndexFromEntry("pc_brick_invincible").ind
- };
- for(Tile& tile: _tiles)
- {
- if(tile.front != 0) {
- if(invincible_blocks.find(tile.front) != invincible_blocks.end())
- tile.pflags |= Tile::PFlagIndestructibleFront;
- }
- }
- }
- // deserialize grounds
- {
- data >> size;
- /// @todo optimize allocations
- std::vector<Ground> temp(size);
- for(Ground &g: temp)
- {
- data >> g.x >> g.y >> g.ind >> g.orientation;
- }
- _grounds.setContent(temp, params.version <= 45);
- }
- if(params.version > 45)
- {
- data >> size;
- _ores.resize(size);
- for(Ore &ore: _ores) {
- data >> ore.ind >> ore.x >> ore.y >> ore.life;
- }
- }
- else
- {
- data >> size;
- _ores.resize(size);
- for(Ore &ore: _ores)
- {
- uint16_t x, y;
- int ind;
- data >> ind >> x >> y >> ore.life;
- ore.x = uint8_t(x);
- ore.y = uint8_t(y);
- if(ind == -1) {
- ore.ind = InvalidObjectInd;
- } else {
- ore.ind = uint16_t(ind);
- }
- }
- }
- if(params.version >= 36) {
- data >> size;
- /// @todo optimize allocations
- std::vector<centauri::Fire> fire_temp(size);
- for(centauri::Fire& f: fire_temp)
- {
- uint8_t flags_bits;
- data >> flags_bits;
- od::bitfield<8> flags(flags_bits);
- uint8_t timer;
- data >> f.x >> f.y >> timer;
- f.timer = timer;
- if(flags[1]) {
- uint16_t energy;
- data >> energy;
- f.remaining_energy = energy;
- } else {
- data >> f.remaining_energy;
- }
- uint16_t heat;
- data >> heat;
- f.heat = heat;
- }
- fire.setContent(fire_temp);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment