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

Hardcore math question

Status
Not open for further replies.
Level 17
Joined
Jul 17, 2011
Messages
1,864
say i have 30 completely random items (random meaning they have different rawcodes e.g boots of speed, sobi mask, ring of regen...) and want to put them in an array, how do i do that so that each item will be unique to the array (no two items will repeat) speed can be compromised
currently to put the items in an array i am using:
  • itemAlgorithm
    • Events
      • Time - Elapsed game time is 2.00 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 30, do (Actions)
        • Loop - Actions
          • Set ItemArray11[(Integer A)] = (Random level -1 Any Class item-type)
random level -1 means that it is any level of item
cant figure out a way of checking whether the item has been already added
pls help :)
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Now, what has this to do with maths? You would either iterate over the array and see whether the rolled item is in or assign a value directly to the item when adding it that you check for. Randomizing to find the right values is shitty though because the worst case is infinitely expensive and a further problem may arise because of the limited amount of operations a thread in wc3 can handle.
 
Level 17
Joined
Jul 17, 2011
Messages
1,864
Now, what has this to do with maths? You would either iterate over the array and see whether the rolled item is in or assign a value directly to the item when adding it that you check for. Randomizing to find the right values is shitty though because the worst case is infinitely expensive and a further problem may arise because of the limited amount of operations a thread in wc3 can handle.

hmm all i need to do is put all items in an array without any 2 items being the same and i think this is the best way to start. i dont quite understand what you are saying could you post an example code, or if you know a better way of doing it then feel free to share.
 
Level 14
Joined
Sep 17, 2009
Messages
1,297
I suggest to flag already chosen items with a boolean, and check if random chooses.
I mean Save Te selected item types in a hasthtable, and when u choose a random item, check if you saved that itemtype before or not. If yes, choose another item...
Not the best solution, but this is the first thing comes to my mind after "Do an item group, and remove picked items from there"
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
gorillabull

1- Create all the items you want to add in the array in a small region of the map
2- Create a trigger that Picks Every Item in that region
3- Get the Rawcode of the Picked ITEM-TYPE
4- Save the rawcode of the Picked Item Typein Items. And remove the picked item.

You'll need 1 integer variable: Count
You'll need 1 Item-Type array: Items

JASS:
function ItemArray takes nothing returns nothing
    set udg_Count = ( udg_Count + 1 )
    set udg_Items[udg_Count] = GetItemTypeId(GetEnumItem())
    call BJDebugMsg("Items[" + I2S(udg_Count) + "]" + " = |cffff0000Name:|r " + GetItemName(GetEnumItem()) + " -- |cffff0000Raw Code:|r " + I2S(udg_Id))
    call RemoveItem(GetEnumItem())
endfunction

function ItemGroup takes nothing returns nothing
    set udg_Count = 0
    set udg_Id = 0
    call EnumItemsInRect(bj_mapInitialPlayableArea /*This is the whole map area*/, null, function ItemArray)
endfunction

//===========================================================================
function InitTrig_Item_Array takes nothing returns nothing
    set gg_trg_Item_Array = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Item_Array, 0.00, false )
    call TriggerAddAction( gg_trg_Item_Array, function ItemGroup )
endfunction


  • Item Array GUI
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set Count = 0
      • Item - Pick every item in (Playable map area) and do (Actions)
        • Loop - Actions
          • Set Count = (Count + 1)
          • Set Items[Count] = (Item-type of (Picked item))
          • Custom Script: call BJDebugMsg("Items[" + I2S(udg_Count) + "]" + " = |cffff0000Name:|r " + GetItemName(GetEnumItem()) + " -- |cffff0000Raw Code:|r " + I2S(udg_Id))
          • Item - Remove (Picked item)
The BJDebugMsg action can be deleted.

This way the game will pick each item in the region, take that item type ID, and save it in the Items array that will grow based on the number of items (Count = Count + 1) you place in the region. The only thing you have to do is create the region, and manually add the items there. They will be removed, so, doesn't matter where you do it. You can also turn off and destroy the trigger, the rect and the region after it's done.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Better for the execution would be to explicitly enter the item types. Some tools like GMSI were made to pickup data from object editor to jass, so you would not have to write it manually. There are not good jass-only options for reading object editor stuff. Would you not want a better classification anyway to exclude unwanted item types? When you have to classify in object editor, you could as well do it in triggers.

For not adding the same value twice as I have suggested above:

Since the number of iterations needed to roll a new unique item is arbitrary, I have not taken a ForEachInteger-loop here but a trigger recursion.

method 1:

  • addItems
    • Events
    • Conditions
    • Actions
      • Set rolledItem = (Random level -1 Any Class item-type)
      • Set found = False
      • For each (Integer A) from 1 to itemsCount, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Conditions
              • rolledItem Equal To items[(Integer A)]
            • 'THEN'-Actions
              • Set found = True //no break option in GUI and loops are very inflexible anyway, so go over the whole array
            • 'ELSE'-Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Conditions
          • found Equal To False
        • 'THEN'-Actions
          • Set items[itemsCount] = rolledItem
          • Set itemsCount = (itemsCount + 1)
        • 'ELSE'-Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Conditions
          • <cancelCondition> //do not know how you want to know/determine when it's time to stop searching for further items
        • 'THEN'-Actions
          • Trigger - Run (This trigger) (ignoring conditions)
        • 'ELSE'-Actions
  • start
    • Actions
      • itemsCount = 0
      • Trigger - Run addItems (ignoring conditions)
method 2:

  • addItems
    • Events
    • Conditions
    • Actions
      • Set rolledItem = (Random level -1 Any Class item-type)
      • Custom script: set udg_index = udg_rolledItem //integer variable named index in GUI
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Conditions
          • (Load 0 of index from table) Equal To False
        • 'THEN'-Actions
          • Set items[itemsCount] = rolledItem
          • Set itemsCount = (itemsCount + 1)
          • Hashtable - Save True as 0 of index in table
        • 'ELSE'-Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Conditions
          • <cancelCondition> //do not know how you want to know/determine when it's time to stop searching for further items
        • 'THEN'-Actions
          • Trigger - Run (This trigger) (ignoring conditions)
        • 'ELSE'-Actions
  • start
    • Actions
      • itemsCount = 0
      • Hashtable - Create a hashtable
      • Set table = (Last created hashtable)
      • Trigger - Run addItems (ignoring conditions)
@Spartipilo: That's as good as classifying them anew.

While we are at it, we could also browse the whole integer range between I000 and IZZZ and check whether GetObjectName(id) != null. ~.~ Under the condition that you have not created any outside of these bounds. When creating new items, you normally get I000, I001, I002 etc. in row but the standard items are still spread out among mentioned range.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Well.. it's pretty simple to create the region and the items he wants to classify. That simple trigger will array them. It's similar to what gorillabull asked. Your methods works too.
 
Level 17
Joined
Jul 17, 2011
Messages
1,864
funny thing is that Spartipilo's method works the same way every time. when i put items in a region and pick each one of them, the array index for each item stays the same even if i restart the map for example book of the dead will always have an array index of 1 unless i move its location i was going to use waterknight's method since the items will not be shuffled every time i start me map but this is no longer a problem thank you for your posts :goblin_good_job::goblin_good_job::goblin_good_job:
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I'm not sure how Wc3 picks the items in a región. I tough it was random. It would be nice to find the order in which Wc3 picks items .

EDIT:
· It's not based on the distance from the center of the region.
· It's not based on the Item Name
· It's not based on the Item-Type ID
· It's not based on the X or Y of the item.
· It's not based on the Item Health
· It's not based on item Custom Value
· It's not the order in which the items were created (placed in the editor), neither the inverse of it. *
· It's not based on the item Priority *


* The placement order in the Editor has something to do. the order from 1 to 5 was inverse of the order in which I placed them, but when I repeated one of them, it didn't took the 6th place, but the 2th. Same happened with Item Priority.
 
Last edited:
Level 17
Joined
Jul 17, 2011
Messages
1,864
no i have checked that its not it random seed is only for random numbers i can only imagine that it has to do with the item's saved position in the map script but how exactly it works i have no idea

EDIT: i will also note that if you are trying to index the life of the item with this method then you will need a wait of no less than one second in the loop otherwise the item's life will not be set
 
Last edited:
Status
Not open for further replies.
Top