Will this script work? Item Recipe

ReVolver

Mega Super Ultra Cool Member
Reaction score
610
I just finished this script and I can't test it "at the moment". I don't know if using structs/methods was a good way of making it.

JASS:
scope RecipeMix

struct RecipeItems
    integer 0 = 'I000'
    integer 1 = 'I001'
    integer 2 = 'I002'
    integer 3 = 'I003'
    unit u
    integer i = 0
    integer this
    item item1 = null
    item item2 = null
    item item3 = null
    
    method CheckItems takes nothing returns nothing
        set this.u = GetTriggerUnit()
            loop
        set this.this = GetItemTypeId(UnitItemInSlot(this.u, this.i))
        if this.this == 0 then
            set this.item1 = UnitItemInSlot(this.u, this.i)
        endif
        if this.this == 1 then
            set this.item2 = UnitItemInSlot(this.u, this.i)
        endif
        if this.this == 2 then
            set this.item3 = UnitItemInSlot(this.u, this.i)
        endif
        set this.i = this.i + 1
        exitwhen this.i >= bj_MAX_INVENTORY
    endloop
    if this.item1 != null and this.item2 != null and this.item3 != null then
        call RemoveItem(this.item1)
        call RemoveItem(this.item2)
        call RemoveItem(this.item3)
        call UnitAddItemById(this.u, 3)
        set this.item1 = null
        set this.item2 = null
        set this.item3 = null
    endif
    endmethod
    
    method RecipeSystem takes nothing returns nothing
        call this.CheckItems()
    endmethod
endstruct

function RecipeInit takes nothing returns nothing
    local RecipeItems IS=RecipeItems.create()
    call IS.RecipeSystem()
endfunction

function Conditions takes nothing returns boolean
    local integer i = GetItemTypeId(GetManipulatedItem())
    return i == 0 or i == 1 or i == 3
endfunction

function RecipeSystem takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( t, function RecipeInit )
    call TriggerAddCondition(t, Condition(function Conditions))
    
endfunction

endscope


If you can find a better or more efficient way, please do tell.
 
Well, what is this supposed to do in the first place?


Just a side note, naming your variables like "this", "i", "u" etc. is generally a bad idea. Especially inside a struct.

You will get lost.


Furthermore, variable names should start with a letter, I seriously doubt whether your code syntaxes.
 
The above guy is right. Be ridiculously descriptive with your function names. I'm looking everything over now.

integer 0 = 'l000'
integer 1 = 'l001'
integer 2 = '1002'
integer 3 = '1003'

Needs letters, example:

integer Unit0_ID = 'l000'

"this.this"
this is a keyword, you cannot name anything "this", it would be like naming an integer integer.


Use more locals in the checkid function
for instance change "integer this" to "local integer curItemID" for a better name and to save some struct space.



You never specify a unit anywhere in your code.
 
Well, what is this supposed to do in the first place?


Just a side note, naming your variables like "this", "i", "u" etc. is generally a bad idea. Especially inside a struct.

You will get lost.


Furthermore, variable names should start with a letter, I seriously doubt whether your code syntaxes.

It's suppose to check for 3 items in the hero slot and replace them with a new one. I will try to stop my habit of using 1 word/number variables.
 
I went at it:

JASS:
scope RecipeMix

struct RecipeItems
    integer item0_id = 'I000'
    integer item1_id = 'I001'
    integer item2_id = 'I002'
    integer recipiemakes_id = 'I003' //changed names for clarity
    unit u
//    integer i = 0
//    integer this // Removed
    item item1 = null
    item item2 = null
    item item3 = null
    
    method CheckItems takes nothing returns nothing
        local integer this_id = 0
        local integer i = 0
// new locals
            loop
        set this_id = GetItemTypeId(UnitItemInSlot(this.u, i))
        if this.this == item0_id then
            set this.item1 = UnitItemInSlot(this.u, i)
        endif
        if this_id == item1_id then
            set this.item2 = UnitItemInSlot(this.u, i)
        endif
        if this_id == item2_id then
            set this.item3 = UnitItemInSlot(this.u, i)
        endif
        set i = i + 1
        exitwhen i >= bj_MAX_INVENTORY
    endloop
    if this.item1 != null and this.item2 != null and this.item3 != null then
        call RemoveItem(this.item1)
        call RemoveItem(this.item2)
        call RemoveItem(this.item3)
        call UnitAddItemById(this.u, recipiemakes_id)
    endif
// I moved these nulls outside of brackets, because otherwise they don't get nulled even if 2/3 match or whatever.
        set this.item1 = null
        set this.item2 = null
        set this.item3 = null
    endmethod
    
    method RecipeSystem takes nothing returns nothing
        call this.CheckItems()
    endmethod
endstruct

function RecipeInit takes nothing returns nothing
    local RecipeItems IS=RecipeItems.create()
//*** this line was moved outside of the struct, otherwise I don't know if you can get the trigger unit.
    set IS.u = GetTriggerUnit()
    call IS.RecipeSystem()
    set IS.u = null
// null it after we're done.
endfunction

function Conditions takes nothing returns boolean
    local integer i = GetItemTypeId(GetManipulatedItem())
    return i == 0 or i == 1 or i == 3
endfunction

function RecipeSystem takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( t, function RecipeInit )
    call TriggerAddCondition(t, Condition(function Conditions))
    
endfunction

endscope



A few extra notes:
Add a total of 6 item IDs, and then if you want a recipie to only use two items, just set the last four items to be the same as one of the first two. It checks them all anyway.

Ex: Recipe pwnsauce needs
1 pwn, with id 'I000'
1 sauce, with id 'I001'

integer item0_id = 'I000'
integer item1_id = 'I001'
integer item2_id = 'I001'
integer item3_id = 'I001'
integer item4_id = 'I001'
integer item5_id = 'I001'

everything would work out fine, except for the removes, but that could be done pretty easily as well.

This would make it a little slower (who cares?) but way more modular.
 
For some reason the trigger doesn't work, I fixed some minor errors but it won't remove the items and give me the new one. :banghead:

JASS:
scope RecipeMix

struct RecipeItems
    integer item0_id = 'I000'
    integer item1_id = 'I001'
    integer item2_id = 'I002'
    integer item3_id = 'I003'
    unit u
//    integer i = 0
//    integer this // Removed
    item item1 = null
    item item2 = null
    item item3 = null
    
    method CheckItems takes nothing returns nothing
        local integer this_id = 0
        local integer i = 0
// new locals
            loop
        set this_id = GetItemTypeId(UnitItemInSlot(this.u, i))
        if this_id == this.item0_id then
            set this.item1 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item1_id then
            set this.item2 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item2_id then
            set this.item3 = UnitItemInSlot(this.u, i)
        endif
        set i = i + 1
        exitwhen i >= bj_MAX_INVENTORY
    endloop
    if this.item1 != null and this.item2 != null and this.item3 != null then
        call RemoveItem(this.item1)
        call RemoveItem(this.item2)
        call RemoveItem(this.item3)
        call UnitAddItemById(this.u, this.item3_id)
    endif
// I moved these nulls outside of brackets, because otherwise they don't get nulled even if 2/3 match or whatever.
        set this.item1 = null
        set this.item2 = null
        set this.item3 = null
    endmethod
    
    method RecipeSystem takes nothing returns nothing
        call this.CheckItems()
    endmethod
endstruct

function RecipeInit takes nothing returns nothing
    local RecipeItems IS=RecipeItems.create()
//*** this line was moved outside of the struct, otherwise I don't know if you can get the trigger unit.
    set IS.u = GetTriggerUnit()
    call IS.RecipeSystem()
    set IS.u = null
// null it after we're done.
endfunction

function Conditions takes nothing returns boolean
    local integer i = GetItemTypeId(GetManipulatedItem())
    return i == 0 or i == 1 or i == 3
endfunction

function RecipeSystem takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( t, function RecipeInit )
    call TriggerAddCondition(t, Condition(function Conditions))
    
endfunction

endscope
 
^^ you can encapsulate it in the struct and then anyone can use it, without having to script any code. Seems like a good deal to me.
 
My personal favorite would go to some function like:
call Recipies(unit, item1, item2, item3, newitem)
that would do the work.

And the trigger action has a bunch such calls.
 
So there is no way of fixing the one I made?

JASS:
scope RecipeMix

struct RecipeItems
    integer item0_id = 'I000'
    integer item1_id = 'I001'
    integer item2_id = 'I002'
    integer item3_id = 'I003'
    unit u
    item item1 = null
    item item2 = null
    item item3 = null
    
    method CheckItems takes nothing returns nothing
        local integer this_id
        local integer i = 0
            loop
        set this_id = GetItemTypeId(UnitItemInSlot(this.u, i))
        if this_id == this.item0_id then
            set this.item1 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item1_id then
            set this.item2 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item2_id then
            set this.item3 = UnitItemInSlot(this.u, i)
        endif
        set i = i + 1
        exitwhen i >= bj_MAX_INVENTORY
    endloop
    if this.item1 != null and this.item2 != null and this.item3 != null then
        call RemoveItem(this.item1)
        call RemoveItem(this.item2)
        call RemoveItem(this.item3)
        call UnitAddItemById(this.u, this.item3_id)
        set this.item1 = null
        set this.item2 = null
        set this.item3 = null
        set this.u = null
    endif
    endmethod
endstruct

function RecipeInit takes nothing returns nothing
    local RecipeItems IS=RecipeItems.create()
    set IS.u = GetTriggerUnit()
    call IS.CheckItems()
endfunction

function Conditions takes nothing returns boolean
    return GetItemTypeId(GetManipulatedItem()) == 'I000' or GetItemTypeId(GetManipulatedItem()) == 'I001' or GetItemTypeId(GetManipulatedItem()) == 'I002'
endfunction

function RecipeSystem takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( t, function RecipeInit )
    call TriggerAddCondition(t, Condition(function Conditions))
    
endfunction

endscope
 
Well I tried my script on another map, for some reason I added units to the map with custom triggers and items but it was saving it as a .w3m now that it was in a .w3x map it worked, I guess it was a bug using NewGen?

Now It works: Here it is

JASS:
scope RecipeMix

struct RecipeItems
    integer item0_id = 'rde1'
    integer item1_id = 'rde2'
    integer item2_id = 'rde3'
    integer item3_id = 'brac'
    unit u
    item item1 
    item item2
    item item3
    
    method CheckItems takes nothing returns nothing
        local integer this_id
        local integer i = 0
            loop
        set this_id = GetItemTypeId(UnitItemInSlot(this.u, i))
        if this_id == this.item0_id then
            set this.item1 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item1_id then
            set this.item2 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item2_id then
            set this.item3 = UnitItemInSlot(this.u, i)
        endif
        set i = i + 1
        exitwhen i >= bj_MAX_INVENTORY
    endloop
    if this.item1 != null and this.item2 != null and this.item3 != null then
        call RemoveItem(this.item1)
        call RemoveItem(this.item2)
        call RemoveItem(this.item3)
        call UnitAddItemById(this.u, this.item3_id)
        set this.item1 = null
        set this.item2 = null
        set this.item3 = null
        set this.u = null
    endif
    endmethod
endstruct

private function Actions takes nothing returns nothing
    local RecipeItems IS=RecipeItems.create()
    set IS.u = GetManipulatingUnit()
    call IS.CheckItems()
endfunction

public function InitTrig takes nothing returns nothing    
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( t, function Actions )
endfunction

endscope
 
Thank you everyone for their help. Especially you AceHart :D

Here is what I have: Do I use

JASS:
call RecipeItems.destroy(IS)


or

JASS:
call IS.destroy()


JASS:
scope RecipeMix

struct RecipeItems
    integer item0_id = 'rde1'
    integer item1_id = 'rde2'
    integer item2_id = 'rde3'
    integer item3_id = 'brac'
    unit u
    item item1 = null
    item item2 = null
    item item3 = null
    
    method CheckItems takes nothing returns nothing
        local integer this_id
        local integer i = 0
            loop
        set this_id = GetItemTypeId(UnitItemInSlot(this.u, i))
        if this_id == this.item0_id then
            set this.item1 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item1_id then
            set this.item2 = UnitItemInSlot(this.u, i)
        endif
        if this_id == this.item2_id then
            set this.item3 = UnitItemInSlot(this.u, i)
        endif
        set i = i + 1
        exitwhen i >= bj_MAX_INVENTORY
    endloop
    if this.item1 != null and this.item2 != null and this.item3 != null then
        call RemoveItem(this.item1)
        call RemoveItem(this.item2)
        call RemoveItem(this.item3)
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl",this.u,"overhead"))
        call UnitAddItemById(this.u, this.item3_id)
        set this.item1 = null
        set this.item2 = null
        set this.item3 = null
        set this.u = null
    endif
    endmethod
endstruct

private function Actions takes nothing returns nothing
    local RecipeItems IS=RecipeItems.create()
    set IS.u = GetManipulatingUnit()
    call IS.CheckItems()
    call IS.destroy()
endfunction

public function InitTrig takes nothing returns nothing    
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( t, function Actions )
endfunction

endscope
 
> Do I use ...

Personal preference.
I use the second one...

Ok, I thought they did different things. I guess I'm getting hang of structs and methods, now to implement structs with kattana's handle vars.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    News portal has been retired. Main page of site goes to Headline News forum now
  • The Helper The Helper:
    I am working on getting access to the old news portal under a different URL for those that would rather use that for news before we get a different news view.
  • Ghan Ghan:
    Easily done
    +1
  • The Helper The Helper:
    https://www.thehelper.net/pages/news/ is a link to the old news portal - i will integrate it into the interface somewhere when i figure it out
  • Ghan Ghan:
    Need to try something
  • Ghan Ghan:
    Hopefully this won't cause problems.
  • Ghan Ghan:
    Hmm
  • Ghan Ghan:
    I have converted the Headline News forum to an Article type forum. It will now show the top 20 threads with more detail of each thread.
  • Ghan Ghan:
    See how we like that.
  • The Helper The Helper:
    I do not see a way to go past the 1st page of posts on the forum though
  • The Helper The Helper:
    It is OK though for the main page to open up on the forum in the view it was before. As long as the portal has its own URL so it can be viewed that way I do want to try it as a regular forum view for a while
  • Ghan Ghan:
    Yeah I'm not sure what the deal is with the pagination.
  • Ghan Ghan:
    It SHOULD be there so I think it might just be an artifact of having an older style.
  • Ghan Ghan:
    I switched it to a "Standard" article forum. This will show the thread list like normal, but the threads themselves will have the first post set up above the rest of the "comments"
  • The Helper The Helper:
    I don't really get that article forum but I think it is because I have never really seen it used on a multi post thread
  • Ghan Ghan:
    RpNation makes more use of it right now as an example: https://www.rpnation.com/news/
  • The Helper The Helper:
  • The Helper The Helper:
    What do you think Tom?
  • tom_mai78101 tom_mai78101:
    I will have to get used to this.
  • tom_mai78101 tom_mai78101:
    The latest news feed looks good

      The Helper Discord

      Staff online

      • Ghan
        Administrator - Servers are fun

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top