diff --git a/SQF/dayz_code/Configs/CfgExtra/HelperVectors.hpp b/SQF/dayz_code/Configs/CfgExtra/HelperVectors.hpp new file mode 100644 index 000000000..793ca631e --- /dev/null +++ b/SQF/dayz_code/Configs/CfgExtra/HelperVectors.hpp @@ -0,0 +1,817 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// modularVectors.hpp +// +// Author: Victor the Cleaner +// Date: August 2021 +// +// Helper array vectors for "Remove" and "Deconstruct" of modular objects. +// Similar to snappoints.hpp, but customized to specific objects for improved visual appeal. +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Known Values +#define mX1 5.28 // metal floor, width (x,y) +#define mZ1 0.3 // metal floor, height (z) +#define pZ1 3.05 // metal pillar, height (z) +#define cZ1 3.37 // cinder wall full, height (z) +#define cH1 1.5 // cinder wall half, height (z) +#define gZ1 6.8 // cinder gate frame, height (z) + +// Metal +#define mX2 2.64 // metal floor, half width +#define mX4 1.32 // metal floor, quarter width +#define mZ2 0.15 // metal floor, half height +#define pZ2 1.525 // metal pillar, half height (z) + +// Cinder +#define cX1 mX1 // cinder wall full, width (x) +#define cX2 2.64 // cinder wall full, half width +#define cZ2 1.685 // cinder wall full, half height +#define cH2 0.75 // cinder wall half, half height +#define gUP 5.055 // cinder gate frame, upper left/right (3/4 z) + +/* +// Metal (derived) +#define mX2 mX1 / 2 // metal floor, half width +#define mX4 mX1 / 4 // metal floor, quarter width +#define mZ2 mZ1 / 2 // metal floor, half height +#define pZ2 pZ1 / 2 // metal pillar, half height (z) + +// Cinder (derived) +#define cX1 mX1 // cinder wall full, width (x) +#define cX2 cX1 / 2 // cinder wall full, half width +#define cZ2 cZ1 / 2 // cinder wall full, half height +#define cH2 cH1 / 2 // cinder wall half, half height +#define gUP cZ2 * 3 // cinder gate frame, upper left/right (3/4 z) +*/ + +class Helpers; +class HelperVectors: Helpers { + + class vector { + size = 3; + radius = 8; + }; + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // Metal Objects + // + /////////////////////////////////////////////////////////////////////////////////////////// + + class MetalFloor_DZ: vector { + points[] = { + { 0, 0, mZ2 }, // Pivot + { 0, -mX2, mZ2 }, // Back + { 0, mX2, mZ2 }, // Front + { -mX2, 0, mZ2 }, // Left + { mX2, 0, mZ2 } // Right + }; + }; + class Land_wreck_metal_floor: vector { + points[] = { + { 0, -mX2, mZ2 }, // Back + { 0, mX2, mZ2 }, // Front + { -mX2, 0, mZ2 }, // Left + { mX2, 0, mZ2 } // Right + }; + }; + class MetalFloor_Half_DZ: vector { + points[] = { + // { 0, 0, mZ2 }, // Pivot (removed) + { 0, -mX2, mZ2 }, // Back + { 0, mX2, mZ2 }, // Front + { -mX4, 0, mZ2 }, // Left + { mX4, 0, mZ2 } // Right + }; + }; + class MetalFloor_Quarter_DZ: vector { + points[] = { + // { 0, 0, mZ2 }, // Pivot (removed) + { 0, -mX4, mZ2 }, // Back + { 0, mX4, mZ2 }, // Front + { -mX4, 0, mZ2 }, // Left + { mX4, 0, mZ2 } // Right + }; + radius = 4; + }; + class MetalFloor4x_DZ: vector { + points[] = { + { 0, 0, mZ2 }, // Pivot + { 0, -mX1, mZ2 }, // Back + { 0, mX1, mZ2 }, // Front + { -mX1, 0, mZ2 }, // Left + { mX1, 0, mZ2 } // Right + }; + radius = 15; + }; + class Land_metal_floor_2x2_wreck: MetalFloor4x_DZ {}; + + class MetalPillar_DZ: vector { + points[] = { + {0, 0, 0 }, // Pivot + {0, 0, pZ1 }, // Top + {0, 0, pZ2 } // Center (replaces L/R) + }; + radius = 4; + }; + class Metal_Drawbridge_DZ: vector { + points[] = { + { 0, 0, 0 }, // Bottom + { -2.40, 0, 3 }, // Left (adjusted) + { 2.46, 0, 3 }, // Right (adjusted) + { 0, 0, 6.05 }, // Top + { 0, 0, 3 } // center (added) + }; + }; + class Metal_DrawbridgeLocked_DZ: Metal_Drawbridge_DZ {}; + + class Door_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -1, 0, 1.34 }, // Left + { 1, 0, 1.34 }, // Right + { 0, 0, 2.67 } // Top + }; + radius = 4; + }; + class DoorFrame_DZ: Door_DZ {}; + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // Glass Objects + // + /////////////////////////////////////////////////////////////////////////////////////////// + + class GlassFloor_DZ: MetalFloor_DZ {}; + class GlassFloor_Half_DZ: MetalFloor_Half_DZ {}; + class GlassFloor_Quarter_DZ: MetalFloor_Quarter_DZ {}; + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // Cinder Objects + // + /////////////////////////////////////////////////////////////////////////////////////////// + + class CinderWallHalf_DZ: vector { + points[] = { + { 0, 0, 0 }, // Bottom + { -cX2, 0, cH2 }, // Left (replacement) + { cX2, 0, cH2 }, // Right (replacement) + { 0, 0, cH1 } // Top + }; + }; + class CinderWallHalf_Gap_DZ: CinderWallHalf_DZ {}; + + class Land_wreck_cinder: vector { + points[] = { + { -1.64, 0, 0.25 }, // Left (replacement) + { 1.64, 0, 0.25 } // Right (replacement) + }; + }; + class CinderWall_DZ { + points[] = { + { 0, 0, 0 }, // Bottom + { -cX2, 0, cZ2 }, // Left + { cX2, 0, cZ2 }, // Right + { 0, 0, cZ1 }, // Top + { 0, 0, cZ2 } // Center (added) + }; + }; + class CinderWallDoorSmall_DZ: CinderWall_DZ {}; + class CinderWallDoorSmallLocked_DZ: CinderWall_DZ {}; + class CinderWallWindow_DZ: CinderWall_DZ {}; + class CinderWallWindowLocked_DZ: CinderWall_DZ {}; + class CinderDoorHatch_DZ: CinderWall_DZ {}; + class CinderDoorHatchLocked_DZ: CinderWall_DZ {}; + class CinderWallDoor_DZ: CinderWall_DZ {}; // garage door + class CinderWallDoorLocked_DZ: CinderWall_DZ {}; // garage door + class CinderGarageOpenTop_DZ: CinderWall_DZ {}; + class CinderGarageOpenTopLocked_DZ: CinderWall_DZ {}; + + class CinderGateFrame_DZ: vector { + points[] = { + { 0, 0, 0 }, // Bottom + { -mX2, 0, cZ2 }, // Lower Left + { mX2, 0, cZ2 }, // Lower Right + { -mX2, 0, gUP }, // Upper Left (added) + { mX2, 0, gUP }, // Upper Right (added) + { 0, 0, gZ1 } // Top + }; + radius = 10; + }; + class CinderGate_DZ: vector { + points[] = { + { 0, 0, 0 }, // Bottom + { -mX2, 0, cZ2 }, // Lower Left + { mX2, 0, cZ2 }, // Lower Right + { -mX2, 0, gUP }, // Upper Left (added) + { mX2, 0, gUP }, // Upper Right (added) + { 0, 0, gZ1 }, // Top + { 0, 0, cZ1 } // Center (added) + }; + radius = 10; + }; + class CinderGateLocked_DZ: CinderGate_DZ {}; + + class Concrete_Bunker_DZ: vector { + points[] = { + { 0, 2.1, 2.8 }, // Front (added) + { 0, -2.1, 2.8 }, // Back (adjusted) + { -2.34, 0, 2.8 }, // Left (adjusted) + { 2.34, 0, 2.8 }, // Right (adjusted) + { 0, 0, 3.4 } // Top + }; + radius = 7; + }; + class Concrete_Bunker_Locked_DZ: Concrete_Bunker_DZ {}; + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // Wood Objects + // + /////////////////////////////////////////////////////////////////////////////////////////// + + class WoodFloor4x_DZ: vector { + points[] = { + { 0, 0, 0.130 }, // Pivot (adjusted) + { 0, -4.64, 0.130 }, // Back + { 0, 4.64, 0.130 }, // Front + { -4.96, 0, 0.130 }, // Left + { 4.95, 0, 0.130 } // Right + }; + radius = 15; + }; + class Land_wood_floor_2x2_wreck: WoodFloor4x_DZ {}; + + class WoodFloor_DZ: vector { + points[] = { + { 0, 0, 0.130 }, // Pivot (adjusted) + { 0, -2.32, 0.130 }, // Back + { 0, 2.32, 0.130 }, // Front + { -2.494, 0, 0.130 }, // Left + { 2.450, 0, 0.130 } // Right + }; + radius = 8; + }; + class Land_wood_wreck_floor: vector { + points[] = { + { 0, -2.32, 0.130 }, // Back + { 0, 2.32, 0.130 }, // Front + { -2.494, 0, 0.130 }, // Left + { 2.450, 0, 0.130 } // Right + }; + radius = 8; + }; + class WoodFloorStairs_DZ: vector { + points[] = { + { -2.3, 1.4, 0.3 }, // Pivot/bottom step (adjusted) + { 0, -2.32, 3.114 }, // Back + { 0, 2.32, 3.114 }, // Front + { -2.52, 0, 3.114 }, // Left + { 2.46, 0, 3.114 } // Right + }; + radius = 8; + }; + class WoodFloorHalf_DZ: vector { + points[] = { + // { 0, 0, 0 }, // Pivot (removed) + { 0, -2.33, 0.107 }, // Back + { 0, 2.33, 0.107 }, // Front + { -1.18, 0, 0.107 }, // Left + { 1.32, 0, 0.107 } // Right + }; + }; + class Land_wood_wreck_half: WoodFloorHalf_DZ {}; + + class WoodFloorQuarter_DZ: vector { + points[] = { + // { 0, 0, 0 }, // Pivot (removed) + { 0, -1.2, 0.107 }, // Back + { 0, 1.11, 0.107 }, // Front + { -1.2, 0, 0.107 }, // Left + { 1.3, 0, 0.107 } // Right + }; + radius = 4; + }; + class Land_wood_wreck_quarter: WoodFloorQuarter_DZ {}; + + class WoodTriangleFloor_DZ: vector { + points[] = { + // { 0, 0, 0 }, // Pivot (removed) + { 0, -1.3, 0.092 }, // Back + { 0, 1.3, 0.092 }, // Front + { -1.258, 0.027, 0.092 }, // Left + { 1.258, 0.027, 0.092 } // Right + }; + radius = 4; + }; + class WoodSmallWallThird_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -2.445, 0, 0.585 }, // Left (lowered) + { 2.445, 0, 0.585 }, // Right (lowered) + { 0, 0, 1.17 } // Top + }; + }; + class Land_wood_wreck_third: vector { + points[] = { + { 0, 0, 0 }, // Pivot (bottom) + { -2.445, 0, 0.585 }, // Left (lowered) + { 2.445, 0, 0.585 } // Right (lowered) + }; + }; + +// class WoodTriangleWall_DZ: vector { + +// Small wood walls +// class WoodSmallWallDoor_DZ: vector { // doorway +// class WoodSmallWallWin_DZ: vector { // window + + class WoodSmallWall_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot (bottom) + { -2.285, 0, 1.5 }, // Left + { 2.285, 0, 1.5 }, // Right + { 0, 0, 3 }, // Top + { 0, 0, 1.5 } // Center (added) + }; + }; + class Land_DZE_WoodDoor: WoodSmallWall_DZ {}; + class Land_DZE_WoodDoorLocked: WoodSmallWall_DZ {}; + class Land_DZE_WoodOpenTopGarageDoor: WoodSmallWall_DZ {}; + class Land_DZE_WoodOpenTopGarageLocked: WoodSmallWall_DZ {}; + + class Land_wood_wreck_frame: vector { + points[] = { + { 0, 0, 0 }, // Pivot (bottom) + { -2.285, 0, 1.5 }, // Left + { 2.285, 0, 1.5 }, // Right + { 0, 0, 3 } // Top + }; + }; + +// Large wood walls +// class WoodLargeWallDoor_DZ // doorway +// class WoodLargeWallWin_DZ: vector { // window + + class WoodLargeWall_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -2.45, 0, 1.5 }, // Left + { 2.45, 0, 1.5 }, // Right + { 0, 0, 3 }, // Top + { 0, 0, 1.5 } // Center (added) + }; + }; + class Land_DZE_LargeWoodDoor: WoodLargeWall_DZ {}; + class Land_DZE_LargeWoodDoorLocked: WoodLargeWall_DZ {}; + class Land_DZE_GarageWoodDoor: WoodLargeWall_DZ {}; + class Land_DZE_GarageWoodDoorLocked: WoodLargeWall_DZ {}; + + class WoodGateFrame_DZ: vector { + points[] = { + { 0, 0, 0 }, // Bottom + { -2.43, 0, 1.5 }, // Lower Left + { 2.45, 0, 1.5 }, // Lower Right + { -2.43, 0, 4.5 }, // Upper Left (added) + { 2.45, 0, 4.5 }, // Upper Right (added) + { 0, 0, 6.05 } // Top + }; + radius = 9; + }; + class Land_DZE_WoodGate: vector { + points[] = { + { 0, 0, 0 }, // Bottom + { -2.43, 0, 1.5 }, // Lower Left + { 2.45, 0, 1.5 }, // Lower Right + { -2.43, 0, 4.5 }, // Upper Left (added) + { 2.45, 0, 4.5 }, // Upper Right (added) + { 0, 0, 6.05 }, // Top + { 0, 0, 3 } // Center (added) + }; + radius = 9; + }; + class Land_DZE_WoodGateLocked: Land_DZE_WoodGate {}; + + class WoodRamp_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -1.5, 3.14, 1.2 }, // Left + { 1.7, 3.14, 1.2 }, // Right + { 0.115, 5.78, 2.82 } // Top + }; + radius = 15; + }; + class WoodStairs_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot (Bottom Step) + { 0, 3.65, 3 }, // Front (Top Step) + // { 0, 1.8, 0 }, // Bottom (removed) + { -0.81, 1.8, 1.5 }, // Left + { 0.78, 1.8, 1.5 } // Right + }; + radius = 5; + }; + class WoodStairsSans_DZ: WoodStairs_DZ {}; + class WoodStairsRails_DZ: WoodStairs_DZ {}; + + class WoodLadder_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -0.4, 0, 1.725 }, // Left + { 0.4, 0, 1.725 }, // Right + { 0, 0, 3.45 } // Top (added) + }; + size = 2; + radius = 4; + }; + class WoodHandrail_DZ: vector { + points[] = { + { 0, 0, 0}, // Pivot + { -1.16, 0, 0.5}, // Left + { 1.2, 0, 0.5}, // Right + { 0, 0, 1 } // Top + }; + size = 2; + radius = 3; + }; + + class WoodPillar_DZ: MetalPillar_DZ {}; + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // Storage + // + /////////////////////////////////////////////////////////////////////////////////////////// + + class GunRack_DZ: vector { + points[] = { + { -0, -0.1, -0.2 } // Center + }; + size = 2; + radius = 2; + }; + class GunRack2_DZ: GunRack_DZ {}; + + class WoodCrate_DZ: vector { + points[] = { + { 0, 0, -0.47 }, // Bottom + { 0, -0.47, 0 }, // Back + { 0, 0.47, 0 }, // Front + { -0.47, 0, 0 }, // Left + { 0.47, 0, 0 }, // Right + { 0, 0, 0.47 } // Top + }; + size = 2; + radius = 2; + }; + class WoodCrate2_DZ: WoodCrate_DZ {}; + + class StorageCrate_DZ: vector { + points[] = { + { 0, 0, 0.08 } // Top + }; + size = 2; + radius = 2; + }; + class CamoStorageCrate_DZ: vector { + points[] = { + { 0, 0, 0.45 } // Top + }; + size = 2; + radius = 2; + }; + class OutHouse_DZ: vector { + points[] = { + { -0.59, 0, 0 }, // Left + { 0.59, 0, 0 }, // Right + { 0, 0.75, 0 }, // Front + { 0, -0.55, 0 } // Back + }; + size = 2; + radius = 2; + }; + class StorageShed_DZ: vector { + points[] = { + { -1.9, 0, 1.5 }, // Left + { 1.47, 0, 1.5 }, // Right + { 0, 0, 2.8 }, // Top + { 0, 1.1, 1.5 }, // Front + { 0, -1.25, 1.5 } // Back + }; + radius = 5; + }; + class StorageShed2_DZ: StorageShed_DZ {}; + + class Wooden_shed_DZ: vector { + points[] = { + { 0.6, -1.5, 0 }, // Back + { 0.6, 1.5, 0 }, // Front + { 3, 0, 0 }, // Right + { 0.6, 0, 1.5 }, // Top + { -1.6, 0, 0 } // Left (cull on open door) + }; + radius = 7; + }; + class Wooden_shed2_DZ: Wooden_shed_DZ {}; + + class WoodShack_DZ: vector{ + points[] = { + { 0, 2.4, 0 }, // Front + { -1.18, 0.6, 0 }, // Left + { 1.18, 0.6, 0 }, // Right + { 0, -1.1, 1.1 } // Top + }; + }; + class WoodShack2_DZ: WoodShack_DZ {}; + + class StashSmall: vector { + points[] = { + { 0, 0, 0.3 } // Top + }; + size = 2; + }; + class StashSmall1: StashSmall {}; + class StashSmall2: StashSmall {}; + class StashSmall3: StashSmall {}; + class StashSmall4: StashSmall {}; + + class StashMedium: vector { + points[] = { + { 0, 0, 0.8 } // Top + }; + size = 2; + }; + class StashMedium1: StashMedium {}; + class StashMedium2: StashMedium {}; + class StashMedium3: StashMedium {}; + class StashMedium4: StashMedium {}; + + class TentStorage: vector { + points[] = { + { 0, 0, 0.55 } // Top + }; + size = 2; + radius = 5; + }; + class TentStorage0: TentStorage {}; + class TentStorage1: TentStorage {}; + class TentStorage2: TentStorage {}; + class TentStorage3: TentStorage {}; + class TentStorage4: TentStorage {}; + class TentStorageWinter: TentStorage {}; + class TentStorageWinter0: TentStorage {}; + class TentStorageWinter1: TentStorage {}; + class TentStorageWinter2: TentStorage {}; + class TentStorageWinter3: TentStorage {}; + class TentStorageWinter4: TentStorage {}; + class IC_Tent: TentStorage {}; + + class DomeTentStorage: vector { + points[] = { + { 0.25, 0, 0.7 } // Top + }; + size = 2; + radius = 5; + }; + class DomeTentStorage0: DomeTentStorage {}; + class DomeTentStorage1: DomeTentStorage {}; + class DomeTentStorage2: DomeTentStorage {}; + class DomeTentStorage3: DomeTentStorage {}; + class DomeTentStorage4: DomeTentStorage {}; + class DesertTentStorage: DomeTentStorage {}; + class DesertTentStorage0: DomeTentStorage {}; + class DesertTentStorage1: DomeTentStorage {}; + class DesertTentStorage2: DomeTentStorage {}; + class DesertTentStorage3: DomeTentStorage {}; + class DesertTentStorage4: DomeTentStorage {}; + class WinterDomeTentStorage: DomeTentStorage {}; + class WinterDomeTentStorage0: DomeTentStorage {}; + class WinterDomeTentStorage1: DomeTentStorage {}; + class WinterDomeTentStorage2: DomeTentStorage {}; + class WinterDomeTentStorage3: DomeTentStorage {}; + class WinterDomeTentStorage4: DomeTentStorage {}; + class IC_DomeTent: DomeTentStorage {}; + + class LockboxStorage: vector { + points[] = { + { 0, 0, 0.25 } // Top + }; + size = 2; + }; + class LockboxStorageLocked: LockboxStorage {}; + class LockboxStorage2: LockboxStorage {}; + class LockboxStorage2Locked: LockboxStorage {}; + class LockboxStorageWinter: LockboxStorage {}; + class LockboxStorageWinterLocked: LockboxStorage {}; + class LockboxStorageWinter2: LockboxStorage {}; + class LockboxStorageWinter2Locked: LockboxStorage {}; + + class VaultStorage: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { 0, 0.284, 0.615 }, // Front + { 0, -0.284, 0.615 }, // Back (door center) + { 0, 0, 1.23 }, // Top + { -0.362, 0, 0.615 }, // Left + { 0.362, 0, 0.615 } // Right + }; + size = 2; + radius = 3; + }; + class VaultStorageLocked: VaultStorage {}; + class VaultStorage2: VaultStorage {}; + class VaultStorage2Locked: VaultStorage {}; + class VaultStorageBroken: VaultStorage {}; + class VaultStorageBroken2: VaultStorage {}; + + class TallSafe: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { 0, 0.35, 1 }, // Front + { 0, -0.35, 1 }, // Back (door center) + { 0, 0, 2 }, // Top + { -0.42, 0, 1 }, // Left + { 0.42, 0, 1 } // Right + }; + size = 2; + radius = 3; + }; + class TallSafeLocked: TallSafe {}; + class TallSafeBroken: TallSafe {}; + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // Fortifications + // + /////////////////////////////////////////////////////////////////////////////////////////// + + class Land_HBarrier1_DZ: vector { + points[] = { + { 0, -0.4, 0 }, // Back + { 0, 0.4, 0 }, // Front + { -0.25, 0, 0 }, // Left + { 0.25, 0, 0 }, // Right + { 0, 0, 0.4 } // Top + }; + radius = 3; + }; + class Land_HBarrier3_DZ: vector { + points[] = { + { 0, -0.4, 0 }, // Back + { 0, 0.4, 0 }, // Front + { -1.35, 0, 0 }, // Left + { 1.35, 0, 0 }, // Right + { 0, 0, 0.4 } // Top + }; + radius = 5; + }; + class Land_HBarrier5_DZ: vector { + points[] = { + { 0, -0.4, 0 }, // Back + { 0, 0.5, 0 }, // Front + { -2.5, 0, 0 }, // Left + { 2.5, 0, 0 }, // Right + { 0, 0, 0.5 } // Top + }; + radius = 8; + }; + class Sandbag1_DZ: vector { + points[] = { + { 0, 0, -0.1 } // Pivot (center) + // { -1.5, -0.1, -0.1 }, // Left + // { 1.5, -0.1, -0.1 } // Right + }; + radius = 4; + }; + class BagFenceRound_DZ: vector { + points[] = { + { 0, -0.30, -0.1 } // Pivot (center) + // { -1.295, 0.38, -0.1 }, // Left + // { 1.295, 0.38, -0.1 } // Right + }; + radius = 3; + }; + class StickFence_DZ: vector { + points[] = { + { 0, 0, 0.6 }, // Top + { -2.95, 0, 0 }, // Left + { 2.95, 0, 0 } // Right + }; + size = 2; + radius = 7; + }; + class MetalGate_DZ: vector { + points[] = { + { -4, 0, 0.3 }, // Left + { 0, 0, 0.3 } // Right + }; + radius = 10; + }; + class MetalPanel_DZ: vector { + points[] = { + { 0, 0, -0.8 }, // Pivot + { -1.5, 0, 0.5 }, // Left + { 1.5, 0, 0.5 }, // Right + { 0, 0, 2 } // Top + }; + radius = 5; + }; + class Fence_corrugated_DZ: vector { + points[] = { + { 0, 0, 1.3 }, // Top + { 0, 0, -0.4 }, // Bottom + { -1.95, 0, 0.4 }, // Left + { 1.95, 0, 0.4 } // Right + }; + }; + class WoodenFence_1_foundation_DZ: vector { + points[] = { + { 0, 0, 0.5 }, // Pivot + { -2.535, 0, 0.5 }, // Left + { 2.535, 0, 0.5 } // Right + }; + }; + class WoodenFence_1_frame_DZ: vector { + points[] = { + { 0, 0, 0.95 }, // Top + { -2.535, 0, 0.95 }, // Left + { 2.535, 0, 0.95 } // Right + }; + }; + class WoodenFence_quaterpanel_DZ: WoodenFence_1_frame_DZ {}; + class WoodenFence_halfpanel_DZ: WoodenFence_1_frame_DZ {}; + class WoodenFence_thirdpanel_DZ: WoodenFence_1_frame_DZ {}; + class WoodenFence_1_DZ: WoodenFence_1_frame_DZ {}; + + class WoodenFence_2_DZ: vector { + points[] = { + { 0, 0, 0.5 }, // Pivot + { -2.535, 0, 1.6 }, // Left + { 2.535, 0, 1.6 }, // Right + { 0, 0, 2.68 } // Top + }; + }; + class WoodenFence_3_DZ: WoodenFence_2_DZ {}; + + class WoodenFence_4_DZ: vector { + points[] = { + { 0, 0, 0.5 }, // Pivot + { -2.535, 0, 2 }, // Left + { 2.535, 0, 2 }, // Right + { 0, 0, 3.58 } // Top + }; + }; + class WoodenFence_5_DZ: WoodenFence_4_DZ {}; + class WoodenFence_6_DZ: WoodenFence_4_DZ {}; + class WoodenFence_7_DZ: WoodenFence_4_DZ {}; + + class MetalFence_1_foundation_DZ: WoodenFence_1_foundation_DZ {}; + + class MetalFence_1_frame_DZ: vector { + points[] = { + { 0, 0, 1.4 }, // Top + { -2.535, 0, 1.4 }, // Left + { 2.535, 0, 1.4 } // Right + }; + }; + class MetalFence_halfpanel_DZ: MetalFence_1_frame_DZ {}; + class MetalFence_thirdpanel_DZ: MetalFence_1_frame_DZ {}; + class MetalFence_1_DZ: MetalFence_1_frame_DZ {}; + + class MetalFence_2_DZ: WoodenFence_2_DZ {}; + class MetalFence_3_DZ: WoodenFence_2_DZ {}; + class MetalFence_4_DZ: WoodenFence_4_DZ {}; + class MetalFence_5_DZ: WoodenFence_4_DZ {}; + class MetalFence_6_DZ: WoodenFence_4_DZ {}; + class MetalFence_7_DZ: WoodenFence_4_DZ {}; + + class WoodenGate_foundation_DZ: vector { + points[] = { + // { 0, 0, 0.95 }, // Top + { -2.535, 0, 0.95 }, // Left + { 2.535, 0, 0.95 } // Right + }; + }; + class WoodenGate_1_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -2.535, 0, 0.95 }, // Left + { 2.535, 0, 0.95 }, // Right + { 0, 0, 2 } // Top + }; + }; + + class WoodenGate_2_DZ: WoodenFence_2_DZ {}; + class WoodenGate_3_DZ: WoodenFence_2_DZ {}; + + class WoodenGate_4_DZ: vector { + points[] = { + { 0, 0, 0 }, // Pivot + { -2.535, 0, 1.9 }, // Left + { 2.535, 0, 1.9 }, // Right + { 0, 0, 3.58 } // Top + }; + }; +}; diff --git a/SQF/dayz_code/actions/player_buildingDowngrade.sqf b/SQF/dayz_code/actions/player_buildingDowngrade.sqf index 467d40125..9fb0bb2cd 100644 --- a/SQF/dayz_code/actions/player_buildingDowngrade.sqf +++ b/SQF/dayz_code/actions/player_buildingDowngrade.sqf @@ -1,111 +1,164 @@ -/* - DayZ Base Building Upgrades - Made for DayZ Epoch please ask permission to use/edit/distribute email vbawol@veteranbastards.com. -*/ -if (dayz_actionInProgress) exitWith {localize "str_epoch_player_48" call dayz_rollingMessages;}; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DayZ Base Building Downgrades +// Made for DayZ Epoch please ask permission to use/edit/distribute email vbawol@veteranbastards.com. +// +// Updated by: Victor the Cleaner +// Date: August 2021 +// +// - Now includes helper spheres for improved player experience. +// - Reapply damage to upgraded object if necessary. +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +if (dayz_actionInProgress) exitWith {localize "str_epoch_player_48" call dayz_rollingMessages;}; // Downgrade is already in progress. dayz_actionInProgress = true; -private ["_location","_dir","_classname","_text","_object","_objectID","_objectUID","_newclassname","_refund","_obj","_upgrade","_objectCharacterID","_ownerID","_i","_invResult","_itemOut","_countOut","_abortInvAdd","_addedItems","_finished","_playerNear"]; - player removeAction s_player_downgrade_build; s_player_downgrade_build = 1; -_obj = _this select 3; +local _obj = _this select 3; -_objectCharacterID = _obj getVariable ["CharacterID","0"]; +local _objectCharacterID = _obj getVariable ["CharacterID","0"]; -if (DZE_Lock_Door != _objectCharacterID) exitWith {dayz_actionInProgress = false; s_player_downgrade_build = -1; localize "str_epoch_player_49" call dayz_rollingMessages;}; +if (DZE_Lock_Door != _objectCharacterID) exitWith { // Unable to downgrade, you do not know the combination. + dayz_actionInProgress = false; + s_player_downgrade_build = -1; + localize "str_epoch_player_49" call dayz_rollingMessages; +}; -_playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 12]) > 1; -if (_playerNear) exitWith {dayz_actionInProgress = false; s_player_downgrade_build = -1; localize "str_pickup_limit_5" call dayz_rollingMessages;}; +local _playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 12]) > 1; -_objectID = _obj getVariable ["ObjectID","0"]; -_objectUID = _obj getVariable ["ObjectUID","0"]; +if (_playerNear) exitWith { // Another player is nearby. Only one player can be near to perform this action. + dayz_actionInProgress = false; + s_player_downgrade_build = -1; + localize "str_pickup_limit_5" call dayz_rollingMessages; +}; -if (_objectID == "0" && _objectUID == "0") exitWith {dayz_actionInProgress = false; s_player_downgrade_build = -1; localize "str_epoch_player_50" call dayz_rollingMessages;}; +local _objectID = _obj getVariable ["ObjectID","0"]; +local _objectUID = _obj getVariable ["ObjectUID","0"]; -_classname = typeOf _obj; +if (_objectID == "0" && _objectUID == "0") exitWith { // Not setup yet. + dayz_actionInProgress = false; + s_player_downgrade_build = -1; + localize "str_epoch_player_50" call dayz_rollingMessages; +}; -_text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName"); -_upgrade = getArray (configFile >> "CfgVehicles" >> _classname >> "downgradeBuilding"); +/////////////////////////////////////////////////////////////////////////////////////////////////// -if ((count _upgrade) > 0) then { - _newclassname = _upgrade select 0; - _refund = _upgrade select 1; +local _classname = typeOf _obj; +local _text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName"); +local _upgrade = getArray (configFile >> "CfgVehicles" >> _classname >> "downgradeBuilding"); - [player,(getPosATL player),40,"repair"] spawn fnc_alertZombies; +if (count _upgrade > 0) then { + + local _newclassname = _upgrade select 0; + local _refund = _upgrade select 1; + + [_obj] call fn_displayHelpers; // create helpers + + [player, (getPosATL player), 40, "repair"] spawn fnc_alertZombies; // make noise + + local _finished = ["Medic",1] call fn_loopAction; // animation + + [] call fn_displayHelpers; // delete helpers - _finished = ["Medic",1] call fn_loopAction; if (!_finished) exitWith {}; ["Working",0,[3,2,4,0]] call dayz_NutritionSystem; - _invResult = false; - _abortInvAdd = false; - _i = 0; - _addedItems = []; - false call dz_fn_meleeMagazines; // Remove melee magazines (BIS_fnc_invAdd fix) + local _invResult = false; + local _i = 0; + local _addedItems = []; + local _itemOut = ""; // item class + + false call dz_fn_meleeMagazines; // Remove melee magazines (BIS_fnc_invAdd fix) { _itemOut = _x select 0; - _countOut = _x select 1; + local _countOut = _x select 1; for "_x" from 1 to _countOut do { - _invResult = [player,_itemOut] call BIS_fnc_invAdd; - if(!_invResult) exitWith { - _abortInvAdd = true; - }; - if(_invResult) then { - _i = _i + 1; - _addedItems set [(count _addedItems),[_itemOut,1]]; - }; - }; - if (_abortInvAdd) exitWith {}; + _invResult = [player, _itemOut] call BIS_fnc_invAdd; + + if (!_invResult) exitWith {}; + + _i = _i + 1; + _addedItems set [(count _addedItems), [_itemOut, 1]]; + }; + if (!_invResult) exitWith {}; } count _refund; + true call dz_fn_meleeMagazines; - if (_i != 0) then { - _location = _obj getVariable["OEMPos",getPosATL _obj]; + if (_i > 0) then { - _dir = getDir _obj; - _vector = [(vectorDir _obj),(vectorUp _obj)]; + local _position = _obj getVariable["OEMPos", getPosATL _obj]; + local _dir = getDir _obj; + local _vector = [(vectorDir _obj), (vectorUp _obj)]; if (_classname in DZE_DoorsLocked) then { - _obj setVariable ["CharacterID",dayz_characterID,true]; + + _obj setVariable ["CharacterID", dayz_characterID, true]; _objectCharacterID = dayz_characterID; }; _classname = _newclassname; - _object = createVehicle [_classname, [0,0,0], [], 0, "CAN_COLLIDE"]; + local _object = createVehicle [_classname, [0,0,0], [], 0, "CAN_COLLIDE"]; //_object setDir _dir; // setdir is incompatible with setVectorDirAndUp and should not be used together on the same object https://community.bistudio.com/wiki/setVectorDirAndUp - _object setVariable["memDir",_dir,true]; + _object setVariable["memDir", _dir, true]; _object setVectorDirAndUp _vector; - _object setPosATL _location; + _object setPosATL _position; - format[localize "str_epoch_player_142",_text] call dayz_rollingMessages; + format[localize "str_epoch_player_142", _text] call dayz_rollingMessages; // You have downgraded %1. - if (DZE_GodModeBase && {!(_classname in DZE_GodModeBaseExclude)}) then {_object addEventHandler ["HandleDamage",{false}];}; + if (DZE_GodModeBase && {!(_classname in DZE_GodModeBaseExclude)}) then { + + _object addEventHandler ["HandleDamage", {false}]; + + } else { + // + // reapply damage based on armor values + // + local _armorOld = getNumber (configFile >> "CfgVehicles" >> (typeOf _obj) >> "armor"); + local _damageOld = damage _obj; + + local _armorNew = getNumber (configFile >> "CfgVehicles" >> _classname >> "armor"); + local _damageNew = _damageOld; + + // check for divide by 0 + if (_armorNew > 0) then { + _damageNew = (_damageOld * _armorOld) / _armorNew; + }; + + _object setDamage _damageNew; + }; if (DZE_permanentPlot) then { - _ownerID = _obj getVariable["ownerPUID","0"]; - _object setVariable ["ownerPUID",_ownerID,true]; - PVDZE_obj_Swap = [_objectCharacterID,_object,[_dir,_location,dayz_playerUID,_vector],_classname,_obj,player,[],dayz_authKey]; - } else { - PVDZE_obj_Swap = [_objectCharacterID,_object,[_dir,_location, _vector],_classname,_obj,player,[],dayz_authKey]; - }; - publicVariableServer "PVDZE_obj_Swap"; + local _ownerID = _obj getVariable["ownerPUID", "0"]; + _object setVariable ["ownerPUID", _ownerID, true]; + + PVDZE_obj_Swap = [_objectCharacterID, _object, [_dir, _position, dayz_playerUID, _vector], _classname, _obj, player, [], dayz_authKey]; + } else { + PVDZE_obj_Swap = [_objectCharacterID, _object, [_dir, _position, _vector], _classname, _obj, player, [], dayz_authKey]; + }; + + publicVariableServer "PVDZE_obj_Swap"; player reveal _object; + } else { - format[localize "str_epoch_player_143",_i,getText(configFile >> "CfgMagazines" >> _itemOut >> "displayName")] call dayz_rollingMessages; + _text = getText(configFile >> "CfgMagazines" >> _itemOut >> "displayName"); + + format[localize "str_epoch_player_143", _i, _text] call dayz_rollingMessages; // %1 of %2 could not be added to your inventory. (not enough room?) // poorly worded { - [player,(_x select 0),(_x select 1)] call BIS_fnc_invRemove; + [player, (_x select 0), (_x select 1)] call BIS_fnc_invRemove; + } count _addedItems; }; } else { - localize "str_epoch_player_51" call dayz_rollingMessages; + localize "str_epoch_player_51" call dayz_rollingMessages; // No downgrades are available }; dayz_actionInProgress = false; diff --git a/SQF/dayz_code/actions/player_upgrade.sqf b/SQF/dayz_code/actions/player_upgrade.sqf index 6150ffb44..c169e56ce 100644 --- a/SQF/dayz_code/actions/player_upgrade.sqf +++ b/SQF/dayz_code/actions/player_upgrade.sqf @@ -1,197 +1,267 @@ -/* - DayZ Base Building Upgrades - Made for DayZ Epoch please ask permission to use/edit/distrubute email vbawol@veteranbastards.com. -*/ -if (dayz_actionInProgress) exitWith {localize "str_epoch_player_52" call dayz_rollingMessages;}; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DayZ Base Building Upgrades +// Made for DayZ Epoch please ask permission to use/edit/distribute email vbawol@veteranbastards.com. +// +// Updated by: Victor the Cleaner +// Date: August 2021 +// +// - Now includes helper spheres for improved player experience. +// - Reapply damage to upgraded object if necessary. +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +if (dayz_actionInProgress) exitWith {localize "str_epoch_player_52" call dayz_rollingMessages;}; // Upgrade is already in progress. dayz_actionInProgress = true; -private ["_location","_dir","_classname","_hasAccess","_missing","_text","_proceed","_num_removed","_object","_missingQty","_itemIn","_countIn","_qty","_removed","_removed_total","_tobe_removed_total","_objectID","_objectUID","_temp_removed_array","_textMissing","_newclassname","_requirements","_obj","_upgrade","_lockable","_combination_1","_combination_2","_combination_3","_combination","_objectCharacterID","_ownerID","_qtyBP","_bpMags","_countNew","_bp2Remove","_count","_friendsArr","_vector","_temp_BP_removed_array","_finished","_neededTools"]; - player removeAction s_player_upgrade_build; s_player_upgrade_build = 1; -_obj = _this select 3; -_objectID = _obj getVariable ["ObjectID","0"]; -_objectUID = _obj getVariable ["ObjectUID","0"]; -_classname = typeOf _obj; +local _obj = _this select 3; +local _objectID = _obj getVariable ["ObjectID","0"]; +local _objectUID = _obj getVariable ["ObjectUID","0"]; +local _classname = typeOf _obj; -if ((_objectID == "0" && {_objectUID == "0"}) || _classname in DZE_DisableUpgrade) exitWith {dayz_actionInProgress = false; s_player_upgrade_build = -1; localize "str_epoch_player_50" call dayz_rollingMessages;}; +if ((_objectID == "0" && _objectUID == "0") || {_classname in DZE_DisableUpgrade}) exitWith { + dayz_actionInProgress = false; + s_player_upgrade_build = -1; + localize "str_epoch_player_50" call dayz_rollingMessages; // Not setup yet. +}; -_hasAccess = [player, _obj] call FNC_check_access; -if (_classname in DZE_LockedStorage && !(_hasAccess select 0)) exitWith {dayz_actionInProgress = false;localize "STR_CL_EC_NOT_OWNER" call dayz_rollingMessages;}; +local _hasAccess = [player, _obj] call FNC_check_access; -_text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName"); -_upgrade = getArray (configFile >> "CfgVehicles" >> _classname >> "upgradeBuilding"); +if (!(_hasAccess select 0) && {_classname in DZE_LockedStorage}) exitWith { + dayz_actionInProgress = false; + localize "STR_CL_EC_NOT_OWNER" call dayz_rollingMessages; // You are not the owner. +}; + +local _text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName"); +local _upgrade = getArray (configFile >> "CfgVehicles" >> _classname >> "upgradeBuilding"); if ((count _upgrade) > 0) then { - _neededTools = _upgrade select 1; - if (["",_neededTools,"none"] call dze_requiredItemsCheck) then { - _newclassname = _upgrade select 0; - _lockable = 0; - if(isNumber (configFile >> "CfgVehicles" >> _newclassname >> "lockable")) then { - _lockable = getNumber(configFile >> "CfgVehicles" >> _newclassname >> "lockable"); - }; - _requirements = _upgrade select 2; - _missingQty = 0; - _missing = ""; - _bpMags = []; - _bp2Remove = []; - _qtyBP = 0; - _proceed = true; + local _neededTools = _upgrade select 1; + + if (["", _neededTools, "none"] call dze_requiredItemsCheck) then { + + local _newclassname = _upgrade select 0; + local _lockable = getNumber(configFile >> "CfgVehicles" >> _newclassname >> "lockable"); + local _requirements = _upgrade select 2; + local _missingQty = 0; + local _missing = ""; + local _bpMags = []; + local _bp2Remove = []; + local _qtyBP = 0; + local _proceed = true; { - _itemIn = _x select 0; - _countIn = _x select 1; - _qty = { (_x == _itemIn) || {configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn} } count magazines player; + local _itemIn = _x select 0; + local _countIn = _x select 1; + local _qty = {(_x == _itemIn) || {configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn}} count magazines player; - if (!isNull (UnitBackpack Player) && {_qty < _countIn}) then { - _bpMags = (getMagazineCargo (unitbackpack player)); + if (!isNull (UnitBackpack Player) && (_qty < _countIn)) then { + _bpMags = getMagazineCargo (unitBackpack player); { - if ((_x == _itemIn) || {configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn}) exitWith { - _qtyBP = ((_bpMags select 1) select _forEachIndex); - _bp2Remove set [(count _bp2Remove), _x]; + if ((_x == _itemIn) || (configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn)) exitWith { + _qtyBP = (_bpMags select 1) select _forEachIndex; + _bp2Remove set [count _bp2Remove, _x]; }; } forEach (_bpMags select 0); }; - if ((_qty < _countIn) && {_qtyBP < (_countIn - _qty)}) exitWith { _missing = _itemIn; _missingQty = (_countIn - (_qty + _qtyBP)); _proceed = false; }; + if (_qty < _countIn && (_qtyBP < (_countIn - _qty))) exitWith { + _missing = _itemIn; + _missingQty = _countIn - (_qty + _qtyBP); + _proceed = false; + }; } forEach _requirements; if (_proceed) then { - [player,(getPosATL player),25,"repair"] spawn fnc_alertZombies; - _finished = ["Medic",1] call fn_loopAction; + [_obj] call fn_displayHelpers; // create helpers + + [player, (getPosATL player), 25, "repair"] spawn fnc_alertZombies; // make noise + + local _finished = ["Medic",1] call fn_loopAction; // animation + + [] call fn_displayHelpers; // delete helpers + if (!_finished) exitWith {}; ["Working",0,[3,2,4,0]] call dayz_NutritionSystem; - _temp_removed_array = []; - _temp_BP_removed_array = []; - _removed_total = 0; - _tobe_removed_total = 0; + local _temp_removed_array = []; + local _temp_BP_removed_array = []; + local _removed_total = 0; + local _tobe_removed_total = 0; { - _removed = 0; - _itemIn = _x select 0; - _countIn = _x select 1; + local _removed = 0; + local _itemIn = _x select 0; + local _countIn = _x select 1; _tobe_removed_total = _tobe_removed_total + _countIn; - { if( (_removed < _countIn) && {(_x == _itemIn) || {configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn}}) then { - _num_removed = ([player,_x] call BIS_fnc_invRemove); - _removed = _removed + _num_removed; - _removed_total = _removed_total + _num_removed; + + local _num_removed = ([player, _x] call BIS_fnc_invRemove); + _removed = _removed + _num_removed; + _removed_total = _removed_total + _num_removed; + if(_num_removed >= 1) then { - _temp_removed_array set [count _temp_removed_array,_x]; + _temp_removed_array set [count _temp_removed_array, _x]; }; }; } forEach magazines player; - if (!isNull (UnitBackpack Player) && {_removed < _countIn}) then { - _bpMags = (getMagazineCargo (unitbackpack player)); - clearMagazineCargoGlobal (unitbackpack player); + if (!isNull (UnitBackpack Player) && (_removed < _countIn)) then { + _bpMags = getMagazineCargo (unitBackpack player); + clearMagazineCargoGlobal (unitBackpack player); { - _count = ((_bpMags select 1) select _forEachIndex); - _countNew = _count; + local _count = (_bpMags select 1) select _forEachIndex; + local _countNew = _count; + if (_x in _bp2Remove && {(_x == _itemIn) || {configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn}}) then { - _countNew = (_count - (_countIn - _removed)); - _bp2Remove = _bp2Remove - [_x]; + _countNew = _count - (_countIn - _removed); + _bp2Remove = _bp2Remove - [_x]; }; if (_countNew > 0) then { - (unitbackpack player) addMagazineCargoGlobal [_x, _countNew]; + (unitBackpack player) addMagazineCargoGlobal [_x, _countNew]; }; - _num_removed = (_count - _countNew); - _temp_BP_removed_array set [(count _temp_BP_removed_array), [_x, _num_removed]]; + + local _num_removed = _count - _countNew; + + _temp_BP_removed_array set [count _temp_BP_removed_array, [_x, _num_removed]]; _removed_total = _removed_total + _num_removed; + } forEach (_bpMags select 0); }; - } forEach _requirements; if (_tobe_removed_total == _removed_total) then { + call player_forceSave; - _location = _obj getVariable["OEMPos",(getposATL _obj)]; - _dir = getDir _obj; - _vector = [(vectorDir _obj),(vectorUp _obj)]; - _objectCharacterID = _obj getVariable ["CharacterID","0"]; - _classname = _newclassname; - _object = createVehicle [_classname, [0,0,0], [], 0, "CAN_COLLIDE"]; + + local _location = _obj getVariable["OEMPos", (getPosATL _obj)]; + local _dir = getDir _obj; + local _vector = [vectorDir _obj, vectorUp _obj]; + local _objectCharacterID = _obj getVariable ["CharacterID","0"]; + _classname = _newclassname; + + local _object = createVehicle [_classname, [0,0,0], [], 0, "CAN_COLLIDE"]; //_object setDir _dir; // setdir is incompatible with setVectorDirAndUp and should not be used together on the same object https://community.bistudio.com/wiki/setVectorDirAndUp - _object setVariable["memDir",_dir,true]; + _object setVariable["memDir", _dir, true]; _object setVectorDirAndUp _vector; _object setPosATL _location; if (_lockable == 3 && {!(_classname in ["WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ"])}) then { - DZE_topCombo = 0; - DZE_midCombo = 0; - DZE_botCombo = 0; - DZE_Lock_Door = ""; - dayz_selectedDoor = objNull; + + DZE_topCombo = 0; + DZE_midCombo = 0; + DZE_botCombo = 0; + + DZE_Lock_Door = ""; + dayz_selectedDoor = objNull; + local _combination = 0; createDialog "ComboLockUI"; waitUntil {!dialog}; - if (keypadCancel || {parseNumber DZE_Lock_Door == 0}) then { - _combination_1 = floor(random 10); - _combination_2 = floor(random 10); - _combination_3 = floor(random 10); - _combination = format["%1%2%3",_combination_1,_combination_2,_combination_3]; - DZE_Lock_Door = _combination; + if (keypadCancel || (parseNumber DZE_Lock_Door == 0)) then { + + local _combination_1 = floor(random 10); + local _combination_2 = floor(random 10); + local _combination_3 = floor(random 10); + + _combination = format["%1%2%3", _combination_1, _combination_2, _combination_3]; + DZE_Lock_Door = _combination; + } else { + _combination = DZE_Lock_Door; }; _objectCharacterID = _combination; - format[localize "str_epoch_player_158",_combination,_text] call dayz_rollingMessages; - systemChat format[localize "str_epoch_player_158",_combination,_text]; + local _message = format[localize "str_epoch_player_158", _combination, _text]; + _message call dayz_rollingMessages; + systemChat _message; // You have upgraded %2. The combination is: %1 + } else { - format[localize "str_epoch_player_159",_text] call dayz_rollingMessages; + format[localize "str_epoch_player_159", _text] call dayz_rollingMessages; // You have upgraded %1. }; + if (DZE_GodModeBase && {!(_classname in DZE_GodModeBaseExclude)}) then { + _object addEventHandler ["HandleDamage",{false}]; + + } else { + // + // reapply damage based on armor values + // + local _armorOld = getNumber (configFile >> "CfgVehicles" >> (typeOf _obj) >> "armor"); + local _damageOld = damage _obj; + + local _armorNew = getNumber (configFile >> "CfgVehicles" >> _classname >> "armor"); + local _damageNew = _damageOld; + + // check for divide by 0 + if (_armorNew > 0) then { + _damageNew = (_damageOld * _armorOld) / _armorNew; + }; + + _object setDamage _damageNew; }; + if (DZE_permanentPlot) then { - _ownerID = _obj getVariable["ownerPUID","0"]; - if (_ownerID == "0") then { _ownerID = dayz_playerUID; }; //APFL is on but UID is 0 so we will claim it to record the ownership. - _object setVariable ["ownerPUID",_ownerID,true]; + + local _ownerID = _obj getVariable["ownerPUID","0"]; + + if (_ownerID == "0") then { + _ownerID = dayz_playerUID; // APFL is on but UID is 0 so we will claim it to record the ownership. + }; + + _object setVariable ["ownerPUID", _ownerID, true]; + if (_lockable == 3) then { - _friendsArr = [[dayz_playerUID,toArray (name player)]]; + + local _friendsArr = [[dayz_playerUID, toArray (name player)]]; _object setVariable ["doorfriends", _friendsArr, true]; - PVDZE_obj_Swap = [_objectCharacterID,_object,[_dir,_location,_ownerID,_vector],_classname,_obj,player,_friendsArr,dayz_authKey]; + + PVDZE_obj_Swap = [_objectCharacterID, _object, [_dir, _location, _ownerID, _vector], _classname, _obj, player, _friendsArr, dayz_authKey]; } else { - PVDZE_obj_Swap = [_objectCharacterID,_object,[_dir,_location,_ownerID,_vector],_classname,_obj,player,[],dayz_authKey]; + PVDZE_obj_Swap = [_objectCharacterID, _object, [_dir, _location, _ownerID, _vector], _classname, _obj, player, [], dayz_authKey]; }; } else { - PVDZE_obj_Swap = [_objectCharacterID,_object,[_dir,_location,_vector],_classname,_obj,player,[],dayz_authKey]; + PVDZE_obj_Swap = [_objectCharacterID, _object, [_dir, _location, _vector], _classname, _obj, player, [], dayz_authKey]; }; + publicVariableServer "PVDZE_obj_Swap"; player reveal _object; } else { - {player addMagazine _x;} count _temp_removed_array; - if (count _temp_BP_removed_array > 0) then { - {(unitbackpack player) addMagazineCargoGlobal _x} count _temp_BP_removed_array; - }; - format[localize "str_epoch_player_145",_removed_total,_tobe_removed_total] call dayz_rollingMessages; + {player addMagazine _x;} count _temp_removed_array; + + if (count _temp_BP_removed_array > 0) then { + {(unitBackpack player) addMagazineCargoGlobal _x} count _temp_BP_removed_array; + }; + format[localize "str_epoch_player_145", _removed_total, _tobe_removed_total] call dayz_rollingMessages; // Missing Parts after first check Item: %1 / %2 }; } else { - _textMissing = getText(configFile >> "CfgMagazines" >> _missing >> "displayName"); - format[localize "STR_EPOCH_ACTIONS_6",_missingQty, _textMissing] call dayz_rollingMessages; - systemchat localize "STR_CRAFTING_NEEDED_ITEMS"; + local _textMissing = getText(configFile >> "CfgMagazines" >> _missing >> "displayName"); + format[localize "STR_EPOCH_ACTIONS_6", _missingQty, _textMissing] call dayz_rollingMessages; // Missing %1 more of %2 + + systemChat localize "STR_CRAFTING_NEEDED_ITEMS"; // Needed items: if (count _requirements > 0) then { { - _text = getText(configFile >> "CfgMagazines" >> (_x select 0) >> "displayName"); - systemchat format ["%2x %1",_text,(_x select 1)]; + local _text = getText(configFile >> "CfgMagazines" >> (_x select 0) >> "displayName"); + systemChat format ["%2x %1", _text, (_x select 1)]; } count _requirements; }; }; }; } else { - localize "str_epoch_player_82" call dayz_rollingMessages; + localize "str_epoch_player_82" call dayz_rollingMessages; // No upgrades are available }; dayz_actionInProgress = false; diff --git a/SQF/dayz_code/actions/remove.sqf b/SQF/dayz_code/actions/remove.sqf index 9894537ba..76814500d 100644 --- a/SQF/dayz_code/actions/remove.sqf +++ b/SQF/dayz_code/actions/remove.sqf @@ -1,52 +1,104 @@ -/* -delete object from db with extra waiting by [VB]AWOL -parameters: _obj -*/ +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// delete object from db with extra waiting by [VB]AWOL +// +// Modified by: Victor the Cleaner +// Date: August 2021 +// +// - Will now accept array parameter: [_obj, _actionContext, _isModular] +// +// * _obj is the object to be removed +// * _actionContext is a unique ID referencing either remove or deconstruct actions +// * _isModular is for handling refunds of modular objects only +// +// - Script now adds colored helpers to modular objects when removing or deconstructing. +// +// * Green: Refund one kit +// * Blue: Refund entire recipe of parts (multiple items) +// * Red: No refund will be given. Either because the object is too damaged, or the refund feature is disabled +// +// - Refunds for non-modular objects are handled by their respective config settings. +// +// - Removed non-lockable storage objects will now refund their contents. +// +// * The corresponding storage kit will be refunded. +// * If there is room outdoors, backpacks will be arranged in a neat circle close to the refund point. +// * If the spawn point is too close to a building, backpacks will spawn at the player's location. +// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (dayz_actionInProgress) exitWith {localize "str_player_actionslimit" call dayz_rollingMessages;}; dayz_actionInProgress = true; -private ["_type","_plotcheck","_PlayerNear","_isMine","_obj","_objectID","_objectUID","_finished","_isOk","_proceed","_counter","_limit","_objType","_itemOut","_countOut","_selectedRemoveOutput","_nearestPole","_refundpart","_isWreck","_IsNearPlot","_brokenTool","_removeTool","_isDestructable","_isRemovable","_objOwnerID","_isOwnerOfObj","_preventRefund","_ipos","_item","_isWreckBuilding","_nameVehicle","_isModular","_success","_lootGroupIndex","_output"]; +local _p = _this select 3; // get addAction parameter +local _obj = _p; // object +local _actionContext = 2; // default to remove action +local _isModular = false; // for removal of non-modular objects -player removeAction s_player_deleteBuild; -s_player_deleteBuild = 1; - -_obj = _this select 3; - -if (isNull _obj) exitWith {dayz_actionInProgress = false; systemChat localize "str_cursorTargetNotFound";}; - -_objOwnerID = "0"; -_isOwnerOfObj = false; - -if (DZE_permanentPlot) then { - _objOwnerID = _obj getVariable["ownerPUID","0"]; - _isOwnerOfObj = (_objOwnerID == dayz_playerUID); -} else { - _objOwnerID = _obj getVariable["CharacterID","0"]; - _isOwnerOfObj = (_objOwnerID == dayz_characterID); +if (typeName _p == "ARRAY") then { // allow for remove/deconstruct array to be passed + _obj = _p select 0; // object + _actionContext = _p select 1; // remove or deconstruct + _isModular = _p select 2; // isModular or isModularDoor +}; +if (isNull _obj) exitWith { + dayz_actionInProgress = false; + systemChat localize "str_cursorTargetNotFound"; // You must be looking at the item to interact with it. +}; +if (_obj getVariable ["GeneratorRunning", false]) exitWith { + dayz_actionInProgress = false; + localize "str_epoch_player_89" call dayz_rollingMessages; // Cannot remove a running generator. }; -if (_obj getVariable ["GeneratorRunning", false]) exitWith {dayz_actionInProgress = false; localize "str_epoch_player_89" call dayz_rollingMessages;}; +local _objType = typeOf _obj; // object's classname +local _bbObject = boundingBox _obj select 1; // positive x,y dimensions -_objectID = _obj getVariable ["ObjectID","0"]; -_objectUID = _obj getVariable ["ObjectUID","0"]; +if (_objType in DZE_DoorsLocked && !(_objType in ["WoodenGate_1_DZ","WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ"])) exitWith { + dayz_actionInProgress = false; + localize "STR_EPOCH_ACTIONS_20" call dayz_rollingMessages; // You must remove the lock to delete this item! +}; -_isOk = true; -_proceed = false; -_objType = typeOf _obj; -if (_objType in DZE_DoorsLocked && !(_objType in ["WoodenGate_1_DZ","WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ"])) exitWith {dayz_actionInProgress = false; localize "STR_EPOCH_ACTIONS_20" call dayz_rollingMessages;}; +/////////////////////////////////////////////////////////////////////////////////////////////////// -// Chance to break tools -_isDestructable = _obj isKindOf "BuiltItems"; -_isWreck = _objType in DZE_isWreck; -_isRemovable = _objType in DZE_isRemovable; -_isWreckBuilding = _objType in DZE_isWreckBuilding; -_isMine = _objType in ["Land_iron_vein_wreck","Land_silver_vein_wreck","Land_gold_vein_wreck"]; -_isModular = _obj isKindOf "ModularItems"; +// prevent player actions appearing during animation cycle +player removeAction s_player_deleteBuild; +player removeAction s_player_deconstruct; +player removeAction s_player_upgrade_build; +player removeAction s_player_maint_build; +s_player_deleteBuild = 1; +s_player_deconstruct = 1; +s_player_upgrade_build = 1; +s_player_maint_build = 1; -_PlayerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 12]) > 1; -if (_PlayerNear && (_isMine or _objType == "Land_ammo_supply_wreck")) exitWith {dayz_actionInProgress = false; localize "str_pickup_limit_5" call dayz_rollingMessages;}; +local _objOwnerID = _obj getVariable["ownerPUID","0"]; +local _isOwnerOfObj = (_objOwnerID == dayz_playerUID); -_limit = 3; +if (!DZE_permanentPlot) then { + _objOwnerID = _obj getVariable["CharacterID","0"]; + _isOwnerOfObj = (_objOwnerID == dayz_characterID); +}; + +local _objectID = _obj getVariable ["ObjectID","0"]; +local _objectUID = _obj getVariable ["ObjectUID","0"]; +local _hasNoID = (_objectID == "0" && _objectUID == "0"); + +local _isDestructable = _obj isKindOf "BuiltItems"; +local _isWreck = _objType in DZE_isWreck; +local _isRemovable = _objType in DZE_isRemovable; +local _isWreckBuilding = _objType in DZE_isWreckBuilding; +local _isMine = _objType in ["Land_iron_vein_wreck","Land_silver_vein_wreck","Land_gold_vein_wreck"]; +local _isAmmoSupplyWreck= _objType == "Land_ammo_supply_wreck"; +local _isPlotPole = _objType == "Plastic_Pole_EP1_DZ"; +local _isFireBarrel = _objType == "FireBarrel_DZ"; +local _isStorageItem = _objType in DZE_refundStorageItemContents; // non-lockable storage (sheds, crates etc.) + +local _playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 12]) > 1; + +if (_playerNear && (_isMine or _isAmmoSupplyWreck)) exitWith { + dayz_actionInProgress = false; + localize "str_pickup_limit_5" call dayz_rollingMessages; // Another player is nearby. Only one player can be near to perform this action. +}; +/////////////////////////////////////////////////////////////////////////////////////////////////// + +local _limit = 3; if (DZE_StaticConstructionCount > 0) then { _limit = DZE_StaticConstructionCount; @@ -56,225 +108,461 @@ if (DZE_StaticConstructionCount > 0) then { }; }; -_plotcheck = [player, false] call FNC_find_plots; -_IsNearPlot = _plotcheck select 1; -_nearestPole = _plotcheck select 2; +local _plotCheck = [player, false] call FNC_find_plots; +local _isNearPlot = _plotCheck select 1; +local _nearestPole = _plotCheck select 2; -if(_IsNearPlot >= 1) then { - private ["_buildcheck","_isowner","_isfriendly"]; +if (_isNearPlot > 0) then { // Since there are plot poles nearby we need to check ownership && friend status - _buildcheck = [player, _nearestPole] call FNC_check_access; - _isowner = _buildcheck select 0; - _isfriendly = ((_buildcheck select 1) or (_buildcheck select 3)); + local _accessCheck = [player, _nearestPole] call FNC_check_access; + local _isowner = _accessCheck select 0; + local _isfriendly = ((_accessCheck select 1) or (_accessCheck select 3)); + if (!_isowner && !_isfriendly) then { - _limit = round(_limit*2); + _limit = round(_limit * 2); }; }; -_nameVehicle = getText(configFile >> "CfgVehicles" >> _objType >> "displayName"); +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Added functionality to display helpers on modular objects +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +local _modularRefund = false; +local _isEnabled = false; +local _refund = []; // can be either STRING or ARRAY +local _helperTexture = DZE_removeTexture; // default helper color: green -format[localize "str_epoch_player_162",_nameVehicle] call dayz_rollingMessages; +if (_isModular) then { + { + if (_objType == _x select 1) exitWith { // find matching class + _isEnabled = _x select 0; // is refund enabled? + _refund = _x select _actionContext; // get refund array + }; + } count DZE_modularConfig; -if (_isModular && {_objType in _x} count DZE_modularConfig == 0) then { - localize "STR_EPOCH_ACTIONS_21" call dayz_rollingMessages; + if (_actionContext == 2) then { // if singular kit + _refund = [[_refund, 1]]; // reformat array + }; + + _modularRefund = (DZE_refundModular && _isEnabled && !((DZE_RefundDamageLimit > 0) && (damage _obj > DZE_RefundDamageLimit))); + + if (_actionContext == 3) then { // if deconstruct + _helperTexture = DZE_deconstructTexture; // blue helpers + }; + if (!_modularRefund) then { // if no refunds are to be given + localize "STR_EPOCH_ACTIONS_21" call dayz_rollingMessages; // notify player - Deconstructing modular buildables will not refund any components. + _helperTexture = DZE_NoRefundTexture; // red helpers + }; }; -// Alert zombies once. -[player,50,true,(getPosATL player)] spawn player_alertZombies; +[_obj, _helperTexture] call fn_displayHelpers; // create helpers -_brokenTool = false; + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Begin Removal +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +local _nameVehicle = getText(configFile >> "CfgVehicles" >> _objType >> "displayName"); +//format[localize "str_epoch_player_162", _nameVehicle] call dayz_rollingMessages; // Starting de-construction of %1. + +local _brokenTool = false; +local _counter = 0; +local _isOk = true; +local _proceed = false; + +[player, 50, true, (getPosATL player)] spawn player_alertZombies; // Alert zombies once // Start de-construction loop -_counter = 0; while {_isOk} do { - // if object no longer exits this should return true. - if(isNull(_obj)) exitWith { + // if object no longer exists this should return true + if (isNull _obj) exitWith { _isOk = false; _proceed = false; }; - format[localize "str_epoch_player_163",_nameVehicle,(_counter + 1),_limit] call dayz_rollingMessages; + format[localize "str_epoch_player_163", _nameVehicle, (_counter + 1), _limit] call dayz_rollingMessages; // De-constructing %1, stage %2 of %3 walk away at anytime to cancel. - [player,(getPosATL player),25,"repair"] spawn fnc_alertZombies; + [player, (getPosATL player), 25, "repair"] spawn fnc_alertZombies; - _finished = ["Medic",1] call fn_loopAction; + local _finished = ["Medic", 1] call fn_loopAction; - if(!_finished) exitWith { + if (!_finished) exitWith { _isOk = false; _proceed = false; }; - - if(_finished) then { + if (_finished) then { _counter = _counter + 1; - // 4% chance to break a required tool each pass - if ((_isDestructable || _isRemovable) && {!_isOwnerOfObj} && {dayz_toolBreaking && {[0.04] call fn_chance}}) then { - _brokenTool = true; + + if (dayz_toolBreaking) then { + if ((_isDestructable || _isRemovable) && !_isOwnerOfObj) then { + if ([0.04] call fn_chance) then { // 4% chance to break a required tool each pass + _brokenTool = true; + }; + }; }; }; - if(_brokenTool) exitWith { + if (_brokenTool) exitWith { _isOk = false; _proceed = false; }; - - if(_counter == _limit) exitWith { + if (_counter == _limit) exitWith { _isOk = false; _proceed = true; }; - }; -_success = true; +[] call fn_displayHelpers; // delete helpers + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// tool breakage +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +local _success = true; if (_brokenTool) then { _success = false; - _removeTool = if (_isWreck) then {"ItemToolbox"} else {["ItemCrowbar","ItemToolbox"] call BIS_fnc_selectRandom}; + local _removeTool = if (_isWreck) then {"ItemToolbox"} else {["ItemCrowbar","ItemToolbox"] call BIS_fnc_selectRandom}; if (_removeTool == "ItemCrowbar" && !("ItemCrowbar" in items player)) then { if ("MeleeCrowbar" in weapons player) then { player removeWeapon "MeleeCrowbar"; _success = true; } else { if (dayz_onBack == "MeleeCrowbar") then { - dayz_onBack = ""; // Remove - player setVariable ["dayz_onBack",dayz_onBack,true]; + dayz_onBack = ""; // Remove item + player setVariable ["dayz_onBack", dayz_onBack, true]; _success = true; if (!isNull (findDisplay 106)) then {((findDisplay 106) displayCtrl 1209) ctrlSetText "";}; }; }; } else { - if (([player,_removeTool,1] call BIS_fnc_invRemove) > 0) then {_success = true;}; + if (([player, _removeTool, 1] call BIS_fnc_invRemove) > 0) then {_success = true;}; }; if (_success) then { - format[localize "str_epoch_player_164",getText(configFile >> "CfgWeapons" >> _removeTool >> "displayName"),_nameVehicle] call dayz_rollingMessages; + format[localize "str_epoch_player_164", getText(configFile >> "CfgWeapons" >> _removeTool >> "displayName"), _nameVehicle] call dayz_rollingMessages; // %1 broke, cannot remove %2. }; }; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// find refund depending on object category +// +/////////////////////////////////////////////////////////////////////////////////////////////////// + // Remove only if player waited AND tool was successfully removed if broken if (_proceed && _success) then { // Double check that object is not null - if(!isNull(_obj)) then { - _ipos = getPosATL _obj; + if !(isNull _obj) then { - if(!_isWreck && !_isWreckBuilding) then { - //Server performs deleteVehicle - PVDZ_obj_Destroy = [_objectID,_objectUID,player,_obj,dayz_authKey]; + local _objectPos = getPosATL _obj; // copy now before object deleted + local _iPos = _objectPos; // default refund position + local _iDir = getDir _obj; // default refund direction + local _selectedRemoveOutput = []; // initialize refund array + local _preventRefund = false; // in case object has no id + local _bpTotal = 0; // total number of backpacks to refund + + call { + /////////////////////////////////////////////////////////////////////////// + // + // dynamic debris wreckage + // + /////////////////////////////////////////////////////////////////////////// + if (_isWreck) exitWith { + + // Find one random part to refund + local _refundpart = ["PartEngine","PartGeneric","PartFueltank","PartWheel","PartGlass","ItemJerrycan"] call BIS_fnc_selectRandom; + + _selectedRemoveOutput = [[_refundpart, 1]]; + }; + + local _lootGroupIndex = dz_loot_groups find _objType; + local _output = []; + + /////////////////////////////////////////////////////////////////////////// + // + // metal vein wreck + // + /////////////////////////////////////////////////////////////////////////// + if (_isMine) exitWith { + + _output = [_lootGroupIndex, 3] call dz_fn_loot_select; + {_selectedRemoveOutput set [count _selectedRemoveOutput, [_x select 1, [_x select 2, _x select 3]]]} forEach _output; + + // chance of gem occurrence + if ([0.4] call fn_chance) then { + + local _gems = []; + local _weights = []; + { + _gems set [count _gems, _x select 0]; + _weights set [count _weights, _x select 1]; + } count DZE_GemOccurance; + + local _gemSelected = [_gems, _weights] call BIS_fnc_selectRandomWeighted; + _selectedRemoveOutput set [count _selectedRemoveOutput, [_gemSelected, 1]]; + }; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // roadside ammo crate + // + /////////////////////////////////////////////////////////////////////////// + if (_isAmmoSupplyWreck) exitWith { + + _output = [_lootGroupIndex, 5] call dz_fn_loot_select; + {_selectedRemoveOutput set [count _selectedRemoveOutput, [_x select 1, 1, _x select 0]]} forEach _output; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // wrecked modular object + // + /////////////////////////////////////////////////////////////////////////// + if (_isWreckBuilding) exitWith { + _selectedRemoveOutput = getArray (configFile >> "CfgVehicles" >> _objType >> "removeoutput"); + }; + + /////////////////////////////////////////////////////////////////////////// + // + // modular object + // + /////////////////////////////////////////////////////////////////////////// + if (_modularRefund) exitWith { + + {_selectedRemoveOutput set [count _selectedRemoveOutput, _x]} forEach _refund; + _preventRefund = _hasNoID; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // non-lockable storage item + // + /////////////////////////////////////////////////////////////////////////// + if (_isStorageItem) exitWith { + + if (!_hasNoID) then { + _selectedRemoveOutput = getArray (configFile >> "CfgVehicles" >> _objType >> "removeoutput"); // refund config array + }; + + local _weapons = getWeaponCargo _obj; + local _magazines = getMagazineCargo _obj; + local _backpacks = getBackpackCargo _obj; + + if ((count _weapons > 0 || {count _magazines > 0 || {count _backpacks > 0}})) then { // has storage items + + // reformat cargo arrays into [class, count, type] and append to _selectedRemoveOutput + local _format = [[_weapons,2],[_magazines,3],[_backpacks,5]]; + { + local _class = _x select 0 select 0; // weapon, magazine, or backpack + local _total = _x select 0 select 1; // count array + local _type = _x select 1; // item type + local _array = []; + { + _count = _total select _forEachIndex; + _array = [_x, _count, _type]; // format array + + _selectedRemoveOutput set [count _selectedRemoveOutput, _array]; // append to output + + if (_type == 5) then {_bpTotal = _bpTotal + _count}; // update backpack count + + } forEach _class; + + } count _format; + }; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // All other removable objects + // + /////////////////////////////////////////////////////////////////////////// + + _selectedRemoveOutput = getArray (configFile >> "CfgVehicles" >> _objType >> "removeoutput"); // refund config array + _preventRefund = _hasNoID; + }; + + call { + /////////////////////////////////////////////////////////////////////////// + // + // check if plot pole helpers remain + // + /////////////////////////////////////////////////////////////////////////// + if (_isPlotPole) exitWith { + if (!isNil "PP_Marks") then { + {deleteVehicle _x;} count PP_Marks; + PP_Marks = nil; + }; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // check if fire barrel was left burning + // + /////////////////////////////////////////////////////////////////////////// + if (_isFireBarrel) exitWith { + local _flame = nearestObjects [_obj, ["flamable_DZ"], 1]; // check for inflamed objects + if (count _flame > 0) then { // if any + _flame = (_flame select 0); // get nearest (typeName changes from "ARRAY" to "OBJECT") + _flame inflame false; // extinguish flame + deleteVehicle _flame; // delete proxy object + }; + }; + }; + + /////////////////////////////////////////////////////////////////////////////////// + // + // delete object from database + // + /////////////////////////////////////////////////////////////////////////////////// + + if (!_isWreck && !_isWreckBuilding) then { + // Server performs deleteVehicle + PVDZ_obj_Destroy = [_objectID, _objectUID, player, _obj, dayz_authKey]; publicVariableServer "PVDZ_obj_Destroy"; } else { deleteVehicle _obj; }; if (_isWreckBuilding) then { - PVDZ_send = [player,"RemoveObject",_ipos,[_ipos,dayz_authKey,player]]; + PVDZ_send = [player, "RemoveObject", _objectPos, [_objectPos, dayz_authKey, player]]; publicVariableServer "PVDZ_send"; }; - format[localize "str_epoch_player_165",_nameVehicle] call dayz_rollingMessages; + //format[localize "str_epoch_player_165", _nameVehicle] call dayz_rollingMessages; // De-constructing %1. ["Working",0,[3,2,4,0]] call dayz_NutritionSystem; - _preventRefund = false; - _selectedRemoveOutput = []; - if(_isWreck) then { - // Find one random part to give back - _refundpart = ["PartEngine","PartGeneric","PartFueltank","PartWheel","PartGlass","ItemJerrycan"] call BIS_fnc_selectRandom; - _selectedRemoveOutput set [count _selectedRemoveOutput,[_refundpart,1]]; - } else { - if(_isWreckBuilding) then { - call { - if (_isMine) exitwith { - _lootGroupIndex = dz_loot_groups find _objType; - _output = [_lootGroupIndex,3] call dz_fn_loot_select; + /////////////////////////////////////////////////////////////////////////////////// + // + // prepare refund and backpack array + // + /////////////////////////////////////////////////////////////////////////////////// - {_selectedRemoveOutput set [count _selectedRemoveOutput, [_x select 1,[_x select 2,_x select 3]]]} forEach _output; - }; - if (_objType == "Land_ammo_supply_wreck") exitwith { - _lootGroupIndex = dz_loot_groups find _objType; - _output = [_lootGroupIndex,5] call dz_fn_loot_select; + if (!_preventRefund && {count _selectedRemoveOutput > 0}) then { - {_selectedRemoveOutput set [count _selectedRemoveOutput, [_x select 1,1,_x select 0]]} forEach _output; - }; - _selectedRemoveOutput = getArray (configFile >> "CfgVehicles" >> _objType >> "removeoutput"); - }; - } else { - if ({_objType in _x} count DZE_modularConfig > 0) then { - { - private ["_class", "_refund"]; + local _item = "WeaponHolder" createVehicle [0,0,0]; + _item setDir _iDir; - _class = _x select 0; - _refund = _x select 1; - - if (_objType == _class) then { - {_selectedRemoveOutput set [count _selectedRemoveOutput,_x];} forEach _refund; - }; - } count DZE_modularConfig; - } else { - _selectedRemoveOutput = getArray (configFile >> "CfgVehicles" >> _objType >> "removeoutput"); - }; - _preventRefund = (_objectID == "0" && _objectUID == "0"); + if ((player distance _objectPos) > 1.5) then { // if player was not close to the object + _iDir = [player, _objectPos] call BIS_fnc_dirTo; // update direction + _iPos = [player, 1.5, _iDir] call BIS_fnc_relPos; // update position }; - }; + _iPos set [2, ((getPosATL player) select 2) max 0]; // Match refund height to player height, or place on ground - if ((count _selectedRemoveOutput) <= 0) then { - [localize "str_epoch_player_90",1] call dayz_rollingMessages; - }; + local _bpDir = floor(random 360); // backpack rotation angle around refund point + local _bpArc = 360 / (_bpTotal max 1); // angle between each backpack (prevents divide by zero) + local _bbMin = ((_bbObject select 0) min (_bbObject select 1)) * 0.5; // 50% of storage object's smallest x,y dimension + local _bpDist = (_bbMin max 0.3) min 0.75; // clamp min/max radial distance from WeaponHolder to backpack pivot point + local _playerPos= getPosATL player; - if (_isMine) then { - if((random 10) <= 4) then { - private ["_gems","_weights","_gemSelected"]; - - _gems = []; - _weights = []; + local _isInside = { // procedure to check whether the supplied position is inside a building's bounding box + local _pos = _this; + local _inside = false; { - _gems set [(count _gems), (_x select 0)]; - _weights set [(count _weights), (_x select 1)]; - } count DZE_GemOccurance; - _gemSelected = [_gems, _weights] call BIS_fnc_selectRandomWeighted; - _selectedRemoveOutput set [(count _selectedRemoveOutput),[_gemSelected,1]]; - }; - }; + local _building = _x; - // give refund items - if((count _selectedRemoveOutput) > 0 && !_preventRefund) then { - private "_posPlayer"; + if (_building != _item) then { // exclude WeaponHolder when placing backpacks + local _relPos = _building worldToModel _pos; - _posPlayer = getPosATL player; - _iPos set [2,_posPlayer select 2]; + local _max = (boundingBox _building) select 1; + local _px = _max select 0; + local _py = _max select 1; + local _pz = _max select 2; + local _myX = abs (_relPos select 0); + local _myY = abs (_relPos select 1); + local _myZ = abs (_relPos select 2); - if (_iPos select 2 < 0) then { - _iPos set [2,0]; + if ((_myX < _px) && {(_myY < _py) && {(_myZ < _pz)}}) then { + _inside = true; + }; + }; + if (_inside) exitWith {}; + } forEach (nearestObjects [_pos, ["Building"], 50]); // scan every "Building" class within 50m + + _inside; }; - _item = "WeaponHolder" createVehicle [0,0,0]; + if (_isStorageItem && (_iPos call _isInside)) then { + _iPos = _playerPos; + _bpDist = 0.1; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // refund items + // + /////////////////////////////////////////////////////////////////////////// + + local _totalCount = 0; // total number of refunded items { - _itemOut = _x select 0; - _countOut = _x select 1; - if (typeName _countOut == "ARRAY") then { - _countOut = round((random (_countOut select 1)) max (_countOut select 0)); + local _itemOut = _x select 0; // item to refund + local _countOut = _x select 1; // how many + + if (typeName _countOut == "ARRAY") then { // check for random refund range + local _min = _countOut select 0; + local _max = _countOut select 1; + local _range = (abs (_max - _min)) + 1; // add 1 because range is numerically inclusive + _countOut = (floor (random _range)) + _min; // randomize }; - if (count _x > 2) then { - _type = _x select 2; + + _totalCount = _totalCount + _countOut; // running total of items + + if (count _x > 2) then { // if array item has 3 elements + local _type = _x select 2; // get corresponding cargo type call { - if (_type == 2) exitwith {_item addWeaponCargoGlobal [_itemOut,_countOut]}; - if (_type == 3) exitwith {_item addMagazineCargoGlobal [_itemOut,_countOut]}; - if (_type == 5) exitwith {_item addBackpackCargoGlobal [_itemOut,_countOut]}; // Needs to make sure object can handle Backpacks or will dump on the ground. + if (_type == 2) exitWith {_item addWeaponCargoGlobal [_itemOut, _countOut]}; + if (_type == 3) exitWith {_item addMagazineCargoGlobal [_itemOut, _countOut]}; + if (_type == 5) exitWith { //_item addBackpackCargoGlobal [_itemOut, _countOut]; // Needs to make sure object can handle Backpacks or will dump on the ground. + + for "_i" from 1 to _countOut do { + + local _bpObj = _itemOut createVehicle [0,0,0]; // create backpack + local _bpPos = [_iPos, _bpDist, _bpDir] call BIS_fnc_relPos; // position it a short distance away from the spawn point + + _bpObj setVectorDirAndUp [ + [0, 0, -1], // lay it flat + [[0, 1, 0], -_bpDir] call BIS_fnc_rotateVector2D // align to holder + ]; + _bpPos set [2, ((_bpPos select 2) max 0) - 0.15]; // match holder height or place on ground (lowered slightly) + + if (_bpPos call _isInside) then { + _bpObj setPosATL _playerPos; // prevent backpack from spawning inside an unenterable building + } else { + _bpObj setPosATL _bpPos; // location is good + }; + _bpDir = (_bpDir + _bpArc) % 360; // arrange backpacks evenly + }; + }; }; } else { - _item addMagazineCargoGlobal [_itemOut,_countOut]; + _item addMagazineCargoGlobal [_itemOut, _countOut]; // default magazine cargo }; } count _selectedRemoveOutput; - _item setposATL _iPos; - player reveal _item; - DZE_GearCheckBypass = true; //Bypass gear menu checks since dialog will always open on item - player action ["Gear", _item]; + if (_totalCount > 0) then { // Only reveal refund if there is something there. Random ranges can produce zero results. + _item setPosATL _iPos; + player reveal _item; + + DZE_GearCheckBypass = true; // Bypass gear menu checks since dialogue will always open on item + player action ["Gear", _item]; + }; + } else { + [localize "str_epoch_player_90", 1] call dayz_rollingMessages; // No parts were found. }; } else { - localize "str_epoch_player_91" call dayz_rollingMessages; + localize "str_epoch_player_91" call dayz_rollingMessages; // Failed, object no longer exists. }; }; -dayz_actionInProgress = false; -s_player_deleteBuild = -1; +dayz_actionInProgress = false; +s_player_deleteBuild = -1; +s_player_deconstruct = -1; +s_player_upgrade_build = -1; +s_player_maint_build = -1; \ No newline at end of file diff --git a/SQF/dayz_code/compile/fn_displayHelpers.sqf b/SQF/dayz_code/compile/fn_displayHelpers.sqf new file mode 100644 index 000000000..dd2e69faf --- /dev/null +++ b/SQF/dayz_code/compile/fn_displayHelpers.sqf @@ -0,0 +1,157 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Display Helpers on buildable/removable objects +// +// Author: Victor the Cleaner +// Date: August 2021 +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// - Display helper spheres on the selected object when removing, deconstructing, +// upgrading, downgrading, maintaining, and packing. +// - Call this function first by passing the object, and optional texture, e.g.: +// +// [_object] call fn_displayHelpers; // create helpers +// [_object, DZE_removeTexture] call fn_displayHelpers; // create helpers +// +// - And then a second time following the looped animation cycle, but without a parameter. +// +// [] call fn_displayHelpers; // delete helpers +// +// - Helper texture values are defined in configVariables.sqf +// - DZE_removeTexture = green | DZE_deconstructTexture = blue | DZE_NoRefundTexture = red +// - If no texture is passed, it will default to green. +// - If no identical object types are nearby, then do not display green helpers. +// - Use DZE_displayOnlyIfNearby to enable/disable. Does not affect blue & green helpers. +// - If the object's door is open during selection, no helper will display at that position. +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +if (DZE_displayHelpers) then { + + if (isNil "HelperArray") then {HelperArray = []}; + + local _p = count _this; + + if (_p > 0) then { + + local _obj = _this select 0; // selected object + local _objType = typeOf _obj; // object's class name + local _green = [0, format["#(argb,8,8,3)color(0,1,0,%1,ca)", (DZE_removeTransparency max 0.1)]]; // reformat with transparency + local _helperTexture = DZE_removeTexture; // default: green + + if (_p == 2) then { + _helperTexture = _this select 1; // specified texture + }; + + /////////////////////////////////////////////////////////////////////////////////// + // + // If no identical objects are nearby, then do not display green helpers + // + /////////////////////////////////////////////////////////////////////////////////// + local _cancel = false; + + if (DZE_displayOnlyIfNearby && [_helperTexture, DZE_removeTexture] call BIS_fnc_areEqual) then { // if only green required + + local _radius = getNumber (configFile >> "HelperVectors" >> _objType >> "radius"); // get object's scan radius + + if (_radius == 0) then { + _radius = getNumber (configFile >> "SnapBuilding" >> _objType >> "radius"); // check here too + }; + + local _objects = _obj nearObjects [_objType, _radius]; // get nearby objects + + if (count _objects == 1) then { // if no identical objects are near + _cancel = true; // do not display helpers + }; + }; + if (_cancel) exitWith {}; + + local _helperSize = DZE_helperSizeDefault; // see configVariables.sqf + local _helperClass = ""; + local _points = []; // vector array + + _points = getArray (configFile >> "HelperVectors" >> _objType >> "points"); // get helper vector array + + local _size = getNumber (configFile >> "HelperVectors" >> _objType >> "size"); // get size + if (_size != 0) then { + _helperSize = _size; // overwrite default size if it exists + }; + + if (count _points > 0) then { // found helper vector + + if (_objType in ["Concrete_Bunker_DZ","Concrete_Bunker_Locked_DZ","Door_DZ"]) exitWith{}; // exclude from helper removal + + /////////////////////////////////////////////////////////////////////////// + // + // Prevent floating helper + // + /////////////////////////////////////////////////////////////////////////// + // + // "DoorL" for MetalGate_DZ, + // Land_DZE_WoodOpenTopGarageDoor, + // Land_DZE_WoodOpenTopGarageLocked, + // CinderGarageOpenTop_DZ, + // CinderGarageOpenTopLocked_DZ + // "dvere1" for Wooden_shed_DZ, Wooden_shed2_DZ + // "open" for StorageShed_DZ, StorageShed2_DZ (Land_Shed_M01) + // "Open_inner" for Metal_Drawbridge_DZ, Metal_DrawbridgeLocked_DZ + // "Open_door" for default + // + /////////////////////////////////////////////////////////////////////////// + + local _resize = false; + local _door = "Open_door"; + local _doorL = ["MetalGate_DZ","Land_DZE_WoodOpenTopGarageDoor","Land_DZE_WoodOpenTopGarageLocked","CinderGarageOpenTop_DZ","CinderGarageOpenTopLocked_DZ"]; + local _open = ["StorageShed_DZ","StorageShed2_DZ"]; + local _dvere1 = ["OutHouse_DZ"]; + local _custom1 = ["Wooden_shed_DZ","Wooden_shed2_DZ"]; + local _custom2 = ["Metal_Drawbridge_DZ","Metal_DrawbridgeLocked_DZ"]; + + call { + if (_objType in _doorL) exitWith {_door = "doorl"}; + if (_objType in _open) exitWith {_door = "open"}; + if (_objType in _dvere1) exitWith {_door = "dvere1"}; + }; + call { + if (_objType in _custom1 && _obj animationPhase "dvere1" < 1) exitWith {_resize = true}; // door is open + if (_objType in _custom2 && _obj animationPhase "Open_inner" < 1) exitWith {_resize = true}; // door is open + if (_obj animationPhase _door > 0) exitWith {_resize = true}; // door is open + }; + if (_resize) then { + _points resize (count _points) - 1; // do not display center helper + }; + } else { // if no vector array exists + _points = getArray (ConfigFile >> "SnapBuilding" >> _objType >> "points"); // try snapping points array + }; + + { + if (_helperSize == _x select 0) exitWith { + _helperClass = _x select 1; + }; // get helper class + } count DZE_helperSize; + + { + local _helperObj = _helperClass createVehicleLocal [0,0,0]; // create helper object + _helperObj setObjectTexture _helperTexture; // set colour + + local _offset = +_x; // copy position array + _offset resize 3; // truncate if necessary + + local _pos = _obj modelToWorld _offset; // translate + + if (surfaceIsWater _pos) then { // adjust for land and sea + _pos set [2, (getPosASL _obj select 2) + (_offset select 2)]; + _helperObj setPosASL _pos; + } else { + _helperObj setPosATL _pos; + }; + + HelperArray set [count HelperArray, _helperObj]; // record list of helpers + } count _points; // if no vectors were found, do nothing + + } else { + + {deleteVehicle _x;} count HelperArray; // delete helpers + HelperArray = []; + }; +}; diff --git a/SQF/dayz_code/compile/fn_selfActions.sqf b/SQF/dayz_code/compile/fn_selfActions.sqf index 79b47f261..60f23702b 100644 --- a/SQF/dayz_code/compile/fn_selfActions.sqf +++ b/SQF/dayz_code/compile/fn_selfActions.sqf @@ -219,14 +219,14 @@ if (_isPZombie) then { }; // Increase distance only if AIR, SHIP or TANK -local _allowedDistance = [4, 8] select ((_cursorTarget isKindOf "Air") || {_cursorTarget isKindOf "Ship"} || {_cursorTarget isKindOf "Tank"}); +local _typeOfCursorTarget = typeOf _cursorTarget; +local _allowedDistance = [5, 9] select ((_typeOfCursorTarget in DZE_largeObjects) || {_cursorTarget isKindOf "Air" || {_cursorTarget isKindOf "Ship" || {_cursorTarget isKindOf "Tank"}}}); local _distance = floor((player distance _cursorTarget) * 100) / 100; // truncate to 2 decimal places for stationary objects local _isVehicle = _cursorTarget isKindOf "AllVehicles"; if (_isVehicle) then {_distance = floor(player distance _cursorTarget)}; // truncate to 0 decimal places for jittery vehicles local _noChange = ((_cursorTarget == DZE_prevTarget) && (_distance == DZE_prevDistance)); if (!isNull _cursorTarget && _noChange && !_inVehicle && !_isPZombie && _canDo && (_distance <= _allowedDistance)) then { - local _typeOfCursorTarget = typeOf _cursorTarget; local _isBicycle = _cursorTarget isKindOf "Bicycle"; local _isDestructable = _cursorTarget isKindOf "BuiltItems"; local _isGenerator = _typeOfCursorTarget == "Generator_DZ"; @@ -259,8 +259,8 @@ if (!isNull _cursorTarget && _noChange && !_inVehicle && !_isPZombie && _canDo & }; local _isDog = (_cursorTarget isKindOf "Pastor" || _cursorTarget isKindOf "Fin"); - local _isModular = _cursorTarget isKindOf "ModularItems"; - local _isModularDoor = _typeOfCursorTarget in ["Land_DZE_WoodDoor","Land_DZE_LargeWoodDoor","Land_DZE_GarageWoodDoor","CinderWallDoor_DZ","CinderWallDoorSmall_DZ","WoodenGate_foundation_DZ","WoodenGate_1_DZ","WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ","Land_DZE_WoodGate","Land_DZE_WoodOpenTopGarageDoor","CinderGate_DZ","CinderGarageOpenTop_DZ","CinderDoorHatch_DZ","Door_DZ","Concrete_Bunker_DZ","Metal_Drawbridge_DZ"]; + local _isModular = (_cursorTarget isKindOf "ModularItems" || {_typeOfCursorTarget in DZE_modularDoors}); + local _hasDeconstructAccess = false; local _player_deleteBuild = false; local _player_lockUnlock_crtl = false; @@ -378,20 +378,22 @@ if (!isNull _cursorTarget && _noChange && !_inVehicle && !_isPZombie && _canDo & }; }; + // Remove Object if (_isAlive) then { local _restrict = _typeOfCursorTarget in DZE_restrictRemoval; - //Allow player to remove objects with no ownership or access required - if (!_restrict && {_isDestructable || {_typeOfCursorTarget in DZE_isWreck} || {_typeOfCursorTarget in DZE_isWreckBuilding} || {_typeOfCursorTarget in DZE_isRemovable}}) then { + // Allow player to remove objects with no ownership or access required + if (!_restrict && (_isDestructable || {_typeOfCursorTarget in DZE_isWreck || {_typeOfCursorTarget in DZE_isWreckBuilding || {_typeOfCursorTarget in DZE_isRemovable}}})) then { if (_hasToolbox && _hasCrowbar) then { _player_deleteBuild = true; }; }; - //Allow player to remove objects only if they have proper ownership or access - if (_restrict || _isModular || _isModularDoor || _isGenerator || {_typeOfCursorTarget in DZE_isDestroyableStorage}) then { + // Allow player to remove objects only if they have proper ownership or access + if (_restrict || _isModular || _isGenerator || {_typeOfCursorTarget in DZE_isDestroyableStorage}) then { if (_hasToolbox && _hasCrowbar) then { _hasAccess = [player, _cursorTarget] call FNC_check_access; - if ((_hasAccess select 0) || {_hasAccess select 2} || {_hasAccess select 3}) then { + if ((_hasAccess select 0) || (_hasAccess select 2) || (_hasAccess select 3)) then { + _hasDeconstructAccess = true; _player_deleteBuild = true; }; }; @@ -402,14 +404,27 @@ if (!isNull _cursorTarget && _noChange && !_inVehicle && !_isPZombie && _canDo & }; }; }; - if (_player_deleteBuild) then { if (s_player_deleteBuild < 0) then { - s_player_deleteBuild = player addAction [format[localize "STR_EPOCH_REMOVE",_text], "\z\addons\dayz_code\actions\remove.sqf",_cursorTarget, 1, false, true]; + + s_player_deleteBuild = player addAction [format[localize "STR_EPOCH_REMOVE", _text], "\z\addons\dayz_code\actions\remove.sqf",[_cursorTarget, 2, _isModular], -3, false, true]; }; } else { player removeAction s_player_deleteBuild; s_player_deleteBuild = -1; + + }; + + // Deconstruct Modular Object + if (DZE_refundModular && DZE_allowDeconstruct && _hasDeconstructAccess && _isModular && !((DZE_RefundDamageLimit > 0) && (damage _cursorTarget > DZE_RefundDamageLimit))) then { + if !(_typeOfCursorTarget in DZE_modularExclude) then { // check if class allows refunds + if (s_player_deconstruct < 0) then { + s_player_deconstruct = player addAction [format[localize "STR_EPOCH_DECONSTRUCT", _text], "\z\addons\dayz_code\actions\remove.sqf",[_cursorTarget, 3, _isModular], -4, false, true]; + }; + }; + } else { + player removeAction s_player_deconstruct; + s_player_deconstruct = -1; }; //remove Own objects @@ -1066,6 +1081,8 @@ if (!isNull _cursorTarget && _noChange && !_inVehicle && !_isPZombie && _canDo & s_player_sleep = -1; player removeAction s_player_deleteBuild; s_player_deleteBuild = -1; + player removeAction s_player_deconstruct; + s_player_deconstruct = -1; player removeAction s_player_cook; s_player_cook = -1; player removeAction s_player_boil; @@ -1141,8 +1158,6 @@ if (!isNull _cursorTarget && _noChange && !_inVehicle && !_isPZombie && _canDo & s_player_maint_build = -1; player removeAction s_player_downgrade_build; s_player_downgrade_build = -1; - player removeAction s_player_towing; - s_player_towing = -1; player removeAction s_player_fuelauto; s_player_fuelauto = -1; player removeAction s_player_fuelauto2; diff --git a/SQF/dayz_code/compile/player_packTent.sqf b/SQF/dayz_code/compile/player_packTent.sqf index f9010b36d..7c1f958cc 100644 --- a/SQF/dayz_code/compile/player_packTent.sqf +++ b/SQF/dayz_code/compile/player_packTent.sqf @@ -1,78 +1,97 @@ -/* - [_obj] call player_packTent; -*/ - -if (dayz_actionInProgress) exitWith {localize "str_player_actionslimit" call dayz_rollingMessages;}; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// [_obj] call player_packTent; +// +// Updated by: Victor the Cleaner +// Date: August 2021 +// +// - Now includes helper spheres for improved player experience +// +/////////////////////////////////////////////////////////////////////////////////////////////////// +if (dayz_actionInProgress) exitWith { + localize "str_player_actionslimit" call dayz_rollingMessages; // Wait for the previous action to complete to perform another! +}; dayz_actionInProgress = true; -private ["_alreadyPacking","_backpacks","_bag","_campItems","_dir","_holder","_magazines","_obj","_objectID","_objectUID","_ownerID","_packobj","_playerNear","_pos","_weapons","_finished","_posPlayer","_text","_typeOf"]; - -_obj = _this; -_typeOf = typeOf _obj; -_ownerID = _obj getVariable["CharacterID","0"]; -_objectID = _obj getVariable["ObjectID","0"]; -_objectUID = _obj getVariable["ObjectUID","0"]; +local _obj = _this; +local _objType = typeOf _obj; +local _ownerID = _obj getVariable["CharacterID","0"]; +local _objectID = _obj getVariable["ObjectID","0"]; +local _objectUID = _obj getVariable["ObjectUID","0"]; if (DZE_permanentPlot) then { _ownerID = _obj getVariable["ownerPUID","0"]; }; -_playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 12]) > 1; -if (_playerNear) exitWith {dayz_actionInProgress = false; localize "str_pickup_limit_5" call dayz_rollingMessages;}; +local _playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 12]) > 1; +if (_playerNear) exitWith { + dayz_actionInProgress = false; + localize "str_pickup_limit_5" call dayz_rollingMessages; // Another player is nearby. Only one player can be near to perform this action. +}; -_packobj = getText (configFile >> "CfgVehicles" >> _typeOf >> "pack"); +local _packobj = getText (configFile >> "CfgVehicles" >> _objType >> "pack"); // classname player removeAction s_player_packtent; s_player_packtent = -1; player removeAction s_player_packtentinfected; s_player_packtentinfected = -1; -_campItems = ["IC_DomeTent","IC_Tent"]; +if (_ownerID in [dayz_characterID, dayz_playerUID] || {_objType in ["IC_DomeTent","IC_Tent"]}) then { // if player is the owner, or infected camp items -if (_ownerID in [dayz_characterID,dayz_playerUID] || {_typeOf in _campItems}) then { - _alreadyPacking = _obj getVariable["packing",0]; - if (_alreadyPacking == 1) exitWith {localize "str_player_beingpacked" call dayz_rollingMessages;}; + local _alreadyPacking = _obj getVariable["packing", 0]; - _obj setVariable["packing",1,true]; - _dir = direction _obj; - _pos = getPosATL _obj; + if (_alreadyPacking == 1) exitWith { + localize "str_player_beingpacked" call dayz_rollingMessages; // That tent is already being packed. + }; - [player,(getPosATL player),20,"tentpack"] spawn fnc_alertZombies; + local _text = getText (configFile >> "CfgVehicles" >> _objType >> "displayName"); + format[localize "str_epoch_player_121", _text] call dayz_rollingMessages; // Packing %1, move from this position to cancel within 5 seconds. - _text = getText (configFile >> "CfgVehicles" >> _typeOf >> "displayName"); - format[localize "str_epoch_player_121",_text] call dayz_rollingMessages; + _obj setVariable["packing", 1, true]; + + local _dir = direction _obj; + local _pos = getPosATL _obj; + + [_obj, DZE_NoRefundTexture] call fn_displayHelpers; // create helpers (red) + + [player,(getPosATL player), 20, "tentpack"] spawn fnc_alertZombies; // make noise + + local _finished = ["Medic",1] call fn_loopAction; // animation + + [] call fn_displayHelpers; // delete helpers - _finished = ["Medic",1] call fn_loopAction; if (isNull _obj) exitWith {}; - if (!_finished) exitWith {_obj setVariable["packing",0,true];}; - _posPlayer = getPosATL player; - _pos set [2,_posPlayer select 2]; + if (!_finished) exitWith {_obj setVariable["packing", 0, true];}; // cancel & reset - if (_pos select 2 < 0) then {_pos set [2,0];}; + _pos set [2, (getPosATL player) select 2]; - _bag = _packobj createVehicle [0,0,0]; + if (_pos select 2 < 0) then { // match player height or place on ground + _pos set [2,0]; + }; + + local _bag = _packobj createVehicle [0,0,0]; // packed tent _bag setDir _dir; _bag setPosATL _pos; - _holder = "WeaponHolder" createVehicle [0,0,0]; + local _holder = "WeaponHolder" createVehicle [0,0,0]; // any packed items go here _holder setPosATL _pos; - _weapons = getWeaponCargo _obj; - _magazines = getMagazineCargo _obj; - _backpacks = getBackpackCargo _obj; + local _weapons = getWeaponCargo _obj; // prepare items + local _magazines = getMagazineCargo _obj; + local _backpacks = getBackpackCargo _obj; - PVDZ_obj_Destroy = [_objectID,_objectUID,player,_pos,dayz_authKey,false]; + PVDZ_obj_Destroy = [_objectID, _objectUID, player, _pos, dayz_authKey, false]; // delete original tent publicVariableServer "PVDZ_obj_Destroy"; deleteVehicle _obj; - [_weapons,_magazines,_backpacks,_holder] call fn_addCargo; + [_weapons, _magazines, _backpacks, _holder] call fn_addCargo; // pile everything onto the ground player reveal _holder; - localize "str_success_tent_pack" call dayz_rollingMessages; + localize "str_success_tent_pack" call dayz_rollingMessages; // Your tent has been packed } else { - localize "str_fail_tent_pack" call dayz_rollingMessages; + localize "str_fail_tent_pack" call dayz_rollingMessages; // You cannot pack this tent, it is not yours }; dayz_actionInProgress = false; diff --git a/SQF/dayz_code/compile/player_packVault.sqf b/SQF/dayz_code/compile/player_packVault.sqf index 306aa130e..c81e2efab 100644 --- a/SQF/dayz_code/compile/player_packVault.sqf +++ b/SQF/dayz_code/compile/player_packVault.sqf @@ -1,62 +1,94 @@ -/* - _obj spawn player_packVault; -*/ +/////////////////////////////////////////////////////////////////////////////////////////////////// +// +// _obj spawn player_packVault; +// +// Updated by: Victor the Cleaner +// Date: September 2021 +// +// - Now includes helper spheres for improved player experience +// +/////////////////////////////////////////////////////////////////////////////////////////////////// -if (dayz_actionInProgress) exitWith {localize "str_player_actionslimit" call dayz_rollingMessages;}; +if (dayz_actionInProgress) exitWith {localize "str_player_actionslimit" call dayz_rollingMessages;}; // Wait for the previous action to complete to perform another! dayz_actionInProgress = true; -private ["_code","_obj","_ownerID","_objectID","_objectUID","_packedClass","_text","_playerNear","_finished","_ComboMatch","_typeOf"]; - -_obj = _this; -_typeOf = typeOf _obj; -_packedClass = getText (configFile >> "CfgVehicles" >> _typeOf >> "packedClass"); -_text = getText (configFile >> "CfgVehicles" >> _typeOf >> "displayName"); +local _obj = _this; +local _typeOf = typeOf _obj; +local _text = getText (configFile >> "CfgVehicles" >> _typeOf >> "displayName"); +local _packedClass = getText (configFile >> "CfgVehicles" >> _typeOf >> "packedClass"); if (isNull _obj || !(alive _obj)) exitWith {dayz_actionInProgress = false;}; -_playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 10]) > 1; -if (_playerNear) exitWith {dayz_actionInProgress = false; localize "str_pickup_limit_5" call dayz_rollingMessages;}; +local _playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 10]) > 1; +if (_playerNear) exitWith { + dayz_actionInProgress = false; + localize "str_pickup_limit_5" call dayz_rollingMessages; // Another player is nearby. Only one player can be near to perform this action. +}; + +local _ownerID = _obj getVariable["CharacterID","0"]; +local _objectID = _obj getVariable["ObjectID","0"]; +local _objectUID = _obj getVariable["ObjectUID","0"]; +local _ComboMatch = (_ownerID == dayz_combination); -_ownerID = _obj getVariable["CharacterID","0"]; -_objectID = _obj getVariable["ObjectID","0"]; -_objectUID = _obj getVariable["ObjectUID","0"]; -_ComboMatch = (_ownerID == dayz_combination); if (DZE_permanentPlot) then {_ownerID = _obj getVariable["ownerPUID","0"];}; +if (_objectID == "0" && _objectUID == "0") exitWith { + dayz_actionInProgress = false; +// s_player_packvault = -1; + format[localize "str_epoch_player_118", _text] call dayz_rollingMessages; // %1 not setup yet. +}; + +if (!_ComboMatch && (_ownerID != dayz_playerUID)) exitWith { + dayz_actionInProgress = false; +// s_player_packvault = -1; + format[localize "str_epoch_player_119", _text] call dayz_rollingMessages; // You cannot pack this %1, you do not know the combination. +}; + +if (isNull _obj && {!alive _obj}) exitWith { // object has been destroyed or deleted +// s_player_packvault = -1; + dayz_actionInProgress = false; +}; + player removeAction s_player_packvault; s_player_packvault = 1; -if (_objectID == "0" && _objectUID == "0") exitWith {dayz_actionInProgress = false; s_player_packvault = -1; format[localize "str_epoch_player_118",_text] call dayz_rollingMessages;}; +format[localize "str_epoch_player_121", _text] call dayz_rollingMessages; // Packing %1, move from this position to cancel within 5 seconds. -if (!_ComboMatch && (_ownerID != dayz_playerUID)) exitWith {dayz_actionInProgress = false; s_player_packvault = -1; format[localize "str_epoch_player_119",_text] call dayz_rollingMessages;}; +[_obj, DZE_NoRefundTexture] call fn_displayHelpers; // create helpers (red) -if (isNull _obj && {!alive _obj}) exitWith {s_player_packvault = -1;dayz_actionInProgress = false;}; -[player,(getPosATL player),20,"tentpack"] spawn fnc_alertZombies; +[player,(getPosATL player),20,"tentpack"] spawn fnc_alertZombies; // make noise -format[localize "str_epoch_player_121",_text] call dayz_rollingMessages; +local _finished = ["Medic",1] call fn_loopAction; // animation -_finished = ["Medic",1] call fn_loopAction; -if (isNull _obj || !_finished) exitWith {s_player_packvault = -1;dayz_actionInProgress = false;}; +[] call fn_displayHelpers; // delete helpers + +if (isNull _obj || !_finished) exitWith { + s_player_packvault = -1; + dayz_actionInProgress = false; +}; (findDisplay 106) closeDisplay 0; // Close gear -_playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 10]) > 1; -if (_playerNear) exitWith {dayz_actionInProgress = false; localize "str_pickup_limit_5" call dayz_rollingMessages;}; +_playerNear = {isPlayer _x} count (([_obj] call FNC_GetPos) nearEntities ["CAManBase", 10]) > 1; // if another player has approached during the packing animation +if (_playerNear) exitWith { + dayz_actionInProgress = false; + localize "str_pickup_limit_5" call dayz_rollingMessages; // Another player is nearby. Only one player can be near to perform this action. +}; ["Working",0,[3,2,4,0]] call dayz_NutritionSystem; dze_waiting = nil; -[_packedClass,objNull] call fn_waitForObject; +[_packedClass, objNull] call fn_waitForObject; -_code = [_obj getVariable["CharacterID","0"],dayz_combination] select (_ComboMatch); +local _code = [_obj getVariable["CharacterID","0"],dayz_combination] select (_ComboMatch); PVDZE_handleSafeGear = [player,_obj,2,_code,dayz_authKey]; publicVariableServer "PVDZE_handleSafeGear"; waitUntil {!isNil "dze_waiting"}; // wait for response from server to verify pack was logged and gear added before proceeding -format[localize "str_epoch_player_123",_text] call dayz_rollingMessages; +format[localize "str_epoch_player_123", _text] call dayz_rollingMessages; // Your %1 has been packed s_player_packvault = -1; dayz_actionInProgress = false; diff --git a/SQF/dayz_code/config.cpp b/SQF/dayz_code/config.cpp index 60dc4615a..e810f7ef7 100644 --- a/SQF/dayz_code/config.cpp +++ b/SQF/dayz_code/config.cpp @@ -125,6 +125,7 @@ class DefaultEventhandlers { #include "Configs\RscDisplay\plotManagement.hpp" #include "Configs\RscDisplay\deathboards.hpp" #include "Configs\CfgExtra\snappoints.hpp" +#include "Configs\CfgExtra\HelperVectors.hpp" #include "external\R3F_Realism\R3F_Weight\R3F_CfgWeight.hpp" #include "Configs\RscDisplay\doorManagement\doorManagement.hpp" #include "Configs\RscDisplay\doorManagement\doorAccess.hpp" diff --git a/SQF/dayz_code/configVariables.sqf b/SQF/dayz_code/configVariables.sqf index fe89faaab..cfe60a626 100644 --- a/SQF/dayz_code/configVariables.sqf +++ b/SQF/dayz_code/configVariables.sqf @@ -157,6 +157,7 @@ if (!isDedicated) then { DZE_NoBuildNear = []; //Array of object class names that are blacklisted to build near. i.e ["Land_Mil_ControlTower","Land_SS_hangar"] etc. DZE_NoBuildNearDistance = 150; // Distance from blacklisted objects to disallow building near. DZE_BuildHeightLimit = 0; // 0 = No building height limit | >0 = Height limit in meters | Changing this to 30 would limit the maximum built height to 30 meters. + DZE_HeightLimitColor = true; // display plot boundary helpers in red if they are above DZE_BuildHeightLimit DZE_requireplot = 1; // Players require a plot to build DZE_PlotPole = [30,45]; // Plot radius, minimum distance between plots DZE_BuildOnRoads = false; // Allow building on roads @@ -197,9 +198,13 @@ if (!isDedicated) then { DZE_MaxPlotFriends = 10; //Max friends allowed on a plot. There is no character limit in the inventory field of the database, but lower values limit the max global setVariable size to improve performance. DZE_maintainCurrencyRate = 100; //The currency rate of what maintaining an item will be, for instance: at 100, 10 items will have a worth of 1000 (1 10oz gold or 1k coins) see actions/maintain_area.sqf for more examples. DZE_limitPlots = 0; // Limit the amount of plot poles per person, Use 0 to disable. UIDS in the DZE_PlotManagementAdmins array are exempt. + DZE_PlotOzone = 10; // distance (in meters) outside the plot radius where the player may stand while building, provided the object remains within the plot radius. + DZE_AxialHelper = true; // when building within a plot radius, display a perpendicular line of helpers from the highest point to lowest point of the plot boundary. + DZE_plotGreenTransparency = 0.4; // green plot pole helper transparency. min = 0.1, max = 1 + DZE_plotRedTransparency = 0.7; // red plot pole helper transparency. min = 0.1, max = 1 DZE_restrictRemoval = ["Fence_corrugated_DZ","M240Nest_DZ","ParkBench_DZ","FireBarrel_DZ","Scaffolding_DZ","CanvasHut_DZ","LightPole_DZ","DeerStand_DZ","MetalGate_DZ","StickFence_DZ","Garage_Green_DZ","Garage_White_DZ","Garage_Brown_DZ","Garage_Grey_DZ","CCTV_DZ","Notebook_DZ","Water_Pump_DZ","Greenhouse_DZ","Bed_DZ","Table_DZ","Office_Chair_DZ"]; //Items that can be removed with a crowbar only with proper ownership or access. It is not necessary to add doors, storage or items that inherit from 'ModularItems' to this list. Items that inherit from 'BuiltItems' can be added to this list if desired. DZE_DisableUpgrade = []; //Array of buildables that are not allowed to be upgraded. For example: DZE_DisableUpgrade = ["WoodShack_DZ","StorageShed_DZ"]; - + // Snap Build and Build Vectors DZE_modularBuild = true; // Enable Snap Building by @raymix and Build Vectors by @strikerforce. DZE_snapExtraRange = 0; // Increase the default range from which objects can snap by this many meters. @@ -207,23 +212,128 @@ if (!isDedicated) then { DZE_vectorDegrees = [0.01, 0.1, 1, 5, 15, 45, 90]; // Degree positions players are able to rotate buildables with using the build vectors action menu. DZE_curDegree = 45; // Starting rotation angle. Prefer any value in the array above. DZE_dirWithDegrees = true; // When rotating objects with Q&E, use the custom degrees. - DZE_buildMaxMoveDistance = 10; // Max distance player can walk from start position when building. Anything >= the differnce between DZE_PlotPole values is not recommended (allows walking into other plots). - DZE_buildMaxHeightDistance = 10; // Max distance player can raise or lower object from start position when building. - DZE_modularConfig = []; - /* - Array of classnames with magazine based loot to be refunded on deconstruction of modular built items that do not typically refund. + // Remove/Deconstruct modular object variables + DZE_refundModular = true; // enable/disable refunding of modular objects + DZE_allowDeconstruct = true; // enable/disable the Deconstruct player action menu. If DZE_refundModular = false, this setting has no effect. + DZE_displayHelpers = true; // enable/disable display of modular object helpers + DZE_displayOnlyIfNearby = false; // if identical object types are nearby, display green helpers. If no identical types are nearby, then do not display. false = always display green helpers. (This setting does not apply to Red and Blue helpers). If DZE_displayHelpers is disabled, then this setting will be ignored. + DZE_RefundDamageLimit = 0.25; // amount of damage an object can withstand before no refunded parts will be given. 0 = disable (will always refund) + DZE_helperSize = [[3,"Sign_sphere100cm_EP1"],[2,"Sign_sphere25cm_EP1"],[1,"Sign_sphere10cm_EP1"]]; // array of helper sizes and corresponding class. Keep in reverse order for optimized lookup + DZE_helperSizeDefault = 3; // default to large sphere + DZE_NoRefundTransparency = 0.15; // Red Basebuilding Helper Transparency. min = 0.1, max = 1 + DZE_removeTransparency = 0.15; // Green Basebuilding Helper Transparency. min = 0.1, max = 1 + DZE_deconstructTransparency = 0.15; // Blue Basebuilding Helper Transparency. min = 0.1, max = 1 + DZE_largeObjects = ["MetalFloor4x_DZ", "Land_metal_floor_2x2_wreck", "WoodFloor4x_DZ", "Land_wood_floor_2x2_wreck", "Scaffolding_DZ", "CinderGateFrame_DZ", "CinderGate_DZ", "WoodGateFrame_DZ", "Land_DZE_WoodGate", "WoodRamp_DZ"]; // adjust _allowedDistance in fn_selfActions.sqf for large modular/crafted objects - For example: - DZE_modularConfig = [ - ["CinderWall_DZ", [["CinderBlocks",7],["MortarBucket",2]]], - ["CinderWallDoor_DZ", [["CinderBlocks",7],["MortarBucket",2],["ItemTankTrap",3],["ItemPole",[1,3]]]] - ]; + // Refund single kits, or modular object recipes as per the build configs + // [[Enable, Modular Object, Refund Kit, [[Refund Class 1, Qty], [Refund Class 2, Qty], [Refund Class 3, Qty], [Refund Class 4, Qty]]]] + // + // Enable: bool If DZE_refundModular = true, then set the Enable column to customize individual modular object refunds to on or off. Default = true. + // Modular Object: class CfgVehicles class of the built object. The string must be in quotes. + // Refund Kit: class CfgMagazines class of the refunded object when using the "Remove" action. Will refund a singular kit only. + // Refund Class n: class When using the "Deconstruct" action, refund multiple parts as per the config recipe. Repeat for each material type, up to 4 types maximum. + // Qty: integer Quantity of each material type, as per the recipe. Or alternatively a range of values using an array, e.g [1,3] will refund a random integer between 1 and 3. - This would refund 7 cinder blocks and 2 mortar for "CinderWall_DZ" - For "CinderWallDoor_DZ" you would get 7 cinder blocks, 2 mortar, 3 tank traps and a random number of poles between 1 and 3. - The refund amount can be an array where the first param is the minimum and the second is the maximum, it will refund a random amount between them. - */ + DZE_modularConfig = [ + + // Enable Modular Object Refund Kit Refund Class 1 Qty Refund Class 2 Qty Refund Class 3 Qty Refund Class 4 Qty + // ====== ============== =============================== =========================================== =========================== =========================== =========================== + // // Glass // + [true, "GlassFloor_DZ", "glass_floor_kit", [["glass_floor_half_kit", 2]]], + [true, "GlassFloor_Half_DZ", "glass_floor_half_kit", [["glass_floor_quarter_kit", 2]]], + [true, "GlassFloor_Quarter_DZ", "glass_floor_quarter_kit", [["ItemPole", 8], ["PartGlass", 4]]], + + // // Metal // + [true, "MetalFloor_DZ", "metal_floor_kit", [["metal_floor_half_kit", 2]]], + [true, "MetalFloor_Half_DZ", "metal_floor_half_kit", [["metal_floor_quarter_kit", 2]]], + [true, "MetalFloor_Quarter_DZ", "metal_floor_quarter_kit", [["ItemPole", 4], ["equip_metal_sheet", 4]]], + [true, "MetalFloor4x_DZ", "metal_floor4x_kit", [["metal_floor_kit", 4]]], + [true, "Metal_Drawbridge_DZ", "metal_drawbridge_kit", [["metal_floor_kit", 2], ["ItemRSJ", 6]]], + [true, "MetalPillar_DZ", "metal_pillar_kit", [["ItemPole", 1], ["equip_metal_sheet", 2]]], + [true, "DoorFrame_DZ", "door_frame_kit", [["ItemPole", 4], ["ItemTankTrap", 4], ["PartGeneric", 2]]], + [true, "Door_DZ", "door_kit", [["door_frame_kit", 1], ["ItemTankTrap", 1], ["ItemPole", 1]]], + [true, "MetalFence_1_foundation_DZ", "metalfence_foundation_kit", [["ItemStone", 8], ["MortarBucket", 1], ["ItemRSJ", 1]]], + [true, "MetalFence_1_frame_DZ", "metalfence_frame_kit", [["ItemPlank", 4], ["ItemRSJ", 1]]], + [true, "MetalFence_halfpanel_DZ", "metalfence_halfpanel_kit", [["ItemMetalSheet", 3], ["ItemScrews", 1]]], + [true, "MetalFence_thirdpanel_DZ", "metalfence_thirdpanel_kit", [["ItemMetalSheet", 3], ["ItemScrews", 1]]], + [true, "MetalFence_1_DZ", "metalfence_1_kit", [["ItemMetalSheet", 3], ["ItemScrews", 1]]], + [true, "MetalFence_2_DZ", "metalfence_2_kit", [["ItemMetalSheet", 4], ["ItemScrews", 1], ["ItemRSJ", 2]]], + [true, "MetalFence_3_DZ", "metalfence_3_kit", [["ItemMetalSheet", 4], ["ItemScrews", 1], ["ItemRSJ", 2]]], + [true, "MetalFence_4_DZ", "metalfence_4_kit", [["ItemScrews", 1], ["ItemRSJ", 4]]], + [true, "MetalFence_5_DZ", "metalfence_5_kit", [["ItemScrews", 1], ["ItemRSJ", 2]]], + [true, "MetalFence_6_DZ", "metalfence_6_kit", [["ItemScrews", 1], ["ItemPole", 4], ["equip_metal_sheet", 4]]], + [true, "MetalFence_7_DZ", "metalfence_7_kit", [["ItemScrews", 1], ["ItemPole", 6], ["PartGeneric", 2]]], + + // // Cinder // + [true, "CinderWallHalf_DZ", "half_cinder_wall_kit", [["CinderBlocks", 3], ["MortarBucket", 1]]], + [true, "CinderWallHalf_Gap_DZ", "half_cinder_wall_gap_kit", [["CinderBlocks", 3], ["MortarBucket", 1]]], + [true, "CinderWall_DZ", "full_cinder_wall_kit", [["CinderBlocks", 7], ["MortarBucket", 2]]], + [true, "CinderWallWindow_DZ", "cinderwall_window_kit", [["CinderBlocks", 5], ["MortarBucket", 1], ["ItemTankTrap", 1], ["ItemPole", 1]]], + [true, "CinderWallSmallDoorway_DZ", "cinder_door_frame_kit", [["CinderBlocks", 4], ["MortarBucket", 1], ["ItemTankTrap", 1]]], + [true, "CinderWallDoorSmall_DZ", "cinder_door_kit", [["cinder_door_frame_kit", 1], ["ItemTankTrap", 1], ["ItemPole", 1]]], + [true, "CinderDoorHatch_DZ", "cinder_door_hatch_kit", [["CinderBlocks", 4], ["MortarBucket", 1], ["ItemTankTrap", 2], ["ItemPole", 1]]], + [true, "CinderWallDoorway_DZ", "cinder_garage_frame_kit", [["CinderBlocks", 3], ["MortarBucket", 1], ["ItemTankTrap", 1]]], + [true, "CinderWallDoor_DZ", "cinder_garage_kit", [["cinder_garage_frame_kit", 1], ["ItemTankTrap", 3], ["ItemPole", 3]]], + [true, "CinderGarageOpenTopFrame_DZ", "cinder_garage_top_open_frame_kit", [["CinderBlocks", 4], ["MortarBucket", 1]]], + [true, "CinderGarageOpenTop_DZ", "cinder_garage_top_open_kit", [["cinder_garage_top_open_frame_kit", 1], ["ItemTankTrap", 3], ["ItemPole", 3]]], + [true, "CinderGateFrame_DZ", "cinder_gate_frame_kit", [["CinderBlocks", 8], ["MortarBucket", 4]]], + [true, "CinderGate_DZ", "cinder_gate_kit", [["cinder_gate_frame_kit", 1], ["equip_metal_sheet", 6], ["ItemRSJ", 2], ["ItemScrews", 2]]], + [true, "Concrete_Bunker_DZ", "cinder_bunker_kit", [["full_cinder_wall_kit", 3], ["ItemConcreteBlock", 5], ["equip_metal_sheet", 3], ["ItemScrews", 1]]], + + // // Wood // + [true, "WoodFloor_DZ", "ItemWoodFloor", [["ItemWoodFloorHalf", 2]]], + [true, "WoodFloor4x_DZ", "ItemWoodFloor4x", [["ItemWoodFloor", 4]]], + [true, "WoodFloorHalf_DZ", "ItemWoodFloorHalf", [["ItemWoodFloorQuarter", 2]]], + [true, "WoodFloorQuarter_DZ", "ItemWoodFloorQuarter", [["PartWoodPlywood", 3], ["PartWoodLumber", 3]]], + [true, "WoodSmallWall_DZ", "ItemWoodWall", [["ItemWoodWallThird", 3]]], + [true, "WoodTriangleWall_DZ", "ItemTriangleWoodWall", [["ItemWoodFloorHalf", 1], ["ItemWoodFloorQuarter",1]]], + [true, "WoodSmallWallThird_DZ", "ItemWoodWallThird", [["PartWoodPlywood", 3], ["PartWoodLumber", 3]]], + [true, "WoodSmallWallWin_DZ", "ItemWoodWallWindow", [["ItemWoodWall", 1], ["PartGlass", 1]]], + [true, "WoodSmallWallDoor_DZ", "ItemWoodWallDoor", [["ItemWoodWallThird", 3]]], + [true, "Land_DZE_WoodDoor", "ItemWoodWallWithDoor", [["ItemWoodWallDoor", 1], ["PartWoodPlywood", 1], ["PartWoodLumber", 1]]], + [true, "Land_DZE_GarageWoodDoor", "ItemWoodWallGarageDoor", [["ItemWoodWallLg", 1], ["PartWoodLumber", 2]]], + [true, "Land_DZE_WoodOpenTopGarageDoor", "ItemWoodOpenTopGarageDoor", [["ItemWoodWallLg", 1], ["PartWoodLumber", 2]]], + [true, "WoodLargeWall_DZ", "ItemWoodWallLg", [["ItemWoodWall", 1], ["PartWoodPlywood", 1], ["PartWoodLumber", 1]]], + [true, "WoodLargeWallWin_DZ", "ItemWoodWallWindowLg", [["ItemWoodWallLg", 1], ["PartGlass", 1]]], + [true, "WoodLargeWallDoor_DZ", "ItemWoodWallDoorLg", [["ItemWoodWall", 1], ["PartWoodPlywood", 1], ["PartWoodLumber", 1]]], + [true, "Land_DZE_LargeWoodDoor", "ItemWoodWallWithDoorLg", [["ItemWoodWallDoorLg", 1], ["PartWoodPlywood", 1], ["PartWoodLumber", 1]]], + [true, "WoodGateFrame_DZ", "ItemWoodGateFrame", [["ItemWoodWallThird", 6]]], + [true, "Land_DZE_WoodGate", "ItemWoodGate", [["ItemWoodGateFrame", 1], ["PartWoodPlywood", 8], ["PartWoodLumber", 2], ["equip_nails", 1]]], + [true, "WoodFloorStairs_DZ", "ItemWoodFloorStairs", [["ItemWoodFloor", 1], ["ItemWoodStairs", 1]]], + [true, "WoodTriangleFloor_DZ", "ItemTriangleWoodFloor", [["ItemWoodFloorHalf", 1], ["ItemWoodFloorQuarter",1]]], + [true, "WoodStairsSans_DZ", "ItemWoodStairs", [["PartWoodLumber", 8], ["equip_nails", 2]]], + [true, "WoodStairs_DZ", "ItemWoodStairsSupport", [["ItemWoodStairs", 1], ["PartWoodLumber", 2]]], + [true, "WoodStairsRails_DZ", "ItemWoodStairsRails", [["ItemWoodStairsSupport", 1], ["PartWoodLumber", 2]]], + [true, "WoodLadder_DZ", "ItemWoodLadder", [["PartWoodLumber", 8], ["equip_nails", 2]]], + [true, "WoodHandrail_DZ", "ItemWoodHandRail", [["PartWoodLumber", 3], ["equip_nails", 1]]], + [true, "WoodPillar_DZ", "ItemWoodPillar", [["PartWoodLumber", 4], ["equip_nails", 1]]], + [true, "WoodRamp_DZ", "wood_ramp_kit", [["ItemDocumentRamp", 1], ["PartWoodLumber", 8]]], + [true, "WoodenFence_1_foundation_DZ", "woodfence_foundation_kit", [["ItemStone", 8], ["MortarBucket", 1], ["ItemPlank", 1]]], + [true, "WoodenFence_1_frame_DZ", "woodfence_frame_kit", [["woodfence_foundation_kit", 1], ["ItemPlank", 4], ["equip_nails", 1]]], + [true, "WoodenFence_quaterpanel_DZ", "woodfence_quaterpanel_kit", [["woodfence_frame_kit", 1], ["ItemPlank", 4], ["equip_nails", 1]]], + [true, "WoodenFence_halfpanel_DZ", "woodfence_halfpanel_kit", [["woodfence_quaterpanel_kit", 1], ["ItemPlank", 4], ["equip_nails", 1]]], + [true, "WoodenFence_thirdpanel_DZ", "woodfence_thirdpanel_kit", [["woodfence_halfpanel_kit", 1], ["ItemPlank", 4], ["equip_nails", 1]]], + [true, "WoodenFence_1_DZ", "woodfence_1_kit", [["woodfence_thirdpanel_kit", 1], ["ItemPlank", 4], ["equip_nails", 1]]], + [true, "WoodenFence_2_DZ", "woodfence_2_kit", [["woodfence_1_kit", 1], ["ItemPlank", 8], ["equip_nails", 2]]], + [true, "WoodenFence_3_DZ", "woodfence_3_kit", [["woodfence_2_kit", 1], ["ItemPlank", 8], ["equip_nails", 2]]], + [true, "WoodenFence_4_DZ", "woodfence_4_kit", [["woodfence_3_kit", 1], ["ItemPlank", 8], ["equip_nails", 2]]], + [true, "WoodenFence_5_DZ", "woodfence_5_kit", [["woodfence_4_kit", 1], ["ItemLog", 5], ["equip_nails", 2]]], + [true, "WoodenFence_6_DZ", "woodfence_6_kit", [["woodfence_5_kit", 1], ["PartWoodPlywood", 4], ["ItemPlank", 2], ["equip_nails", 2]]], + [true, "WoodenFence_7_DZ", "woodfence_7_kit", [["woodfence_6_kit", 1], ["ItemWoodLadder", 1], ["equip_nails", 1]]], + [true, "WoodenGate_foundation_DZ", "woodfence_gate_foundation_kit", [["ItemLog", 6]]], + [true, "WoodenGate_1_DZ", "woodfence_gate_1_kit", [["woodfence_gate_foundation_kit", 1], ["ItemPlank", 8], ["equip_nails", 1], ["ItemComboLock", 1]]], + [true, "WoodenGate_2_DZ", "woodfence_gate_2_kit", [["woodfence_gate_1_kit", 1], ["ItemPlank", 10], ["equip_nails", 1]]], + [true, "WoodenGate_3_DZ", "woodfence_gate_3_kit", [["woodfence_gate_2_kit", 1], ["ItemPlank", 10], ["equip_nails", 1]]], + [true, "WoodenGate_4_DZ", "woodfence_gate_4_kit", [["woodfence_gate_3_kit", 1], ["ItemPlank", 10], ["equip_nails", 1]]] + ]; + + DZE_modularExclude = []; + { + if !(_x select 0) then { + DZE_modularExclude = DZE_modularExclude + [_x select 1]; + }; + } count DZE_modularConfig; // Door Management DZE_doorManagementMustBeClose = false; //Players must be within 10m of door to be added as a door friend. diff --git a/SQF/dayz_code/init/compiles.sqf b/SQF/dayz_code/init/compiles.sqf index 78a67038a..dc5b273b5 100644 --- a/SQF/dayz_code/init/compiles.sqf +++ b/SQF/dayz_code/init/compiles.sqf @@ -176,6 +176,8 @@ if (!isDedicated) then { player_unlockDoor = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_unlockDoor.sqf"; player_unlockVault = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_unlockVault.sqf"; player_upgradeVehicle = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_upgradeVehicle.sqf"; + fn_displayHelpers = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\fn_displayHelpers.sqf"; + if (DZE_permanentPlot) then { PlotGetFriends = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\plotManagement\plotGetFriends.sqf"; PlotNearbyHumans = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\plotManagement\plotNearbyHumans.sqf"; diff --git a/SQF/dayz_code/init/variables.sqf b/SQF/dayz_code/init/variables.sqf index 6fe423ed9..6c0371583 100644 --- a/SQF/dayz_code/init/variables.sqf +++ b/SQF/dayz_code/init/variables.sqf @@ -19,7 +19,7 @@ AllPlayers = ["SurvivorW2_DZ","Survivor2_DZ","Sniper1_DZ","Soldier1_DZ","Camo1_D // Epoch Additions dayz_activeInvites = []; DZE_DoorsLocked = ["Land_DZE_GarageWoodDoorLocked","Land_DZE_LargeWoodDoorLocked","Land_DZE_WoodDoorLocked","CinderWallDoorLocked_DZ","CinderWallDoorSmallLocked_DZ","WoodenGate_1_DZ","WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ","Land_DZE_WoodGateLocked","CinderGateLocked_DZ","Metal_DrawbridgeLocked_DZ","Land_DZE_WoodOpenTopGarageLocked","CinderGarageOpenTopLocked_DZ","DoorLocked_DZ","CinderWallWindowLocked_DZ","CinderDoorHatchLocked_DZ","Concrete_Bunker_Locked_DZ"]; -DZE_isWreckBuilding = ["Land_wreck_metal_floor","Land_wood_wreck_half","Land_wood_floor_2x2_wreck","Land_metal_floor_2x2_wreck","Land_wreck_cinder","Land_wood_wreck_quarter","Land_wood_wreck_floor","Land_wood_wreck_third","Land_wood_wreck_frame","Land_iron_vein_wreck","Land_silver_vein_wreck","Land_gold_vein_wreck","Land_ammo_supply_wreck"]; +DZE_isWreckBuilding = ["Land_wood_floor_2x2_wreck","Land_metal_floor_2x2_wreck","Land_wreck_metal_floor","Land_wreck_cinder","Land_wood_wreck_quarter","Land_wood_wreck_half","Land_wood_wreck_floor","Land_wood_wreck_third","Land_wood_wreck_frame","Land_iron_vein_wreck","Land_silver_vein_wreck","Land_gold_vein_wreck","Land_ammo_supply_wreck"]; DZE_LockedStorage = ["VaultStorageLocked","VaultStorage2Locked","LockboxStorageLocked","LockboxStorage2Locked","LockboxStorageWinterLocked","LockboxStorageWinter2Locked","TallSafeLocked"]; DZE_UnLockedStorage = ["VaultStorage","VaultStorage2","LockboxStorage","LockboxStorage2","LockboxStorageWinter","LockboxStorageWinter2","TallSafe"]; DZE_isNewStorage = ["OutHouse_DZ","Wooden_shed_DZ","Wooden_shed2_DZ","WoodShack_DZ","WoodShack2_DZ","StorageShed_DZ","StorageShed2_DZ","GunRack_DZ","GunRack2_DZ","WoodCrate_DZ","WoodCrate2_DZ","Advanced_WorkBench_DZ","CookTripod_DZ","Stoneoven_DZ","Commode_DZ","Wardrobe_DZ","Fridge_DZ","Washing_Machine_DZ","Server_Rack_DZ","ATM_DZ","Armchair_DZ","Sofa_DZ","Arcade_DZ","Vendmachine1_DZ","Vendmachine2_DZ","StorageCrate_DZ","CamoStorageCrate_DZ"]; @@ -180,7 +180,6 @@ if (!isDedicated) then { s_player_upgrade_build = -1; s_player_maint_build = -1; s_player_downgrade_build = -1; - s_player_towing = -1; s_halo_action = -1; s_player_SurrenderedGear = -1; s_player_maintain_area = -1; @@ -217,6 +216,7 @@ if (!isDedicated) then { s_player_copyToKey = -1; s_player_claimVehicle = -1; s_garage_dialog = -1; + s_player_deconstruct = -1; }; call dayz_resetSelfActions; @@ -301,6 +301,17 @@ if (!isDedicated) then { dayz_treeTypes = ["","MAP_t_picea1s","MAP_t_picea2s","MAP_t_picea3f","MAP_t_pinusN2s","MAP_t_pinusS2f","MAP_t_populus3s","MAP_t_betula2s","MAP_t_fagus2s","MAP_t_fagus2W","MAP_t_malus1s"]; DayZ_DropDrageeObjects = ["TentStorage","TentStorage0","TentStorage1","TentStorage2","TentStorage3","TentStorage4","Wire_cat1","Sandbag1_DZ","Fence_DZ","Generator_DZ","Hedgehog_DZ","DomeTentStorage","DomeTentStorage0","DomeTentStorage1","DomeTentStorage2","DomeTentStorage3","DomeTentStorage4","VaultStorageLocked","BagFenceRound_DZ","Fort_RazorWire","WoodGate_DZ","Land_HBarrier1_DZ","Land_HBarrier3_DZ","Land_HBarrier5_DZ","Fence_corrugated_DZ","M240Nest_DZ","ParkBench_DZ","MetalGate_DZ","OutHouse_DZ","Wooden_shed_DZ","Wooden_shed2_DZ","WoodShack_DZ","WoodShack2_DZ","StorageShed_DZ","StorageShed2_DZ","StickFence_DZ","SandNest_DZ","MetalPanel_DZ","WorkBench_DZ","WoodLargeWall_DZ","WoodLargeWallDoor_DZ","WoodLargeWallWin_DZ","WoodSmallWall_DZ","WoodSmallWallWin_DZ","WoodSmallWallDoor_DZ","LockboxStorageLocked","WoodSmallWallThird_DZ","WoodLadder_DZ","Land_DZE_GarageWoodDoor","Land_DZE_LargeWoodDoor","Land_DZE_WoodDoor","Land_DZE_GarageWoodDoorLocked","Land_DZE_LargeWoodDoorLocked","Land_DZE_WoodDoorLocked","CinderWallHalf_DZ","CinderWall_DZ","CinderWallDoorway_DZ","CinderWallDoor_DZ","CinderWallDoorLocked_DZ","CinderWallSmallDoorway_DZ","CinderWallDoorSmall_DZ","CinderWallDoorSmallLocked_DZ","DesertTentStorage","DesertTentStorage0","DesertTentStorage1","DesertTentStorage2","DesertTentStorage3","DesertTentStorage4","WoodFloorHalf_DZ","WoodFloor_DZ","WoodFloorQuarter_DZ","WoodStairs_DZ","WoodStairsSans_DZ","WoodStairsRails_DZ","MetalFloor_DZ","WoodRamp_DZ","WoodenFence_1_foundation_DZ","WoodenFence_1_frame_DZ","WoodenFence_quaterpanel_DZ","WoodenFence_halfpanel_DZ","WoodenFence_thirdpanel_DZ","WoodenFence_1_DZ","WoodenFence_2_DZ","WoodenFence_3_DZ","WoodenFence_4_DZ","WoodenFence_5_DZ","WoodenFence_6_DZ","MetalFence_1_foundation_DZ","MetalFence_1_frame_DZ","MetalFence_halfpanel_DZ","MetalFence_thirdpanel_DZ","MetalFence_1_DZ","MetalFence_2_DZ","MetalFence_3_DZ","MetalFence_4_DZ","MetalFence_5_DZ","MetalFence_6_DZ","MetalFence_7_DZ","WoodenGate_foundation_DZ","WoodenGate_1_DZ","WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ","WoodGateFrame_DZ","Land_DZE_WoodGate","Land_DZE_WoodGateLocked","CinderGateFrame_DZ","CinderGate_DZ","CinderGateLocked_DZ","Metal_Drawbridge_DZ","Metal_DrawbridgeLocked_DZ","WoodTriangleWall_DZ","WoodHandrail_DZ","WoodFloorStairs_DZ","WoodPillar_DZ","Land_DZE_WoodOpenTopGarageDoor","Land_DZE_WoodOpenTopGarageLocked","CinderGarageOpenTopFrame_DZ","CinderGarageOpenTop_DZ","CinderGarageOpenTopLocked_DZ","DoorFrame_DZ","Door_DZ","DoorLocked_DZ","CinderWallWindow_DZ","CinderWallWindowLocked_DZ","CinderDoorHatch_DZ","CinderDoorHatchLocked_DZ","MetalPillar_DZ","MetalFloor_Half_DZ","MetalFloor_Quarter_DZ","GlassFloor_DZ","Concrete_Bunker_DZ","Concrete_Bunker_Locked_DZ","TallSafe","TallSafeLocked","Advanced_WorkBench_DZ","CookTripod_DZ","Stoneoven_DZ","Commode_DZ","Wardrobe_DZ","Fridge_DZ","Washing_Machine_DZ","Server_Rack_DZ","ATM_DZ","Armchair_DZ","Sofa_DZ","Arcade_DZ","Vendmachine1_DZ","Vendmachine2_DZ","Notebook_DZ","Water_Pump_DZ","Greenhouse_DZ","Bed_DZ","Table_DZ","Office_Chair_DZ","MetalFloor4x_DZ","GlassFloor_Half_DZ","GlassFloor_Quarter_DZ","WoodFloor4x_DZ","WoodTriangleFloor_DZ","CinderWallHalf_Gap_DZ","TentStorageWinter","TentStorageWinter0","TentStorageWinter1","TentStorageWinter2","TentStorageWinter3","TentStorageWinter4","WinterDomeTentStorage","WinterDomeTentStorage0","WinterDomeTentStorage1","WinterDomeTentStorage2","WinterDomeTentStorage3","WinterDomeTentStorage4","VaultStorageBroken","VaultStorageBroken2","TallSafeBroken","LockboxStorageBroken","LockboxStorage2Broken","LockboxStorageWinterBroken","LockboxStorageWinter2Broken","StorageCrate_DZ","CamoStorageCrate_DZ","Garage_Green_DZ","Garage_White_DZ","Garage_Brown_DZ","Garage_Grey_DZ","Helipad_Civil_DZ","Helipad_Rescue_DZ","Helipad_Army_DZ","Helipad_Cross_DZ","Helipad_ParkBorder_DZ","CCTV_DZ"]; Dayz_fishingItems = ["MeleeFishingPole"]; + DZE_maintainRange = (DZE_PlotPole select 0) + 0.1; // Default: maintain building objects within plot radius + 0.1 meters. + DZE_modularDoors = ["Land_DZE_WoodDoor","Land_DZE_LargeWoodDoor","Land_DZE_GarageWoodDoor","CinderWallDoor_DZ","CinderWallDoorSmall_DZ","WoodenGate_foundation_DZ","WoodenGate_1_DZ","WoodenGate_2_DZ","WoodenGate_3_DZ","WoodenGate_4_DZ","Land_DZE_WoodGate","Land_DZE_WoodOpenTopGarageDoor","CinderGate_DZ","CinderGarageOpenTop_DZ","CinderDoorHatch_DZ","Door_DZ","Concrete_Bunker_DZ","Metal_Drawbridge_DZ"]; + DZE_refundStorageItemContents = ["GunRack_DZ","GunRack2_DZ","WoodCrate_DZ","WoodCrate2_DZ","StorageCrate_DZ","CamoStorageCrate_DZ","OutHouse_DZ","StorageShed_DZ","StorageShed2_DZ","Wooden_shed_DZ","Wooden_shed2_DZ","WoodShack_DZ","WoodShack2_DZ","Advanced_WorkBench_DZ","StashSmall","StashSmall1","StashSmall2","StashSmall3","StashSmall4","StashMedium","StashMedium1","StashMedium2","StashMedium3","StashMedium4","Generator_DZ","M240Nest_DZ","CookTripod_DZ","Stoneoven_DZ","Commode_DZ","Wardrobe_DZ","Fridge_DZ","Washing_Machine_DZ","Server_Rack_DZ","ATM_DZ","Armchair_DZ","Sofa_DZ","Arcade_DZ","Vendmachine1_DZ","Vendmachine2_DZ"]; // array of non-lockable storage objects that will refund their contents when the object is removed + + // Helper Colors Require Reformatting + DZE_NoRefundTexture = [0, format["#(argb,8,8,3)color(1,0,0,%1,ca)", (DZE_NoRefundTransparency max 0.1)] ]; // red + DZE_removeTexture = [0, format["#(argb,8,8,3)color(0,1,0,%1,ca)", (DZE_removeTransparency max 0.1)] ]; // green + DZE_deconstructTexture = [0, format["#(argb,8,8,3)color(0,0,1,%1,ca)", (DZE_deconstructTransparency max 0.1)] ]; // blue + DZE_plotRed = [0, format["#(argb,8,8,3)color(1,0,0,%1,ca)", (DZE_plotRedTransparency max 0.1)] ]; // red + DZE_plotGreen = [0, format["#(argb,8,8,3)color(0,1,0,%1,ca)", (DZE_plotGreenTransparency max 0.1)] ]; // green + snapGizmos = []; // may not need this snapGizmosNearby = []; // may not need this diff --git a/SQF/dayz_code/stringtable.xml b/SQF/dayz_code/stringtable.xml index a119f7819..ee1441295 100644 --- a/SQF/dayz_code/stringtable.xml +++ b/SQF/dayz_code/stringtable.xml @@ -34838,6 +34838,27 @@ Zombifiziertes Huhn Зомбированная курица + + Deconstruct %1 + Деконструировать %1 + Deconstruir %1 + Dekonstruovat %1 + Déconstruire %1 + %1 abbauen + Deconstrueren %1 + + + You moved too far! + Du hast dich zu weit weg bewegt! + + + Object moved too far! + Objekt zu weit weg! + + + You moved too fast! + Du hast dich zu schnell bewegt! +