package Builder import Entity import ClosureTimers import public BuilderConstants import public GameConstants import initlater RegionData import Key import initlater InstantBuild import Tome import JukeBox import initlater Boss import Boots import initlater BossDamager import Coin import ChannelAbilityPreset public constant BUILDER_CIRCLES_ID = compiletime(UNIT_ID_GEN.next()) public constant BUILDER_OBJECTS_ID = compiletime(UNIT_ID_GEN.next()) public constant BUILDER_ENVIROMENTAL_ID = compiletime(UNIT_ID_GEN.next()) public constant BUILDER_DECORATIONS_ID = compiletime(UNIT_ID_GEN.next()) public constant MENU_CIRCLES_ID = compiletime(ABIL_ID_GEN.next()) public constant MENU_OBJECTS_ID = compiletime(ABIL_ID_GEN.next()) public constant MENU_ENVIROMENTALS_ID = compiletime(ABIL_ID_GEN.next()) public constant MENU_DECORATIONS_ID = compiletime(ABIL_ID_GEN.next()) constant CHAOS_BUILDER_1 = compiletime(ABIL_ID_GEN.next()) constant CHAOS_BUILDER_2 = compiletime(ABIL_ID_GEN.next()) constant CHAOS_BUILDER_3 = compiletime(ABIL_ID_GEN.next()) constant CHAOS_BUILDER_4 = compiletime(ABIL_ID_GEN.next()) /** The builder (banshee) class. Handles switching between builders, auto teleport and all other builder functions. */ public class Builder extends UnitEntity int regionCount = 0 boolean hasBossMenu = false construct(player p) super(createUnit(p, BUILDER_CIRCLES_ID, vec2(-6000, -7160), angle(0))) registerListeners() this.setCurrentRegion() function registerListeners() EventListener.add(actor, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, () -> onOrder()) EventListener.add(actor, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, () -> onOrder()) EventListener.add(actor, EVENT_PLAYER_UNIT_SPELL_CAST, () -> onCast()) EventListener.add(actor, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, () -> GetTriggerUnit().remove()) function onCast() let id = GetSpellAbilityId() let tpos = EventData.getSpellTargetPos() let rdata = getRegionData(tpos) if rdata == null return switch id case MENU_CIRCLES_ID actor.addAbility(CHAOS_BUILDER_1) case MENU_2 actor.addAbility(CHAOS_BUILDER_2) case MENU_3 actor.addAbility(CHAOS_BUILDER_3) case MENU_DECORATIONS_ID actor.addAbility(CHAOS_BUILDER_4) case MENU_OBJECTS_ID actor.addAbility(CHAOS_BUILDER_2) case MENU_ENVIROMENTALS_ID actor.addAbility(CHAOS_BUILDER_3) case KEY_SPELL_ID if rdata.canBuild(owner) new Key(tpos, owner) else DisplayTextToPlayer(owner, 0, 0, "|cffC51019You have no permission to place items in this region!") case BOOTS_SPELL_ID if rdata.canBuild(owner) new Boots(tpos, owner) else DisplayTextToPlayer(owner, 0, 0, "|cffC51019You have no permission to place items in this region!") case TOME_SPELL_ID if rdata.canBuild(owner) new Tome(tpos, owner) else DisplayTextToPlayer(owner, 0, 0, "|cffC51019You have no permission to place items in this region!") case COIN_SPELL_ID if rdata.canBuild(owner) new Coin(tpos, owner) else DisplayTextToPlayer(owner, 0, 0, "|cffC51019You have no permission to place items in this region!") case BM_BOSS_ID if rdata.canBuild(owner) and rdata.bossRegion if rdata.boss == null rdata.boss = new Boss(owner, tpos, rdata.getTypeSet().bossId) else DisplayTextToPlayer(owner, 0, 0, "|cffC51019You can only have one boss each region!") else DisplayTextToPlayer(owner, 0, 0, "|cffC51019You are not allowed to place Boss objects in this region!") case BM_SPELLTARGET_ID if rdata.canBuild(owner) and rdata.bossRegion new SpellTarget(tpos, owner) case BM_DAMAGER_ID if rdata.canBuild(owner) and rdata.bossRegion new BossDamager(tpos, owner) case BM_WEAPON_ID if getRegionData(tpos).canBuild(owner) and getRegionData(tpos).bossRegion skip // TODO? // new WeaponObject(tpos, owner) default jukeBox.checkSpell(id) function setBossMenu() hasBossMenu = true actor.addAbility(MENU_BOSS) function onOrder() let i = GetOrderTargetItem() let u = GetOrderTargetUnit() var orderPos = EventData.getOrderPos() if i != null orderPos = i.getPos() else if u != null orderPos = u.getPos() let rdata = getRegionData(orderPos) if rdata != RegionData.EMPTY_REGION and (rdata.getTypeSet() == RegionType.UNKNOWN.getTypeSet() or rdata.canBuild(owner) or rdata.theRect == gg_rct_Start) if i != null and rdata.canBuild(owner) if i.getEntity() != null Log.debug("Builder Terminate") i.getEntity().terminate() else RemoveItem(i) actor.abortOrder() else let orderId = GetIssuedOrderId() if isOrderBuildOrder(orderId) doAfter(0.01, () -> instantBuild(this, orderPos, orderId)) actor.abortOrder() else if OrderId2String(orderId) == "smart" or OrderId2String(orderId) == "move" setPos(orderPos.toVec3()) else actor.abortOrder() function filter() returns boolean return GetUnitTypeId(GetFilterUnit()) == REGION_ADMIN_ID function isBuilderUnit() returns boolean let id = GetUnitTypeId(GetTriggerUnit()) return id == BUILDER_CIRCLES_ID or id == BUILDER_OBJECTS_ID or id == BUILDER_ENVIROMENTAL_ID or id == BUILDER_DECORATIONS_ID @objectgen function genBuilder() new AbilityDefinitionTankUpgrade(CHAOS_BUILDER_1) ..setRequirements("") ..setNewUnitType(1, (BUILDER_CIRCLES_ID).toRawCode()) new AbilityDefinitionTankUpgrade(CHAOS_BUILDER_2) ..setRequirements("") ..setNewUnitType(1, (BUILDER_OBJECTS_ID).toRawCode()) new AbilityDefinitionTankUpgrade(CHAOS_BUILDER_3) ..setRequirements("") ..setNewUnitType(1, (BUILDER_ENVIROMENTAL_ID).toRawCode()) new AbilityDefinitionTankUpgrade(CHAOS_BUILDER_4) ..setRequirements("") ..setNewUnitType(1, (BUILDER_DECORATIONS_ID).toRawCode()) new ChannelAbilityPreset(MENU_CIRCLES_ID, 1, TRUE) ..setName("Builder: Menu: Circles") ..presetTooltipNormal(lvl -> "Menu: Circles [|cffFFCC00W|r]") ..presetTooltipNormalExtended(lvl -> "Swap to the Buildingmenu for circles.") ..presetIcon("ReplaceableTextures\\CommandButtons\\BTNCOP.blp") ..presetButtonPosNormal(1, 2) ..presetHotkey("W") ..presetTargetTypes(Targettype.NONE) ..setHeroAbility(FALSE) new ChannelAbilityPreset(MENU_OBJECTS_ID, 1, TRUE) ..setName("Builder: Menu: Objects") ..presetTooltipNormal(lvl -> "Menu: Objects [|cffFFCC00E|r]") ..presetTooltipNormalExtended(lvl -> "Swap to the Buildingmenu for objects.") ..presetIcon("ReplaceableTextures\\CommandButtons\\BTNPackBeast.blp") ..presetButtonPosNormal(2, 2) ..presetHotkey("E") ..presetTargetTypes(Targettype.NONE) ..setHeroAbility(FALSE) new ChannelAbilityPreset(MENU_ENVIROMENTALS_ID, 1, TRUE) ..setName("Builder: Menu: Enviromental") ..presetTooltipNormal(lvl -> "Menu: Enviromental [|cffFFCC00R|r]") ..presetTooltipNormalExtended(lvl -> "Swap to the Buildingmenu for enviromental stuff.") ..presetIcon("ReplaceableTextures\\CommandButtons\\BTNEditor-MultipleDoodads.blp") ..presetButtonPosNormal(3, 2) ..presetHotkey("R") ..presetTargetTypes(Targettype.NONE) ..setHeroAbility(FALSE) new ChannelAbilityPreset(MENU_DECORATIONS_ID, 1, TRUE) ..setName("Builder: Menu: Decorations") ..presetTooltipNormal(lvl -> "Menu: Decorations [|cffFFCC00F|r]") ..presetTooltipNormalExtended(lvl -> "Swap to the Buildingmenu for decorations.") ..presetIcon("ReplaceableTextures\\CommandButtons\\BTNBrilliance.blp") ..presetButtonPosNormal(2, 1) ..presetHotkey("F") ..presetTargetTypes(Targettype.NONE) ..setHeroAbility(FALSE) new UnitDefinition(BUILDER_CIRCLES_ID, 'uaco') ..setName("|cFF0080FFBuilder 1|r |cffFFAD29Circles") ..setHotkey("") ..setTooltipBasic("") ..setTooltipExtended("") ..setIconGameInterface("ReplaceableTextures\\CommandButtons\\BTNEditor-MultipleDoodads.blp") ..setNormalAbilities(commaList('A03C', MENU_CIRCLES_ID, MENU_OBJECTS_ID, MENU_ENVIROMENTALS_ID, MENU_DECORATIONS_ID, GHOST_VIS_ID, INVULNERABILITY_ID)) ..setStructuresBuilt(commaList(BOOSTER_ID, TELEPORTER_ID, JUMPER_ID, REVIVE_POINT_ID, UNIT_CREATOR_ID, TC_BLOCKER_ID, UNIT_REMOVER_ID, WAYPOINT_ID, TEXTER_ID, TRAP_ID, EXECUTER_ID)) ..setButtonPositionX(0) ..setButtonPositionY(0) ..setSightRadiusDay(300) ..setSightRadiusNight(300) ..setBuildTime(1) ..setAttacksEnabled(0) ..setTargetedAs("air") ..setDefenseUpgradeBonus(0) ..setDeathType(0) ..setAnimationBlendTimeseconds(0) ..setAnimationCastBackswing(0) ..setAnimationCastPoint(0) ..setModelFile("units\\undead\\Banshee\\Banshee.mdl") ..setSpeedBase(1000) ..setTurnRate(1) ..setMovementType(MovementType.Fly) ..setUnitSoundSet("Sorceress") ..setCanDropItemsOnDeath(FALSE) ..setUpgradesUsed("") ..setBuildTime(1) ..setRepairTime(1) ..setUnitClassification("peon") ..setHitPointsMaximumBase(100000000) ..setHitPointsRegenerationRate(0) ..setHitPointsRegenerationType("none") ..setGoldCost(0) ..setRepairGoldCost(0) ..setHideMinimapDisplay(true) new UnitDefinition(BUILDER_OBJECTS_ID, 'uaco') ..setName("|cFF0080FFBuilder 2|r |cffFFAD29Objects") ..setHotkey("") ..setTooltipBasic("") ..setTooltipExtended("") ..setIconGameInterface("ReplaceableTextures\\CommandButtons\\BTNEditor-MultipleDoodads.blp") ..setNormalAbilities(commaList('A03C', MENU_CIRCLES_ID, MENU_OBJECTS_ID, MENU_ENVIROMENTALS_ID, MENU_DECORATIONS_ID, GHOST_VIS_ID, INVULNERABILITY_ID)) ..setStructuresBuilt(commaList(BOMB_TOWER_ID, VORTEX_ID, CONGA_LINE_HEAD_ID, POWER_NODE_ID, FOUNTAIN_BOTH_ID, BUILD_TRACKS_ID, SPINNER_ID, DOORDUMMY_ID, ARCANERY_ID, PED_ID)) ..setButtonPositionX(0) ..setButtonPositionY(0) ..setSightRadiusDay(300) ..setSightRadiusNight(300) ..setBuildTime(1) ..setAttacksEnabled(0) ..setTargetedAs("air") ..setDefenseUpgradeBonus(0) ..setDeathType(0) ..setAnimationBlendTimeseconds(0) ..setAnimationCastBackswing(0) ..setAnimationCastPoint(0) ..setModelFile("units\\undead\\Banshee\\Banshee.mdl") ..setSpeedBase(1000) ..setTurnRate(1) ..setMovementType(MovementType.Fly) ..setUnitSoundSet("Sorceress") ..setCanDropItemsOnDeath(FALSE) ..setUpgradesUsed("") ..setBuildTime(1) ..setRepairTime(1) ..setUnitClassification("peon") ..setHitPointsMaximumBase(100000000) ..setHitPointsRegenerationRate(0) ..setHitPointsRegenerationType("none") ..setGoldCost(0) ..setRepairGoldCost(0) ..setHideMinimapDisplay(true) new UnitDefinition(BUILDER_ENVIROMENTAL_ID, 'uaco') ..setName("|cFF0080FFBuilder 3|r |cffFFAD29Enviromental") ..setHotkey("") ..setTooltipBasic("") ..setTooltipExtended("") ..setIconGameInterface("ReplaceableTextures\\CommandButtons\\BTNEditor-MultipleDoodads.blp") ..setNormalAbilities(commaList('A03C', MENU_CIRCLES_ID, MENU_OBJECTS_ID, MENU_ENVIROMENTALS_ID, MENU_DECORATIONS_ID, GHOST_VIS_ID, INVULNERABILITY_ID)) ..setStructuresBuilt(commaList(VOLCANO_ID, WALL_ID, VER_WALL_ID, HOR_WALL_ID, SOBS_DUMMY_ID, BOBS_DUMMY_ID, HOBS_DUMMY_ID, TREE_DUMMY_ID)) ..setButtonPositionX(0) ..setButtonPositionY(0) ..setSightRadiusDay(300) ..setSightRadiusNight(300) ..setBuildTime(1) ..setAttacksEnabled(0) ..setTargetedAs("air") ..setDefenseUpgradeBonus(0) ..setDeathType(0) ..setAnimationBlendTimeseconds(0) ..setAnimationCastBackswing(0) ..setAnimationCastPoint(0) ..setModelFile("units\\undead\\Banshee\\Banshee.mdl") ..setSpeedBase(1000) ..setTurnRate(1) ..setMovementType(MovementType.Fly) ..setUnitSoundSet("Sorceress") ..setCanDropItemsOnDeath(FALSE) ..setUpgradesUsed("") ..setBuildTime(1) ..setRepairTime(1) ..setUnitClassification("peon") ..setHitPointsMaximumBase(100000000) ..setHitPointsRegenerationRate(0) ..setHitPointsRegenerationType("none") ..setGoldCost(0) ..setRepairGoldCost(0) ..setHideMinimapDisplay(true) new UnitDefinition(BUILDER_DECORATIONS_ID, 'uaco') ..setName("|cFF0080FFBuilder 4|r |cffFFAD29Decorations") ..setHotkey("") ..setTooltipBasic("") ..setTooltipExtended("") ..setIconGameInterface("ReplaceableTextures\\CommandButtons\\BTNEditor-MultipleDoodads.blp") ..setNormalAbilities(commaList('A03C', MENU_CIRCLES_ID, MENU_OBJECTS_ID, MENU_ENVIROMENTALS_ID, MENU_DECORATIONS_ID, GHOST_VIS_ID, INVULNERABILITY_ID)) ..setStructuresBuilt(commaList(REMAINS_ID, FARM_ID, ICE_CRYSTAL_ID, OBELISK_ID, POISON_EGGS_ID, LANTERN_ID, MUSHROOM_ID, POST_LANTERN_ID, RUNE_ID, TORCH_ID, SUPERLIGHT_ID)) ..setButtonPositionX(0) ..setButtonPositionY(0) ..setSightRadiusDay(300) ..setSightRadiusNight(300) ..setBuildTime(1) ..setAttacksEnabled(0) ..setTargetedAs("air") ..setDefenseUpgradeBonus(0) ..setDeathType(0) ..setAnimationBlendTimeseconds(0) ..setAnimationCastBackswing(0) ..setAnimationCastPoint(0) ..setModelFile("units\\undead\\Banshee\\Banshee.mdl") ..setSpeedBase(1000) ..setTurnRate(1) ..setMovementType(MovementType.Fly) ..setUnitSoundSet("Sorceress") ..setCanDropItemsOnDeath(FALSE) ..setUpgradesUsed("") ..setBuildTime(1) ..setRepairTime(1) ..setUnitClassification("peon") ..setHitPointsMaximumBase(100000000) ..setHitPointsRegenerationRate(0) ..setHitPointsRegenerationType("none") ..setGoldCost(0) ..setRepairGoldCost(0) ..setHideMinimapDisplay(true)