import 'package:wolf_dart/classes/cardinal_direction.dart'; import 'package:wolf_dart/features/difficulty/difficulty.dart'; abstract class MapObject { // --- Player Spawns --- static const int playerNorth = 19; static const int playerEast = 20; static const int playerSouth = 21; static const int playerWest = 22; // --- Static Decorations --- static const int waterPuddle = 23; static const int greenBarrel = 24; static const int chairTable = 25; static const int floorLamp = 26; static const int chandelier = 27; static const int hangingSkeleton = 28; static const int dogFoodDecoration = 29; static const int whiteColumn = 30; static const int pottedPlant = 31; static const int blueSkeleton = 32; static const int vent = 33; static const int kitchenCans = 34; static const int exitSign = 35; static const int brownPlant = 36; static const int bowl = 37; static const int armoredSuit = 38; static const int emptyCage = 39; static const int cageWithSkeleton = 40; static const int bones = 41; static const int goldenKeyBowl = 42; // --- Collectibles --- static const int goldKey = 43; static const int silverKey = 44; static const int bed = 45; static const int basket = 46; static const int food = 47; static const int medkit = 48; static const int ammoClip = 49; static const int machineGun = 50; static const int chainGun = 51; static const int cross = 52; static const int chalice = 53; static const int chest = 54; static const int crown = 55; static const int extraLife = 56; // --- Environmental --- static const int bloodPoolSmall = 57; static const int barrel = 58; static const int wellFull = 59; static const int wellEmpty = 60; static const int bloodPoolLarge = 61; static const int flag = 62; static const int aardwolfSign = 63; static const int bonesAndSkull = 64; static const int wallHanging = 65; static const int stove = 66; static const int spearRack = 67; static const int vines = 68; // --- Logic & Triggers --- static const int pushwallTrigger = 98; static const int secretExitTrigger = 99; static const int normalExitTrigger = 100; // Bosses (Shared between WL1 and WL6) static const int bossHansGrosse = 214; // WL6 Exclusive Bosses static const int bossDrSchabbs = 215; static const int bossTransGrosse = 216; static const int bossUbermutant = 217; static const int bossDeathKnight = 218; static const int bossMechaHitler = 219; static const int bossHitlerGhost = 220; static const int bossGretelGrosse = 221; static const int bossGiftmacher = 222; static const int bossFettgesicht = 223; // --- Enemy Range Constants --- static const int guardStart = 108; // 108-143 static const int officerStart = 144; // 144-179 (WL6) static const int ssStart = 180; // 180-215 (WL6) static const int dogStart = 216; // 216-251 static const int mutantStart = 252; // 252-287 (WL6) // --- Missing Decorative Bodies --- static const int deadGuard = 124; // Decorative only in WL1 static const int deadAardwolf = 125; // Decorative only in WL1 /// Returns true if the object ID exists in the Shareware version. /// Returns true if the object ID exists in the Shareware version. static bool isSharewareCompatible(int id) { // Standard Decorations & Collectibles if (id <= vines) return true; // Logic Triggers (Exits/Pushwalls) if (id >= pushwallTrigger && id <= normalExitTrigger) return true; // Guards (108-143 includes dead bodies at 124/125) if (id >= guardStart && id < officerStart) return true; // Dogs (216-251) - These ARE in Shareware! if (id >= dogStart && id < mutantStart) return true; // Episode 1 Boss if (id == bossHansGrosse) return true; return false; } static double getAngle(int id) { switch (id) { case playerNorth: return CardinalDirection.north.radians; case playerEast: return CardinalDirection.east.radians; case playerSouth: return CardinalDirection.south.radians; case playerWest: return CardinalDirection.west.radians; } // FIX: Expand the boundary to include ALL enemies (Dogs and Mutants) if (id < guardStart || id > (mutantStart + 35)) return 0.0; int baseId; if (id >= mutantStart) { baseId = mutantStart; } else if (id >= dogStart) { baseId = dogStart; } else if (id >= ssStart) { baseId = ssStart; } else if (id >= officerStart) { baseId = officerStart; } else { baseId = guardStart; } // FIX: Normalize patrolling enemies back to the standing block, THEN get the 4-way angle int directionIndex = ((id - baseId) % 18) % 4; return CardinalDirection.fromEnemyIndex(directionIndex).radians; } static bool shouldSpawn(int id, Difficulty selectedDifficulty) { // FIX: Expand the boundary so Dogs and Mutants aren't bypassing difficulty checks if (id < guardStart || id > (mutantStart + 35)) return true; int baseId; if (id >= mutantStart) { baseId = mutantStart; } else if (id >= dogStart) { baseId = dogStart; } else if (id >= ssStart) { baseId = ssStart; } else if (id >= officerStart) { baseId = officerStart; } else { baseId = guardStart; } int relativeId = (id - baseId) % 18; return switch (relativeId) { < 4 => true, < 8 => selectedDifficulty.level >= Difficulty.dontHurtMe.level, < 12 => selectedDifficulty.level >= Difficulty.bringEmOn.level, < 16 => selectedDifficulty.level >= Difficulty.iAmDeathIncarnate.level, _ => true, }; } }