Arcing Loot

This bundle is marked as pending. It has not been reviewed by a staff member yet.

GIF by @Killcide

Based on Zephyr Contest #14 - Unique Summoning along with ArcingLoot which I wrote in Zinc a few years back.

Uses my Recipe system and ArcingTextTag by Maker, converted to wurst by me.

Put items in the cauldron and press esc to make it it spit out a crafted item!​

package ArcingLoot

import LinkedListModule
import TimerUtils
import Fx

constant real arc          = 75 //modifies the  arcing shape
constant real arcHeight    = 350 //how high the arc reach at its peak
constant real travelTime   = 0.9 //time it takes for the arc to reach destination
constant real convertArc   = arc / 100.00 // do not touch 
constant string sfx        = "Objects\\InventoryItems\\TreasureChest\\treasurechest.mdl" //effect, the item chest in this case
constant real loopSpeed    = 0.03 //how often the system runs its loop. Higher value equals better perfomance

constant location loc = Location(0,0)

function vec2.getZ() returns real
    MoveLocation(loc, this.x, this.y)
    return GetLocationZ(loc)

public class ArcingItem
    use LinkedListModule

    static timer t

    integer id

    Fx fx
    angle angle

    real distance
    real maxDistance
    real arc
    real speed

    effect e

    vec2 pos
    vec2 destination
    construct(integer itemId, vec2 start, vec2 dest)
        pos          = start
        fx           = new Fx(pos, angle(0), sfx)
        angle        = pos.angleTo(dest)
        distance     = pos.distanceTo(dest)
        maxDistance  = distance
        speed        = distance / (travelTime / loopSpeed)
        destination  = dest
        arc          = distance * convertArc

        id           = itemId

        e = fx.getDummy().addEffect("Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdl", "chest")

        if(t == null)
            ..startPeriodic(loopSpeed, function ArcingItem.onLoop)

    static function onLoop()
        thistype current = ArcingItem.first
        while(current != null)
            current =
    function update()
        pos.x = pos.x + speed * Cos(angle.radians)
        pos.y = pos.y + speed * Sin(angle.radians)

        distance = pos.distanceTo(destination)

        real one     = (4.00 * arc) / maxDistance
        real two     = maxDistance - distance
        real three   = distance / maxDistance
        real four    = pos.getZ()

        real height  = (one * two * three) + (four)

        fx.getDummy().setPosFly(vec3(pos.x, pos.y, height))
        if(height <= 0)
            createItem(id, pos)
            destroy fx
            destroy this

package ArcingText

import LinkedListModule
import TimerUtils

// Arcing Text Tag v1.0.0.3 by Maker
// Converted to wurst by Chaosy

constant    real    SIZE_MIN        = 0.018         // Minimum size of text
constant    real    SIZE_BONUS      = 0.012         // Text size increase
constant    real    TIME_LIFE       = 1.0           // How long the text lasts
constant    real    TIME_FADE       = 0.8           // When does the text start to fade
constant    real    Z_OFFSET        = 50            // Height above unit
constant    real    Z_OFFSET_BON    = 50            // How much extra height the text gains
constant    real    VELOCITY        = 2             // How fast the text move in x/y plane

timer   TMR            = getTimer()

public class ArcingTextTag
    use LinkedListModule

    private texttag tt
    private real as         // angle, sin component
    private real ac         // angle, cos component
    private real ah         // arc height
    private real t          // time
    private vec3 pos
    private string s        // text

    private function update()
        real p
        p = Sin(bj_PI * t)
        t = t - 0.03125
        pos.x = pos.x + ac
        pos.y = pos.y + as
        pos.z = Z_OFFSET + Z_OFFSET_BON * p
        tt.setText(s, (SIZE_MIN + SIZE_BONUS * p) * 434.78)
        if t <= 0
            destroy this
            if == null
    private static function onLoop()
        thistype current = ArcingTextTag.first
        while(current != null)
            current =

    construct(string msg, unit u)
        real a = GetRandomReal(0, 2*bj_PI)

        s = msg
        pos.x = GetUnitX(u)
        pos.y = GetUnitY(u)
        t = TIME_LIFE
        as = Sin(a) * VELOCITY
        ac = Cos(a) * VELOCITY
        ah = 0.
        if IsUnitVisible(u, GetLocalPlayer())
            tt = CreateTextTag()
            ..setText(s, SIZE_MIN)

        if ArcingTextTag.first == this
            TMR.startPeriodic(0.03125, function ArcingTextTag.onLoop)


package demo

import ObjectIdGenerator
import ChannelAbilityPreset
import UnitObjEditing
import ObjectIds

import Crafting
import ArcingLoot
import ArcingText

string onCraftEffect = "Abilities\\Spells\\Other\\Transmute\\GoldBottleMissile.mdl"

integer testUnit = compiletime(

@compiletime function generate()
    new UnitDefinition(testUnit, 'hkni')
    ..setName("Witch's Cauldron")

unit cauldron

constant string yellow = "|c00FFFF00"
constant string blue   = "|c007EBFF1"

    // Create recipe and add components
    new ItemRecipe('shar')
    ..addComponent('whwd', 2)
    ..addComponent('pghe', 1)
    ..addComponent('phlt', 1)

    // Crafting Demo
    cauldron = createUnit(players[0], testUnit, vec2(0, 0), angle(0))
    createUnit(players[0], 'Hpal', vec2(0, 0), angle(0))
    // try to craft on esc press

    ..registerPlayerEvent(players[0], EVENT_PLAYER_END_CINEMATIC)
    ..addAction() ->
        new ArcingTextTag("|c007EBFF1" + GetUnitName(cauldron) + "|r is Crafting", cauldron)
            addEffect(onCraftEffect, cauldron.getPos()).destr()
            let recipes = cauldron.craft()
            for r in recipes
                let id = r.craftable
                new ArcingItem(id, cauldron.getPos(), cauldron.getPos().polarOffset(angle(GetRandomDirectionDeg()), GetRandomReal(200, 400)))
        print("No more items can be crafted")

    ..addAction() ->
        if(GetManipulatingUnit() == cauldron)
            item i = GetManipulatedItem()
            new ArcingTextTag(blue + "Added: " + yellow + i.getName(), cauldron)

Arcing Loot (Map)




Oh this is so sweet... flying coins and items. Gonna test!