0 Members and 1 Guest are viewing this topic.
Well, it haven't been much time since my last post, and syntax-writing have started to take over my GUI-usage more and more. But I got a question I want answered; How do I pick units in a line (for creating a trigger-based spell like shockwave or similar). I have before used a number of rects to simulate the line-effect, but is there a better way, then I am interested in hearing it.
And a little of-topic question; a quite long time ago, I read a topic about vJass and its strengths against normal GUI, and one particular thing I remembered was that someone mentioned another way to fire of triggers rather than the way triggers runs of in the GUI that was more efficient, but I can't recall how nor where I read it. Someone who knows anything about it?
Ok, do I need to nullify real-locals?
Btw, is there a way to store a integer in a ability or similar (or even better, store a number of different integers in certain unit-types) so I could instead of using a large number of if/then/else after eachothers, I could just get the numbers directly? (A little like a Hashtable, but backwards or something).
Since I want to have complete control over all damage done, I don't want to use the already made- attacktypes and armortypes to declare certain strengths and weaknesses.
Edit: I ran across a annoying Compile-error.. The following code returns a "unexpected "("?"-error..Code: jasscall GroupEnumUnitsInRange(unitsinrange, GetUnitX(attackedR), GetUnitY(attackedR), 300, Filter(function IsUnitEnemy(GetFilterUnit(), Player(attackerid)) == true and (GetFilterUnit() == attackedR) == false))I need to store a unitgroup (a group I call "unitsinrange)
Ok, but perhaps I'll stick with the ability-things for the moment (I use a "Vulnerable to"/"Resistant to"-system instead of the ordinarie fixed armor-type-system, which gives me the ability to hand-tailor the damage-modifiers for every unit I would use, and the abilities serves as a teller for the player of what the unit is vulnerable to)However, since Heroes uses alot of more values than in the vanilla wc3 (and the damage-values is very missleading) I would like to use a multiboard (or similar) to show this values. However.. It seems impossible to just show a specific multiboard for just one player, while I show another multiboard for another one.. I could use a chattext-triggered function to show all the stats, but I would like to hear if anyone has another idea. (I have calculated that I am using 26custom-values for heroes right now (with a small chance of reduction, I don't think I would be using anything more), so a text-message which shows 26lines of text is maybe not the best way)
Edit: I have encountered a very annoying glitch (which doesn't seem to be very unusual); the TriggerSleepAction is completely bugged.. It seems to do the same as SkipRemainingActions in many cases... Here is the the last part of the code;Code: jass //other code above here call TriggerSleepAction( 0.50 ) set i = 0 //i is just a integer used for loops here loop exitwhen i > ( 4 + ( udg_herolevelmodifier[casterOId] + casterlvl ) ) call UnitDamageTarget( caster, targets[i], damageCend[i], FALSE, TRUE, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS ) set targets[i] = null call DisplayTextToForce( GetPlayersAll(), I2S(i)) set i = i + 1 endloop set targetpoint = null call DestroyGroup(ug) set ug = null set caster = null set target = null set dummy = null set targetO = null set casterO = null return true else endifreturn falseendfunction The code doesn't generate any error-messages, and works completely fine when TriggerSleepAction is deactivated or removed. But active, nothing after it will do anything at all. This wait is used to get a visual sync between the fireballs created by dummies earlier in the code, and isn't REALLY necessary for gameplay, but still, the bug is annoying. Heard about PolledWaits, but after both read it's very slow and by taking a quick look at the function and thinking the bug should not be fixed since that function also uses TriggerSleepAction, it feels like it really isn't a good idea at all. Now, the remaining option of what I can see, is a timer, but this trigger have a great chance of running multiple times, so I can't use globals for the trigger that would run when the timer runs out. Is it at this point that I should learn about some other kinds of variables (I don't know how privates work..)?
Ok, thanks! (:But I really have no clue of how to do a very MUI-trigger using a timer? An array was a idea, but the size would need to be quite big... Cause, I don't know a safe, MUI, good way of using the data from one function to the function that starts after the timer..
EDIT: I fixed it. The only thing worring me is that I am using a loop to detect which array the timer is using, and since the size is on 1050 before reseting to 0, I am worried about the process-part.
Moyack,if u haven't already figured it out, here is the angle-calculation of the line-spell; ((Area / Dist) * (180 / pii)) + ((180/pii) * Atan2(TPY - CPY, TPX - CPX)) > (180/pii) * Atan2 (TPY- CPY, TPX - CPX) > ((Area / Dist) * (180 / pii)) - ((180/pii) * Atan2(TPY - CPY, TPX - CPX))Area = Area of the spellDist = the distance from the unit to the caster(calc.: ((Target X - Caster X)^2) + ((Target Y - Caster Y)^2)TPX/TPY = Target Unit X or YCPX/CPY = Casterunits X or Y
My worry implies in that there's a few chance to catch a unit because it should be exactly at the same angle, and that situation normally doesn't happen You need to have a kind of "range" so it can cast more units in a more or less lined way.
function LineKillFilter takes nothing returns booleanlocal unit u = GetFilterUnit()local real unitx = GetUnitX(u)local real unity = GetUnitY(u)local real startx = GetUnitX(gg_unit_hfoo_0001)local real starty = GetUnitY(gg_unit_hfoo_0001)local real endx = GetUnitX(gg_unit_hfoo_0002)local real endy = GetUnitY(gg_unit_hfoo_0002)local real a1 = 57.2958 * Atan2(unity - starty, unitx - startx)local real a2 = 57.2958 * Atan2(endy - starty, endx - startx)local real distance = SquareRoot(((unitx - startx) * (unitx - startx)) + ((unity - starty) * (unity - starty))) if (a1) < (((100/distance) * 57.2958) + (a2)) then //The number 100 is the area of the line divided by 2, and could be changed to any value. if (a1) > ((a2) - ((200/distance) * 57.2958) ) then call KillUnit(GetFilterUnit()) // 57.2958 is the round off from 180/pii set u = null return TRUE else endif else endif return FALSEendfunctionfunction Trig_linekill_Actions takes nothing returns nothinglocal group g = CreateGroup()local real x1 = GetUnitX(gg_unit_hfoo_0001)local real x2 = GetUnitX(gg_unit_hfoo_0002)local real y1 = GetUnitY(gg_unit_hfoo_0001)local real y2 = GetUnitY(gg_unit_hfoo_0002)local real dx = x1 + 500 * Cos(Atan2(y2 - y1, x2 - x1))local real dy = y1 + 500 * Sin(Atan2(y2 - y1, x2 - x1))call GroupEnumUnitsInRange(g, dx, dy, 1000.00 , Condition(function LineKillFilter))endfunction//===========================================================================function InitTrig_linekill takes nothing returns nothinglocal trigger t = CreateTrigger() call TriggerRegisterPlayerChatEvent( t, Player(0), "-kill", false ) call TriggerAddAction( t, function Trig_linekill_Actions ) set t = nullendfunction
It works now, sure, the math wasn't completely right, but I shall change the calculation. Btw, is there a place where I can upload a map to show my succes? (x
Code: [Select]function LineKillFilter takes nothing returns booleanlocal unit u = GetFilterUnit()local real unitx = GetUnitX(u)local real unity = GetUnitY(u)local real startx = GetUnitX(gg_unit_hfoo_0001)local real starty = GetUnitY(gg_unit_hfoo_0001)local real endx = GetUnitX(gg_unit_hfoo_0002)local real endy = GetUnitY(gg_unit_hfoo_0002)local real a1 = 57.2958 * Atan2(unity - starty, unitx - startx)local real a2 = 57.2958 * Atan2(endy - starty, endx - startx)local real distance = SquareRoot(((unitx - startx) * (unitx - startx)) + ((unity - starty) * (unity - starty))) if (a1) < (((100/distance) * 57.2958) + (a2)) then //The number 100 is the area of the line divided by 2, and could be changed to any value. if (a1) > ((a2) - ((200/distance) * 57.2958) ) then call KillUnit(GetFilterUnit()) // 57.2958 is the round off from 180/pii set u = null return TRUE else endif else endif return FALSEendfunctionfunction Trig_linekill_Actions takes nothing returns nothinglocal group g = CreateGroup()local real x1 = GetUnitX(gg_unit_hfoo_0001)local real x2 = GetUnitX(gg_unit_hfoo_0002)local real y1 = GetUnitY(gg_unit_hfoo_0001)local real y2 = GetUnitY(gg_unit_hfoo_0002)local real dx = x1 + 500 * Cos(Atan2(y2 - y1, x2 - x1))local real dy = y1 + 500 * Sin(Atan2(y2 - y1, x2 - x1))call GroupEnumUnitsInRange(g, dx, dy, 1000.00 , Condition(function LineKillFilter))endfunction//===========================================================================function InitTrig_linekill takes nothing returns nothinglocal trigger t = CreateTrigger() call TriggerRegisterPlayerChatEvent( t, Player(0), "-kill", false ) call TriggerAddAction( t, function Trig_linekill_Actions ) set t = nullendfunctionThis code will kill everyone between the 2 footmen on my map (right now including the second footman) in an area of 200 and a range of 1000EDIT: The prior error is fixed
Ok, it seems to work nicely. But I got one question; what is the "for u in g"-code? Never seen it and didn't know it was possible to do so. O.oBut, if it is, then I belive that is something I might start to useEDIT: Ok, I tested the "for u in g" and it works, so no need to fill me in on that. However, why is this code completely hidden? I mean, it doesn't highlight like other "similar" things (like loop, if, endif and so on). No matter, your code works and big creds for that, and the way your ability works have let me understand why to create the middle-point between the casters location and the target location. However, I have myself a similar solution too now, and I do belive that the speed and efficiency is quite equal to yours (not certain which one is fastest though) and I know exactly what everything in it does, so I will stick with my version. (Could post the code and a testmap if any1 is curious)
for u in g