| 04-04-2009, 11:33 PM | #1 |
ChanceToProc by Ammorth Documentation included in script. Changed the weight to be effective over the entire range (from 0.00 to 1.00) and removed the destroy function. JASS:// ================================================================================== // ChanceToProc - by Ammorth, April 13, 2009 - rev2 // Please give credit when using this in your map // This, and myself, can be found at wc3c.net // // Can be used for random events to prevent a string of the same event happening for // an extended period of time (think critical strike or bash). // // This does not return a number, only if it proced or not! // // Requirements: // - vJass // // Installation: // - Create a new trigger called ChanceToProc and convert it to custom text // - Copy the code to the new trigger, placing everything // // How To Use: // - Create a new Chance struct with Chance.create(percent, weight) // - call .isProc() to get if an event is to proc // - call .getWeight() and .getPercent() to check the current values // - call .setPercent(percent, weight) to chance the percent and weight values // - call .reset() to reset the proc chance "table" // - destroy with .destroy() // // Notes: // - Percent and weight are values within 0.000 and 1.000, other values // will be rounded to this range and will show a message when in debug mode. // - .isProc(), when called, will change the chance to stop strings of the event // from happenning. Therefore, only call this once each time, as it does change. // - Weight is a scalar value that multiplies the weight value (based on the base percent) // which determines how much the code tries to change the base percent and keep the short // term random within the desired value. Aka: A higher weight will me less randomness // while a lower weight will be more random but may deviate farther from the desired percent // Using a weight value of 0 will cause the script to act like the generic "is X greater than number." // // ================================================================================== library ChanceToProc struct Chance private real base private real current private real weight method setPercent takes real base, real weight returns nothing if base < 0. then set .base = 0. debug call BJDebugMsg("SpecialRandom: Base must be between 0.00 and 1.00") elseif base > 1. then set .base = 1. debug call BJDebugMsg("SpecialRandom: Base must be between 0.00 and 1.00") else set .base = base endif if weight < 0. then set .weight = 0. debug call BJDebugMsg("SpecialRandom: Weight must be between 0.00 and 1.00") elseif weight > 1. then set .weight = 1. debug call BJDebugMsg("SpecialRandom: Weight must be between 0.00 and 1.00") else set .weight = weight endif set .weight = .weight/4 // since weight is only effective from 0.0 to .25, this normalizes it up to 1.0 set .current = base endmethod static method create takes real base, real weight returns Chance local Chance this = Chance.allocate() call .setPercent(base, weight) return this endmethod method isProc takes nothing returns boolean // true if procs (for lack of a better word) if .base == 1.0 then // why should it even be random then? return true elseif .base == .0 then // why should it even be random then? return false else if (.current >= GetRandomReal(0., 1.)) then // this is the random part set .current = .current - ((.weight)/(.base)) //reduce the threshold to make it less likely return true else set .current = .current + ((.weight)/(1-.base)) //increase the threshold to make it more likely return false endif endif endmethod method getPercent takes nothing returns real return .base endmethod method getWeight takes nothing returns real return .weight*4 // multiply by 4 to get back to the original value endmethod method reset takes nothing returns nothing set .current = .base // incase you want to reset the threshold for some reason endmethod endstruct endlibrary |
| 04-05-2009, 04:49 AM | #2 |
I'm confused? How is this different than simply using GetRandomInt(0,100) > X? |
| 04-05-2009, 05:34 AM | #3 |
A 5% proc, although not likely has a chance to proc 10 times in a row. This stops that by changing X by how many times a proc or not proc happens. |
| 04-05-2009, 06:56 AM | #4 |
the purpose of this script seems to be to simulate random occurrence of events. but the fact that it modifies the factor makes it less random - more controlled. seems contradictory. i mean that since it modifies the factor in its way, the occurrence approximates a value (which can be expressed by time), say N times over a period of time with some number of intervals wherein the chance for proc occurs. that is, the occurrence/proc approaches some definite value (according to a function that hgas a factor that is the degree/margin by which the factor is modified) - how is this random? |
| 04-05-2009, 07:17 AM | #5 |
Uh... Unless I misunderstood, this just prevents a proc (whatever the hell that is) from repeating multiple times in a row, to prevent (albeit rare) occurances of rapid-fire proc events (think a custom crit strike that fired 20 times in a row. This would prevent such a thing by allowing you to say "only twice per 3 seconds" or whatever). So I think that regardless, this is still random. Did I get that right? Or does this just increase/decrease the chance to proc? (What is that?) |
| 04-05-2009, 07:56 AM | #6 |
It's weighted proc. Basically, if I have something that has a 10% chance of occuring and used just a normal get random it'd have 10% chance EACH HIT of occuring. With weighted random, no-matter how many hits you have there's only a 10% chance OVERALL for it to occur. |
| 04-05-2009, 08:14 AM | #7 |
Isnt this how blizzards critical strike and evasion work? This might be really nice actually. |
| 04-05-2009, 03:00 PM | #8 | ||||
Quote:
Exactly where I was using it for. I made a custom evasion and critical strike system that used a damage detect system and preventing damage, yada yada yada. This was the basis of the random thing and I thought it was nifty, so I made it into a script. Quote:
If you want to get technical, the random number generator in this game is not truly random either. With that being said, you can take this to be a way to stop a bad seed from causing a player to evade with a custom ability, 10 times in a row (assuming low evasion). Quote:
That is correct. Proc stands for special procedure, but you can think of it as a random chance of some effect occurring. It become a standard word in mmorpgs, describing the chance for an item to do some event on a certain action. Quote:
More or less. I did a test with this system versus the generic GetRandomReal(0., 1.) >= percent. The percents were 50% and the weight was 0.1 for this script. After 800 tries, the basic method had a max proc streak of 10 and a max miss streak of 9. Not shown here, but it continually had large streaks of a certain value, although they are not shown. This system, with a weight of 0.1, had a max proc streak of 4 and a max miss streak of 5. Changing the value to 0.3, it had a max proc streak of 2 and a max miss streak of 2 (0.25 is the max effective weight at 50%). Therefore, you can see that by using a larger weight, you can reduce the streaks of a proc/no proc and keep the short-term close to the desired percent. Personally speaking, I would prefer to have the short-term close to 50%, so I can actually evade 50% of 1 enemies attacks, rather than 50% over the course of my entire gaming career. I would also hate for someone who hits criticals 5% of the time, to get more than 3 in a row on me (although not plausible, definitely possible without this script). |
| 04-05-2009, 03:26 PM | #9 | |
Quote:
I have a custom critical strike functions too for both Spell and Attack critical and Im using UnitProperties to track those chance to crit values. I guess Ill try to replace those values with Chance instances and see how it works. Hm, I dont know if I should use this for evasion and miss chances too.. Would have to tinker EvasionModule then, which is not a problem, but if Blizzard doesnt use weighted chances for evasion, maybe I should not use them either to make it work more like normal warcraft.. Anyways, this is definitely useful. |
| 04-05-2009, 07:49 PM | #10 |
In your onDestroy you don't actually have to nullify those reals. They don't leak. This is kind of cute, but I don't want to pass judgment without some second opinions from reviewers. |
| 04-06-2009, 05:09 AM | #11 |
Removed the onDestroy trigger and changed it so the weight is effective over the entire range (was previously set so that 0.25 and 1.00 [including all value in-between]), produced the same results. |
| 04-13-2009, 03:41 AM | #12 |
Very good, might just want to remove the mention of evasion from the documentation (since that doesn't work this way). You can replace it with another example such as bash. In the Notes you should explain what the weight value does, how it works. The other value, percent, is pretty self-explanatory. |
| 04-13-2009, 08:39 AM | #13 |
Good point. Updated the notes. |
| 04-13-2009, 01:50 PM | #14 |
Approved. |
| 04-13-2009, 02:40 PM | #15 | |
Quote:
isn't that the same thing? 10% / hit = 10% overall its like a coin flip random is all about how lucky you can get, and by removing that aspect its no longer random, its boring might as well tell the player that every 10th hit will crit, and let him use that aspect in his play strategy\ in the short run chance to proc skills are all about getting lucky (or unlucky) - if you want to remove that aspect, just add a base % bonus to the spell and call it a day, because thats all you're really doing |
