| 636 | |
| 637 | |
| 638 | void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy) |
| 639 | { |
| 640 | // Block types are compulsory, block metas are voluntary |
| 641 | if (!HasBlockTypes() || !a_Src.HasBlockTypes()) |
| 642 | { |
| 643 | LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__); |
| 644 | return; |
| 645 | } |
| 646 | |
| 647 | // Dst is *this, Src is a_Src |
| 648 | int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading |
| 649 | int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing |
| 650 | int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy |
| 651 | |
| 652 | int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading |
| 653 | int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing |
| 654 | int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy |
| 655 | |
| 656 | int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading |
| 657 | int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing |
| 658 | int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy |
| 659 | |
| 660 | const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas(); |
| 661 | NIBBLETYPE * DstMetas = m_BlockMetas; |
| 662 | bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL)); |
| 663 | |
| 664 | if (IsDummyMetas) |
| 665 | { |
| 666 | SrcMetas = new NIBBLETYPE[a_Src.GetBlockCount()]; |
| 667 | DstMetas = new NIBBLETYPE[GetBlockCount()]; |
| 668 | } |
| 669 | |
| 670 | switch (a_Strategy) |
| 671 | { |
| 672 | case msOverwrite: |
| 673 | { |
| 674 | InternalMergeBlocks( |
| 675 | m_BlockTypes, a_Src.GetBlockTypes(), |
| 676 | DstMetas, SrcMetas, |
| 677 | SizeX, SizeY, SizeZ, |
| 678 | SrcOffX, SrcOffY, SrcOffZ, |
| 679 | DstOffX, DstOffY, DstOffZ, |
| 680 | a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), |
| 681 | m_Size.x, m_Size.y, m_Size.z, |
| 682 | MergeCombinatorOverwrite |
| 683 | ); |
| 684 | break; |
| 685 | } // case msOverwrite |
| 686 | |
| 687 | case msFillAir: |
| 688 | { |
| 689 | InternalMergeBlocks( |
| 690 | m_BlockTypes, a_Src.GetBlockTypes(), |
| 691 | DstMetas, SrcMetas, |
| 692 | SizeX, SizeY, SizeZ, |
| 693 | SrcOffX, SrcOffY, SrcOffZ, |
| 694 | DstOffX, DstOffY, DstOffZ, |
| 695 | a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), |
no test coverage detected