Ahorn Scripts - EverestAPI/Resources GitHub Wiki

⚠️ Using any Ahorn scripts might break your map if you're not careful! Remember to take a backup of your map before running anything.

Table of Contents

Enabling the Debug console

By default you will not be able to open the debug console. To enable it open ahorn and go to Edit -> Settings -> Debug, and check Debug menu dropdown. A debug dropdown will become available, with opening the console being one of its options.

Directories and Assets

Change Map Package Name

loadedState.map.package = "abc"

Change the Directory of all BG Decals

for room in loadedState.side.map.rooms
    for bgdecal in room.bgDecals
        bgdecal.texture = replace(bgdecal.texture, "OldFolderName" => "NewFolderName")
    end
end

Change the Directory of all FG Decals

for room in loadedState.side.map.rooms
    for bgdecal in room.bgDecals
        bgdecal.texture = replace(bgdecal.texture, "OldFolderName" => "NewFolderName")
    end
end

Copy Stylegrounds

m = loadMap("AbsolutePathToYour.bin")
fg = deepcopy(m.style.foregrounds)
bg = deepcopy(m.style.backgrounds)
append!(loadedState.map.style.foregrounds, fg)
append!(loadedState.map.style.backgrounds, bg)
return true

Spinners

Change Settings of all Frost Helper Spinners

for room in loadedState.side.map.rooms
	for entity in room.entities
		if entity.name == "FrostHelper/IceSpinner"
			entity.data["directory"] = "danger/FrostHelper/icecrystal", # change to what you want
                        entity.data["spritePathSuffix"] = "", # change to what you want
                        entity.data["destroyColor"] = "b0eaff", # change to what you want
                        entity.data["tint"] = "ffffff", # change to what you want
                        entity.data["bloomAlpha"] = 0.0, # change to what you want
                        entity.data["bloomRadius"] = 0.0, # change to what you want
                        entity.data["moveWithWind"] = false, # change to what you want
                        entity.data["dashThrough"] = false, # change to what you want
                        entity.data["rainbow"] = false, # change to what you want
			entity.data["collidable"] = true # change to what you want
		end
	end
end

Convert all Vanilla Spinners to Frost Helper Spinners

for room in loadedState.side.map.rooms
	for entity in room.entities
		if entity.name == "spinner"
			# create new spinner copying the old one
			newSpinner = Entity("FrostHelper/IceSpinner", Dict{String,Any}(
				"x" => entity.data["x"],
				"y" => entity.data["y"],
				"attachToSolid" => entity.data["attachToSolid"],
				"destroyColor" => "b0eaff", # change to what you want
				"directory" => "danger/FrostHelper/icecrystal", # change to what you want
                                "spritePathSuffix" => "", # change to what you want
				"tint" => "ffffff", # change to what you want
				"moveWithWind" => false, # change to what you want
				"dashThrough" => false, # change to what you want
				"bloomAlpha" => 0.0, # change to what you want
				"bloomRadius" => 0.0, # change to what you want
                                "rainbow" => false, # change to what you want
				"collidable" => true, # change to what you want
			), entity.id)
			push!(room.entities, newSpinner)
		end
	end
	
	# remove all vanilla spinners
	filter!(entity -> entity.name != "spinner", room.entities)
end

Change Frost Helper Spinners to Vanilla Spinners

for room in loadedState.side.map.rooms
	for entity in room.entities
		if entity.name == "FrostHelper/IceSpinner"
			# create new spinner copying the old one
			newSpinner = Entity("spinner", Dict{String,Any}(
				"x" => entity.data["x"],
				"y" => entity.data["y"],
                                "attachToSolid" => entity.data["attachToSolid"],
				"color" => "Blue", # change to what you want - can be Blue,Red,Purple,Rainbow
				"dust" => false, # change to what you want
			), entity.id)
			push!(room.entities, newSpinner)
		end
	end
	
	# remove all Custom Spinners
	filter!(entity -> entity.name != "FrostHelper/IceSpinner", room.entities)
end

Rooms

Copy a Room from Another Map

m = loadMap("AbsolutePathToYour.bin")
roomName = "lvl_a-00"
room = getRoomByName(m, roomName)
push!(loadedState.map.rooms, room)
updateTreeView!(roomList, getTreeData(loadedState.map))
return true

Copy Room Within the Current Map

roomName = "1"
room = getRoomByName(loadedState.map, roomName)
roomcopy = deepcopy(room)
roomcopy.name = "1-copy"
roomcopy.position = roomcopy.position .+ (200,200)
push!(loadedState.map.rooms, roomcopy)
updateTreeView!(roomList, getTreeData(loadedState.map))
return true

Remove all Vanilla Filler Rooms

empty!(loadedState.map.fillers)

Change Rooms Coordinates

for room in Ahorn.loadedState.map.rooms
    room.position = room.position .+ (0, 500)
end

updateTreeView!(roomList, getTreeData(loadedState.map))

Change Rooms Color

for room in Ahorn.loadedState.map.rooms
    room.color = 0
end

updateTreeView!(roomList, getTreeData(loadedState.map))

Print Rooms List

println.(getfield.(Ahorn.loadedState.map.rooms, :name))

Credit to orbittwz, JaThePlayer, and coloursofnoise for the wonderful scripts.


>_ The Julia Terminal

The following scripts are designed to be run directly in the Julia terminal, not the Ahorn debug console.
Most of these are not complete scripts, but snippets designed to pasted into the terminal in the desired sequence. A baseline knowledge of programming is highly recommended.

To write your own scripts, reference the Maple Source :link:.

Setup

In order to use Maple from any Julia terminal, it needs to be added to the global package scope:

julia> using Pkg
julia> Pkg.add(PackageSpec(url="https://github.com/CelestialCartographers/Maple.git"))

From then on, enter using Maple in every new terminal session to import and use the Maple package.

General Snippets

Change current working folder

cd("pathToNewFolder")
pwd() # Pring Working Directory

Load and Save a Map

side = loadSide("filePath")
map = side.map
encodeSide(side, "filePath")

Iterate through all map files in the current folder

for file in filter(f -> endswith(f, ".bin"), readdir("."))
	# do stuff
end

Map Analysis

Get all unique decals

set = Set(Base.map(d -> d.texture, Iterators.flatten([[room.bgDecals;room.fgDecals] for room in map.rooms])))
# sort and output to a file
write("decals.txt", join(sort(collect(set)), "\n"))

Manipulations

Remove all decals matching a string

for room in map.rooms
	filter!(d -> !startswith(d.texture, "starting text", room.fgDecals)
	filter!(d -> !startswith(d.texture, "starting text", room.bgDecals)
end

startswith can be replaced with endswith or contains as appropriate.
Supports Regular Expressions :link: such as "any letter" (r"[a-zA-Z]").