/** * Load a voxel stack from the save game file. * @param ldr Input stream to read. */ void VoxelStack::Load(Loader &ldr) { this->Clear(); uint32 version = ldr.OpenBlock("VSTK"); if (version >= 1 && version <= 3) { int16 base = ldr.GetWord(); uint16 height = ldr.GetWord(); uint8 owner = ldr.GetByte(); if (base < 0 || base + height > WORLD_Z_SIZE || owner >= OWN_COUNT) { ldr.SetFailMessage("Incorrect voxel stack size"); } else { this->base = base; this->height = height; this->owner = (TileOwner)owner; delete[] this->voxels; this->voxels = (height > 0) ? MakeNewVoxels(height) : nullptr; for (uint i = 0; i < height; i++) this->voxels[i].Load(ldr, version); /* In version 3 of VSTK, the fences of the lowest corner of steep slopes have moved from the top voxel to the base voxel. */ if (version < 3) { static const uint16 low_fences_mask[4] = { // Mask for getting the low fences. (0xf << (4 * EDGE_SE)) | (0xf << (4 * EDGE_SW)), // ISL_TOP_STEEP_NORTH (0xf << (4 * EDGE_SW)) | (0xf << (4 * EDGE_NW)), // ISL_TOP_STEEP_EAST (0xf << (4 * EDGE_NW)) | (0xf << (4 * EDGE_NE)), // ISL_TOP_STEEP_SOUTH (0xf << (4 * EDGE_NE)) | (0xf << (4 * EDGE_SE)), // ISL_TOP_STEEP_WEST }; for (uint i = 0; i < height; i++) { if (this->voxels[i].GetGroundType() == GTP_INVALID) continue; if (!IsImplodedSteepSlopeTop(this->voxels[i].GetGroundSlope())) continue; uint16 mask = low_fences_mask[this->voxels[i].GetGroundSlope() - ISL_TOP_STEEP_NORTH]; /* Take out the fences of the top voxel that should be in the base voxel. * Make the low fences in the high voxel invalid. */ uint16 fences = this->voxels[i].GetFences(); uint16 lower_fences = fences & mask; uint16 high_invalid = ALL_INVALID_FENCES & mask; mask ^= 0xffff; this->voxels[i].SetFences(high_invalid | (fences & mask)); /* Fix low fences. */ fences = this->voxels[i + 1].GetFences(); this->voxels[i + 1].SetFences(lower_fences | (fences & mask)); break; // Only one steep ground slope in a voxel stack at most. } } } } ldr.CloseBlock(); }
/** * Load the world from a file. * @param ldr Input stream to read from. */ void VoxelWorld::Load(Loader &ldr) { uint32 version = ldr.OpenBlock("WRLD"); uint16 xsize = 64; uint16 ysize = 64; if (version == 1) { xsize = ldr.GetWord(); ysize = ldr.GetWord(); } else if (version != 0) { ldr.SetFailMessage("Unknown world version."); } if (xsize >= WORLD_X_SIZE || ysize >= WORLD_Y_SIZE) { xsize = std::min<uint16>(xsize, WORLD_X_SIZE); ysize = std::min<uint16>(ysize, WORLD_Y_SIZE); ldr.SetFailMessage("Incorrect world size"); } ldr.CloseBlock(); this->SetWorldSize(xsize, ysize); if (!ldr.IsFail() && version != 0) { for (uint16 x = 0; x < xsize; x++) { for (uint16 y = 0; y < ysize; y++) { VoxelStack *vs = this->GetModifyStack(x, y); vs->Load(ldr); } } } if (version == 0 || ldr.IsFail()) this->MakeFlatWorld(8); }
/** * Load guests from the save game. * @param ldr Input stream to read. */ void Guests::Load(Loader &ldr) { uint32 version = ldr.OpenBlock("GSTS"); if (version == 1) { this->start_voxel.x = ldr.GetWord(); this->start_voxel.y = ldr.GetWord(); this->daily_frac = ldr.GetWord(); this->next_daily_index = ldr.GetWord(); this->free_idx = ldr.GetLong(); uint active_guest_count = ldr.GetLong(); for (uint i = 0; i < active_guest_count; i++) { Guest *g = this->block.Get(ldr.GetWord()); g->Load(ldr); } } else { ldr.SetFailMessage("Incorrect version of Guests block."); } ldr.CloseBlock(); }
/** * Load a voxel from the save game. * @param ldr Input stream to read. * @param version Version to load. */ void Voxel::Load(Loader &ldr, uint32 version) { this->ClearVoxel(); if (version >= 1 && version <= 3) { this->ground = ldr.GetLong(); /// \todo Check sanity of the data. this->instance = ldr.GetByte(); if (this->instance == SRI_FREE) { this->instance_data = 0; // Full rides load after the world, overwriting map data. } else if (this->instance >= SRI_RIDES_START && this->instance < SRI_FULL_RIDES) { this->instance_data = ldr.GetWord(); } else { this->instance_data = 0; // Full rides load after the world, overwriting map data. ldr.SetFailMessage("Unknown voxel instance data"); } if (version >= 2) this->fences = ldr.GetWord(); } else { ldr.SetFailMessage("Unknown voxel version"); } }