• 🏆 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] Skilltree

Status
Not open for further replies.
Level 11
Joined
Sep 30, 2009
Messages
697
Here is my new Skilltree System. Should be more than MUI and contain no leaks. If you find any bugs please send me a PM or VM or post in this thread.

Have Fun :)
180725-albums3240-picture44159.jpg



JASS:
library SkilltreeInit initializer onInit

    globals
        constant    real                SKILLTREE_WIDTH         = 64 * 7
        constant    real                SKILLTREE_HEIGHT        = 64 * 9
        constant    real                SKILLTREE_SIZE          = 0.5
        constant    real                SKILLTREE_STEP          = 64 * SKILLTREE_SIZE
        constant    real                SKILLTREE_POS_X         = -2200
        constant    real                SKILLTREE_POS_Y         = 2400
        constant    integer             SKILLS_PER_ROW          = 5
        constant    integer             SKILLS_PER_COLUMN       = 5
        
        constant    real                BORDER_OFFSET_X         = SKILLTREE_WIDTH  / (SKILLS_PER_ROW    * 2)
        constant    real                BORDER_OFFSET_Y         = SKILLTREE_HEIGHT / (SKILLS_PER_COLUMN * 2)
        
                    trigger             TRACKABLE_HIT           = CreateTrigger()
                    trigger             TRACKABLE_HOVER         = CreateTrigger()
                    hashtable           SKILLTREE_HASHTABLE     = InitHashtable()         
                    key                 KEY_TRACKABLES
        
                    unit                SKILLTREE_DUMMY         = null
                    rect                SKILLTREE_RECT          = null
                    
        constant    integer             SKILLTREE_DUMMY_ID      = 'stdy' 
        constant    integer             C_SKILL_TITLE           = 0xFFFFFF
        constant    integer             C_SKILL_NAME            = 0xFFFFFF
        constant    integer             C_SKILL_CURR            = 0xFFFFFF
        constant    integer             C_SKILL_NEXT            = 0xFFFFFF
        constant    integer             C_SKILL_DESCRIPTION     = 0xFFFFFF
                    timer               SKILLTREE_TIMER         = null
                    boolean array       IS_PLAYER_VIEWING
                    boolean             SKILLTREE_TIMER_RUNNING = false
                    SkilltreeBoard array SkilltreeBoards
    endglobals
    
    private function CreateBackground takes nothing returns nothing
        local real xMin = GetRectMinX(SKILLTREE_RECT)
        local real yMin = GetRectMinY(SKILLTREE_RECT)
        local real xMax = GetRectMaxX(SKILLTREE_RECT)
        local real yMax = GetRectMaxY(SKILLTREE_RECT)
        local real x    = xMin
        local real y    = yMin
        local integer xTimes = R2I((xMax - xMin) / 64)
        local integer yTimes = R2I((yMax - yMin) / 64)
        local integer xCur = 0
        local integer yCur = 0
        
        loop
            exitwhen xCur >= xTimes
            
            set yCur = 0
            set y = yMin
            loop
                exitwhen yCur >= yTimes
                
                set y = y + 64
                call SetTerrainType(x, y, 'cOc1', 0, 1, 0)
                
                set yCur = yCur + 1
            endloop
            
            set x = x + 64
            set xCur = xCur + 1
        endloop
    endfunction
    
    private function CreateBorder takes nothing returns nothing
        local real x = SKILLTREE_POS_X - SKILLTREE_WIDTH /2
        local real y = SKILLTREE_POS_Y + SKILLTREE_HEIGHT /2
        local integer i = 0
        call CreateDestructable('cwlu', x, y, 270, SKILLTREE_SIZE, 0)
        
        set y = SKILLTREE_POS_Y - SKILLTREE_HEIGHT /2
        call CreateDestructable('cwld', x, y, 270, SKILLTREE_SIZE, 0)
        
        set x = SKILLTREE_POS_X + SKILLTREE_WIDTH /2
        call CreateDestructable('cwrd', x, y, 270, SKILLTREE_SIZE, 0)
        
        set y = SKILLTREE_POS_Y + SKILLTREE_HEIGHT /2
        call CreateDestructable('cwru', x, y, 270, SKILLTREE_SIZE, 0)
        
        set x = SKILLTREE_POS_X - SKILLTREE_WIDTH /2
        set y = SKILLTREE_POS_Y - SKILLTREE_HEIGHT /2
        
        loop
            set i = i + 1
            set y = y + SKILLTREE_STEP
            call CreateDestructable('cwlf', x, y, 270, SKILLTREE_SIZE, 0)
            exitwhen i >= SKILLTREE_HEIGHT / SKILLTREE_STEP - 1
        endloop
        
        set y = SKILLTREE_POS_Y + SKILLTREE_HEIGHT /2
        set i = 0
        
        loop
            set i = i + 1
            set x = x + SKILLTREE_STEP
            call CreateDestructable('cwup', x, y, 270, SKILLTREE_SIZE, 0)
            exitwhen i >= SKILLTREE_WIDTH / SKILLTREE_STEP - 1
        endloop
        
        set x = SKILLTREE_POS_X + SKILLTREE_WIDTH /2
        set i = 0
        loop
            set i = i + 1
            set y = y - SKILLTREE_STEP
            call CreateDestructable('cwrg', x, y, 270, SKILLTREE_SIZE, 0)
            exitwhen i >= SKILLTREE_HEIGHT / SKILLTREE_STEP - 1
        endloop
        
        set y = SKILLTREE_POS_Y - SKILLTREE_HEIGHT /2
        set i = 0
        loop
            set i = i + 1
            set x = x - SKILLTREE_STEP
            call CreateDestructable('cwbt', x, y, 270, SKILLTREE_SIZE, 0)
            exitwhen i >= SKILLTREE_WIDTH / SKILLTREE_STEP - 1
        endloop
        
        set SKILLTREE_RECT = Rect(SKILLTREE_POS_X - 2048 /2, SKILLTREE_POS_Y - 1024 /2, SKILLTREE_POS_X + 2048 /2, SKILLTREE_POS_Y + 1024 /2)
    endfunction
    
    private function onInit takes nothing returns nothing
        call CreateBorder()
        call CreateBackground()
        
        set SKILLTREE_DUMMY = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), SKILLTREE_DUMMY_ID, SKILLTREE_POS_X, SKILLTREE_POS_Y, 0)
        call UnitAddAbility(SKILLTREE_DUMMY, 'Aloc')
        
        call TriggerAddAction(TRACKABLE_HIT, function SkillTrackable.onHitTracker)
        call TriggerAddAction(TRACKABLE_HOVER, function SkillTrackable.onHoverTracker)
    endfunction

endlibrary


JASS:
library SkilltreeAPI requires SkilltreeInit
    
    // returns the level of a Skill for any unit. 
    function GetUnitSkillLevel takes unit u, SkillTemplate t returns integer
        local Skill s = LoadInteger(SKILLTREE_HASHTABLE, GetHandleId(u), t)
        return s.level
    endfunction
    
    // returns true if a unit has the Skill in any of its Skilltrees (even if it's not learned)
    function HasUnitSkill takes unit u, SkillTemplate t returns boolean
        return HaveSavedInteger(SKILLTREE_HASHTABLE, GetHandleId(u), t)
    endfunction
    
    // returns true if the unit meets the requirements for the Skills next level.
    // If the unit does not have that Skill it will always return false.
    function IsSkillLearnable takes unit u, SkillTemplate t returns boolean
        local Skill s = LoadInteger(SKILLTREE_HASHTABLE, GetHandleId(u), t)
        return t.check(s.st.u, s, s.level + 1) and s.st.skillpoints >= s.skillpointsNeeded and s.level < s.maxLevel
    endfunction
    
    // shows a Skilltree to the owner of the unit associated with it.
    function ShowSkilltree takes Skilltree st, boolean visible returns nothing
        call st.show(visible)
    endfunction
    
    // shows the Skilltree if it is not shown, or closes the Skilltree if it is shown.
    function ShowSkilltreeSwitch takes Skilltree st returns nothing
        call st.show(not st.visible)
    endfunction
    
    
endlibrary


JASS:
library Skilltree requires SkilltreeInit, SkilltreeBoard, Skills

    struct Skilltree[8000]      // I think 160 instances are more than enough
        
        Skill array skills[50]  // 50 Skills per Skilltree.
        
        static Skill array lastSkill    
        integer total                   
        integer skillpoints             
    
        destructable selector          
        unit u                          
                    
        fogmodifier fm                  
        boolean visible                 = false       
        
        string name                    
        
        method operator owner takes nothing returns player
            return GetOwningPlayer(.u)
        endmethod
        
        method update takes Skill s returns nothing
            
            if .selector != null then
                call RemoveDestructable(.selector)
            endif
            
            if s != 0 then
                set .selector = CreateDestructable('cwsl', s.x, s.y, 270, .76, 0)
            endif
            
            if GetLocalPlayer() != .owner then
                call ShowDestructable(.selector, false)
            endif
            
            call SkilltreeBoards[GetPlayerId(.owner)].update(s)
        endmethod
        
        method show takes boolean visible returns nothing
            local integer i = 0
            set .visible = visible

            call SkilltreeBoards[GetPlayerId(.owner)].show(this, .visible)

            set IS_PLAYER_VIEWING[GetPlayerId(.owner)] = .visible
            
            if GetLocalPlayer() == .owner then
                call ShowDestructable(.selector, .visible)
            endif
            
            call DestroyFogModifier(.fm)
            
            if .visible then
                set .fm = CreateFogModifierRect(.owner, FOG_OF_WAR_VISIBLE, SKILLTREE_RECT, false, false)
            else
                set .fm = CreateFogModifierRect(.owner, FOG_OF_WAR_MASKED, SKILLTREE_RECT, false, false)
                set Skilltree.lastSkill[GetPlayerId(.owner)] = 0
                
                if .selector != null then
                    call RemoveDestructable(.selector)
                endif
                
                if GetLocalPlayer() == .owner then
                    call ResetToGameCamera(0)
                endif
            endif
            
            call FogModifierStart(.fm)
    
            loop
                if GetLocalPlayer() == .owner then 
                    call ShowDestructable(skills[i].dest.dest, .visible)
                endif
                set i = i + 1
                exitwhen i >= total
            endloop
            call ShowBorder(.owner, .visible)
            if not SKILLTREE_TIMER_RUNNING then
                
                if SKILLTREE_TIMER == null then
                    set SKILLTREE_TIMER = CreateTimer()
                endif
                
                set SKILLTREE_TIMER_RUNNING = true
                call TimerStart(SKILLTREE_TIMER, 0.1, true, function thistype.setView)
            endif

        endmethod
        
        static method setView takes nothing returns nothing
            local integer i = 0            
            loop
                if IS_PLAYER_VIEWING[GetPlayerId(Player(i))] then
                    if GetLocalPlayer() == Player(i) then
                        call SetCameraPosition(SKILLTREE_POS_X, SKILLTREE_POS_Y)
                        call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 270, 0)
                        call SetCameraField(CAMERA_FIELD_ROTATION, 90, 0)
                        call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1200, 0)
                        call SetCameraTargetController(SKILLTREE_DUMMY, 0, 0, false)
                    endif
                endif
                set i = i + 1
                exitwhen i >= 12
            endloop
        endmethod
        
        static method create takes unit u returns thistype
            local thistype this = thistype.allocate()
            set .u = u
            if SkilltreeBoards[GetPlayerId(.owner)] == 0 then
                set SkilltreeBoards[GetPlayerId(.owner)]                    = SkilltreeBoard.create(.owner)
                set SkilltreeBoards[GetPlayerId(.owner)].bit                = SkilltreeBoards[GetPlayerId(.owner)].board[0][25]
                set SkilltreeBoards[GetPlayerId(.owner)].board.all.width    = .2
            endif
            return this
        endmethod
        
    endstruct

endlibrary


JASS:
library SkilltreeBoard requires SubStringLastWord, Board

    struct SkilltreeBoard   
        Board board     
        static BoardItem bit
        static integer y
        
        method addName takes Skill s returns nothing
            local string  n = ""
            set n = s.name + " - Level " + I2S(s.level)
            
            loop
                set n       = " " + n + " "
                exitwhen StringLength(n) >= 50
            endloop
            
            set bit                  = board[0][y]
            set bit.text             = n
            set bit.color            = C_SKILL_NAME
        endmethod
        
        method addDescription takes Skill s returns nothing
            local integer x  = 0
            local integer l  = StringLength(s.description)
            local string sub = ""
            
            set y = y + 2
            if  l > 42 then
                loop
                    set sub         = SubStringLastWord(s.description, x, x + 42)
                    set bit         = board[0][y]
                    set bit.text    = sub
                    set bit.color   = C_SKILL_DESCRIPTION
                    set x           = x + StringLength(sub)
                    exitwhen l <= x + 42
                    set y           = y + 1
                endloop
                
                if SubString(s.description, x, l) != "" then
                    set y           = y + 1
                    set bit         = board[0][y]
                    set bit.text    = SubString(s.description, x, l)
                    set bit.color   = C_SKILL_DESCRIPTION
                endif
            
            else
                set bit             = board[0][y]
                set bit.text        = s.description
                set bit.color       = C_SKILL_DESCRIPTION
            endif
        endmethod
        
        method addStats takes Skill s returns nothing
            local integer x  = 0
            local integer l  = StringLength(s.stats)
            local string sub = ""
            
            set y = y + 2
            if  l > 42 then
                loop
                    set sub         = SubStringLastWord(s.stats, x, x + 42)
                    set bit         = board[0][y]
                    set bit.text    = sub
                    set bit.color   = C_SKILL_CURR
                    set x           = x + StringLength(sub)
                    exitwhen l <= x + 42
                    set y           = y + 1
                endloop
                
                if SubString(s.stats, x, l) != "" then
                    set y            = y + 1
                    set bit          = board[0][y]
                    set bit.text     = SubString(s.stats, x, l)
                    set bit.color    = C_SKILL_CURR
                endif
            
            else
                set bit              = board[0][y]
                set bit.text         = s.stats
                set bit.color        = C_SKILL_CURR
            endif
        endmethod
        
        method addRequirements takes Skill s returns nothing
            local integer x  = 0
            local integer l  = StringLength(s.requirements)
            local string sub = ""
            
            set y = y + 2
            if  l > 42 then
                loop                    
                    set sub         = SubStringLastWord(s.requirements, x, x + 42)
                    set bit         = board[0][y]
                    set bit.text    = sub
                    set bit.color   = C_SKILL_NEXT
                    set x           = x + StringLength(sub)
                    exitwhen l <= x + 42
                    set y           = y + 1
                endloop
                
                if SubString(s.description, x, l) != "" then
                    set y           = y + 1
                    set bit         = board[0][y]
                    set bit.text    = SubString(s.requirements, x, l)
                    set bit.color   = C_SKILL_NEXT
                endif
                
            else
                set bit             = board[0][y]
                set bit.text        = s.requirements
                set bit.color       = C_SKILL_NEXT
            endif
        endmethod
        
        method addStatsNext takes Skill s returns nothing
            local integer x  = 0
            local integer l  = StringLength(s.statsNext)
            local string sub = ""
            
            set y = y + 2
            if  l > 42 then
                loop
                    set sub         = SubStringLastWord(s.statsNext, x, x + 42)
                    set bit         = board[0][y]
                    set bit.text    = sub
                    set bit.color   = C_SKILL_NEXT
                    set x           = x + StringLength(sub)
                    exitwhen l <= x + 42
                    set y           = y + 1
                endloop
                
                if SubString(s.statsNext, x, l) != "" then
                    set y            = y + 1
                    set bit          = board[0][y]
                    set bit.text     = SubString(s.statsNext, x, l)
                endif
            else
                set bit              = board[0][y]
                set bit.text         = s.statsNext
                set bit.color        = C_SKILL_NEXT
            endif
        endmethod
        
        method clearText takes nothing returns nothing
            set board.title = ""
            loop
                set bit              = board[0][y]
                set bit.text = ""
                set y = y + 1
                exitwhen y > 25
            endloop
            set y = 0
        endmethod
        
       method update takes Skill s returns nothing
            set y = 0
            
            call .clearText()
            set board.title = s.st.name
                
            if s != 0  then
                call .addName(s)
                call .addDescription(s)

                
                if s.level > 0 then
                    set y = y + 4
                    set bit                     = board[0][y]    
                    set bit.text                = "Current Level"
                    set bit.color               = C_SKILL_CURR
                    
                    call .addStats(s)
                else
                    set y = y + 4
                    set bit                     = board[0][y]    
                    set bit.text                = "Skill not learned yet."
                    set bit.color               = C_SKILL_CURR
                endif
                
                set y = y + 3
                set bit              = board[0][y]    
                set bit.text            = "-------------------------------------------"
                
                if s.level < s.maxLevel then
                    set y = y + 3
                    set bit                 = board[0][y]    
                    set bit.text            = "Next Level - Costs " + I2S(s.skillpointsNeeded) + " Skillpoints"
                    set bit.color           = C_SKILL_NEXT
                    
                    call .addRequirements(s)
                    call .addStatsNext(s)

                else
                    set y = y + 2
                    set bit                 = board[0][y]    
                    set bit.text            = "Maximum Level reached for this Skill"
                    set bit.color           = C_SKILL_NEXT
                endif
                
                set y = 24
                set bit                     = board[0][y]    
                set bit.text                = "Skillpoints: " + I2S(s.st.skillpoints)
                set bit.color               = C_SKILL_NEXT
            
            else
                set y                       = 2
                set bit                     = board[0][y]
                set bit.text                = "No skill selected."
            endif
            set bit = 0
            set y   = 0
        endmethod
    
        method show takes Skilltree st, boolean visible returns nothing
            set  .board.visible[st.owner] = visible
            set  .board.minimized         = false
            call .update(0)
        endmethod
        
        static method create takes player p returns thistype
            local thistype this =  thistype.allocate()
            set .board = Board.create()
            return this
        endmethod
        
    endstruct

endlibrary


JASS:
library Skills requires SkillDestructables, SkillTrackables, SimError
    
    interface SkillTemplate
        method check takes unit u, Skill s, integer newLevel returns boolean defaults true
        method learn takes unit u, Skill s, integer newLevel returns nothing defaults nothing
        
        string name                 
        integer posX             
        integer posY                
        integer icon                
        integer icon_unknown        
        integer maxLevel            
        integer skillpointsNeeded   
    endinterface
    
    struct Skill
        Skilltree st                
        SkillDestructable dest      
        SkillTrackable tracker      
        SkillTemplate t             
        
        integer posX                
        integer posY                
        integer icon                
        integer icon_unknown        
    
        integer maxLevel            
    
        real x                      
        real y                      
        integer level               
        integer skillpointsNeeded   
    
        string name                
        string description          
        string stats                
        string requirements         
        string statsNext            
        
        method clickSkill takes nothing returns nothing
            if .t.check(.st.u, this, .level + 1) and .st.skillpoints >= .skillpointsNeeded and .level < .maxLevel then
                set  .level             = .level + 1
                set  .st.skillpoints    = .st.skillpoints - .skillpointsNeeded
            
                if .level == 1 then
                    call RemoveDestructable(.dest.dest)
                    set .dest.dest = CreateDestructable(.icon, .x, .y, 270, SKILLTREE_SIZE * 4/3, 0)
                endif
            
                call .t.learn(.st.u, this, .level)
                call .st.update(this)
            else
                call SimError(.st.owner, "Can't learn this Skill")
            endif
        endmethod
    
        method addToSkilltree takes Skilltree st returns nothing
            set .st                     = st
            set .st.skills[st.total]    = this
            set .st.total               = st.total + 1
            set .x                      = SKILLTREE_POS_X + BORDER_OFFSET_X - SKILLTREE_WIDTH  / 2  + SKILLTREE_WIDTH  / SKILLS_PER_ROW    * .posX
            set .y                      = SKILLTREE_POS_Y + BORDER_OFFSET_Y - SKILLTREE_HEIGHT / 2  + SKILLTREE_HEIGHT / SKILLS_PER_COLUMN * .posY
            set .tracker                = SkillTrackable.create(this)
            set .dest                   = SkillDestructable.create(this)
            
            call SaveInteger(SKILLTREE_HASHTABLE, GetHandleId(.st.u), .t, this)
            
            if GetLocalPlayer() != .st.owner then
                call ShowDestructable(.dest.dest, false)
            endif
        
            if GetLocalPlayer() == .st.owner then
                call ShowDestructable(.dest.dest, .st.visible)
            endif
        endmethod
        
        private method destroy takes nothing returns nothing
            call .dest.destroy()
            call .tracker.destroy()
            call .deallocate()
        endmethod
        
        static method create takes SkillTemplate t returns thistype
            local thistype this     = thistype.allocate()
            set .t                  = t
            set .name               = t.name      
            set .posX               = t.posX        
            set .posY               = t.posY                     
            set .icon               = t.icon           
            set .icon_unknown       = t.icon_unknown   
            set .maxLevel           = t.maxLevel   
            set .skillpointsNeeded  = t.skillpointsNeeded
            return this
        endmethod
    endstruct

endlibrary


JASS:
library SkillDestructables

    struct SkillDestructable
        Skill s              
        destructable dest      
        integer icon         
        integer icon_unknown   
        real x                  
        real y                  
    
        static method create takes Skill s returns thistype
            local thistype this = thistype.allocate()
            set .s              = s
            set .x              = .s.x
            set .y              = .s.y
            set .icon           = .s.icon
            set .icon_unknown   = .s.icon_unknown
        
            if .s.level > 0 then
                set .dest = CreateDestructable(.icon, .x, .y, 270, SKILLTREE_SIZE * 4/3, 0)
            else
                set .dest = CreateDestructable(.icon_unknown, .x, .y, 270, SKILLTREE_SIZE * 4/3, 0)
            endif
        
            return this
        endmethod
    
    endstruct

endlibrary


JASS:
library SkillTrackables requires SimError

    struct SkillTrackable
        Skill s             
        trackable tracker  
        player owner       
        real x      
        real y        
        string path     
    
        static method get takes trackable tr returns thistype
            return LoadInteger(SKILLTREE_HASHTABLE, KEY_TRACKABLES, GetHandleId(tr))
        endmethod
    
        static method create takes Skill s returns thistype
            local thistype this = thistype.allocate()
            set .s              = s
            set .x              = .s.x
            set .y              = .s.y
            set .owner          = .s.st.owner
        
            if GetLocalPlayer() == .owner then
                set path        = "Skilltree\\Tracker.mdl"
            endif
        
            set .tracker        = CreateTrackable(.path, .x, .y, 0)
            call SaveInteger(SKILLTREE_HASHTABLE, KEY_TRACKABLES, GetHandleId(.tracker), this)
            call TriggerRegisterTrackableHitEvent(TRACKABLE_HIT, .tracker)
            call TriggerRegisterTrackableTrackEvent(TRACKABLE_HOVER, .tracker)
            return this
        endmethod
    
        static method onHitTracker takes nothing returns nothing
            local thistype this = .get(GetTriggeringTrackable())
            if .s.st.visible then
                call .s.clickSkill()
            endif
        endmethod
    
        static method onHoverTracker takes nothing returns nothing
            local thistype this = .get(GetTriggeringTrackable())
            if .s.st.visible and Skilltree.lastSkill[GetPlayerId(.owner)] != this then
                set Skilltree.lastSkill[GetPlayerId(.owner)] = this
                call .s.st.update(.s)
            endif
        endmethod
    endstruct


endlibrary








- the border is now only visible to players looking at a Skilltree
- the Skill icons were shown to all players instead of only the owner, it should be fixed now (thx to aaron79 for testing help)
- added a requirement to SkilltreeAPI

- remade SkilltreeBoard again so it works now correctly
- one board per player now instead of one for all
- some minor changes

- removed null presets (thx to Bribe)
- all Skilltrees use the same Board now instead of one Board for each Skilltree
- implemented SimError
- some minor changes

- added more functionality
- added another skill to the testing skilltree
- the board is now automatically resized based on the length of the description etc

- first release



- give proper Credits
- add description etc to the code
- make a better testmap
- add more API
- add more configurables
- make the system more user friendly
- rename some variables
- remove the variable chaos
- slay the dragon and rescue the princess
 

Attachments

  • Skilltree v0.05.w3x
    77.8 KB · Views: 250
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
If it's improvements you're looking for, I might advise avoiding default values when declaring struct members (i = 0, s = null, r = 0.00) because those are set automatically and are pretty redundant to set them to their same value again. If you want to set some values to 0, I might advise doing it from the destroy method, as it will yield better results.
 
Level 11
Joined
Sep 30, 2009
Messages
697
Now this is turning out really nice! But you can use it now at the moment or do I have to modify it if I want to use it?

Well the only thing you need to do is to import the Destructables and the Models for the border and icons. Also you need to create 2 destructables for every skill (will make a textmacro for this soon). Also you need to have some sort of free space in your map where the destructables can be placed (best would be a flat area in a corner of the map)

But you do not really need to modify anything else

You really should add support for Bribe's New Table.

Maybe I should implement it yeah
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I don't think anybody has noticed this but some of your libraries are missing requirements. By default placement the syntax checker may not be picking it up but your library SkilltreeAPI doesn't require library SkilltreeInit but it uses members from that library.

Other than that, and maybe some of the things other people have mentioned, this seems to be pretty good work. I like your separation of duties into separate libraries, that's how it should be done. I wish I had modularized my Projectiles library a little more like this.

(By the way it seems like you're only missing the one requirement, but I didn't read through very thoroughly)
 
Level 8
Joined
Aug 2, 2008
Messages
193
Pretty nice system i have to say first ;)

Some proposals:
  • May reduce the field, the system requires, by scaling everything smaller (if possible), so it doesn't require that much place, which is, imo, pretty much atm.
  • I wouldnt use the DISBTN Buttons for none-learned spells but the PASBTN Buttons, it looks too dark but maybe this is just my opinion^^
  • Make the board always maximized when hovering a skill
  • When changing SKILLTREE_SIZE, only the icons of the spells are smaller, everything else seems to have the normal size, maybe transfer this to the whole skilltree. (you probably need to change the size of the trackable dummies)
  • Maybe create a texttag in the edge of each spell to show the level or something like that
  • Dont use the "Nothing"-Terrain-Texture, just use a black texture as destructable that is behind each button etc. Just increase the height of each button then.


I tried to change some values to make it 5 times smaller:

attachment.php



Look at the minimap, only a very, very small box.
What I've done:
Decreased the size of the selector model and the tracker model to 20%.
Changed the camera distance of the dummy to 300.
SKILLTREE_SIZE = 0.1
SKILLTREE_WIDTH = 12.8 * 7
SKILLTREE_HEIGHT = 12.8 * 9
And in the SkillTreeMain-Library:
set .selector = CreateDestructable('cwsl', s.x, s.y, 270, 0.152, 0)
0.152 = 0.76 / 5 (to fit the rest).


Btw, i saw, that its not a good idea to use a dummy unit, because you cant place the skilltree in the left corner then, what i've tried. maybe just move the camera with a periodic timer back to the center of the skilltree and fix the FogModifier, which are too large, if you change SKILLTREE_SIZE.


Models ect are in the map I attached...
Overall, I quite like the system, but not if it takes that much place, which was the reason I did this.
 

Attachments

  • Skilltree v0.05.w3x
    77.7 KB · Views: 71
  • Screen.png
    Screen.png
    239.4 KB · Views: 351
Level 11
Joined
Sep 30, 2009
Messages
697
Pretty nice system i have to say first ;)

Some proposals:

May reduce the field, the system requires, by scaling everything smaller (if possible), so it doesn't require that much place, which is, imo, pretty much atm.

Well the user still can do that if he wants. I prefer the size it is actually.

I wouldnt use the DISBTN Buttons for none-learned spells but the PASBTN Buttons, it looks too dark but maybe this is just my opinion^^

Well this is something the user has to decide anyway. What I did is just an example.

Make the board always maximized when hovering a skill
Will do this thanks.

When changing SKILLTREE_SIZE, only the icons of the spells are smaller, everything else seems to have the normal size, maybe transfer this to the whole skilltree. (you probably need to change the size of the trackable dummies)

The Border gets scaled too already.
If you change the size the user has to rescale the dummy model anyways and he can change the size with other constants already.

Maybe create a texttag in the edge of each spell to show the level or something like that
Dont use the "Nothing"-Terrain-Texture, just use a black texture as destructable that is behind each button etc. Just increase the height of each button then.

This would create even more destructables i prefer the terrain method, but maybe I will create an option to do like you want it.

Btw, i saw, that its not a good idea to use a dummy unit, because you cant place the skilltree in the left corner then, what i've tried. maybe just move the camera with a periodic timer back to the center of the skilltree and fix the FogModifier, which are too large, if you change SKILLTREE_SIZE.

Well I like the method with the dummy unit but I could create an option here, too.

Anyway thanks for the feedback.
 
Level 11
Joined
Sep 30, 2009
Messages
697
The problem using you method with the black ground is, that it requires the tile in the pallete, afaik. This is, imo a huge problem for maps that already hit the texture-limit.

This would create even more destructables i prefer the terrain method, but maybe I will create an option to do like you want it.

As I said if I find the time I will add this.
 
Status
Not open for further replies.
Top