onilink_

Untitled

Apr 8th, 2022
1,022
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.98 KB | None | 0 0
  1. void Chunk::deserialize(od::StreamReader& data, const SaveParams& params)
  2. {
  3.     enum {
  4.         FlagFluidType,
  5.         FlagFluid,
  6.         FlagFront2,
  7.         FlagBack2,
  8.         FlagPalFront,
  9.         FlagPalBack
  10.     };
  11.    
  12.     od::bitfield<8> header;
  13.     if(params.version >= 45) {
  14.         uint8_t header_bits;
  15.         data >> header_bits;
  16.         header = od::bitfield<8>(header_bits);
  17.     } else {
  18.         header = od::bitfield<8>(0xFF);
  19.     }
  20.    
  21.     decorations.clear();
  22.    
  23.     _tiles.resize(width * width);
  24.     decorations.resize(width * width);
  25.    
  26.     unsigned size;
  27.     data >> size;
  28.     od::runLengthEncodingDecompress(
  29.                 _tiles.begin(), _tiles.end(),
  30.                 &Tile::front, 0xFFFF, data, size);
  31.    
  32.     data >> size;
  33.     od::runLengthEncodingDecompress(
  34.                 _tiles.begin(), _tiles.end(),
  35.                 &Tile::back, 0xFFFF, data, size);
  36.    
  37.     if(params.version >= 30)
  38.     {
  39.         if(header[FlagFront2]) {
  40.             data >> size;
  41.             od::runLengthEncodingDecompress(
  42.                     _tiles.begin(), _tiles.end(),
  43.                     &Tile::front2, 0xFFFF, data, size);
  44.         }
  45.        
  46.         if(header[FlagBack2]) {
  47.             data >> size;
  48.             od::runLengthEncodingDecompress(
  49.                     _tiles.begin(), _tiles.end(),
  50.                     &Tile::back2, 0xFFFF, data, size);
  51.         }
  52.     }
  53.    
  54.     data >> size;
  55.     od::runLengthEncodingDecompress(
  56.                 _tiles.begin(), _tiles.end(),
  57.                 &Tile::slope_front, 0xFF, data, size);
  58.    
  59.     data >> size;
  60.     od::runLengthEncodingDecompress(
  61.                 _tiles.begin(), _tiles.end(),
  62.                 &Tile::slope_back, 0xFF, data, size);
  63.    
  64.     if(params.version >= 17)
  65.     {
  66.         data >> size;
  67.         od::runLengthEncodingDecompress(
  68.                     _tiles.begin(), _tiles.end(),
  69.                     &Tile::pflags, 0xFF, data, size);
  70.        
  71.         // remove old volatile flags
  72.         if(params.version <= 39) {
  73.             for(Tile& t: _tiles) {
  74.                 t.pflags &= 7;
  75.             }
  76.         }
  77.     }
  78.    
  79.     if(params.version < 16) // load corrupted data ...
  80.     {
  81.         _fluids.resize(width * width);
  82.        
  83.         data >> size;
  84.         runLengthEncodingDecompressNoCheck(
  85.                     _fluids.begin(), _fluids.end(),
  86.                     &FluidCell::fluid, 0xFF, data, size);
  87.        
  88.         data >> size;
  89.         runLengthEncodingDecompressNoCheck(
  90.                     _fluids.begin(), _fluids.end(),
  91.                     &FluidCell::flags, 0xFF, data, size);
  92.        
  93.         // prevent corrupted fluid data
  94.         for(FluidCell& cell: _fluids) {
  95.             if(cell.fluid > FluidCell::MaxFluid)
  96.                 cell.fluid = FluidCell::MaxFluid;
  97.         }
  98.     }
  99.     else if(params.version <= 37)
  100.     {
  101.         std::cout << "Import old fluids" << std::endl;
  102.         // Convert old fluid system to new fluid system
  103.         // 1. Import old fluids
  104.         std::vector<FluidCell> fluids(_tiles.size());
  105.        
  106.         data >> size;
  107.         od::runLengthEncodingDecompress(
  108.                     fluids.begin(), fluids.end(),
  109.                     &FluidCell::fluid, 0xFF, data, size);
  110.        
  111.         data >> size;
  112.         od::runLengthEncodingDecompress(
  113.                     fluids.begin(), fluids.end(),
  114.                     &FluidCell::flags, 0xFF, data, size);
  115.        
  116.         // 2. Convert fluid using the new system (tiles attributes)
  117.         for(unsigned i=0; i<fluids.size(); ++i)
  118.         {
  119.             _tiles[i].fluid = fluids[i].fluid;
  120.             if(fluids[i].flags == FluidCell::Water) {
  121.                 _tiles[i].fluid_type = Tile::FluidWater;
  122.             }
  123.             else if(fluids[i].flags == FluidCell::Lava) {
  124.                 _tiles[i].fluid_type = Tile::FluidLava;
  125.             }
  126.             else {
  127.                 _tiles[i].fluid_type = Tile::FluidEmpty;
  128.             }
  129.         }
  130.        
  131.         // 3. fix corrupted fluids
  132.         for(Tile& t: tiles())
  133.         {
  134.             if(t.fluid > Tile::MaxFluid) {
  135.                 t.fluid = 0;
  136.                 t.fluid_type = Tile::FluidEmpty;
  137.             }
  138.         }
  139.     }
  140.     else
  141.     {
  142.         if(header[FlagFluidType]) {
  143.             data >> size;
  144.             od::runLengthEncodingDecompress(
  145.                         _tiles.begin(), _tiles.end(),
  146.                         &Tile::fluid_type, 0xFF, data, size);
  147.         }
  148.        
  149.         if(header[FlagFluid]) {
  150.             data >> size;
  151.             od::runLengthEncodingDecompress(
  152.                         _tiles.begin(), _tiles.end(),
  153.                         &Tile::fluid, 0xFF, data, size);
  154.         }
  155.     }
  156.    
  157.     // Import colors
  158.     if(params.version >= 45)
  159.     {
  160.         if(header[FlagPalFront]) {
  161.             data >> size;
  162.             od::runLengthEncodingDecompress(
  163.                         _tiles.begin(), _tiles.end(),
  164.                         &Tile::pal_front, 0xFF, data, size);
  165.         }
  166.         if(header[FlagPalBack]) {
  167.             data >> size;
  168.             od::runLengthEncodingDecompress(
  169.                         _tiles.begin(), _tiles.end(),
  170.                         &Tile::pal_back, 0xFF, data, size);
  171.         }
  172.     }
  173.    
  174.     /// @todo ne devrait pas être ici, mais bon, on est plus a ça pres...
  175.     // update la vie des tiles en fonction du type de block (vu que la vie n'a pas été save)
  176.     for(auto& tile: _tiles)
  177.     {
  178.         if(tile.front != 0) {
  179.             tile.life = BlockInfo::get(tile.front).life();
  180.         } else {
  181.             tile.life = BlockInfo::get(tile.back).life();
  182.         }
  183.     }
  184.    
  185.     // generate invincible flags
  186.     if(params.version < 17) // < 3-3-2017 (0.6.15)
  187.     {
  188.         static const std::set<int> invincible_blocks = {
  189.             itemIndexFromEntry("pc_brick_monk1").ind,
  190.             itemIndexFromEntry("pc_brick_monk2").ind,
  191.             itemIndexFromEntry("pc_brick_monk3").ind,
  192.             itemIndexFromEntry("pc_brick_monk4").ind,
  193.             itemIndexFromEntry("pc_brick_monk5").ind,
  194.             itemIndexFromEntry("pc_brick_monk6").ind,
  195.             itemIndexFromEntry("pc_brick_monk7").ind,
  196.             itemIndexFromEntry("pc_brick_monk8").ind,
  197.             itemIndexFromEntry("pc_brick_monk9").ind,
  198.             itemIndexFromEntry("pc_brick_monk10").ind,
  199.             itemIndexFromEntry("pc_brick_monk11").ind,
  200.             itemIndexFromEntry("pc_brick_donjon1").ind,
  201.             itemIndexFromEntry("pc_brick_donjon2").ind,
  202.             itemIndexFromEntry("pc_brick_donjon3").ind,
  203.             itemIndexFromEntry("pc_brick_donjon4").ind,
  204.             itemIndexFromEntry("pc_brick_donjon_speed_right").ind,
  205.             itemIndexFromEntry("pc_brick_donjon_speed_left").ind,
  206.             itemIndexFromEntry("pc_brick_donjon_speed_up").ind,
  207.             itemIndexFromEntry("pc_brick_donjon_speed_down").ind,
  208.             itemIndexFromEntry("pc_brick_donjon_speed_h").ind,
  209.             itemIndexFromEntry("pc_brick_invincible").ind
  210.         };
  211.         for(Tile& tile: _tiles)
  212.         {
  213.             if(tile.front != 0) {
  214.                 if(invincible_blocks.find(tile.front) != invincible_blocks.end())
  215.                     tile.pflags |= Tile::PFlagIndestructibleFront;
  216.             }
  217.         }
  218.     }
  219.    
  220.     // deserialize grounds
  221.     {
  222.         data >> size;
  223.         /// @todo optimize allocations
  224.         std::vector<Ground> temp(size);
  225.         for(Ground &g: temp)
  226.         {
  227.             data >> g.x >> g.y >> g.ind >> g.orientation;
  228.         }
  229.        
  230.         _grounds.setContent(temp, params.version <= 45);
  231.     }
  232.    
  233.    
  234.     if(params.version > 45)
  235.     {
  236.         data >> size;
  237.         _ores.resize(size);
  238.         for(Ore &ore: _ores) {
  239.             data >> ore.ind >> ore.x >> ore.y >> ore.life;
  240.         }
  241.     }
  242.     else
  243.     {
  244.         data >> size;
  245.         _ores.resize(size);
  246.         for(Ore &ore: _ores)
  247.         {
  248.             uint16_t x, y;
  249.             int ind;
  250.             data >> ind >> x >> y >> ore.life;
  251.             ore.x = uint8_t(x);
  252.             ore.y = uint8_t(y);
  253.             if(ind == -1) {
  254.                 ore.ind = InvalidObjectInd;
  255.             } else {
  256.                 ore.ind = uint16_t(ind);
  257.             }
  258.         }
  259.     }
  260.    
  261.     if(params.version >= 36) {
  262.         data >> size;
  263.         /// @todo optimize allocations
  264.         std::vector<centauri::Fire> fire_temp(size);
  265.         for(centauri::Fire& f: fire_temp)
  266.         {
  267.             uint8_t flags_bits;
  268.             data >> flags_bits;
  269.            
  270.             od::bitfield<8> flags(flags_bits);
  271.            
  272.             uint8_t timer;
  273.             data >> f.x >> f.y >> timer;
  274.             f.timer = timer;
  275.            
  276.             if(flags[1]) {
  277.                 uint16_t energy;
  278.                 data >> energy;
  279.                 f.remaining_energy = energy;
  280.             } else {
  281.                 data >> f.remaining_energy;
  282.             }
  283.            
  284.             uint16_t heat;
  285.             data >> heat;
  286.             f.heat = heat;
  287.         }
  288.         fire.setContent(fire_temp);
  289.     }
  290. }
Advertisement
Add Comment
Please, Sign In to add comment