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

[JASS] Trouble whit Code

Status
Not open for further replies.
Level 2
Joined
Mar 7, 2013
Messages
20
Problem Sloved!
Hi there.
I'm pretty new to Jass and made my self a trigger:cute:

If I test my map with the editor and the event fires my trigger.
The Game complitly crashes(throws up an error report, saying something like "bla couldn't be written"(maybe a pointer-error?!)):eekani:
I'm using the jessnewgenpack and didn't get any syntax-errros(expected the "Undeclared Varibale gg_trg..."-error) so I can't figure out what exactly causes the problem.
I noticed, that if i don't save the map befor testing WC3 throws me back to the menu(What usually happens if there's an error in the code).


Would be nice if someone could help me out ^^

JASS:
globals
    hashtable hBratenTimer = InitHashtable() //Hashtable for Timers
    constant integer BRATEN_TIMER_COLUMN=0
    constant integer BRATEN_ITEM_COLUMN=1
    constant integer BRATEN_UNIT_COLUMN=2
    integer anzTimer = 0
    constant integer GEB_FLEISCH = 'I00A'
    constant integer EISEN_BARREN = 'I00E'
    constant integer BROT = 'I00S'
endglobals
//------------------------------------------------

function Item_is_Teig takes item whichItem returns boolean
    return GetItemTypeId(whichItem) == 'I00T'
endfunction

function Item_is_Fleisch takes item whichItem returns boolean
    return GetItemTypeId(whichItem) == 'I002'
endfunction

function Item_is_Eisenerz takes item whichItem returns boolean
    return GetItemTypeId(whichItem) == 'I00D'
endfunction

 function Handlerfunc takes nothing returns nothing
    local item whichItem
    local integer whichProd
    local unit whichUnit
    local integer charges
    local timer t = GetExpiredTimer()
    set whichItem = LoadItemHandle( hBratenTimer, GetHandleId(t), BRATEN_ITEM_COLUMN)
    set whichUnit = LoadUnitHandle( hBratenTimer, GetHandleId(t), BRATEN_UNIT_COLUMN)
    set charges = GetItemCharges(whichItem)
    if(Item_is_Teig(whichItem)) then
        set whichProd = BROT
    elseif(Item_is_Fleisch(whichItem)) then
        set whichProd = GEB_FLEISCH
    elseif(Item_is_Eisenerz(whichItem)) then
        set whichProd = EISEN_BARREN
    endif
    //-------
    if( UnitHasItem( whichUnit, whichItem )) then
        if( charges == 1 ) then
            call RemoveItem(whichItem)
            //--- "Delete" Timer+Entrie
            call PauseTimer(t)
            call DestroyTimer(t)
            //call SaveBoolean( hBratenTimer, timerRow, BRATEN_INUSE_COLUMN, false )
        else
            call SetItemCharges(whichItem, (charges-1))
        endif
        call CreateItemLoc(whichProd, GetUnitLoc(whichUnit))
    else
        call RemoveItem(whichItem)
        //--- "Delete" Timer+Entrie
        call PauseTimer(t)
        call DestroyTimer(t)
        //call SaveBoolean( hBratenTimer, timerRow, BRATEN_INUSE_COLUMN, false )
    endif
    call CreateTextTagUnitBJ( ( GetItemName(GetLastCreatedItem())+" fertig."), whichUnit, 0, 10, 50, 100, 50, 0 )
    call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )
    call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 64, 90 )
    call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 1.00 )
    set t = null
 endfunction

function Lagerfeuer_braten takes unit whichUnit, item whichItem returns nothing
    local timer t = CreateTimer()
    local integer i
    //------Different Timers for drifferent Indigrents
    if(Item_is_Teig(whichItem)) then
        call TimerStart(t, 20.00, true, function Handlerfunc)
    elseif(Item_is_Fleisch(whichItem)) then 
        call TimerStart(t, 10.00, true, function Handlerfunc)
    elseif(Item_is_Eisenerz(whichItem)) then
        call TimerStart(t, 40.00, true, function Handlerfunc)
    endif
    //------Save Timer+Variables in Hashtable
    if Item_is_Teig(whichItem) or Item_is_Fleisch(whichItem) or Item_is_Eisenerz(whichItem) then
        call BJDebugMsg("SpeichereTimer")
        call SaveTimerHandle( hBratenTimer, GetHandleId(t), BRATEN_TIMER_COLUMN, t )
        call SaveItemHandle( hBratenTimer, GetHandleId(t), BRATEN_ITEM_COLUMN, whichItem )
        call SaveUnitHandle( hBratenTimer, GetHandleId(t), BRATEN_UNIT_COLUMN, whichUnit )
        call CreateTextTagUnitBJ( ( GetItemName(whichItem)+" wird verarbeitet.(Dauer: "+R2S(TimerGetTimeout(t))+"sek.)"), whichUnit, 0, 10, 50, 100, 50, 0 )
        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )
        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 64, 90 )
        call SetTextTagFadepointBJ( GetLastCreatedTextTag(), 1.00 )
        set t = null
    endif
    
endfunction

//---------------------Trigger Functions--------------------------
function Trig_Lagerfeuer_fuellen_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'h009'
endfunction

function Trig_Lagerfeuer_fuellen_Actions takes nothing returns nothing
    call Lagerfeuer_braten(GetTriggerUnit(), GetManipulatedItem())
endfunction

//===========================================================================
function InitTrig_Lagerfeuer_fuellen takes nothing returns nothing
    set gg_trg_Lagerfeuer_fuellen = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Lagerfeuer_fuellen, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddCondition( gg_trg_Lagerfeuer_fuellen, Condition( function Trig_Lagerfeuer_fuellen_Conditions ) )
    call TriggerAddAction( gg_trg_Lagerfeuer_fuellen, function Trig_Lagerfeuer_fuellen_Actions )
endfunction

So the reason I was creating this trigger is:
In the map I've a unit, that can cook.
If I put a cookable inigrent into the inventory of the cook-unit, it should decreas the charges remaining in the indigrent by 1 and creat a product after a period of time.
If there still charges remaining it should do this(decreas the charges remaining in the indigrent by 1 and creat a product after a period of time) again.
If the charges remain are 0 then it should remove the item.


If the trigger is fiered it calls the "Lagerfeuer_braten"-Funktion(maybe cook is a better name^^). The "Lagerfeuer_braten"-Funktion starts a periodic timer, wich expiretime depens on the Item(Indigrent) given to the Cook-Unit. Becouse I need to know what Item and which Unit is involved I save the Timers-Handel in a hashtable and connect it with the needed data. When the timer fieres it calls the "Timer_Create_Product_out_of_Item"-Function this Function Loads the needed Variables form the hashtable and decreases the Unit's Item charges by one or if they're 0 removes it and destroys the Timer.


Maybe I used to much Wrappers, but I like them, couse they give the Post a little bit of tidiness.
 
Last edited:
Level 2
Joined
Mar 7, 2013
Messages
20
For now I think my Code doesn't create an Item ^^
But thanks I'll keep that in my mind ich I add this=)

By the way I noticed something:
Could the Cause of the error be, that every time my Functions fiered it adds a new entrie to the hashtable and don't remove it if it's expired so it if there's an error, causing that the Functions repeats to often may it runs out of "free"-memory and the Pointer points at an Part of the Memory where's not allowed to write. Would be a explination for the error.
(got hopefully fixed)
But why skould it repied that often that fast(I can't imagine)?
 
Last edited:
Level 2
Joined
Mar 7, 2013
Messages
20
To eplain what I want:
If I put a cookable inigrent into the inventory of the cook-unit, it should decreas the charges remaining in the indigrnt and creat a product after a period of time.
If the charges remain are 0 then it should remove the item.

If the trigger is fiered it calls the "Lagerfeuer_braten"-Funktion(maybe cook is a better name^^). The "Lagerfeuer_braten"-Funktion starts a trigger, wich expiretime depens on the Item(Indigrent) given to the Cook-Unit. Becouse I need to know what Item and which Unit is involved I save the Timers-Handel in a hashtable and connect it with the needed data. When the timer fieres it calls the "Timer_Create_Product_out_of_Item"-Function this Function Loads the needed Variables form the hashtable and decreases the Unit's Item charges by one or if they're 0 removes it. If charges remain in the Item it calls the same code the "Lagerfeuer_braten"-Funktion does(Becouse it should cook again;)). The reason for that is, that I can't call the "Lagerfeuer_braten"-Funktion it self, becouse it's not possible in Jass to make Functions call each other.
 
Last edited:
Level 9
Joined
Dec 12, 2007
Messages
489
you can try debugging that trigger by put some part into comment to isolate the bugged part starting from the bottom.

while at it, you should remove those unneeded BJ functions and use the native counterpart and optimizes the code further, some example:
JASS:
function Trig_Lagerfeuer_fuellen_Conditions takes nothing returns boolean
    if ( not ( GetUnitTypeId(GetTriggerUnit()) == 'h009' ) ) then
        return false
    endif
    return true
endfunction
can be simplified into
JASS:
function Trig_Lagerfeuer_fuellen_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'h009'
endfunction

and you can inline those function to check itemtype.
 
Level 9
Joined
Dec 12, 2007
Messages
489
What do you mean with unneeded BJ-Functions?
since you use JNGP, you can see that different functions are colored differently, just like when you post the code here. those colored red indicates that it is BJ function.

BJ function usually call a set of functions to simplify several function call, but few BJ function actually just a wrapper function of single function to accomodate function input through GUI, since you are using JASS, you can just call the native function, mainly the single wrapper kind, for example in your code:
JASS:
LoadTimerHandleBJ(i, bratenTimer_Row, hBratenTimer))
in JNGP's trigger editor, you can hold CTRL then click on the function or use the Function List feature to see the function which will display:
JASS:
function LoadTimerHandleBJ takes integer key, integer missionKey, hashtable table returns timer
    return LoadTimerHandle(table, missionKey, key)
endfunction
you see, LoadTimerHandleBJ is just a wrapper to a single function, why need to do 2 function call (1 wrapper, 1 native call) when you can just do 1 function call?
example code above can be simplified into these by using the parameter directly in the native
JASS:
LoadTimerHandle(hBratenTimer, bratenTimer_Row, i)
this is just an example, there is a lot of tutorial about avoiding BJ or inlining function, you can find them here too (use the search). that's out of topic anyway.

have you tried debugging it? which part is bugged?
 
Level 2
Joined
Mar 7, 2013
Messages
20
Thx for the dercription:)
I just started debugging but I noticed that the /* as a start of a comment thwros up an JNGP-Syntax-Error:eekani: Is this normal?
 
So do u have an Idea why my JNGP throws that error? Would really help me out ^^
  • Check for errors around the /*, maybe JassHelper is reporting the line wrong. Also make sure you close it */.
  • Get latest JassHelper.
  • If you're using JNGP 2.0 make sure to use vexorian's JH not cohadars (up to you, I guess).
  • Make sure you have JNGP 5d or 2.0.
 
Level 2
Joined
Mar 7, 2013
Messages
20
Finally I got the Comments work. And...
Found the code causing the error:
JASS:
    local itemtype gebFleisch = ConvertItemType('I00A')
    local itemtype eisenBarren = ConvertItemType('I00E')
    local itemtype brot = ConvertItemType('I00S')
Would be nc if someone could tell me why this causes an error and what I'd wrong there :D
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
You're not supposed to use ConvertItemType like this way, in fact you're no supposed to use it at all.
Use the constants instead :

JASS:
constant itemtype ITEM_TYPE_PERMANENT = ConvertItemType(0)
constant itemtype ITEM_TYPE_CHARGED = ConvertItemType(1)
constant itemtype ITEM_TYPE_POWERUP = ConvertItemType(2)
constant itemtype ITEM_TYPE_ARTIFACT = ConvertItemType(3)
constant itemtype ITEM_TYPE_PURCHASABLE = ConvertItemType(4)
constant itemtype ITEM_TYPE_CAMPAIGN = ConvertItemType(5)
constant itemtype ITEM_TYPE_MISCELLANEOUS = ConvertItemType(6)
constant itemtype ITEM_TYPE_UNKNOWN = ConvertItemType(7)
constant itemtype ITEM_TYPE_ANY = ConvertItemType(8)

// Deprecated, should use ITEM_TYPE_POWERUP
constant itemtype ITEM_TYPE_TOME = ConvertItemType(2)
But i don't think you want that, what are you trying to do exactly ?
 
Level 2
Joined
Mar 7, 2013
Messages
20
Ok thank u all vey much :D
Now I've another problem:
I tested it but as I put an item in the cook-unit's iventory nothing happed.
Code has been updated;)
Pls help me:D
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Yes rawcodes like 'xxxx' are just integers in a different base, you can translate them in 10 base (the one we use every day), but that's pointless.
Also you really should use constant integers instead of rawcodes everywhere in your code.

JASS:
constant integer MY_ITEM = 'I000'

...

call CreateItem(MY_ITEM,...)
This way your code is quicker/easier to edit, less bug prone and more readable.
 
Level 2
Joined
Mar 7, 2013
Messages
20
SO now I added the Constants.
I tested it but as I put an item in the cook-unit's iventory nothing happed.
Code has been updated;)
Pls help me:D
Has anyone an Idea why it doesn't work, I can't figure it out.
 
Level 2
Joined
Mar 7, 2013
Messages
20
No there's no error anymore :)
But the Code doesn't do what I want it to do :thumbs_down:
I tested the map an after puting an item into the cook-unti's invetrory and waiting a huge amount of time nothing happend.
 
Level 2
Joined
Mar 7, 2013
Messages
20
I just debugged the code and found out, that the Timer maybe doesn't start the Function. Is this possible? Do u know how to fix that?
 
Level 2
Joined
Mar 7, 2013
Messages
20
Oh thy didn't know there is an "elseif"-command. What conditions do u mean? Do the Trigger-conditions influence the timer?
I'm definitely sure the timer is started, but the HandlerFunction isn't called.
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well, in your edited code i still don't see text messages in the code below :

So no, you are not sure that the timer is started.

if(Item_is_Teig(whichItem)) then
call TimerStart(t, 10.00, true, function Timer_Create_Product_out_of_Item_Handlerfunc)
elseif(Item_is_Fleisch(whichItem)) then
call TimerStart(t, 5.00, true, function Timer_Create_Product_out_of_Item_Handlerfunc)
elseif(Item_is_Eisenerz(whichItem)) then
call TimerStart(t, 15.00, true, function Timer_Create_Product_out_of_Item_Handlerfunc)
endif
 
Level 2
Joined
Mar 7, 2013
Messages
20
Found the error :
JASS:
 function Handlerfunc takes nothing returns nothing
    local item whichItem
    local integer whichProd
    local unit whichUnit
   --> local integer charges = GetItemCharges(whichItem) <--
    local timer t = GetExpiredTimer()
I didn't Load the Variable whichitem from hastable befor, the Timer simply didn't start the CallBackFunction because of this(Don't know why).
Thy for all of u're help :)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
If you use a not initialized variable (without any value, included "null"), then the thread crash, like a "return", that's probably why.
There is an exception for arrays though, it just works like it has the default null type of the variable, "false" for boolean, "0" for integer, and so one.
Also GUI variables have always a value (but not obvioulsy the one written in the variable editor if you use it in a vjass initializer without any wait, check the generated map script if you want to know more about it)
 
Status
Not open for further replies.
Top