• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJass] SpellExperience

Level 11
Joined
Sep 30, 2009
Messages
697
Here is a simple but very interesting and quite new system by me. The description should answer all questions.
Feel free to write what you think about the system. What should be added, improved...

JASS:
library SpellExperience requires optional AutoIndex
//############################### CREDITS     ###############################//
//##
//## Idea & System: Axarion
//## AutoIndex: grim001
//##
//############################### DESCRIPTION ###############################//
//##
//## This small library allows you to aquire a totally new way of 
//## spell-leveling. Instead of letting the player choose a spell 
//## which spell should increase after a hero gains a level, spells 
//## acquire experience for being cast, damaging enemies or whatever 
//## you want. 
//##
//############################### HOW TO USE ###############################//
//##
//## To use this system you need to extend SpellExp. In your struct you 
//## have to call the textmacro SpellExpConstructor. You can add all of 
//## the methods listed in the interface below. You should not add your own
//## create method since its done via the textmacro. To add exp to a spell
//## you first need to call: 
//##
//## Yourstruct.create(unit, integer)
//##
//## Then whenever you want you can use the method below to get an instance:
//## 
//## YourStruct.get(unit u, integer spellid) 
//##
//## Finally you can change the experience just by:
//##
//## set InstanceName.spellExp = newValue
//##
//## The method expNeeded is used to check if the spell has enough experience.
//## You dont need to level up manualy just set the exp to .expNeeded() to
//## increase the spells level by 1.
//##
//############################################################################//

globals
    // feel free to use your own hashtable here, if you aren't
    // using the units handle and the spells rawcode as keys already.
    private hashtable h = InitHashtable()
endglobals

//############################### END OF USER AREA ########################//

private interface SpellExpEvents 
    method onSpellLevelUp takes nothing returns nothing defaults nothing
    method onSpellExpGain takes nothing returns nothing defaults nothing
    method onSpellInit    takes nothing returns nothing defaults nothing
    method expNeeded      takes nothing returns real    defaults 200.
endinterface

struct SpellExp extends SpellExpEvents
    integer spellId2    = 0
    integer spellLevel  = 1
    integer maxLevel    = 3
    unit spellUnit      = null
    real spellExp2      = 0

//########################### START OF OPERATORS #############################// 

    method operator spellId takes nothing returns integer
        return .spellId2
    endmethod
    
    method operator spellId= takes integer id returns nothing
        call RemoveSavedInteger(h, GetHandleId(.spellUnit), .spellId2)
        set .spellId2 = id
        call SaveInteger(h, GetHandleId(.spellUnit), .spellId, this)
    endmethod
    
    method operator spellExp takes nothing returns real
        return .spellExp2
    endmethod
    
    method operator spellExp= takes real exp returns nothing
        if .spellLevel < .maxLevel and .spellExp + exp > 0 then

            set .spellExp2 = exp
        
            if .spellExp2 >= .expNeeded() then
                set .spellExp2 = .spellExp2 -.expNeeded()
                call .levelUp()
            endif
            call .onSpellExpGain()
        endif
    endmethod
    
//########################### END OF OPERATORS #############################//    
    
    method levelUp takes nothing returns nothing
        if .spellLevel < .maxLevel then
            set .spellLevel = .spellLevel + 1
            call .onSpellLevelUp()
            
            call SetUnitAbilityLevel(.spellUnit, .spellId, .spellLevel)
            
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl", .spellUnit, "origin"))
        endif
    endmethod
    
    static method get takes unit u, integer id returns thistype
        return LoadInteger(h, GetHandleId(u), id)
    endmethod

    static method create takes unit u, integer id returns thistype
        local thistype this = thistype.allocate()
        set .spellUnit = u
        set .spellId   = id
        
        return this
    endmethod

endstruct

//! textmacro SpellExpConstructor
static method create takes unit u, integer id returns thistype
    local thistype this = thistype.allocate(u, id)
    set .spellUnit = u
    set .spellId   = id
        
    call .onSpellInit()
        
    set me = u
    return this
endmethod
implement optional AutoDestroy
//! endtextmacro

endlibrary
 

Attachments

  • SpellExperience.w3x
    50.8 KB · Views: 89
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
Probably my only thing with this is that it uses AutoIndex, the worst of all of the indexing libs ; |. Otherwise, I think this looks pretty good ^>^. My other slight things are the interface (woulda coded that manually to get a bit more performance) and the macro.

JASS:
struct Spell extends array
    private static constant integer SPELL_ID = 'bleh'
    
    //from module
    //public real expNeeded
    //public method operator unit (unit that has spell)

    private method onSpellLevelUp takes nothing returns nothing
    endmethod

    private method onSpellExpGain takes nothing returns nothing
    endmethod

    private method onSpellCreate takes nothing returns nothing
    endmethod

    implement SpellExpStruct
endstruct
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Table by Vexorian would reduce the need of that hashtable.

http://www.wc3c.net/showthread.php?t=101246

Yeah, AutoIndex is garbage with its lack of updates (needs a lot of fixes). I would recommend adding an alternate option or two, namely UnitIndexer (by Nestharus) and AIDS (by Jesus4Lyf). UnitIndexer is the shiny new thing, and the API is much more intuitive than AIDS.

UnitIndexer : http://www.hiveworkshop.com/forums/submissions-414/unit-indexer-172090/
AIDS : http://www.thehelper.net/forums/showthread.php?t=130752
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Hm, this seems like a pretty interesting idea.

  • I don't really see any point in the textmacro...?
    You could allow the user to declare a create method; it's just that they need to make sure they pass the correct parameters into thistype.allocate()
    You could also call .onSpellInit inside the default create method.
  • Allow some kind of configuration with the special effect settings.
  • I think you should make the struct members private or else the methods you provided are kind of useless since the user can easily access them.
  • I think you should clear the hashtable's data when the struct gets destroyed.
  • Maybe you should have a method that combines the create and get method together. What I'm thinking of is something that will either create a struct if it's not in the hashtable or return the struct that's stored if something exists. (It would just be there to make it easier for the user.)
  • I would like to see more documentation on the API. =P
  • It would be nice if you gave some kind of template for units to easily gain experience from casting spells rather than making the user code everything by himself. (It's not really necessary.)
 
Last edited:
Top