| 06-20-2004, 04:21 PM | #1 |
ok thats a bad discreption for that what i am asking for so bear with me, cause i couldn't think of anything better. I am making spell that when used it will fire a projectile in a straight line in the direction that the Casting unit is facing. So i want to know if the projectile is going to hit a unit(i only want it to hit 1 then stop), and if it does which unit. I am wondering how i can do this and there is probably a really obvious option that i am missing since my plan can go wrong. There are probably going to be around 8-12 units on the field at once. What i thought of was something along these lines Code:
function triggerchild takes nothing returns nothing
StoreUnit(Unit within range of entering unit)
DestroyTrigger
endfunction
function Fire takes unit caster, real range returns unit
local trigger t = CreateTrigger()
local unit b = unit that moves VERY FAST
add action to trigger t (function triggerchild)
ForGroup(units on field)
- Add Event to Trigger t (Unit comes within range of Picked Unit)
Create Unit b
Order unit b to move in a straight line in the facing direction of caster
SleepAction(0)
return StoredUnit from triggerchild
endfunction |
| 06-20-2004, 05:11 PM | #2 |
ok that majorly confused me because it was like GUI-jass (fun to prounounce, Gooeyjass) oh wait, i think i kind of get what ur saying. its a like warstop type thing where u just press a button, i got it. well in the tank commandos map they used attack ground. but your best bet would somehow find the closest unit matching angle between units is GetUnitFacing. ok slipped into jass there but yeah. theres some functions at the jassvualt i think that can get the closest unit. oh and then after you have the right unit order a dummy caster to use shockwave with projectile art on the unit. |
| 06-20-2004, 05:16 PM | #3 |
ok twister thanks but 1 problem, wouldn't that require you to be perfectly alined with the enemy unit? i want there to be some le-way, since this is going to be pretty fast paced also i just encountered a problem when trying to code my way... ummm how do i make sure that the child trigger has the right entering unit and not some entering from a different cast? Edit: can any one tell me how i can c'n'p a function from the download and not have it all be on 1 line??? ty. |
| 06-20-2004, 08:27 PM | #4 |
oh, well sure you can make leeway but then you want vars just because. ok.. i guess ill write out the function sort of... Code:
function in_line001 takes nothing returns boolean return (AngleBetweenPoints < GetUnitFacing(GetSpellAbilityUnit()) + 10 and AngleBetweenPoints > GetUnitFacing(GetSpellAbilityUnit()) - 10) endfunction function in_line takes nothing returns nothing local unit target = FindClosestUnitMatching( GetUnitLoc(GetSpellAbilityUnit()), function in_line001) if (DistanceBetweenPoints(GetUnitLoc(GetSpellAbilityUnit()), GetUnitLoc(target)) =< 1000) then//1000 is the maximun range call CreateUnitAtLoc( GetOwningPlayer(GetSpellAbilityUnit()),'hfoo', GetUnitLoc(GetSpellAbilityUnit()) bj_UNIT_FACING) call IssueTargetOrder(GetLastCreatedUnit(), shockwave, target)//i dont know actual function but its one that orders a unit to do something to another else call DisplayTextToPlayer(GetOwningPlayer(GetSpellAbilityUnit()), 0,0 "There are no units in range.") endfunction target is set to the closest unit to the caster but it has to be within 10 degrees of the unit direction the unit is facing. Next we make sure that our closest unit is close enough then if it is we create our dummy unit. then order it to use shockwave on our unit. BUT if the unit wasnt close enough we tell them so :) I think im gonna go through later and make it a workable function. ooh and i just figured out what yours does. I wouldnt suggest it because selectable missiles always just turns me off and if u give it locust well, eh units arent meant to be spell effects they are meant to use spells. edit: ok I made it more real jass edit2: ok, i just found out that there is no blizzard FindClosestUnit But at the jass vault there is and it is required for this. Code:
function FindClosestUnitMatching takes location whichLoc, boolexpr matchingCondition returns unit
local group G = CreateGroup()
local real Dist = 1000000
local unit Closest
local unit U
call GroupEnumUnitsInRect(G,GetEntireMapRect(),matchingCondition)
loop
set U = FirstOfGroup(G)
exitwhen U == null
if DistanceBetweenPoints(GetUnitLoc(U),whichLoc) < Dist then
set Closest = U
set Dist = DistanceBetweenPoints(GetUnitLoc(U),whichLoc)
endif
call GroupRemoveUnit(G,U)
endloop
call DestroyGroup(G)
return Closest
endfunction |
| 06-21-2004, 02:48 AM | #5 |
Woah umm just some questions/comments 1.) Thanks for the help 2.) Ok yours makes alot more sense, should be faster and have alot less room for error + be multistance able, i was looking for a better method, knew that it would be something along these lines, but couldn't quite put it together 3.) after looking at your post again, i see less and less problems but could you explain in_line001 a bit more, im kinda confuzzuled. 4.) Thanks again =) |
| 06-21-2004, 02:54 AM | #6 |
ok, in_line001 is what give it some leeway so it doesnt have to be a direct line. if the unit is facing 90 degrees it checks to make sure that the angle between the casting unit and target unit is 90 + or - 10. so the unit angle can be 80-100 degrees. if it was restricted to the facing angle the area would look like this | this function makes it look like this \/ I really dont know how i figured that out.. it just came to me o_O I haven't tested it yet so it may not work. |
| 06-21-2004, 03:19 AM | #7 |
yeah thats what i was thinking of but wouldn't that actually make units that are farther away easier to hit than units that are closer? I'll try to figure out a better condition, Thanks again crap trying to figure out how to define a region by giving 4 locations, not going to work apparentaly =( |
| 06-21-2004, 03:35 AM | #8 |
It will be easier to hit a further away target, but a closer target is easier to point ur guy at. and also if you make the range close enough it wont be MUCH of a difference. One way would be to make a rect in front of the unit and check if the unit is in the rect. but i have no clue how you would go about doing that. edit: oh and anyways, even if the unit did have to be in a direct line the player would be able to get it anyways because they will most like just right mouse click on the unit making thier hero fact them then they would use your spell. what kind of spell is this anyways? |
| 06-21-2004, 04:12 AM | #9 |
well something in me tells me that i figured out the condition, this isn't so much a spell, but the core system in my FPS type map, you'll press a button and your guy fires, this is going to be the core function to decide weither you got a hit or miss and which unit you got, the right click will probably be used a bit but im not sure, i was hoping on arrow keys and keyboard =) once again thx for all of the help i'll post the condition when i fully figure it out, which might be 10 min =) thx again edit: arggg so close to done but my mind is buggin on the last part, i'll figure it out tommorrow edit2: ok this is what i came up with gunna test it out edit3: THANK YOU TWISTAR ok the coding is done and it works very nicely this is the final product... for now =) Code:
function FindClosestUnitMatching takes location whichLoc, boolexpr matchingCondition returns unit
local group G = CreateGroup()
local real Dist = udg_range
local unit Closest
local unit U
call GroupEnumUnitsInRect(G,GetEntireMapRect(),matchingCondition)
loop
set U = FirstOfGroup(G)
exitwhen U == null
if DistanceBetweenPoints(GetUnitLoc(U),whichLoc) < Dist then
set Closest = U
set Dist = DistanceBetweenPoints(GetUnitLoc(U),whichLoc)
endif
call GroupRemoveUnit(G,U)
endloop
call DestroyGroup(G)
return Closest
endfunction
function in_line001 takes nothing returns boolean
local location gunnerloc = GetUnitLoc(udg_gunner)
local location x1 = OffsetLocation(gunnerloc, -1*udg_width, 0)
local location x2 = OffsetLocation(gunnerloc, udg_width, udg_range)
local rect area = RectFromLoc(x1,x2)
local location y = GetUnitLoc(GetFilterUnit())
local location y1 = PolarProjectionBJ(gunnerloc, DistanceBetweenPoints(gunnerloc, y), ( AngleBetweenPoints(gunnerloc, y) + ( 90.00 - GetUnitFacing(udg_gunner) ) ))
if ( not ( RectContainsLoc(area, y1) == true ) ) or GetFilterUnit() == udg_gunner then
call RemoveLocation(x1)
call RemoveRect(area)
call RemoveLocation(x2)
call RemoveLocation(gunnerloc)
call RemoveLocation(y)
call RemoveLocation(y1)
return false
endif
call RemoveLocation(x1)
call RemoveRect(area)
call RemoveLocation(x2)
call RemoveLocation(gunnerloc)
call RemoveLocation(y)
call RemoveLocation(y1)
return true
endfunction
function in_line takes unit gunner, real range, real width returns unit
local location x = GetUnitLoc(gunner)
local unit ret
set udg_range = range
set udg_width = width/2
set udg_gunner = gunner
set ret = FindClosestUnitMatching( x, Condition(function in_line001))
call RemoveLocation(x)
return ret
endfunction |
| 06-22-2004, 03:10 AM | #10 |
Well.. i say you did the hard part i just got you on track. But i actually have a question about yours. rects and regions have just recently been brought to my attention so i dont know much at all about those functions. I'm assuming that RectFromLoc uses the 2 given points as opposite corners in a rectangle? and also to figure out your condition i actually had to draw a picture. lol AND im also assuming that you made a function and not an action so you could adjust the attack range and stuff, so like width increases accuracy and range increases well range? also in your in_line calling function I'm guessing you have to make sure that in_line doesn't equal null because if there is no closest unit it will return null and your function would run all wierd. Sorry my Jass world has been like totaly expanded cause of summer which = time so im still learning some stuff like how to return non-integer\string stuff. I did find 1 error tho Code:
call GroupEnumUnitsInRect(G,GetEntireMapRect(),matching[color=red]-[/color]Condition) wow, i ended up having more questions then you o_O |
| 06-22-2004, 04:01 AM | #11 |
well i'll be happy to ask any questions you have =) since you helped me its the least that i can do. Everything you said though seems pretty accurate. also simply put what the condition does is make a rect that is the area that would be considered a hit if the gunner was facing exactly 90 degrees, i then figure out if the battlefeild was rotated in such a way that the gunner would facing 90 degrees then were would the enemy be? and would he be in the rect? |
