Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Triggers & Scripts (http://www.wc3c.net/forumdisplay.php?f=8)
-   -   (JASS) Trigger shows text 2 times? (http://www.wc3c.net/showthread.php?t=103666)

Idontneedaname 12-08-2008 01:37 PM

(JASS) Trigger shows text 2 times?
 
Hey!

I started with JASS some time ago and wrote my first code now.
The function: It's a simple calculator.
But, of course, it does not work properly. The problem is, that it shows the result two times if one of the 2 numbers is negative and the arithmetic operator is not - .

The syntax and other things are explained at the beginning of the code.

This is the complete trigger:

Collapse JASS:
///////////////////////////////////////////////////////////////////////////////////////
///
///   THIS TRIGGER WAS CREATED BY IDONTNEEDANAME (Europe/Northrend). DO NOT USE WITHOUT CREDITS!
///
///////////////////////////////////////////////////////////////////////////////////////
///                   
///   The syntax is .=<number1><arithmetic_operator><number2>
///   It accepts both , and . as commas and knows the a.operators + - * / ^ 
///   For example,  .=-2,4--1.2  gives " -2.4 - -1.2 = -1.2 "
///   You cannot fool Warcraft with that: .=-9^0.5 (which would be impossible normally), by any reason it returns " -9 ^ 0.5 = 3 "
///
///   It accepts only one a.operator and does not know ) and (
///
///
///   Bug reports and/or ideas may be sent to [email]hotshot_beam@haefft.de[/email]
///
///
///   Idontneedaname, 7.12.2008
///////////////////////////////////////////////////////////////////////////////////////

function Trig_Nahkampf_Initialisierung_Kopieren_Actions takes nothing returns nothing
    local integer a = 0 //Position of the comma in the first number
    local integer b = 0 //Position of the comma in the second number
    local integer c = 0 //Position of the a.operator
    local real d = 0.0 //The first number
    local real e = 0.0 //The second number

if ( SubStringBJ(GetEventPlayerChatString(), 1, 2) == ".=") then

///////////////////////////////////////////////////////////////////////////////////////
///
///   Get the position of the a.operator and the positions of the commas.
///
///////////////////////////////////////////////////////////////////////////////////////

    set bj_forLoopAIndex = 4
    set bj_forLoopAIndexEnd = ( StringLength(GetEventPlayerChatString()) - 1 )

    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd

        if ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "+" ) then
            if ( c == 0 ) then
                set c = GetForLoopIndexA()
            else
            endif
        elseif ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "-" ) then
            if ( c == 0 ) then
                set c = GetForLoopIndexA()
            else
            endif
        elseif ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "*" ) then
            set c = GetForLoopIndexA()
        elseif ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "/" ) then
            set c = GetForLoopIndexA()
        elseif ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "^" ) then
            set c = GetForLoopIndexA()
        else
            if ( ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "," ) or ( SubStringBJ(GetEventPlayerChatString(), GetForLoopIndexA(), GetForLoopIndexA()) == "." ) ) then
                if ( c == 0 ) then // which means that we are still before the a.operator.
                    set a = GetForLoopIndexA()
                else
                    set b = GetForLoopIndexA()
                endif
            else
            endif
        endif
            set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop

///////////////////////////////////////////////////////////////////////////////////////
///
///   Create the numbers
///
///////////////////////////////////////////////////////////////////////////////////////

    if ( a == 0 ) then
        set d = S2R(SubStringBJ(GetEventPlayerChatString(), 3, ( c - 1 )))
    else
        set d = (S2R(( SubStringBJ(GetEventPlayerChatString(), 3, ( a - 1 )) + SubStringBJ(GetEventPlayerChatString(), ( a + 1 ), ( c - 1 )) ))) * ( Pow(0.1,((c-a)-1)) )
    endif
    if ( b == 0 ) then
        set e = S2R(SubStringBJ(GetEventPlayerChatString(), ( c + 1 ), StringLength(GetEventPlayerChatString())))
    else
        set e = (S2R(( SubStringBJ(GetEventPlayerChatString(), ( c + 1 ), ( b - 1 )) + SubStringBJ(GetEventPlayerChatString(), ( b + 1 ), StringLength(GetEventPlayerChatString())) ))) * ( Pow(0.1, (StringLength(GetEventPlayerChatString())-b)))
    endif

///////////////////////////////////////////////////////////////////////////////////////
///
///   Do the calculation and display the result to all players.
///
///////////////////////////////////////////////////////////////////////////////////////

    if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "^" ) then
        call DisplayTextToForce( GetPlayersAll(), R2S(d)+" ^ "+R2S(e)+" = "+R2S( Pow(d, e)) )
    else
        if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "+" ) then
            call DisplayTextToForce( GetPlayersAll(), R2S(d)+" + "+R2S(e)+" = "+R2S(( d + e )) )
        else
            if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "-" ) then
                call DisplayTextToForce( GetPlayersAll(), R2S(d)+" - "+R2S(e)+" = "+R2S(( d - e )) )
            else
                if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "*" ) then
                    call DisplayTextToForce( GetPlayersAll(), R2S(d)+" * "+R2S(e)+" = "+R2S(( d * e )) )
                else
                    call DisplayTextToForce( GetPlayersAll(), R2S(d)+" / "+R2S(e)+" = "+R2S(( d / e )) )
                endif
            endif
        endif
    endif
else
endif
endfunction

function InitTrig_Trigger takes nothing returns nothing
    set gg_trg_Trigger = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_Trigger, Player(0), "+", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_Trigger, Player(0), "-", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_Trigger, Player(0), "*", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_Trigger, Player(0), "/", false )
    call TriggerRegisterPlayerChatEvent( gg_trg_Trigger, Player(0), "^", false )
    call TriggerAddAction( gg_trg_Trigger, function Trig_Nahkampf_Initialisierung_Kopieren_Actions )
endfunction


I don't know what causes that, so I can't have an idea how to fix it.
(Okay, perhaps my warcraft has some errors in it, you may copy it and use it in a test map, as it does not use global variables.)

Thanks in advance,


Idontneedaname

Pyrogasm 12-09-2008 06:34 AM

Your code is sort-of convoluted and hard to read because it looks like half-converted GUI code. You should look at others' code and see how long if-then-else blocks can be re-written, excess parenthesis can be removed, and that sort of thing.

For example:
Collapse JASS:
    if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "^" ) then
        call DisplayTextToForce( GetPlayersAll(), R2S(d)+" ^ "+R2S(e)+" = "+R2S( Pow(d, e)) )
    else
        if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "+" ) then
            call DisplayTextToForce( GetPlayersAll(), R2S(d)+" + "+R2S(e)+" = "+R2S(( d + e )) )
        else
            if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "-" ) then
                call DisplayTextToForce( GetPlayersAll(), R2S(d)+" - "+R2S(e)+" = "+R2S(( d - e )) )
            else
                if ( SubStringBJ(GetEventPlayerChatString(), c, c) == "*" ) then
                    call DisplayTextToForce( GetPlayersAll(), R2S(d)+" * "+R2S(e)+" = "+R2S(( d * e )) )
                else
                    call DisplayTextToForce( GetPlayersAll(), R2S(d)+" / "+R2S(e)+" = "+R2S(( d / e )) )
                endif
            endif
        endif
    endif

//Becomes:
  //local string Display = ""
  //local string Check = ""

    set Check = SubStringBJ(GetEventPlayerChatString(), c, c)
    if Check == "^"  then
        set Display = R2S(d)+" ^ "+R2S(e)+" = "+R2S(Pow(d, e))
    elseif Check == "+" then
         set Display = R2S(d)+" + "+R2S(e)+" = "+R2S(d + e)
    elseif Check == "-" then
        set Display = R2S(d)+" - "+R2S(e)+" = "+R2S(d - e)
    elseif Check == "*" then
        set Display = R2S(d)+" * "+R2S(e)+" = "+R2S(d * e)
    elseif Check == "/" then
        set Display = R2S(d)+" / "+R2S(e)+" = "+R2S(d/e)
    endif
    call DisplayTextToForce(GetPlayersAll(), Display)
Anyway, I think the text is showing up multiple times because the trigger is firing multiple times, due to the events that have been added to the trigger. It will fire once for the negative number (detects a - sign) and once for the other operation. As for the third message, I don't know.

Idontneedaname 12-09-2008 02:14 PM

Tried it - that was exactly the problem.
Yeah, it was made out of GUI (c'mon, it's my first JASS trigger!) and I made parts of it shorter, but I forgot the elseifs in the 3rd part.
+Rep

Idontneedaname 04-13-2010 02:46 PM

New
 
Ok before I start a new thread, I can also use this old one - it's the same topic anyway.

The triggers work, but I need some comments and/or critics on the coding (simpler solutions somewhere or need of more locals etc.; you get my point).

Collapse JASS:
function calc takes real a, real b, string x returns real 
local real r 

if     x == "+" then
    set r = a + b
elseif x == "-" then
    set r = a - b
elseif x == "*" then
    set r = a * b
elseif x == "/" then
    set r = a / b
elseif x == "^" then
    set r = Pow(a,b)
endif

return r

endfunction


function constants takes string s returns real
local real r

if     s == "g" then
    set r = I2R(GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD))
elseif s == "l" then
    set r = I2R(GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_LUMBER))
elseif s == "f" then
    set r = I2R(GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED))
endif

return r

endfunction


function cutter takes string s returns real
local string STBC = s
local string    a
local integer   g = StringLength(STBC)
local integer   i = 1
local integer   l = 0
local integer   u 
local real     re

loop
    set a = SubString(STBC, i - 1, i)
    if a == "+" or a == "-" or a == "*" or a == "/" or a == "^" then
        if ((a == "-" or a == "+") and i == l + 1) then
        else
            if l == 0 then
                set l = i
            else
                set u = g
                set STBC = R2S(calc(S2R(SubString(STBC, 0, l - 1)),S2R(SubString(STBC, l, i - 1)),SubString(STBC, l - 1, l)))+SubString(STBC, i - 1, u)
                set g = StringLength(STBC)
                set l = i - (u - g)
                set i = i - (u - g)
            endif
        endif
    else
        if a == "$" then
            set u = g
            set STBC = SubString(STBC, 0, i - 1)+R2S(constants(SubString(STBC, i, i + 1)))+SubString(STBC, i + 1, u)
            set g = StringLength(STBC)
            set i = 1 + i + (u - g)
        endif
        if i == g and l == 0 then
            set re = S2R(STBC)
        elseif i >= g and l != 0 then
            set re = calc(S2R(SubString(STBC, 0, l - 1)),S2R(SubString(STBC, l, i)),SubString(STBC, l - 1, l))
        endif
    endif
    exitwhen i >= g
    set i = i + 1
endloop

return re

endfunction


function colors takes string s returns nothing
    local string   a = s
    local string   b
    local string   c
    local string   d
    local integer  e = 1

loop
    set b = SubString(a, e - 1, e)
    set c = SubString(a, 0, e-1)
    set d = SubString(a, e, StringLength(a))

    if (b == "+") or (b == "-") or (b == "*") or (b == "/") or (b == "^") then
        set a = c + " |c00FF5151" + b + "|r " + d
        set e = e + 14
    elseif (b == "(") or (b == ")") then
        set a = c + "|c000080FF" + b + "|r" + d
        set e = e + 12
    elseif (b == ".") then
        set a = c + "|c004FFF4F.|r" + d
        set e = e + 12
    elseif  b == "$" then
        set a = c + "|c00990099" + SubString(a, e - 1, e + 1) + "|r"+ SubString(a, e + 1, StringLength(a))
        set e = e + 13
    endif
    exitwhen e == StringLength(a)
    set e = e + 1
endloop

set a = a + " |c00FFFF80=|r"
call DisplayTimedTextToForce(GetPlayersAll(), 6.00, a)
set a = ""

endfunction


function Trig_Parser_Actions takes nothing returns nothing
//the locals are in order of appearance :D
    local string  S = SubString(GetEventPlayerChatString(), 2, StringLength(GetEventPlayerChatString())) //writen in mayor letter because it's teh string!!
    local integer a = 1
    local string  b
    local integer c = 1
    local string  d
    local real    e

call colors(S)

if StringLength(GetEventPlayerChatString()) > 2 and SubString(GetEventPlayerChatString(), 0, 2) == ".=" then
    loop
        exitwhen a > StringLength(S)
        set b = SubString(S, a-1, a)
        if b == "(" then
            set c = a + 1
            loop
                exitwhen c > StringLength(S)
                set d = SubString(S, c - 1, c)
                if d == ")" then
                set e = cutter(SubString(S, a, c - 1))
                    if SubString(S, a - 5, a - 1) == "sqrt" then
                        set S = SubString(S, 0, a - 5) + R2S(SquareRoot(e)) + SubString(S, c, StringLength(S))
                    elseif SubString(S, a - 4, a - 1) == "abs" then
                        set S = SubString(S, 0, a - 4) + R2S(RAbsBJ(e)) + SubString(S, c, StringLength(S))
                    else
                        set S = SubString(S, 0, a - 1 ) + R2S(e) + SubString(S, c, StringLength(S))
                    endif
                set a = 0
                exitwhen true
                else
                    if d == "(" then
                        set a = c
                    else
                    endif
                endif
                set c = c + 1
            endloop
        else
        endif
        set a = a + 1
    endloop
    // One last run in case there have been no brickets.
    set S = R2S(cutter(S))
    if S2R(S) == I2R(R2I(S2R(S))) then
        set S = I2S(R2I(S2R(S)))
    else
    endif
    call DisplayTimedTextToForce(bj_FORCE_PLAYER[0], 6.00, S)
else
endif
endfunction


function InitTrig_Parser takes nothing returns nothing
    set gg_trg_Parser = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_Parser, Player(0), ".=", false )
    call TriggerAddAction( gg_trg_Parser, function Trig_Parser_Actions )
endfunction


If the answer doesn't continue any advice to get vJASS (i know it kthx) and is helpfull, i'll give +Rep of course.

0zyx0 04-13-2010 04:03 PM

It is hard to read your code, because you don't use indentation correctly. Look at any script in the resource section to find out how it should be. Secondly, please don't use a,b,c etc. as variable names. The names should describe what the variable is there for. It is very hard to figure out what your code does because of this, and therefore it is hard to give you any advice.

PurgeandFire111 04-14-2010 01:58 AM

This:
Collapse JASS:
//is this needed? =P
function calc takes real a, real b, string x returns real 
//local real r 
if     x == "+" then
    /*set r =*/ return a + b
elseif x == "-" then
    /*set r =*/ return a - b
elseif x == "*" then
    /*set r =*/ return a * b
elseif x == "/" then
    /*set r =*/ return a / b
elseif x == "^" then
    /*set r = Pow(a,b)*/
    return a^b //should be faster
endif 
return 0
endfunction

For function "constants", just use direct returns (as done above) as well.
Collapse JASS:
call DisplayTimedTextToForce(GetPlayersAll(), 6.00, a)
set a = ""

Use bj_FORCE_ALL_PLAYERS directly instead of GetPlayersAll(), and you don't need to set a to "".

Also, I don't understand this code that much:
Collapse JASS:
    if S2R(S) == I2R(R2I(S2R(S))) then
        set S = I2S(R2I(S2R(S)))
    endif

Well, unless you are trying to compare it to the truncated value.

That's all I could really find at the moment.

Idontneedaname 04-14-2010 02:00 PM

Thanks for doing more than just flipping over the code.

return a^b
is not possible, but the others work fine. Thanks.
The part you don't understand is just to check if the real has numbers after the comma
12.200 -> 12 -> 12.000 != 12.200 , display real
but
13.000 -> 13 -> 13.000 == 13.000, display integer

Deaod 04-16-2010 12:57 AM

not ModuloReal(a, 1.)==0.
Thats how


All times are GMT. The time now is 05:17 PM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services