Thanks for the info everyone. I like the .fetch
and default
way!! I think I’m going to use that for now
I am using a Tuple because it works well for bracket notation access, its .to_json
converts it into a string delimited list, and intertwines beautifully with db.query
methods. Examples:
ItemQuery = "itemid, rpg_items_id, slot_position, q, equipped, sockets, identified, i_atk_speed, i_phys, i_crit_chance, crit_multiplier, i_hp, i_ms, i_cast_speed, in_item, socket_data, i_defense, to_life, quality, fire_res, cold_res, lightning_res, rare_name"
alias ItemTuple = {Int64, Int32, String, Int16, Int8, String, Int8, Int16, Int16, Int16, Int16, Int16, Int16, Int16, String, String, Int16, Int16, Int8, Int8, Int8, Int8, String}
def db_get_user_items(client, tabid = 0)
db.query_all "select #{ItemQuery} from rpg_user_items where rpg_character_id = ? and user_id = ? and in_stash = #{tabid} and hardcore = ? and ladder = ?", client.selected_characterid, client.user_id, client.hardcore, client.ladder, as: ItemTuple.types
end
I tried to use a class, but it became too convoluted. Had to maintain a DB.mapping, property
macros, create custom overloads for bracket notation access (which I couldn’t figure out how to do), create a to_json
overload to convert all ivars into a delimited string, etc. Just became too much. A Tuple
seems to do more stuff out of the box for what I need, and seems more powerful.
I use classes a lot, I just don’t think using a class for this is a good idea with my current knowledge of Crystal.
I suspect that this could be more easily solved with a struct, though. How do you get your hash in the first place?
Depends on the type of item. I have static Hashes loaded that represent the modifications to select from based on what item is being used. In the example below, it’s ModGlobalWeapons
or ModGlobalArmors
. The data is stored in MYSQL and exported as csv
, then converted into Hashes in Crystal.
Example:
when "transmute_orb"
raise "Item must be normal rarity." if current_item_mods.size > 0
mod_rolls = Array(String).new
query_update = QueryUpdate.new
if main_on_item["type"] == "Weapons"
mod_rolls = ModGlobalWeapons.dup
mod_rolls = mod_rolls.shuffle.first(2)
else # assume boots/armors
mod_rolls = ModGlobalArmors.dup
if main_on_item["type"] == "Gloves"
mod_rolls << "i_atk_speed"
end
mod_rolls = mod_rolls.shuffle.first(2)
end
mod_rolls.each do |mod_key|
mod_struct_main = GlobalItemModsMapping[mod_key]
mod_struct = mod_struct_main[mod_struct_main.keys.shuffle.first]
final_roll_value = rand(mod_struct.min_value..mod_struct.max_value)
query_update[mod_struct.mod_type] = final_roll_value
tuple_index = GlobalItemTuple.index(mod_struct.mod_type)
client.stash[tabid_on].items[on_itemid] = modify_item_tuple(client.stash[tabid_on].items[on_itemid], tuple_index, final_roll_value)
end
if query_update.size > 0
db.exec "update rpg_user_items set #{hash_to_delimited_query_list(query_update)} where itemid = ? and user_id = ?", on_itemid, client.user_id
client.send ({a: 4, new_data: query_update, q: new_item_quantity, on_itemid: on_itemid, itemid: incoming_itemid}), "ITEMUPDATE"
# Remove 1 quantity from the orb..
client.stash[tabid].items[incoming_itemid] = modify_item_tuple(item, 3, new_item_quantity)
else
raise "Item use failed.."
end