• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Custom Item System Part 3

Status
Not open for further replies.
Level 6
Joined
Apr 1, 2009
Messages
201
I am in the process of developing a custom item system. In this part of the system after the object has been cleaned, it can now be identified. What I mean by this is you dig up items that are unknown, which then have to be cleaned, turning it into a "General Item", and from there it is inspected to determine what the item is exactly. Part 3 is the inspecting process. Below is PART of my trigger. I was wondering if there was an easier way to do this or to store different "General Items" in another trigger so this part doesn't get any longer. I have about 16 "General Items" which will each have about 5-15 Items that can be identified from 1 "General Item".

  • Inspect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Inspect
    • Actions
      • -------- Set Unit --------
      • Set InspectUnit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Item-type of (Target item of ability being cast)) Equal to |c00FFFF00Amulet|R
        • Then - Actions
          • -------- Set Insepct Chance --------
          • Set InspectChances = (Random integer number between 1 and 100)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • InspectChances Greater than 0
              • InspectChances Less than or equal to 45
            • Then - Actions
              • -------- Remove "General Item" --------
              • Item - Remove (Target item of ability being cast)
              • -------- Add Identified Item --------
              • Hero - Create |cff32cd32Regular Amulet|r and give it to InspectUnit
              • -------- Display to player item name --------
              • Game - Display to (Player group((Owner of InspectUnit))) the text: |c00FFFF00Appears t...
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • InspectChances Greater than 45
              • InspectChances Less than or equal to 60
            • Then - Actions
              • Item - Remove (Target item of ability being cast)
              • Hero - Create |cff32cd32Silver Necklace|r and give it to InspectUnit
              • Game - Display to (Player group((Owner of InspectUnit))) the text: |c00FFFF00Appears t...
            • Else - Actions
 
Level 9
Joined
Jul 10, 2011
Messages
562
you could store the general item with the "real items" in a hash and call the saved items for each chance. (you could also store the chances for example if you want^^)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Eh.... exactly what claptomanic said. Create a Hashtable and store each itemChance on the ItemType ID. First one has 45% chance (1-45) second one hast 15 (46-60). You have to create a random integer for every drop chance, else, you would always have a drop.
 
Level 6
Joined
Apr 1, 2009
Messages
201
I could use a little help getting started. I'm not seeing where to store item types in Hashtables. I just checked the tutorials sections and found two dealing with Hastables, but both are for spells and not systems. Not sure how to tweak them, I haven't really dealt with Hastables before. Do I store the Item types in an item type variable with an array? Then save into my Hastable?? If so how would I set the percentages? Random integers between 1 - 45 for a 45% chance, then set another random value between 1-100 for each or will just one do?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
1. Create a Hashtable variable called "Hash"
2. On map header (The first object in the trigger list) do this:
3. set udg_Hash = InitHashtable()
4. Do the list this way
JASS:
// udg_Hash is the Hash we just created
// 'xyzx' is the ItemType Raw code. You can see it in the object editor by pressing CTRL+D. You have to use the quotes -> '' <-
// 0 is the "Slot" of the ItemType ID where we'll save the Chance
// YourChanceForThisItem is the chance you want that item to have (15, 28, 44, whatever)

set udg_Hash = InitHashtable()

call SaveInteger(udg_Hash, 'xxxx', 0, YourChanceForThisItem) // Item 1 Chance
call SaveInteger(udg_Hash, 'xxxx', 1, 'asdf') // Item 1 Item
call SaveInteger(udg_Hash, 'xxxx', 0, YourChanceForThisItem) // Item 2Chance
call SaveInteger(udg_Hash, 'xxxx', 1, 'asdf') // Item 2 Item
call SaveInteger(udg_Hash, 'xxxx', 0, YourChanceForThisItem) // Item 3 Chance
call SaveInteger(udg_Hash, 'xxxx', 1, 'asdf') // Item 3 Item

5. On the trigger you do
  • t
  • Custom script: set udg_IntegerVariableName = GetItemTypeId(GetManipulatedItem())
  • Set AnotherIntegerVariable = (Load 0 of IntegerVariableName from Hash)
  • Set ItemTypeVariable = (Load 1 of IntegerVariableName from Hash)
Now, you do the chance "If Random Integer Between 0 and 100 is less than or equal to AnotherIntegerVariable then -> Replace the Unidentified item with the ItemTypeVariable


Is store in the Unidentified item the Possible items that unidentified item can become, and the chance for each one. You also should use 1 slot to save the number of items that item can become, so, you can do 1 loop to determine the item that unidentified item will become.

You can work the chances this way:
If item 1 has 20% and item 2 has 5% chance, you check if The random integer is less than or equal to 20, ELSE, if it's less than or equal to 25 (since the loop will first check the Item1, then for item 2, only 21, 22, 23, 24, and 25 will be available.).

btw, This is a mere sketch, didn't work on it very much. It's just the idea.
 
Level 6
Joined
Apr 1, 2009
Messages
201
Let me see if I understand this correctly

'xxxx' = Item Type (Real Item)
'asdf' = Item Type (General Item)


Gets the item type id of the item being manipulated from the integer variable name
  • Custom script: set udg_IntegerVariableName = GetItemTypeId(GetManipulatedItem())
Load item type and chance
  • Set AnotherIntegerVariable = (Load 0 of IntegerVariableName from Hash)
Load item type (Real and General)
  • Set ItemTypeVariable = (Load 1 of IntegerVariableName from Hash)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
<< EDIT >>

This trigger holds all you need. This is the whole function.
- Registers all the item chances and possible outcomes.
- Removes the Unidentified Item
- Gives the Identified Item
- Displays text message with the new item name.
- Leakless.

JASS:
function ItemChanceConditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AUan' // Modify this ID with your IdentifyItem ability ID
endfunction

function ItemChance takes nothing returns nothing
    local integer itemID = GetItemTypeId(GetSpellTargetItem())
    local integer random  = GetRandomInt(1, 100)
    local item i
    set bj_forLoopAIndex = 1
    loop
        exitwhen bj_forLoopAIndex > LoadInteger(udg_Hash, itemID, 0)*2
        if random <= LoadInteger(udg_Hash, itemID, bj_forLoopAIndex) then
            call RemoveItem(GetSpellTargetItem())
            set i = CreateItem(LoadInteger(udg_Hash, itemID, bj_forLoopAIndex+1), 0, 0)
            call UnitAddItem(GetTriggerUnit(), i)
            call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Acquired |cffff0000" + GetItemName(i) + "|r")
            set bj_forLoopAIndex = 500 // This stops the loop
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex+2
    endloop
    set i = null
endfunction

//===========================================================================
function InitTrig_ItemChance takes nothing returns nothing
    set gg_trg_ItemChance = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ItemChance , EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ItemChance , Condition( function ItemChanceConditions))
    call TriggerAddAction( gg_trg_ItemChance, function ItemChance )
    local integer i = 0
    
    set udg_Hash = InitHashtable()

// Item ID is the UNIDENTIFIED ITEM
// 0 Holds the possible outcomes
// Impair slots holds the chances.
// Pair Slots hold the result item.
    
// Item 1 
    set i = 'xxxx' // ItemID
    call SaveInteger(udg_Hash, i, 0, 3) // 3 Possible items can become from this item identification
    call SaveInteger(udg_Hash, i, 1, 20) // 20% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 2, 'asdf') // Item
    call SaveInteger(udg_Hash, i, 3, 36) // 16% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 4, 'dfgh') // Item
    call SaveInteger(udg_Hash, i, 5, 100) // 64% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 6, 'ufom') // Item
    
// Item 2...
    set i = 'uuuu' // ItemID
    call SaveInteger(udg_Hash, i, 0, 3) // 3 Possible items can become from this item identification
    call SaveInteger(udg_Hash, i, 1, 2) // 2% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 2, 'asdf') // Item
    call SaveInteger(udg_Hash, i, 3, 36) // 34% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 4, 'dfgh') // Item
    call SaveInteger(udg_Hash, i, 5, 70) // 34% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 6, 'ufom') // Item
    
// Item 3...
endfunction
 
Last edited:
Level 6
Joined
Apr 1, 2009
Messages
201
Now I understand it. Just realized it won't solve my problem though. I wasn't thinking clearly when I posted this. Either way I will have to do a lot of copy and paste for the Item Remove, Create item and give to hero, and Display to player. I'm terribly sorry for wasting your time, +rep
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Me several modifications to the trigger to optimize it even more. I don't think it could get easier than that.
 
Last edited:
Level 6
Joined
Apr 1, 2009
Messages
201
That's very true, eventually I'll have to do that do all my triggers. I might as well do it now. I was just rushing to get a demo map ready. Love the system.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Ok. There are some things we could improve.

If you don't use the ItemLevel in the object editor we could use it as a "Chance". Reducing the number of Saving/Loadings by 1 for each possible item result. It's a bit better for the system itself, but modifying each item level is a lot messy and time consuming than it's with the hash :p
 
Level 6
Joined
Apr 1, 2009
Messages
201
I am using Kobas's IDS system. Although I can replace it, I only need two item slot restrictions. Also how do I set the spell that is cast on the item to identify it? Also do I increase the "0" after "i," ? I have added 6 more items to the trigger.

JASS:
call SaveInteger(udg_Hash, i, 0, 9) // 9 Possible items can become from this item identification
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I am using Kobas's IDS system. Although I can replace it, I only need two item slot restrictions. Also how do I set the spell that is cast on the item to identify it? Also do I increase the "0" after "i," ? I have added 6 more items to the trigger.

JASS:
call SaveInteger(udg_Hash, i, 0, 9) // 9 Possible items can become from this item identification

I don't think you have to modify anything in Kobas IDS system, but you have to test. This doesn't do anything too complicated

Base the spell of "Channel" and modify it however you want. Make it target only "Item". Then just use "A unit starts the effect of an ability" and condition "Ability being cast Equal To Your ability". I modified the Script in the other post to show you how.

Basically added this
JASS:
function ItemChanceConditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AUan' // Modify this ID with your IdentifyItem ability ID
endfunction

// All the item functions...

// This goes on the Trigger Creation Function.
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ItemChance , EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ItemChance , Condition( function ItemChanceConditions))
About the numbers:

0 - Item Results
1 - First Item Chance
2 - First Item ID
3 - Seconds Item Chance
4 - Second Item ID
... and so on untill 18 (9 chances, 9 items)
 
Level 6
Joined
Apr 1, 2009
Messages
201
Probably putting things in the wrong places but I keep getting errors. Here's what I have so far.

JASS:
function ItemChanceConditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A003' // Modify this ID with your IdentifyItem ability ID
endfunction

function ItemChance takes nothing returns nothing
    local integer itemID = GetItemTypeId(GetSpellTargetItem())
    local integer random  = GetRandomInt(1, 100)
    local integer i = 0
    set bj_forLoopAIndex = 1
    loop
        exitwhen bj_forLoopAIndex > LoadInteger(udg_Hash, itemID, 0)*2
        if random <= LoadInteger(udg_Hash, itemID, bj_forLoopAIndex) then
            call RemoveItem(GetSpellTargetItem())
            set i = CreateItem(LoadInteger(udg_Hash, itemID, bj_forLoopAIndex+1), 0, 0)
            call UnitAddItem(GetTriggerUnit(), i)
            call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Acquired |cffff0000" + GetItemName(i) + "|r")
            set bj_forLoopAIndex = 500 // This stops the loop
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex+2
    endloop
    set i = null
endfunction

//===========================================================================
function InitTrig_Inspect takes nothing returns nothing
    set gg_trg_ItemChance = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ItemChance , EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_ItemChance , Condition( function ItemChanceConditions))
    set udg_Hash = InitHashtable()

// Item ID is the UNIDENTIFIED ITEM
// 0 Holds the possible outcomes
// Impair slots holds the chances.
// Pair Slots hold the result item.
    
// Item 1
    set i = 'I001' // ItemID
    call SaveInteger(udg_Hash, i, 0, 9) // 9 Possible items can become from this item identification
    call SaveInteger(udg_Hash, i, 1, 10) // 10% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 2, 'I004') // Item
    call SaveInteger(udg_Hash, i, 3, 25) // 15% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 4, 'I00I') // Item
    call SaveInteger(udg_Hash, i, 5, 32) // 7% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 6, 'I00J') // Item
    call SaveInteger(udg_Hash, i, 7, 36) // 4% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 8, 'I00K') // Item
    call SaveInteger(udg_Hash, i, 9, 44) // 8% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 10, 'I00L') // Item
    call SaveInteger(udg_Hash, i, 11, 49) // 5% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 12, 'I00M') // Item
    call SaveInteger(udg_Hash, i, 13, 54) // 5% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 14, 'I00N') // Item
    call SaveInteger(udg_Hash, i, 15, 55) // 1% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 16, 'I000') // Item
    call SaveInteger(udg_Hash, i, 17, 100) // 45% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 18, 'I00O') // Item

// Item 2...
endfunction
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Triggers are made of 4 parts
1- The trigger itself
JASS:
set gg_trg_ItemChance = CreateTrigger(  )
2- The events
JASS:
call TriggerRegisterAnyUnitEventBJ( InitTrig_Inspect , EVENT_PLAYER_UNIT_SPELL_EFFECT )
3- The conditions
JASS:
call TriggerAddCondition( InitTrig_Inspect , Condition( function ItemChanceConditions))
4- The actions
JASS:
call TriggerAddAction( InitTrig_Inspect , function ItemChance )

You were adding the event and the conditions to a non-existing trigger (because you copied my code, and I named the trigger differently).
You weren't adding the trigger main actions
You are not creating the local integer i.

JASS:
function InitTrig_Inspect takes nothing returns nothing
    local integer i
    set gg_trg_ItemChance = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( InitTrig_Inspect , EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( InitTrig_Inspect , Condition( function ItemChanceConditions))
    call TriggerAddAction( InitTrig_Inspect , function ItemChance )
...
 
Level 6
Joined
Apr 1, 2009
Messages
201
Another attempt at it. I hope this is right. When I save with this I get 11 compile errors :/

JASS:
function ItemChanceConditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A003' // Modify this ID with your IdentifyItem ability ID
endfunction

function ItemChance takes nothing returns nothing
    local integer itemID = GetItemTypeId(GetSpellTargetItem())
    local integer random  = GetRandomInt(1, 100)
    local item i
    set bj_forLoopAIndex = 1
    loop
        exitwhen bj_forLoopAIndex > LoadInteger(udg_Hash, itemID, 0)*2
        if random <= LoadInteger(udg_Hash, itemID, bj_forLoopAIndex) then
            call RemoveItem(GetSpellTargetItem())
            set i = CreateItem(LoadInteger(udg_Hash, itemID, bj_forLoopAIndex+1), 0, 0)
            call UnitAddItem(GetTriggerUnit(), i)
            call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, 10, "Acquired |cffff0000" + GetItemName(i) + "|r")
            set bj_forLoopAIndex = 500 // This stops the loop
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex+2
    endloop
    set i = null
endfunction

//===========================================================================
function InitTrig_Inspect takes nothing returns nothing
    local integer i
    set gg_trg_ItemChance = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( InitTrig_Inspect , EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( InitTrig_Inspect , Condition( function ItemChanceConditions))
    call TriggerAddAction( InitTrig_Inspect , function ItemChance )   
    set udg_Hash = InitHashtable()

// Item ID is the UNIDENTIFIED ITEM
// 0 Holds the possible outcomes
// Impair slots holds the chances.
// Pair Slots hold the result item.
    
    set i = 'I001' // ItemID
    call SaveInteger(udg_Hash, i, 0, 9) // 9 Possible items can become from this item identification
    call SaveInteger(udg_Hash, i, 1, 10) // 10% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 2, 'I004') // Item
    call SaveInteger(udg_Hash, i, 3, 25) // 15% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 4, 'I00I') // Item
    call SaveInteger(udg_Hash, i, 5, 32) // 7% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 6, 'I00J') // Item
    call SaveInteger(udg_Hash, i, 7, 36) // 4% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 8, 'I00K') // Item
    call SaveInteger(udg_Hash, i, 9, 44) // 8% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 10, 'I00L') // Item
    call SaveInteger(udg_Hash, i, 11, 49) // 5% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 12, 'I00M') // Item
    call SaveInteger(udg_Hash, i, 13, 54) // 5% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 14, 'I00N') // Item
    call SaveInteger(udg_Hash, i, 15, 55) // 1% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 16, 'I000') // Item
    call SaveInteger(udg_Hash, i, 17, 100) // 45% to obtain item in Next Slot
    call SaveInteger(udg_Hash, i, 18, 'I00O') // Item
    
// Item 2...

// Item 3...
endfunction
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
What are the errors about? Copy/paste or take a screenshot.

Btw, you don't need to create all those comments on each line. It was just a guide to understand. You could just place the % to see it more clearly without the "to obtain item in Next Slot" and replace "// Item" with the real item name.

The idea of comments is letting you read and understand easily what the code means.
 
Level 6
Joined
Apr 1, 2009
Messages
201
Here they are
 

Attachments

  • Error 1.jpg
    Error 1.jpg
    433.7 KB · Views: 102
  • Error 2.jpg
    Error 2.jpg
    460.9 KB · Views: 93
Level 20
Joined
Jul 14, 2011
Messages
3,213
Well.. seems pretty clear to me.

1- "Undeclared variable udg_Hash" You have to create a Hashtable variable called "Hash"

2- "Undeclared variable gg_trg_ItemChance"
You have
JASS:
set gg_trg_ItemChance = CreateTrigger(  )
But should be
JASS:
set gg_trg_Inspect = CreateTrigger(  )
since that's the name of your trigger (gg_trg_YourTriggerName)
 
Level 6
Joined
Apr 1, 2009
Messages
201
Now I get one error "Undeclared variable InitTrig_Inspect" (4th line)

JASS:
function InitTrig_ItemChance takes nothing returns nothing
    local integer i
    set gg_trg_Inspect = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( InitTrig_Inspect , EVENT_PLAYER_UNIT_SPELL_EFFECT ) // Error is here
    call TriggerAddCondition( InitTrig_Inspect , Condition( function ItemChanceConditions))
    call TriggerAddAction( InitTrig_Inspect , function ItemChance )   
    set udg_Hash = InitHashtable()
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Oh... The thing is that Wacraft 3 compiles the InitTrig_TriggerName as numbers and InitTrig_Inspect corresponds to Number 1. We're adding the the function of the trigger being initializated, when we should add there the trigger itself.

JASS:
call TriggerRegisterAnyUnitEventBJ( gg_trg_Inspect , EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Inspect , Condition( function ItemChanceConditions))
call TriggerAddAction( gg_trg_Inspect , function ItemChance )

Done, it will work for sure.
 
Status
Not open for further replies.
Top