• 🏆 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!

OnDeathTexttag v3.0.0.1

This system basically creates a texttag above a unit when it dies.
This texttag is chosen randomly from 2 lists or predefined by the user.
The 2 lists are "Hard-kill-texts" and "Easy-kill-texts".

Hard kills are defined by the user within a filter function.
You can also filter out units from having any texts.
The only thing that overrides that is the custom death text defined by the user for a certain unit.

JASS:
/************************************************
*
*   OnDeathTexttag
*   v3.0.0.1
*   By Magtheridon96
*
*   - Displays a randomly selected or predefined texttag
*   over a unit when it dies based on unit characteristics.
*
*   API:
*   ----
*
*       - struct OnDeathTexttag extends array
*
*           - static method addEasy takes string s returns nothing
*               - Adds an easy-kill text to the system.
*           - static method addHard takes string s returns nothing
*               - Adds a hard-kill text to the system.
*
*           - static method getEasy takes nothing returns string
*               - Gets a random easy-kill text.
*           - static method getHard takes nothing returns string
*               - Gets a random hard-kill text.
*
*           - static method getUnit takes unit whichUnit returns string
*               - Returns the unit death text.
*           - static method setUnit takes unit whichUnit, string s returns nothing
*               - Gives a unit a custom death text that overrides the others. This will also override the filters.
*
*           - static method resetUnit takes unit whichUnit returns nothing
*               - Resets a the death text of a unit so it uses the easy and hard ones.
*           - static method unitHas takes unit whichUnit returns boolean
*               - Determines if a unit has a custom death text or not.
*
*
*       - function AddEasyDeathText takes string s returns nothing
*           - Adds an easy-kill text to the system.
*       - function AddHardDeathText takes string s returns nothing
*           - Adds a hard-kill text to the system.
*
*       - function GetEasyDeathText takes nothing returns string
*           - Gets a random easy-kill text.
*       - function GetHardDeathText takes nothing returns string
*           - Gets a random hard-kill text.
*
*       - function GetUnitDeathText takes unit whichUnit returns string
*           - Returns the unit death text.
*       - function SetUnitDeathText takes unit whichUnit, string s returns nothing
*           - Gives a unit a custom death text that overrides the others. This will also override the filters.
*
*       - function ResetUnitDeathText takes unit whichUnit returns nothing
*           - Resets a the death text of a unit so it uses the easy and hard ones.
*       - function UnitHasDeathText takes unit whichUnit returns boolean
*           - Determines if a unit has a custom death text or not.
*
************************************************/
library OnDeathTexttag requires Table, RegisterPlayerUnitEvent
    
    globals
        // Texttag Age
        private constant real AGE      = 2.50
        // Texttag Fading Age
        private constant real FADE     = 1.75
        // Texttag Size
        private constant real FONT     = 10
        // Texttag Velocity
        private constant real SPEED    = 16
        // Texttag Angle
        private constant real ANGLE    = 90
        // Texttag Z
        private constant real HEIGHT   = 32
    endglobals
    
    private function UnitFilter takes unit u returns boolean
        return IsUnitType(u, UNIT_TYPE_HERO)
    endfunction
    
    private function HardUnitFilter takes unit u returns boolean
        return GetUnitState(u, UNIT_STATE_MAX_LIFE) >= 1500
    endfunction
    
    private function VisibilityFilter takes player dyingPlayer, player otherPlayer returns boolean
        return true
    endfunction
    
    private module Configuration
        private static method onInit takes nothing returns nothing
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.run)
            
            call addEasy("N00b!")
            call addEasy("Feeder!")
            call addEasy("OMG")
            call addEasy("Fail")
            call addEasy("xaxaxaxa")
            call addEasy("Maphack!")
            call addEasy("H4xx!!")
            call addEasy("jajajaja")
            call addEasy("Pro!")
            call addEasy("*Ragequit*")
            call addEasy("...")
            call addEasy("trololol")
            call addEasy(":@")
            call addEasy("whosyourdaddy")
            
            call addHard("Pwned")
            call addHard("Owned")
            call addHard("qft")
            call addHard("Epic!")
            call addHard("Awesome!")
            call addHard(":D")
            
            // Setting player color strings
            set color[0] = "|cffff0303"
            set color[1] = "|cff0042ff"
            set color[2] = "|cff1ce6b9"
            set color[3] = "|cff540081"
            set color[4] = "|cffffff01"
            set color[5] = "|cfffe8a0e"
            set color[6] = "|cff20c000"
            set color[7] = "|cffe55bb0"
            set color[8] = "|cff959697"
            set color[9] = "|cff7ebff1"
            set color[10] = "|cff106246"
            set color[11] = "|cff4e2a04"
            set color[12] = "|cffffffff"
            set color[13] = "|cffffffff"
            set color[14] = "|cffffffff"
            set color[15] = "|cffffffff"
            
            set unitStrings = Table.create()
        endmethod
    endmodule
    
    struct OnDeathTexttag extends array
        private static string array easyStrings
        private static string array hardStrings
        private static Table unitStrings
        private static integer easyCount = -1
        private static integer hardCount = -1
        private static string array color
        
        private static constant real X = SPEED * 0.0005546875 * Cos(ANGLE * bj_DEGTORAD)
        private static constant real Y = SPEED * 0.0005546875 * Sin(ANGLE * bj_DEGTORAD)
        private static constant real SIZE = FONT * 0.0023
        
        static method addEasy takes string s returns nothing
            set easyCount = easyCount + 1
            set easyStrings[easyCount] = s
        endmethod
        
        static method addHard takes string s returns nothing
            set hardCount = hardCount + 1
            set hardStrings[hardCount] = s
        endmethod
        
        static method getEasy takes nothing returns string
            return easyStrings[GetRandomInt(0, easyCount)]
        endmethod
        
        static method getHard takes nothing returns string
            return hardStrings[GetRandomInt(0, hardCount)]
        endmethod
        
        static method getUnit takes unit whichUnit returns string
            return unitStrings.string[GetHandleId(whichUnit)]
        endmethod
        
        static method setUnit takes unit whichUnit, string s returns nothing
            set unitStrings.string[GetHandleId(whichUnit)] = s
        endmethod
        
        static method resetUnit takes unit whichUnit returns nothing
            set unitStrings.string[GetHandleId(whichUnit)] = null
        endmethod
        
        static method unitHas takes unit whichUnit returns boolean
            return getUnit(whichUnit) != null
        endmethod
        
        private static method run takes nothing returns nothing
            local unit triggerUnit = GetTriggerUnit()
            local string s = unitStrings.string[GetHandleId(triggerUnit)]
            local texttag text
            
            // Check the unit filter
            if UnitFilter(triggerUnit) then
            
                // If the unit has no custom death text
                if s == null then
                
                    // Check if the kill was hard or easy
                    if HardUnitFilter(triggerUnit) then
                        set s = getHard()
                    else
                        set s = getEasy()
                    endif
                
                endif
            
            elseif s == null then
            
                // The unit wasn't accepted by any of the filters
                // It also didn't have a custom death text
                set triggerUnit = null
                return
            endif
            
            set text = CreateTextTag()
            
            call SetTextTagText(text, color[GetPlayerId(GetTriggerPlayer())] + s, SIZE)
            call SetTextTagPosUnit(text, triggerUnit, HEIGHT)
            call SetTextTagVelocity(text, X, Y)
            
            call SetTextTagPermanent(text, false)
            call SetTextTagLifespan(text, AGE)
            call SetTextTagFadepoint(text, FADE)
            
            call SetTextTagVisibility(text, VisibilityFilter(GetTriggerPlayer(), GetLocalPlayer()))
            
            set triggerUnit = null
            set text = null
        endmethod
        
        implement Configuration
    endstruct
    
    function AddEasyDeathText takes string s returns nothing
        call OnDeathTexttag.addEasy(s)
    endfunction
    
    function AddHardDeathText takes string s returns nothing
        call OnDeathTexttag.addHard(s)
    endfunction
    
    function GetEasyDeathText takes nothing returns string
        return OnDeathTexttag.getEasy()
    endfunction
    
    function GetHardDeathText takes nothing returns string
        return OnDeathTexttag.getHard()
    endfunction
    
    function SetUnitDeathText takes unit whichUnit, string s returns nothing
        call OnDeathTexttag.setUnit(whichUnit, s)
    endfunction
    
    function GetUnitDeathText takes unit whichUnit returns string
        return OnDeathTexttag.getUnit(whichUnit)
    endfunction
    
    function UnitHasDeathText takes unit whichUnit returns boolean
        return GetUnitDeathText(whichUnit) != null
    endfunction
    
    function ResetUnitDeathText takes unit whichUnit returns nothing
        call OnDeathTexttag.resetUnit(whichUnit)
    endfunction
endlibrary

I've provided you with some good examples of easy/kill texts in the configuration module.
You can modify them.

Feel free to comment and rate..

(Note: This system was originally written in GUI and it was horrible, so the comments in the beginning may seem a bit 'off')

Keywords:
System, Kills, Hero, Arena, Hero Arena, Kill, Floating, Text, Floating Text, String, Magtheridon96, Spell, JASS, vJASS, Dota, PWN, Spree, Sys, texts.
Contents

Just another Warcraft III map (Map)

Reviews
21 Nov 2011 Bribe: This is a clear and simple resource. Nice to work with and has good configurable options.

Moderator

M

Moderator

21 Nov 2011
Bribe: This is a clear and simple resource. Nice to work with and has good configurable options.
 
Review?

It is and it isn't.
Yes: Just make a floating text and damage a point (area). It just creates above a dying unit's head.
No: Floating texts are not the simplest things in Warcraft 3, and cleaning them up is a pain. Which he did not clean up (leaks).

Leaks
None!
Suggestions
  • Place dying unit into a unit variable to null later, also saves on code typing and function calls.
  • Place the owning player of dying unit into a player variable to null later, also saves on code typing and function calls -OR- just save the player number of the owner of the dying unit.
Uses
  • Could be used to display pwnage text in a hero arena.
  • Used to display a custom bounty system.
  • Can really be used to display anything when you kill a unit (duh).
Overall: Simple but kinda useful, so long as you clean the leaks. Getting better, i would organize your if's better, but very nice. Rated at 3.5/5, but i'll press the 4 pt button since i can't do halves (as far as im aware of).
 
Last edited:
Level 12
Joined
Apr 16, 2010
Messages
584
The only thing i noticed was bad is that when some hero dies, he was killed very hard and then it types like "lol" or smth like that, it would better type "PWNED!!!"
You need to add a lot of conditions checking for being a player noob or not, cuz it will be wrong if some guys dies, but made a 3 kills before and it says "Noob!".
Improve it there's no way making a RANDOM quote above triggering unit.
I vote 2/5
 
one question guys: How can i null player variables?
Also, Zeatherann, you were right. Cleaning up floating texts IS a pain. What do u suggest i should do?

---------------------------------------------------------

I fixed it. Check out this version, and tell me if i missed a leak or 2.
Suggestions are accepted too.
 
Last edited:
is the system better now? ( u know, after i fixed the leaks and all )
what would be ur RATING? ( Am i even allowed to ask that? ) lol
And that link u gave Zeatherann, for lightning effects, the code looks fine, but i don't see how that's gonna help me in the development of THIS spell. It might come in handy some day considering that i like to make a QUANTITY of spells instead of QUALITY.
thanks in advance :)
 
Last edited:
I'm updating this system:

I just have one small problem concerning the floating texts: They won't appear :(

Here's the code:
JASS:
scope FTKS initializer InitFTKS
//************************************************************************
//                  Floating Text Kills System v2.0.0
//
//                             Created by:
//                            Magtheridon96
//
//                          Written in: vJASS
//                                                        
//                         [url]www.hiveworkshop.com[/url]
//************************************************************************
//
//************************************************************************
//
//      This system was created on January 30, 2011.
//      
//      To implement the system, simply go to the "Implementation" 
//      section of the Documentation and follow the given instructions.
//      
//      If you find any bugs, exploits, leaks, or problems in general, 
//      please report them to me at [url]www.hiveworkshop.com[/url]. Suggestions 
//      and "gentle" constructive critisism would be appreciated.
//
//      Remember to give credit to me (Magtheridon96) if you implement 
//      this system into your map.
//  
//************************************************************************
//
//************************************************************************
//
//
//                                Changelog
//
//  Last Updated: April 9, 2011
//
//  *** v1.0.0 ***
//  Release of Floating Text Kills System
//
//  *** v1.1.0 ***
//  Fixed some leaks
//  Added new strings
//  Gave system a bit of intelligence (It's still stupid anyways :P)
//  
//  *** v2.0.0 ***
//  Completely rewrote the system in vJASS
//  Changed version numbers =P
//
//************************************************************************
//
//************************************************************************
//
//                             Implementation
//
//  1- Create a new trigger
//  2- Click Edit -> Convert to Custom Text
//  3- Copy all the contents of this trigger into your trigger
//  4- Enjoy :)
//
//************************************************************************
//
//************************************************************************
//
//                              Modifications
//
//  This system is just begging for user modifications.
//  I gave you samples of strings you can use as floating texts.
//  Feel free to modify them, and in rare cases, if your map has 
//  completely different player colors, feel free to change the 
//  Player Color variables.
//
//************************************************************************
    globals
        // The Kill Strings
        private     constant    string  array   KS
        // The Player Colors
        private     constant    string  array   KC
        // How many strings correspond to a hard kill?
        private     constant    integer         SH              = 5
        // How many strings are there?
        private     constant    integer         MAX_STRINGS     = 10
        // What do you consider as "High HP" in your map?
        private     constant    real            HIGH_HP         = 2000.00
        // Does the system work for heroes and ONLY heroes?
        private     constant    boolean         ONLY_FOR_HEROES = false
        // The lifespan of the floating text
        private     constant    real            TEXT_AGE        = 2.50
        // The fading age of the floating text
        private     constant    real            TEXT_FADE_AGE   = 1.75
        // The size of the floating text
        private     constant    real            TEXT_FONT       = 8.00
        // The velocity of the floating text
        private     constant    real            TEXT_SPEED      = 64.00
        // The angle of the floating text
        private     constant    real            TEXT_ANGLE      = 90.00
    endglobals
    
    private function Settings takes nothing returns nothing
        //======================================
        // Strings that correspond to hard kills
        //======================================
        set KS[1] = "PWNED"
        set KS[2] = "OWNED"
        set KS[3] = "ULTRA KILL!"
        set KS[4] = "EPIC!"
        set KS[5] = "AWESOME!"
        //======================================
        // Strings that correspond to easy kills
        //======================================
        set KS[6] = "NOOB!"
        set KS[7] = "lol"
        set KS[8] = "Omg"
        set KS[9] = "Ouch :/"
        set KS[10] = "HEY!"
        //==============
        // Player Colors
        //==============
        set KC[1] = "|cffff0303"
        set KC[2] = "|cff0042ff"
        set KC[3] = "|cff1ce6b9"
        set KC[4] = "|cff540081"
        set KC[5] = "|cffffff01"
        set KC[6] = "|cfffe8a0e"
        set KC[7] = "|cff20c000"
        set KC[8] = "|cffe55bb0"
        set KC[9] = "|cff959697"
        set KC[10] = "|cff7ebff1"
        set KC[11] = "|cff106246"
        set KC[12] = "|cff4e2a04"
        set KC[13] = "|cffffffff"
        set KC[14] = "|cffffffff"
        set KC[15] = "|cffffffff"
        set KC[16] = "|cffffffff"
    endfunction
    
    private function CreateFT takes integer i, integer i2 returns nothing
        local   unit        u       = GetTriggerUnit()
        local   player      p       = GetOwningPlayer(u)
        local   integer     pi      = GetPlayerId(p)
        local   texttag     tt
        local   real        v
        local   real        x
        local   real        y
        //===============================
        // We create the floating text
        //===============================
        set tt = CreateTextTag()
        //===============================
        // Here, we set:
        //
        //    -Text
        //    -Text Age
        //    -Text Fading Age
        //    -Text Position
        //    -Text Permanency
        //    -Text Font
        //===============================
        call SetTextTagAge(tt, TEXT_AGE)
        call SetTextTagText(tt, KC[pi+1] + KS[GetRandomInt(i, i2)] + "|r", TEXT_FONT)
        call SetTextTagPosUnit(tt, u, 100.00)
        call SetTextTagFadepoint(tt, TEXT_FADE_AGE)
        call SetTextTagPermanent(tt, false)
        
        //===============================
        // Here, we give the floating
        // text it's velocity.
        //===============================
        set v = TEXT_SPEED * 0.0005546875 // Don't ask :P
        set x = v * Cos(TEXT_ANGLE * bj_DEGTORAD)
        set y = v * Sin(TEXT_ANGLE * bj_DEGTORAD)
        call SetTextTagVelocity(tt, x, y)
    endfunction
    
    private function execFTKS takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local real hp = GetUnitState(u, UNIT_STATE_MAX_LIFE)
        local integer i = 1
        
        if (ONLY_FOR_HEROES) then
            if IsUnitType(u, UNIT_TYPE_HERO) and hp <= HIGH_HP then
                call CreateFT(1, SH)
            else
                call CreateFT(SH + 1, MAX_STRINGS)
            endif
        else
            if hp <= HIGH_HP then
                call CreateFT(1, SH)
            else
                call CreateFT(SH + 1, MAX_STRINGS)
            endif
        endif
    endfunction

    private function InitFTKS takes nothing returns nothing
        local trigger t
        local integer i = 0
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
        call Settings()
        call TriggerAddAction(t, function execFTKS)
    endfunction
endscope
 
Level 4
Joined
Feb 28, 2011
Messages
37
Change call SetTextTagAge(tt, TEXT_AGE) to call SetTextTagLifespan(tt, TEXT_AGE).
I think you mixed them up.

Store the x and y values for the velocity in some globals, so you don't have to calculate them every time a unit dies.

Since you already use GetTriggerUnit() in your execFTKS, you can give the value to your CreateFT instead of using it twice.

You should use TriggerAddCondition instead of TriggerAddAction.

I hope the floating texts appear now :p
 
finally a FT system that isn't for showing damage... ^_^

hmmm... since you use GetUnitLevel, it will return a wrong value for heroes right???? since Hero level is different from unit level...

and trigger conditions are faster than actions... you just need to make that action return boolean, and add a return false at the end so that you can use it as a condiiton... (also add false to all returns)

something like this:
JASS:
private function execFTKS takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local real hp = GetUnitState(u, UNIT_STATE_MAX_LIFE)
        local integer lvl = GetUnitLevel(u)
        
        // Debugging (for you ;p)
        static if (DEBUG_MODE) then
            if HIGH_HP <= 0.00 then
                call BJDebugMsg("[|cffffcc00FTKS|r]|cffff0000Error:|r Invalid High HP global")
                return false
            endif
            if HIGH_LEVEL < 1 then
                call BJDebugMsg("[|cffffcc00FTKS|r]|cffff0000Error:|r Invalid High level global")
                return false
            endif
            if SH > MAX_STRINGS then
                call BJDebugMsg("[|cffffcc00FTKS|r]|cffff0000Error:|r The SH global is assumed to be greater than MAX_STRINGS")
                return false
            endif
            if BASIS < 0 or BASIS > 3 then
                call BJDebugMsg("[|cffffcc00FTKS|r]|cffff0000Error:|r The Basis Id is invalid.")
                return false
            endif
        endif
        
        if BASIS == 0 then
            static if (ONLY_FOR_HEROES) then
                if IsUnitType(u, UNIT_TYPE_HERO) and hp >= HIGH_HP then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            else
                if hp >= HIGH_HP then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            endif
        elseif BASIS == 1 then
            static if (ONLY_FOR_HEROES) then
                if IsUnitType(u, UNIT_TYPE_HERO) and lvl >= HIGH_LEVEL then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            else
                if lvl >= HIGH_LEVEL then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            endif
        elseif BASIS == 2 then
            static if (ONLY_FOR_HEROES) then
                if IsUnitType(u, UNIT_TYPE_HERO) and hp >= HIGH_HP and lvl >= HIGH_LEVEL then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            else
                if hp >= HIGH_HP and lvl >= HIGH_LEVEL then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            endif
        elseif BASIS == 3 then
            static if (ONLY_FOR_HEROES) then
                if IsUnitType(u, UNIT_TYPE_HERO) then
                    call CreateFT(1, SH, u)
                else
                    call CreateFT(SH + 1, MAX_STRINGS, u)
                endif
            else
                call CreateFT(1, MAX_STRINGS, u)
            endif
        endif
        
        set u = null
        return false
    endfunction
    
    private function InitFTKS takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        loop
            exitwhen i >= 16
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
            set i = i + 1
        endloop
        call Settings()
        call TriggerAddCondition(t, Condition(function execFTKS))
    endfunction
 
Level 5
Joined
Jan 24, 2011
Messages
49
<Downloading>..... then <testing>..... I guess it's too simple to make it in GUI and someone can spend a small time to make something like that, well, From system you will just create script with an generic unit event If the unit "dies" if you want an exceptions from other units, heroes or structures. From condition might be use a unit, boolean, also the player comparison... then in action make an action "if,then,else multiple action" each of this has a math random numbers (Integer Comparison Condition) and an action "then" have a different kind of floating text from action "else" another "if,then,else multiple action" with different random numbers also floating text again from action "then" and another "if,then,else multiple action" again and again (if you want alot of floating kind of text)...
 
Level 5
Joined
Jan 24, 2011
Messages
49
Not to hate... Honestly I felt bit confuse from Jass/ vJass... But something, what is the purpose from making some Jazz/ vJazz when the kind of system or ability possible to make in GUI?... from me I recommend to use Jass/ vJass from advance script making such as the system I saw before... Attack Detection System, well I forgot who is the maker of this but yet it's vJazz, right? but I saw from it's script it has some conditions cannot found from ordinary GUI scripts so this system is better to be in vJass thats what I want to point about what you said... Adiktuz?...
 
Level 5
Joined
Jan 24, 2011
Messages
49
Yet like everyone said it's easy to use Jass, whatever... Just I recently use GUI I not a god to stop someone from use Jass because from my reason, haha... but yet from my first comment I'll just showing up a GUI version of this that could be use of other newbies from world editing because you can lately notice the warcraft script is not only a GUI kind it's vJass too, like what I've been experience before I discovered only here that kind of scripts when I was a newbie about wc3 world editing who looking from some guides about map making also skill making... :D
 
Level 13
Joined
May 11, 2008
Messages
1,198
i guess you never played scorched earth, but what you are saying is essentially what i said that you are trying to make the game more like scorched earth.

in that game, when tanks fired they would send chat messages and when they died they would do the same.

there were some pretty funny ones and you could edit the .cfg files to change them up however you like.

edit: when was the last time i +rep you? it's a cool idea...
 
The system was pretty well off in GUI. I gave it a 3.5, however since you used *ick* vJASS I have to say two things:
  1. I can't read it. Nor do I want to.
  2. I'll assume it's better and leak free.

Side note: what is the difference from a static if and a normal if in vJASS? because warcraft 3 ONLY has 1 if type.

Final Rating: 4.5/5 Very useful, but I now can't use it.
 
Top