| 01-07-2009, 05:52 AM | #1 |
I saw Vexorian's 'Table' and I considered making something like it - but for groups of objects. I don't know why, it seemed like a good idea. I don't know if the U2I, D2I, It2I, etc. are redundant for H2I. Are they? I also don't know if B2I works. Do they work? This script is supposed to make it easy to store groups of stuff, which don't necessarily need to be of the same type ('handle', 'unit', integer, etc.). You can pick out the first, or a random thing, or a certain thing, or a thing matching a definition, from a group. Because these are all in a struct, you can share this data (I think...zzz); you can recycle the struct... etc... Each GroupData object is a bunch of groups that take up one 'mission' in the script's own gamecache. Each item in a group is associated with a 'key' that is: the group's label + its index in the group (I2S(thing) style gotten from 'Table'). Save stuff in a group - or singly, if you want - and retrieve them. You can retrieve a random trhing from a group (as PickRandomUnit/Player/whatever) or you can the first-saved thing in the group, or you can get a particular thing by its index in the group (if your way of saving the things in the group is so ordered and not dynamic according to game events), or you can just find which thing in the group matches whatever you are looking for. NOTE: No 2 groups can use the same label. Criticism? Anything I should change? JASS:library GroupData initializer Init function B2I takes boolean value returns integer return value return 0 endfunction function I2B takes integer value returns boolean if value != 0 and value != 1 then call ExecuteFunc("A non-real boolean value is being retrieved.") endif return value return false endfunction function R2IEx takes real value returns integer return I2R(value * 100.00) endfunction function I2REx takes integer value returns real return R2I(value) / 100.00 endfunction function U2I takes unit value returns integer return value return 0 endfunction function I2U takes integer value returns unit return value return null endfunction function It2I takes item value returns integer return value return 0 endfunction function I2It takes integer value returns item return value return null endfunction function D2I takes destructable value returns integer return value return 0 endfunction function I2D takes integer value returns destructable return value return null endfunction globals private constant integer MAX_INSTANCES = 8190 private constant integer MAX_LABELS = 4094 //Total members in a group data = 8190 //.intCountLabel + MAX_LABELS*(.strLabel[]) + MAX_LABELS*(.intLabelCountItem[]) = 8190 //1 + 2(MAX_LABELS) = 8190 //MAX_LABELS = (8190-1)/2 // = 4094 //NOTE: Though the number of Label-Groups // are limited (MAX_LABELS), the number of the data // that can be stored in one Label-Group is unlimited, // as in gamecache. endglobals function interface MatcherFunc takes integer value returns boolean struct GroupData[MAX_INSTANCES] private string array strLabel[MAX_LABELS] private integer array intLabelCountItem[MAX_LABELS] private integer intCountLabel public static method Create takes nothing returns GroupData return GroupData.allocate() endmethod public method GetFromLabelMatching takes string label, MatcherFunc func returns integer local integer INT_Index = 0 local integer INT_Index2 = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then loop exitwhen INT_Index2 == .intLabelCountItem[INT_Index] if .func.evaluate(GetStoredInteger(GroupData.gc, I2S(this), label+I2S(INT_Index))) then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(INT_Index)) endif set INT_Index2 = INT_Index2 + 1 endloop endif set INT_Index = INT_Index + 1 endloop return 0 endmethod public method GetFirstOfLabel takes string label returns integer local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label and .intLabelCountItem[INT_Index] > 0 then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(0)) endif set INT_Index = INT_Index + 1 endloop return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(0)) endmethod public method GetFromLabel takes string label, integer index returns integer local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label and index < .intLabelCountItem[INT_Index] then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(index)) endif set INT_Index = INT_Index + 1 endloop return 0 endmethod public method GetRandomFromLabel takes string label returns integer local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(GetRandomInt(0, .intLabelCountItem[INT_Index]))) endif set INT_Index = INT_Index + 1 endloop return 0 endmethod public method AddLabel takes string label returns boolean local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then return false endif endloop set .strLabel[.intCountLabel] = label set .intCountLabel = .intCountLabel + 1 return true endmethod public method RemoveLabel takes string label returns boolean local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then call .FlushLabel(label) set .intCountLabel = .intCountLabel - 1 set .strLabel[INT_Index] = .strLabel[.intCountLabel] set .strLabel[.intCountLabel] = null return true endif endloop return false endmethod public method AddToLabel takes string label, integer value returns boolean local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then call StoreInteger(GroupData.gc, I2S(this), I2S(.intLabelCountItem[INT_Index]), value) set .intLabelCountItem[INT_Index] = .intLabelCountItem[INT_Index] + 1 return true endif set INT_Index = INT_Index + 1 endloop return false endmethod public method RemoveFromLabel takes string label, integer value returns boolean local integer INT_Index = 0 local integer INT_Index2 = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then loop exitwhen INT_Index2 == .intLabelCountItem[INT_Index] if GetStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2)) == value then call FlushStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2)) set .intLabelCountItem[INT_Index] = .intLabelCountItem[INT_Index] - 1 call StoreInteger((GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2, GetStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(.intLabelCountItem[INT_Index]))) call FlushStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(.intLabelCountItem[INT_Index])) return true endif set INT_Index2 = INT_Index2 + 1 endloop endif set INT_Index = INT_Index + 1 endloop return false endmethod public method FlushLabel takes string label returns boolean local integer INT_Index = 0 local integer INT_Index2 = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then loop exitwhen INT_Index2 == .intLabelCountItem[INT_Index] call FlushStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2)) set INT_Index2 = INT_Index2 + 1 endloop endif set INT_Index = INT_Index + 1 endloop return false endmethod public method FlishAllLabels takes nothing returns nothing call FlushStoredMission(GroupData.gc, I2S(this)) endmethod public method Destroy takes nothing returns nothing call .FlushAll() set this = 0 endmethod private static gamecache gc = null public static method Initialize takes nothing returns nothing set GroupData.gc = InitGameCache("GroupData") endmethod endstruct private function Init takes nothing returns nothing call GroupData.Initialize() endfunction endlibrary |
| 01-07-2009, 10:27 AM | #2 |
call ExecuteFunc("A non-real boolean value is being retrieved.") Youre crashing WC3 on purpose here? You can simplify the I2B function if you remove that if-statement. Theres no need for it. Oh, you shouldnt use I2H. JASS:function R2IEx takes real value returns integer return I2R(value * 100.00) endfunction function I2REx takes integer value returns real return R2I(value) / 100.00 endfunction |
| 01-07-2009, 12:44 PM | #3 |
JASS:library GroupData initializer Init function B2I takes boolean value returns integer return value return 0 endfunction function I2B takes integer value returns boolean return value return false endfunction function R2IEx takes real value returns integer return R2I(value * 100.00) endfunction function I2REx takes integer value returns real return I2R(value) / 100.00 endfunction function U2I takes unit value returns integer return value return 0 endfunction function I2U takes integer value returns unit return value return null endfunction function It2I takes item value returns integer return value return 0 endfunction function I2It takes integer value returns item return value return null endfunction function D2I takes destructable value returns integer return value return 0 endfunction function I2D takes integer value returns destructable return value return null endfunction globals private constant integer MAX_INSTANCES = 8190 private constant integer MAX_LABELS = 4094 //Total members in a group data = 8190 //.intCountLabel + MAX_LABELS*(.strLabel[]) + MAX_LABELS*(.intLabelCountItem[]) = 8190 //1 + 2(MAX_LABELS) = 8190 //MAX_LABELS = (8190-1)/2 // = 4094 //NOTE: Though the number of Label-Groups // are limited (MAX_LABELS), the number of the data // that can be stored in one Label-Group is unlimited, // as in gamecache. endglobals function interface MatcherFunc takes integer value returns boolean struct GroupData[MAX_INSTANCES] private string array strLabel[MAX_LABELS] private integer array intLabelCountItem[MAX_LABELS] private integer intCountLabel public static method Create takes nothing returns GroupData return GroupData.allocate() endmethod public method GetFromLabelMatching takes string label, MatcherFunc func returns integer local integer INT_Index = 0 local integer INT_Index2 = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then loop exitwhen INT_Index2 == .intLabelCountItem[INT_Index] if func.evaluate(GetStoredInteger(GroupData.gc, I2S(this), label+I2S(INT_Index))) then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(INT_Index)) endif set INT_Index2 = INT_Index2 + 1 endloop endif set INT_Index = INT_Index + 1 endloop return 0 endmethod public method GetFirstOfLabel takes string label returns integer local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label and .intLabelCountItem[INT_Index] > 0 then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(0)) endif set INT_Index = INT_Index + 1 endloop return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(0)) endmethod public method GetFromLabel takes string label, integer index returns integer local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label and index < .intLabelCountItem[INT_Index] then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(index)) endif set INT_Index = INT_Index + 1 endloop return 0 endmethod public method GetRandomFromLabel takes string label returns integer local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then return GetStoredInteger(GroupData.gc, I2S(this), label+I2S(GetRandomInt(0, .intLabelCountItem[INT_Index]))) endif set INT_Index = INT_Index + 1 endloop return 0 endmethod public method AddLabel takes string label returns boolean local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then return false endif endloop set .strLabel[.intCountLabel] = label set .intCountLabel = .intCountLabel + 1 return true endmethod public method RemoveLabel takes string label returns boolean local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then call .FlushLabel(label) set .intCountLabel = .intCountLabel - 1 set .strLabel[INT_Index] = .strLabel[.intCountLabel] set .strLabel[.intCountLabel] = null return true endif endloop return false endmethod public method AddToLabel takes string label, integer value returns boolean local integer INT_Index = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then call StoreInteger(GroupData.gc, I2S(this), I2S(.intLabelCountItem[INT_Index]), value) set .intLabelCountItem[INT_Index] = .intLabelCountItem[INT_Index] + 1 return true endif set INT_Index = INT_Index + 1 endloop return false endmethod public method RemoveFromLabel takes string label, integer value returns boolean local integer INT_Index = 0 local integer INT_Index2 = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then loop exitwhen INT_Index2 == .intLabelCountItem[INT_Index] if GetStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2)) == value then call FlushStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2)) set .intLabelCountItem[INT_Index] = .intLabelCountItem[INT_Index] - 1 call StoreInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2), GetStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(.intLabelCountItem[INT_Index]))) call FlushStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(.intLabelCountItem[INT_Index])) return true endif set INT_Index2 = INT_Index2 + 1 endloop endif set INT_Index = INT_Index + 1 endloop return false endmethod public method FlushLabel takes string label returns boolean local integer INT_Index = 0 local integer INT_Index2 = 0 loop exitwhen INT_Index == .intCountLabel if .strLabel[INT_Index] == label then loop exitwhen INT_Index2 == .intLabelCountItem[INT_Index] call FlushStoredInteger(GroupData.gc, I2S(this), .strLabel[INT_Index]+I2S(INT_Index2)) set INT_Index2 = INT_Index2 + 1 endloop endif set INT_Index = INT_Index + 1 endloop return false endmethod public method FlushAllLabels takes nothing returns nothing call FlushStoredMission(GroupData.gc, I2S(this)) endmethod public method Destroy takes nothing returns nothing call .FlushAllLabels() set this = 0 endmethod private static gamecache gc = null public static method Initialize takes nothing returns nothing set GroupData.gc = InitGameCache("GroupData") endmethod endstruct private function Init takes nothing returns nothing call GroupData.Initialize() endfunction endlibrary Anything else? P.S. I tested out I2B(10) and it worked. By and If result == true elseif result == false else run, I found out that it returns something other than true or false. What else can be the value of a boolean besides 'true' and 'false'? |
| 01-07-2009, 01:45 PM | #4 |
JASS:function I2B takes integer i returns boolean return i==1 endfunction |
| 01-07-2009, 09:30 PM | #5 | |
Quote:
'true' 'false' 'broken' |
| 01-08-2009, 01:49 AM | #6 |
'Broken' doesn't seem to be a valid boolean value. |
| 01-08-2009, 06:52 AM | #7 |
Why bother with booleans? 0/1 ftw. |
| 01-08-2009, 10:46 AM | #8 |
I don't know but I want to accommodate them. |
| 01-08-2009, 04:33 PM | #9 |
JASS:function I2B takes integer value returns boolean if (value<=0) then return false endif return true endfunction Or as Jazradel says: JASS:function I2B takes integer value returns boolean local boolean bool=null if (value==0) then set bool=false elseif (value==1) then set bool=true endif return bool endfunction I'm not sure about the third return value type, but it should be: true, false, or null. |
| 01-09-2009, 09:47 PM | #10 |
You shouldn't be typecasting integers to handles... |
| 01-10-2009, 08:27 AM | #11 |
What is 'typecasting'? |
| 01-10-2009, 09:23 AM | #12 |
You ask that as if all the knowledge of this world was not at your fingertips. I, of course, speak of the return bug. |
| 01-10-2009, 11:59 AM | #13 |
So why shouldn't I be typecasting integers to handles? |
| 01-10-2009, 12:12 PM | #14 | |
Quote:
SO remember: - H2I is good - I2H is evil |
| 01-10-2009, 04:48 PM | #15 |
Integer to Handle conversions are dangerous because you aren't sure if the integer you're typecasting to a certain handle type is valid, destroying triggers with triggeractions that still executes causes the handle allocator to give 2 different handles the same handle Id. For example, you can typecast integer value 1 to a unit JASS:function I2H takes integer i returns unit return i return null endfunction function test takes nothing returns nothing local unit u=I2H(1) call KillUnit(u) set u=null endfunction |
