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

[System/Library] Scrolling Combat Text (SCT)

Status
Not open for further replies.
Level 16
Joined
Feb 22, 2006
Messages
960
Current Version: 0.21

Hey,

I started working on a system which should be able to show some information about the combat on the UI. Actually it may only show damage but will feature more in later versions.

The current version is fully written in galaxy and may can be improved.

You can test the system with the attached map, or just import the library, therefor I would recommend to use the numbers I've created (Images .dds format)


attachment.php




JASS:
            //*********************************************************************************************************
            //* Scrolling Combat Text (SCT) v.021 by xD.Schurke
            //* -----------------------------------------------
            //*
            //* Please report any bugs and give feedback!
            //*
            //*
            //* Future features:
            //*          - Support of different damage types (setup different colors etc.)
            //*          - More then just damage.
            //*          - More dynamic structure
            //*          - Maybe u have more ideas ;)
            //*
            //*
            //*
            //* Requires:
            //*          - Imagepack with numbers 0-9, .dds format with alpha-channel (Path can be adjusted in 
            //*            init function
            //*          - Basic galaxy knowledge for setting up the system.
            //*
            //*
            //* Features:
            //*          - Supports multiple units (MUI) and of course MPI
            //*          - Can be used without a locked camera, but got small update laggs -> does not look that 
            //*            smooth
            //*          - Full color support
            //*
            //*
            //*
            //* Functions:
            //*         SCTAddUnit(unit u): This function is used to register an unit, so that the SCT can show stuff
            //*         SCTRemoveUnit(unit u): This function removes an unit from the system, SCT won't show stuff
            //*                                anymore
            //*
            //*
            //*********************************************************************************************************     
            const   int                 playerCount     =   3; //Should represent the playercount
            const   fixed               duration        =   1.5; //Duration of SCT , how long the information should be shown
            const   fixed               interval        =   0.03125; //standard interval 32 frames per second (since it's sc the used value is highe)
            const   fixed               multipler       =   0.95; //Lower the value to speed up the shrinking
            //The following two values are used for the parabol movement of the damage shown        
                    fixed               maxDistance     =   300.0;
                    fixed               maxHeightY      =   150.0;
                    int                 speed           =   FixedToInt(300/(duration/interval)+0.5);
            const   int                 maxLength       =   10;
            const   color               numColor        =   Color(100,100,100);
            //Just setup the following two variables if you want to adjust the shown damage (e.g. if you use a specific
            //camera system, hence this one works with the center of camera view
            //
            //Infos:
            //      - Negative Y-Values move the shown damage downwards on the screen, positive upwards
            //      - Negative X-Values move the shown damage towards left, positive right
            //
            const   int                 adjustX         =   0;
            const   int                 adjustY         =   0;        
            
            //Do not change anything below this line without knowledge.
                    unitgroup           group           =   UnitGroupEmpty();
                    trigger             register        =   TriggerCreate("registerFunc");
                    string  [10]        numbers;
                    int [playerCount]   dialog;
            void SCTAddUnit(unit u){
                UnitGroupAdd(group,u);
            }
            void SCTRemoveUnit(unit u){
                UnitGroupRemove(group,u);
            }
            int getY(int x){
                return FixedToInt((((4.0 * (maxHeightY / maxDistance)) * (maxDistance - x)) * (x / maxDistance))+0.5);
            }   
            point getUIPos(point p1,point p2){
                fixed angle = AngleBetweenPoints(p1,p2)*-1+180;
                fixed distance = DistanceBetweenPoints(p1,p2)*60;
                return PointWithOffsetPolar(p1,distance,angle);
            }
            void convertToDialog(unit source, unit target, int damage,int player){
                string damageString = IntToString(damage);
                string tmpString = "";
                int damageLength = StringLength(damageString);
                int [maxLength] items;
                timer t = TimerCreate();
                int i = damageLength;
                int x = 0;
                fixed size = 50;
                fixed math;
                int multi = 1;
                point uiP = getUIPos(CameraGetTarget(player),UnitGetPosition(target));
                int valueY = (FixedToInt(PointGetY(uiP)+0.5)+adjustX)*-1;
                int valueX = (FixedToInt(PointGetX(uiP)+0.5)+adjustY)*-1;
                if(RandomInt(0,1) == 0){
                    multi = -1;
                }
                while(i > 0){
                    tmpString = StringSub(damageString,i,i);
                    libNtve_gf_CreateDialogItemImage(dialog[player-1], 50, 50, c_anchorCenter, valueX+50*i, valueY,StringToText(""), 
                                                     numbers[StringToInt(tmpString)], c_triggerImageTypeNormal, false, Color(100,100,100),
                                                     c_triggerBlendModeNormal);            
                    items[i] = DialogControlLastCreated();
                    libNtve_gf_SetDialogItemColor(items[i], numColor, PlayerGroupAll());
                    i -= 1;
                }
                TimerStart(t,duration,false,c_timeReal);
                while(TimerGetRemaining(t) > 0){
                        uiP = getUIPos(CameraGetTarget(player),UnitGetPosition(target));                    
                        //will find another way...
                        if(UnitIsAlive(target)){
                            valueY = FixedToInt(PointGetY(uiP)+0.5)*-1;
                            valueX = FixedToInt(PointGetX(uiP)+0.5)*-1;
                        }
                        i = damageLength;       
                        size *= multipler;
                        x += speed;
                        math = getY(x);
                        while(i > 0){            
                            DialogControlSetPosition(items[i],PlayerGroupSingle(player),c_anchorCenter,(valueX+(x*multi)+FixedToInt(size+0.5)*i),
                                                    -FixedToInt(math+0.5)-(-valueY));
                            DialogControlSetSize(items[i],PlayerGroupSingle(player),FixedToInt(size+0.5),FixedToInt(size+0.5));
                            i -= 1;
                        }
                    
                    Wait(interval,c_timeReal);    
                }
                i = damageLength;
                while(i > 0){
                    DialogControlSetVisible(items[i],PlayerGroupSingle(player),false);
                    i -= 1;
                }    
            }
            bool registerFunc (bool testConds, bool runActions){
                int  damage = FixedToInt(EventUnitDamageAmount()+0.5);
                unit source = EventUnitDamageSourceUnit();
                unit target = EventUnit();
                if(testConds){
                    if(!UnitGroupHasUnit(group,source)){
                        return false;
                    }
                }
                convertToDialog(source,target,damage,UnitGetOwner(source));
                return true;
            }
            void init (){
                int i = 0;
                TriggerAddEventUnitDamaged(register, null, c_unitDamageTypeAny, c_unitDamageEither, null);
                while(i < 3){
                    if(PlayerStatus(i+1) == c_playerStatusActive){
                        dialog[i] = DialogCreate(1, 1, c_anchorCenter, 0, 0, true);
                        DialogSetFullscreen(dialog[i],true);
                        DialogSetVisible(dialog[i],PlayerGroupSingle(i+1),true);
                        DialogSetImageVisible(dialog[i],false);
                    }
                    i += 1;
                }
                //Add Number Images -> Import and adjust this part if needed
                numbers[0] = "Numbers\\0.dds";
                numbers[1] = "Numbers\\1.dds";
                numbers[2] = "Numbers\\2.dds";
                numbers[3] = "Numbers\\3.dds";
                numbers[4] = "Numbers\\4.dds";
                numbers[5] = "Numbers\\5.dds";
                numbers[6] = "Numbers\\6.dds";
                numbers[7] = "Numbers\\7.dds";
                numbers[8] = "Numbers\\8.dds";
                numbers[9] = "Numbers\\9.dds";
            }


Would be nice to get some feedback or tips. What can be improved, what would you like to see in this system?
 

Attachments

  • Screenshot2010-07-14 16_04_17.jpg
    Screenshot2010-07-14 16_04_17.jpg
    394.4 KB · Views: 2,109
  • SCT.SC2Lib
    9.2 KB · Views: 266
  • numbers.dds.rar
    5.1 KB · Views: 100
  • SCT v0.21.SC2Map
    25.8 KB · Views: 184
Level 11
Joined
Aug 1, 2009
Messages
963
Eh, too lazy to localize it for NA but from the screenshots looks pretty nice. The way dialog items show up relative to units is pretty ingenious though.

Maybe add in the ability to define colors specific to certain damage effects (or even text for certain ones, like a miss or a critical hit). Might be able to do this via the data editor using catalog functions, dunno.
 
Level 8
Joined
Aug 2, 2008
Messages
193
Why didn't you wrote this System in Andromeda? ;)
Think this would make the code some more cleaner.
Maybe not now, but if something like JNPG will be released for Galaxy, I would rewrite this System in Andromeda.
And btw, doesn't that may cause issues with other resolutions? Because these Dialogs work like pixels.. don't know exactly^^
 
Level 16
Joined
Feb 22, 2006
Messages
960
actually it's adjusted for the standard zoom, resolution shouldnt be the problem, and if one wants to adjust it you've got 2 vars to move this stuff :D

edit: I won't use andromeda. For which reason? It adds no new functionality to the galaxy scripting language
 
Last edited:
Level 17
Joined
Jun 17, 2007
Messages
1,433
Surely a lot of those math functions (AngleBetweenPoints, etc..) could be replaced with more efficient alternatives?
JASS:
return FixedToInt((((4.0 * (maxHeightY / maxDistance)) * (maxDistance - x)) * (x / maxDistance))+0.5);
Can be cleaned up a bit.
JASS:
return FixedToInt ((4.0 * maxHeightY / maxDistance * (maxDistance - x) * x / maxDistance) +0.5);
That should be it, but I might have made a mistake since I'm pretty tired.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,191
return FixedToInt( 4 * maxHeightY * (maxDistance - x) * x / (maxDistance*maxDistance) + 0.5);

return FixedToInt( 4 * maxHeightY * x * (1 - x/maxDistance)/maxDistance + 0.5);

Both should do the exact same thing.

Also there is no reason to write it in another more complicated language.... In WC3 you were required to use vJASS inorder to axcess globals in a usable way where as in SC2 you already have that level of control.
 
Last edited:
Level 16
Joined
Feb 22, 2006
Messages
960
ok I will try both ways, I did it this way since somehow the way I had it before allways returned 0, but the calculator returned the correct value , was curious.

edit:
@DSG
both of your functions don't seem to return the correct value. I made a calculator test with some values I've chosen. The correct return value should be 833.3....

your first function return 83.3... so just multiple this with 10
the second one returned -134999999900

@hvo
your way seems to return the correct value, will test if it works with the editor :O
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,191
The first one is correct, you must have messed up with the maths.

The second one was incorrect cause I forgot it was to the power of -2 not +2 however I have now fixed that.

Both return the same values (in theory) as the orignal formula. Any differences in values are caused by how SC2 processes the calculation.
 
Status
Not open for further replies.
Top