wurstscript / WurstScript

Programming language and toolkit to create Warcraft III Maps
https://wurstlang.org
Apache License 2.0
224 stars 30 forks source link

Compiletime variables #840

Closed nelloy-git closed 5 years ago

nelloy-git commented 5 years ago

Hi! Can you add opportunity to change variable (or/and constants) inside compiletime functions? For example in my unit stats control library i use spell book for hiding pissives. Library can get new unit parameter types thought config function. So number of passives to hide can be changed. I want count number of needed spell book in compiletime and do not generate extra ability id.

constant int param_books_count = 7
constant int array param_book_id = [compiletime (ABIL_ID_GEN.next()),
                                    compiletime (ABIL_ID_GEN.next()),
                                    compiletime (ABIL_ID_GEN.next()),
                                    compiletime (ABIL_ID_GEN.next()),
                                    compiletime (ABIL_ID_GEN.next()),
                                    compiletime (ABIL_ID_GEN.next()),
                                    compiletime (ABIL_ID_GEN.next())] 

public function hidePassives(LinkedList<string> list)
    if compiletime
        int used_books = list.size() div 11
        if (used_books > param_books_count)
            compileError("ParamBook error: Need more parameter books to hide " + list.size().toString() + " passives.")

        for i = 0 to used_books - 1    
            var book_list = new LinkedList<string>
            for j = 0 to 11
                book_list.push(list.pop())

            new AbilityDefinitionSpellBook (param_book_id[i])
                ..setLevels(1)
                ..setHeroAbility (false)
                ..setItemAbility (false)
                ..setMaximumSpells(1, 11)
                ..setBaseOrderID(1, order_factory.getOrderString(false))
                ..setSpellList(1, book_list.joinBy(","))
    else
        for i = 0 to param_books_count - 1
            preloadAbility(param_book_id[i])
            for j = 0 to bj_MAX_PLAYER_SLOTS - 1
                players[i].setAbilityAvailable(param_book_id[j], false)

function initType(ParameterType init_tmp, LinkedList<string> list_to_add_abils)
    init_tmp.initParamType()
    var used_abils = init_tmp.getUsedAbilities()
    list_to_add_abils.addAll(used_abils)
    destroy used_abils

/* Default configuration. */
@compiletime @configurable function initAllParameters()
    var all_used_abils = new LinkedList<string>

    initType(AttackSpeed.init_tmp, all_used_abils)
    initType(CriticalStrike.init_tmp, all_used_abils)
    initType(Dodge.init_tmp, all_used_abils)
    initType(MaxHealth.init_tmp, all_used_abils)
    initType(MaxMana.init_tmp, all_used_abils)
    initType(Recovery.init_tmp, all_used_abils)
    initType(Regeneration.init_tmp, all_used_abils)
    initType(Resistance.init_tmp, all_used_abils)

    hidePassives(all_used_abils)
Frotty commented 5 years ago

I want count number of needed spell book in compiletime and do not generate extra ability id.

What Wurst version are you using? A recent update introduced data retention for objects in compiletime expression (https://github.com/wurstscript/WurstScript/pull/822/files) and int/real/string from hashtables also gets transferred from compiletime to runtime iirc. So you could try a HashMap to save the counter.

nelloy-git commented 5 years ago

Im using the latest version. So can i add something like this?

Globals: constant hashtable hash = InitHashtable() constant int param_books_count = hash.loadInt(0, 0)

To hidePassives func: hash.saveInt(0, 0, used_books)

nelloy-git commented 5 years ago

And i thought ID_GEN can give different values in compiletime and init time

Frotty commented 5 years ago

Im using the latest version. So can i add something like this?

You of course need to wrap the InitHashtable() in a compiletime expression..

And i thought ID_GEN can give different values in compiletime and init time

The preset id generators are not inside compiletime expressions either, nothing has changed there.

nelloy-git commented 5 years ago

Thanks for explanation.
int value = 5 @compiletime function changeValue() value = 10

init print(value.toString())

This code will print 10, is it truth?

Frotty commented 5 years ago

This code will print 10, is it truth?

Why don't you test it? And no, it won't. Remember: compiletime-function != compiletime-expression. As I said, you need an object or a hashtable.

Here is an example (untested):

class Counter
    var count = 0

constant COUNTER = compiletime(new Counter())

@compiletime function doStuff()
    COUNTER.count++

init
    print(COUNTER.count.toString()) // Will print 1
Frotty commented 5 years ago

Did you get it to work? Closing for now.