| 03-11-2009, 10:07 PM | #1 |
Ok guys, again recently I searched the database for a recent shape system, but I only found systems using Kattana's ... which is obviously bad and outdated, so I decided to start making my own shape system. So far the system is quite basic, and is very easy to read once you understand structure Line and Circle. I hope people have suggestions, I intend to add more geometric formulas, and after that submit it to the community. My spell for contest 14 uses an Alpha version of this system. The current version I present here is more advanced. Hope people like it =) JASS://=========================================================================== //A system that allows the user to create many shapes in a very simple and //customizable way. // //Requires TimerUtils // //@author Flame_Phoenix // //@credits //- ThredNThrash, for the main idea and math formulas // //@version 1.0 //=========================================================================== library SimpleShapes requires TimerUtils struct Circle group effs timer t real x1 real y1 real centerX real centerY real unitSize integer unitId real radius player owner integer start integer end static method createEff takes nothing returns nothing //we get the structure from the timer local Circle data = Circle(GetTimerData(GetExpiredTimer())) if data.start <= data.end then //polar projection stuff set data.x1 = data.centerX + data.radius * Cos(data.start * ( 360.00 / (data.radius / data.unitSize )) * bj_DEGTORAD) set data.y1 = data.centerY + data.radius * Sin(data.start * ( 360.00 / (data.radius / data.unitSize )) * bj_DEGTORAD) call GroupAddUnit(data.effs, CreateUnit(data.owner, data.unitId, data.x1, data.y1, 0)) set data.start = data.start + 1 else call PauseTimer(data.t) endif endmethod static method create takes real x, real y, real radius, integer unitId, real unitSize, player owner, real delay returns Circle local Circle data = Circle.allocate() //recycling the group is always good if data.effs == null then set data.effs = CreateGroup() endif set data.owner = owner set data.centerX = x set data.centerY = y set data.start = 1 set data.radius = radius set data.unitSize = unitSize set data.unitId = unitId set data.end = R2I(radius / unitSize) set data.t = NewTimer() //we attach the struct to the timer call SetTimerData(data.t, integer(data)) call TimerStart(data.t, delay, true, function Circle.createEff) return data endmethod method onDestroy takes nothing returns nothing local unit f loop set f = FirstOfGroup(.effs) exitwhen(f == null) call GroupRemoveUnit(.effs, f) call KillUnit(f) endloop call GroupClear(.effs) call ReleaseTimer(.t) endmethod endstruct struct Line real startX real startY real dist real x1 real y1 real angle integer start integer unitsNum //the maximum amount of units we create group effs timer t player owner integer unitId static method createEffL takes nothing returns nothing //we get the structure from the timer local Line data = Line(GetTimerData(GetExpiredTimer())) if data.start <= data.unitsNum then //polar projection stuff set data.x1 = data.startX + ((data.start * data.dist) / data.unitsNum) * Cos(data.angle) set data.y1 = data.startY + ((data.start * data.dist) / data.unitsNum) * Sin(data.angle) call GroupAddUnit(data.effs, CreateUnit(data.owner, data.unitId, data.x1, data.y1, 0)) set data.start = data.start + 1 else call PauseTimer(data.t) endif endmethod static method create takes real sX, real sY, real eX, real eY, integer unitId, real unitSize, player owner, real delay returns Line local Line data = Line.allocate() local real dx local real dy //setting members and group set data.owner = owner set data.unitId = unitId //points, lenght, angle and distance set data.startX = sX set data.startY = sY set dx = sX - eX set dy = sY - eY set data.angle = Atan2(eY - sY, eX - sX) set data.dist = SquareRoot(dx*dx + dy*dy) //number of units needed set data.unitsNum = R2I(data.dist / (unitSize * 5) ) set data.start = 1 //starting our counter //recycling the group =P if data.effs == null then set data.effs = CreateGroup() endif set data.t = NewTimer() call SetTimerData(data.t, integer(data)) call TimerStart(data.t, delay, true, function Line.createEffL) return data endmethod method onDestroy takes nothing returns nothing local unit f loop set f = FirstOfGroup(.effs) exitwhen(f == null) call GroupRemoveUnit(.effs, f) call KillUnit(f) endloop call GroupClear(.effs) call ReleaseTimer(.t) endmethod endstruct struct Pentagram Line l1 Line l2 Line l3 Line l4 Line l5 static method create takes real x, real y, real radius, integer unitId, real unitSize, player owner, real delay returns Pentagram local Pentagram data = Pentagram.allocate() local real x1 local real y1 local real x2 local real y2 //all this stuff creates the first line of the start ... set x1 = x + radius * Cos(234.0 * bj_DEGTORAD) set y1 = y + radius * Sin(234.0 * bj_DEGTORAD) set x2 = x + radius * Cos(90. * bj_DEGTORAD) set y2 = y + radius * Sin(90. * bj_DEGTORAD) set data.l1 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) //now prepare for the second line of the start lol... don't worry, it //only has 5 lines xD set x1 = x + radius * Cos(90. * bj_DEGTORAD) set y1 = y + radius * Sin(90. * bj_DEGTORAD) set x2 = x + radius * Cos(306. * bj_DEGTORAD) set y2 = y + radius * Sin(306. * bj_DEGTORAD) set data.l2 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) //now for the 3rd line set x1 = x + radius * Cos(306. * bj_DEGTORAD) set y1 = y + radius * Sin(306. * bj_DEGTORAD) set x2 = x + radius * Cos(162. * bj_DEGTORAD) set y2 = y + radius * Sin(162. * bj_DEGTORAD) set data.l3 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) //now for the 4th line, don't worry, we are almost there set x1 = x + radius * Cos(162. * bj_DEGTORAD) set y1 = y + radius * Sin(162. * bj_DEGTORAD) set x2 = x + radius * Cos(19. * bj_DEGTORAD) set y2 = y + radius * Sin(19. * bj_DEGTORAD) set data.l4 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) //at last the last line of our David star! set x1 = x + radius * Cos(19.0 * bj_DEGTORAD) set y1 = y + radius * Sin(19.0 * bj_DEGTORAD) set x2 = x + radius * Cos(234. * bj_DEGTORAD) set y2 = y + radius * Sin(234. * bj_DEGTORAD) set data.l5 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) return data endmethod method onDestroy takes nothing returns nothing call .l1.destroy() call .l2.destroy() call .l3.destroy() call .l4.destroy() call .l5.destroy() endmethod endstruct struct Xspot Line l1 Line l2 static method createDefault takes real origX, real origY, real length, integer unitId, real unitSize, player owner, real delay returns Xspot local Xspot data = Xspot.allocate() local real x1 = origX + length * Cos(315. * bj_DEGTORAD) local real y1 = origY + length * Sin(315. * bj_DEGTORAD) local real x2 = origX + length * Cos(135. * bj_DEGTORAD) local real y2 = origY + length * Sin(135. * bj_DEGTORAD) set data.l1 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) set x1 = origX + length * Cos(225. * bj_DEGTORAD) set y1 = origY + length * Sin(225. * bj_DEGTORAD) set x2 = origX + length * Cos(45. * bj_DEGTORAD) set y2 = origY + length * Sin(45. * bj_DEGTORAD) set data.l2 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) return data endmethod static method createCustom takes real origX, real origY, real length, real angle1, real angle2, real angle3, real angle4, integer unitId, real unitSize, player owner, real delay returns Xspot local Xspot data = Xspot.allocate() local real x1 = origX + length * Cos(angle1 * bj_DEGTORAD) local real y1 = origY + length * Sin(angle1 * bj_DEGTORAD) local real x2 = origX + length * Cos(angle2 * bj_DEGTORAD) local real y2 = origY + length * Sin(angle2 * bj_DEGTORAD) set data.l1 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) set x1 = origX + length * Cos(angle3 * bj_DEGTORAD) set y1 = origY + length * Sin(angle3 * bj_DEGTORAD) set x2 = origX + length * Cos(angle4 * bj_DEGTORAD) set y2 = origY + length * Sin(angle4 * bj_DEGTORAD) set data.l2 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) return data endmethod method onDestroy takes nothing returns nothing call .l1.destroy() call .l2.destroy() endmethod endstruct struct Square Line l1 Line l2 Line l3 Line l4 static method create takes real origX, real origY, real radius, integer unitId, real unitSize, player owner, real delay returns Square local Square data = Square.allocate() local real x1 = origX + radius * Cos(225. * bj_DEGTORAD) local real y1 = origY + radius * Sin(225. * bj_DEGTORAD) local real x2 = origX + radius * Cos(315. * bj_DEGTORAD) local real y2 = origY + radius * Sin(315. * bj_DEGTORAD) set data.l1 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) set x1 = origX + radius * Cos(315. * bj_DEGTORAD) set y1 = origY + radius * Sin(315. * bj_DEGTORAD) set x2 = origX + radius * Cos(45. * bj_DEGTORAD) set y2 = origY + radius * Sin(45. * bj_DEGTORAD) set data.l2 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) set x1 = origX + radius * Cos(45. * bj_DEGTORAD) set y1 = origY + radius * Sin(45. * bj_DEGTORAD) set x2 = origX + radius * Cos(135. * bj_DEGTORAD) set y2 = origY + radius * Sin(135. * bj_DEGTORAD) set data.l3 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) set x1 = origX + radius * Cos(135. * bj_DEGTORAD) set y1 = origY + radius * Sin(135. * bj_DEGTORAD) set x2 = origX + radius * Cos(225. * bj_DEGTORAD) set y2 = origY + radius * Sin(225. * bj_DEGTORAD) set data.l4 = Line.create(x1, y1, x2, y2, unitId, unitSize, owner, delay) return data endmethod method onDestroy takes nothing returns nothing call .l1.destroy() call .l2.destroy() call .l3.destroy() call .l4.destroy() endmethod endstruct endlibrary The system is really easy to use, I hope people like it. Here is a test Demo map with samples. |
| 03-11-2009, 11:10 PM | #2 |
How exactly do you use this? I don't mean, how do you call the constructors/destructors, I mean what does it do with these geometric shapes? Upon further reading it seems like it creates units (and adds them to a group) in geometric patterns, is this correct? |
| 03-11-2009, 11:12 PM | #3 |
Geometric Midnight Theatre anyone? I'll bring the rulers. Seriously though, even with spell application..hmm.. maybe you should add in a guide on what it can be used FOR rather than HOW :p. |
| 03-11-2009, 11:13 PM | #4 |
Blacktastic you will never beat me to the punch. Stop trying. |
| 03-11-2009, 11:15 PM | #5 |
Gotta have something to occupy my time unitl someone gets back to me about my item issue because for once I am completely dumbfounded as to how something so simple isnt functioning. Anyway, back on topic, I will say this is pretty cool regardless. |
| 03-11-2009, 11:25 PM | #6 |
you do LOTS of calculations in the timer callbacks which can be before ...and you should stop using degrees ....use radians ... |
| 03-12-2009, 06:06 AM | #7 |
I would make this system allow for user input in the following way:
|
| 03-12-2009, 11:53 AM | #8 |
Rather than making it a struct you could probably just make it an interface. |
| 03-12-2009, 01:16 PM | #9 | ||||||||
Quote:
Quote:
The main idea of it's use is for spells, in my spell, if the units step on the symbol they take damage. How ? Well, the units of the group have immolation =D I may do a few more spells using this system and post them here =P Quote:
Quote:
Quote:
Quote:
Quote:
Btw, I dunno how to use interfaces on structures =S Quote:
3 libraries for 1 system mmm =S I am willing to make the required changes you guys find necessary, but I need specific instructions, I need to know exactly what you want me to upgrade. Btw, I will give rep+ to people who help me and give credits as well. Thx for the posts guys! |
| 03-12-2009, 01:24 PM | #10 | |
Quote:
#1 example: ( 360.00 / (data.radius / data.unitSize )) * bj_DEGTORAD #2: it doesnt decrease readability ...and if the user still wants to use radians they can call your system with something like 90*bj_DEGTORAD, beside they dont even need to call methods of your "system" ...with any angles as parameter ... So its all about you being stubborn .. 0.o |
| 03-12-2009, 03:09 PM | #11 |
@akolyt0r: I will check point 1 and see if I can avoid some calculations. Thx for pointing it out. About point 2, making the conversion is the duty of the system not of the user, the system is meant to be simple to use, forcing a user to pass radians as arguments is a stupidity having in mind degrees are much easier to use. Also, the user NEEDS to pass angles as parameters, just check my Xspot.createCustom method ... Seriously, if I am so stubborn then perhaps you could tell me why I am taking opinions from Pyro and xombie? Just because I don't accept all you suggestions it doesn't mean I am stubborn, live with it. |
| 03-12-2009, 03:22 PM | #12 |
Parameters for user-end functions/methods should usually take an angle measured in degrees, while anything internal should use radians for processing speed. |
| 03-12-2009, 03:30 PM | #13 | |
Quote:
radians arent difficult to use ...and i wouldnt use that system when i use radians basically everywhere ...since all functions which matter for angles use radians (except unitfacing stuff) ...so its pretty LOGICAL to use radians... users of this should really be wise enough to do a [ljass]X*bj_DEGTORAD[ljass] ...when they really want to use degrees and not radians ... But well if you dont believe that ...dont do it for your public methods (the ones the user can call..) But you should at least get rid of degrees in methods the user wont call, really... for example in Circle.createEff.. shouldnt that method be private by the way ?! |
| 03-12-2009, 03:57 PM | #14 | |
Quote:
and yes, it should definitely be private, I don't want people to call that method, it is for exclusive use of the create method and that's all. |
| 03-12-2009, 04:08 PM | #15 | |
Quote:
Well than change it later, when you think you are finished with the development of the rest of the system... |
