HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

GetItemCostById

06-08-2006, 04:57 AM#1
weaaddar
Edit: Version 1.1 Adds lumber cost getting magic.

This is a demo map to show off my work around to get an item's cost.

Picking up an item will cause a text message to appear with its name, and the items cost, after which the item is destroyed.

Code:
|----------------------------------------------------------------
| What is this map for?
|----------------------------------------------------------------
 ____________________________________________________________________________
|function GetItemCostById takes integer id,boolean whichtype returns integer |
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

As the name suggests, given an item id, it will get its cost.
When whichtype is true it returns gold, otherwise lumber
This is for me a very seeked functionality, so I'm very happy.
This is very effecient, and about as customizable as a standalone function gets.

Implementation is very easy:
1) Create a gamecache variable called gc
2) Copy the trigger GetItemCostById to your map.

That is it. If you can get Jesp Spells to work this function shouldn't be that hard!

|---------------------------------------------------------------
|How does it work?
|---------------------------------------------------------------

It makes a shop and a hero for player 15, and places them outside of the viewable map area.
When called with an id
1) I check in gamecache if I already stored the item's cost, if I did I return it.
2) Otherwise I add 50,000 gold and lumber to player 15's gold
3) Then I add the item's id to the shop
4) I order the hero to buy the item
5) I figure out how much the item cost, by doing 50,000-Current gold/lumber for player 15
6) I cache the cost
7) I destroy the item, and remove it from the stock of the shop
8) I return the cost

ChangeLog
==============
1.1 Added support to get an items lumber cost. Made the code a bit cleaner.

____________________

cohadar has updated this function to use the new vJASS syntax and has fixed a bug when both lumber and gold cost were 0. Thanks to him we have a new version (which uses Vexorian's Table):
Collapse JASS:
//===========================================================================
//  vJASS version of weaaddar's GetItemCostById system
//===========================================================================
//
//  * Uses Table system
//  * Fixed an issue that could happen if item cost was zero for both gold and lumber
//  * This version is compatible with original one
//  * Added some helper functions: GetItemGoldCost, GetItemLumberCost, GetItemGoldCostById, GetItemLumberCostById
//
//===========================================================================
library GetItemCostById initializer Init uses Table

globals
    private constant player  BuyerPlayer = Player(15)
    private constant integer BuyerTypeId = 'hpal'
    private constant integer ShopTypeId = 'nshe'
    private constant integer MAX_PRICE = 50000
    
    // check Init function
    private Table GoldPrice = 0
    private Table LumberPrice = 0
    private unit Buyer = null
    private unit Shop = null
endglobals

//===========================================================================
//  whichtype == true --> gold
//  whichtype == false --> lumber
//===========================================================================
function GetItemCostById takes integer id, boolean whichtype returns integer
    local integer gold
    local integer lumber

    if GoldPrice.exists(id) then
        set gold = GoldPrice[id]
        set lumber = LumberPrice[id]
    else
        call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD,   MAX_PRICE)
        call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER, MAX_PRICE)
        call AddItemToStock(Shop, id, 1, 1)
        call IssueNeutralImmediateOrderById(BuyerPlayer, Shop, id)
        call RemoveItem(UnitItemInSlot(Buyer, 0))
        call RemoveItemFromStock(Shop, id)
        set gold   = MAX_PRICE - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD)
        set lumber = MAX_PRICE - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER)
        set GoldPrice[id] = gold
        set LumberPrice[id] = lumber
    endif
    
    if whichtype then
        return gold
    else
        return lumber
    endif
endfunction

//===========================================================================
function GetItemGoldCost takes item i returns integer
    return GetItemCostById(GetItemTypeId(i), true)
endfunction

//===========================================================================
function GetItemLumberCost takes item i returns integer
    return GetItemCostById(GetItemTypeId(i), false)
endfunction

//===========================================================================
function GetItemGoldCostById takes integer id returns integer
    return GetItemCostById(id, true)
endfunction

//===========================================================================
function GetItemLumberCostById takes integer id returns integer
    return GetItemCostById(id, false)
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local rect r = GetWorldBounds()
    
    set Buyer = CreateUnit(BuyerPlayer, BuyerTypeId, 0, 0, 0)
    call SetUnitX(Buyer, GetRectMaxX(r))
    call SetUnitY(Buyer, GetRectMaxY(r))
    
    set Shop = CreateUnit(BuyerPlayer, ShopTypeId, 0, 0, 0)
    call SetUnitX(Shop,GetRectMaxX(r))
    call SetUnitY(Shop,GetRectMaxY(r))
    
    call UnitAddAbility(Shop, 'Asid')
    call UnitRemoveAbility(Shop, 'Awan')
    call UnitAddAbility(Shop, 'Aloc')

    set GoldPrice = Table.create()
    set LumberPrice = Table.create()
    
    call RemoveRect(r)
    set r = null
endfunction

endlibrary
Attached Images
File type: jpgGetItemCostById.JPG (50.3 KB)
Attached Files
File type: w3xGetItemCostById.w3x (14.8 KB)
06-08-2006, 06:07 AM#2
Blade.dk
Very nice, approved :).
06-08-2006, 07:19 AM#3
BertTheJasser
That's juts really nice. +Rep
06-08-2006, 07:26 AM#4
aquilla
I've seen this function on wc3j but this is better. A little note though; items that cost lumber won't be sold (if anyone has that). Oh, and you forgot to null player p

nice work :)
06-08-2006, 07:49 AM#5
PipeDream
Ah glad to see it got solved.
Quote:
you forgot to null player p
No, only leaks if you try to deallocate.
06-08-2006, 08:22 AM#6
Anitarf
As far as I was told it leaks a bit anyway, the big problem is the handle index, which doesn't matter in this case since players don't get removed, but the pointer itself supposedly leaks a few bytes as well.

Is it neccesary to cache items? I understand getting it's cost is a complicated procedure, but since it probably isn't used too often, it shouldn't be such a performance drain. Not that making a gc variable is soo hard, but... Is it at least compatible with CSCache, for example, so that they could use the same game cahce?

Other than these cople of questions, it's a really cool function.
06-08-2006, 01:43 PM#7
Chuckle_Brother
Super useful stuff right there.

Would rep, but it goes against my beliefs.
06-08-2006, 02:56 PM#8
weaaddar
Right, I'm making a pocket shop and so I need this to help me do selling/buying. I didn't realize there are any melee items that cost wood but if needed I could make a version that gets both wood and gold and returns that in a location list or something.
06-08-2006, 03:15 PM#9
emjlr3
neato, nicely done
06-08-2006, 04:01 PM#10
weaaddar
Uploaded version 1.1 gets lumber costs too.
06-10-2006, 11:55 PM#11
weaaddar
sheep is still visible :?
Attached Images
File type: jpgsheep.JPG (6.4 KB)
12-15-2008, 05:31 PM#12
cohadar
Just a fresh remake of an old script.
You can attach it to the original submission.
I wish no credit for this.
Collapse JASS:
//===========================================================================
//  vJASS version of weaaddar's GetItemCostById system
//===========================================================================
//
//  * Uses Table system
//  * Fixed an issue that could happen if item cost was zero for both gold and lumber
//  * This version is compatible with original one
//  * Added some helper functions: GetItemGoldCost, GetItemLumberCost, GetItemGoldCostById, GetItemLumberCostById
//
//===========================================================================
library GetItemCostById initializer Init uses Table

globals
    private constant player  BuyerPlayer = Player(15)
    private constant integer BuyerTypeId = 'hpal'
    private constant integer ShopTypeId = 'nshe'
    private constant integer MAX_PRICE = 50000
    
    // check Init function
    private Table GoldPrice = 0
    private Table LumberPrice = 0
    private unit Buyer = null
    private unit Shop = null
endglobals

//===========================================================================
//  whichtype == true --> gold
//  whichtype == false --> lumber
//===========================================================================
function GetItemCostById takes integer id, boolean whichtype returns integer
    local integer gold
    local integer lumber

    if GoldPrice.exists(id) then
        set gold = GoldPrice[id]
        set lumber = LumberPrice[id]
    else
        call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD,   MAX_PRICE)
        call SetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER, MAX_PRICE)
        call AddItemToStock(Shop, id, 1, 1)
        call IssueNeutralImmediateOrderById(BuyerPlayer, Shop, id)
        call RemoveItem(UnitItemInSlot(Buyer, 0))
        call RemoveItemFromStock(Shop, id)
        set gold   = MAX_PRICE - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_GOLD)
        set lumber = MAX_PRICE - GetPlayerState(BuyerPlayer, PLAYER_STATE_RESOURCE_LUMBER)
        set GoldPrice[id] = gold
        set LumberPrice[id] = lumber
    endif
    
    if whichtype then
        return gold
    else
        return lumber
    endif
endfunction

//===========================================================================
function GetItemGoldCost takes item i returns integer
    return GetItemCostById(GetItemTypeId(i), true)
endfunction

//===========================================================================
function GetItemLumberCost takes item i returns integer
    return GetItemCostById(GetItemTypeId(i), false)
endfunction

//===========================================================================
function GetItemGoldCostById takes integer id returns integer
    return GetItemCostById(id, true)
endfunction

//===========================================================================
function GetItemLumberCostById takes integer id returns integer
    return GetItemCostById(id, false)
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local rect r = GetWorldBounds()
    
    set Buyer = CreateUnit(BuyerPlayer, BuyerTypeId, 0, 0, 0)
    call SetUnitX(Buyer, GetRectMaxX(r))
    call SetUnitY(Buyer, GetRectMaxY(r))
    
    set Shop = CreateUnit(BuyerPlayer, ShopTypeId, 0, 0, 0)
    call SetUnitX(Shop,GetRectMaxX(r))
    call SetUnitY(Shop,GetRectMaxY(r))
    
    call UnitAddAbility(Shop, 'Asid')
    call UnitRemoveAbility(Shop, 'Awan')
    call UnitAddAbility(Shop, 'Aloc')

    set GoldPrice = Table.create()
    set LumberPrice = Table.create()
    
    call RemoveRect(r)
    set r = null
endfunction

endlibrary
12-16-2008, 12:15 AM#13
Pyrogasm
Why is H2I in there? You never use it.

Other than that I see this being fine, though I would also add:
Collapse JASS:
globals
    boolean COST_TYPE_GOLD = true
    boolean COST_TYPE_LUMBER = false
endglobals
For the sake of clarity and ease of understanding in code that uses this function.
12-16-2008, 02:12 AM#14
Ammorth
Only thing I would do is move to Tables so that you don't have a gamecache just for this script.
12-16-2008, 04:36 AM#15
Pyrogasm
Table uses gamecache...