package TerrainChanger import SetupObject import Preloader import ChannelAbilityPreset constant TERRAIN_CHANGER_ID = 'trrc' constant TERRAIN_O_WALKABLE_ID = 'A02G' constant TERRAIN_O_UNWALKABLE_ID = 'A02C' constant TERRAIN_O_ICE_ID = 'A02B' constant TERRAIN_O_UNICE_ID = 'A02E' constant TERRAIN_I_WALKABLE_ID = 'A02H' constant TERRAIN_I_UNWALKABLE_ID = 'A02F' constant TERRAIN_I_ICE_ID = 'A02A' constant TERRAIN_I_UNICE_ID = 'A02D' constant TERRAIN_INC_H_ID = 'A01K' constant TERRAIN_INC_V_ID = 'A01M' constant TERRAIN_DEC_H_ID = 'A01U' constant TERRAIN_DEC_V_ID = 'A01T' public class TerrainChanger extends SetupObject let sizeX = new ConfigValue(1, 1, "Width") let sizeY = new ConfigValue(1, 1, "Height") ebrtile currentTile var innerTile = '0000' var outerTile = '0001' construct(vec2 pos, player owner) super(createUnit(owner, TERRAIN_CHANGER_ID, pos, angle(0)), createUnit(owner, TERRAIN_CHANGER_ID, pos, angle(0)), 0) EventListener.add(setup, EVENT_PLAYER_UNIT_SPELL_CAST, () -> onCast()) currentTile = pos.getEBRTile() innerTile = this.getCurrentRegion().getTypeSet().walkableId outerTile = this.getCurrentRegion().getTypeSet().unwalkableId sleeps = false override function update() super.update() let rdata = getRegionData(pos) if not rdata.canBuild(owner) return int tileID let tX = (pos.x/128).round() let tY = (pos.y/128).round() if tX != currentTile.x or tY != currentTile.y let sizeXI = sizeX.getInt() let sizeYI = sizeY.getInt() // Clear old terrain var xoffset = 0 var yoffset = 0 if tX < currentTile.x xoffset = (sizeXI*2) for i = -(sizeYI) to sizeYI checkAndSetTile(rdata, tX+sizeXI+1, tY+i, outerTile) else if tX > currentTile.x xoffset = (-sizeXI*2) for i = -(sizeYI) to sizeYI checkAndSetTile(rdata, tX-sizeXI-1, tY+i, outerTile) if tY < currentTile.y yoffset = (sizeYI*2) for j = -(sizeXI) to sizeXI checkAndSetTile(rdata, tX+j, tY + sizeYI+1, outerTile) else if tY > currentTile.y yoffset = (-sizeYI*2) for j = -(sizeXI) to sizeXI checkAndSetTile(rdata, tX+j, tY - sizeYI-1, outerTile) if xoffset != 0 and yoffset != 0 checkAndSetTile(rdata, tX+xoffset, tY+yoffset, outerTile) // Make new currentTile = pos.getEBRTile() for i = -(sizeYI) to sizeYI for j = -(sizeXI) to sizeXI let stile = getTile(tX+j, tY+i) if not stile.hasModifier(TileModifier.BLOCK) tileID = innerTile stile.setType(tileID) function checkAndSetTile(RegionData rdata, int x, int y, int id) let tile = getTile(x, y) if not tile.hasModifier(TileModifier.BLOCK) let newP = vec2(x*128., y*128.) if rdata.theRect.contains(newP) tile.setType(id) function cleanArea() let tin = innerTile let tout = outerTile innerTile = this.getCurrentRegion().getTypeSet().unwalkableId outerTile = this.getCurrentRegion().getTypeSet().unwalkableId update() innerTile = tin outerTile = tout function onCast() let i = GetSpellAbilityId() switch i case TERRAIN_INC_H_ID sizeX.increment(this, 3) case TERRAIN_INC_V_ID sizeY.increment(this, 3) case TERRAIN_DEC_H_ID cleanArea() sizeX.decrement(this, 0) case TERRAIN_DEC_V_ID cleanArea() sizeY.decrement(this, 0) case TERRAIN_I_WALKABLE_ID innerTile = this.getCurrentRegion().getTypeSet().walkableId case TERRAIN_I_UNWALKABLE_ID innerTile = this.getCurrentRegion().getTypeSet().unwalkableId case TERRAIN_I_ICE_ID innerTile = CONTROLLABLEICE case TERRAIN_I_UNICE_ID innerTile = UNCONTROLLABLEICE case TERRAIN_O_WALKABLE_ID outerTile = this.getCurrentRegion().getTypeSet().walkableId case TERRAIN_O_UNWALKABLE_ID outerTile = this.getCurrentRegion().getTypeSet().unwalkableId case TERRAIN_O_ICE_ID outerTile = CONTROLLABLEICE case TERRAIN_O_UNICE_ID outerTile = UNCONTROLLABLEICE update() override function serialize() returns Json let json = super.serialize() json ..addProperty(new Property(KEY_TYPE, TC_INDEX.toString())) return json override function setEnabled(boolean b) ondestroy destroy sizeX destroy sizeY init preloadAbility(TERRAIN_O_WALKABLE_ID) preloadAbility(TERRAIN_O_UNWALKABLE_ID) preloadAbility(TERRAIN_O_ICE_ID) preloadAbility(TERRAIN_O_UNICE_ID) preloadAbility(TERRAIN_I_WALKABLE_ID) preloadAbility(TERRAIN_I_UNWALKABLE_ID) preloadAbility(TERRAIN_I_ICE_ID) preloadAbility(TERRAIN_I_UNICE_ID) preloadAbility(TERRAIN_INC_H_ID) preloadAbility(TERRAIN_INC_V_ID) preloadAbility(TERRAIN_DEC_H_ID) preloadAbility(TERRAIN_DEC_V_ID) @objectgen function genTerrainChanger() new UnitDefinition(TERRAIN_CHANGER_ID, 'nlv1') ..setAttacksEnabled(0) ..setTargetedAs("air") ..setAnimationBlendTimeseconds(0) ..setAnimationCastBackswing(0) ..setAnimationCastPoint(0) ..setScalingValue(0.6) ..setIconGameInterface("ReplaceableTextures\\CommandButtons\\BTNDragonHawk.blp") ..setModelFile("units\\human\\BloodElfDragonHawk\\BloodElfDragonHawk.mdl") ..setTintingColorBlue(185) ..setTintingColorGreen(95) ..setTintingColorRed(125) ..setSelectionScale(0.6) ..setUnitSoundSet("") ..setCollisionSize(0) ..setSpeedBase(180) ..setMovementHeight(16) ..setMovementHeightMinimum(16) ..setTurnRate(0.2) ..setNormalAbilities(commaList('A029', 'A01H', 'A08J', 'A01E', MAKE_UNIT_INVISIBLE_ID, REMOVE_OBJECT_ID, GHOST_VIS_ID, INVULNERABILITY_ID)) ..setName("|cff0894E6TerrainChanger") ..setTooltipBasic("Spawns a Terrainchanger at |cffFFCC00Rallypoint|r.|nIt is a fully configureable, " + "mobile unit which changes the regionspecific terrain below it.|nUse TC-Blockers (First Builder menu) to " + "create protected tiles.|n|n|cff5ABD4ADoes not kill Escapers") ..setHitPointsMaximumBase(100000000) ..setSightRadiusDay(0) ..setSightRadiusNight(0) ..setHideMinimapDisplay(true) ..setCategorizationSpecial(false) ..setRace(Race.Undead)