| 09-09-2008, 06:28 PM | #1 | |||
MUI: Yes. GUI/JASS/vJass: vJass. Leakless: Should be. Laggless: As far as I can tell. Requirements: xebasic, xedamage and xepreload
Code://=========================================================================================== // Goblin Bomber - v 1.3 by Tukki //============================================================================================ // // Requires: //-------------------------------------------------------------------------------------------- // * A point-targetable spell. // * The dummy model. (Made by Vexorian) // * This trigger. // * A vJass preprocessor. // * xebasic, xepreload and xedamage ([url]http://www.wc3campaigns.net/showthread.php?t=101150[/url]) // // How to import: //-------------------------------------------------------------------------------------------- // * Import xe according to the link if you haven't got it. // * Copy this trigger into your map. // * Assign the appropriate values to the globals further down. // // Description; //-------------------------------------------------------------------------------------------- // Spell Type: Goblin Explosion // Cooldown: 20 - 14 Seconds. // // Sends a goblin zeppelin, full with explosive stuff, towards the targeted point. // Once it reaches it bombs will begin to fall, dealing damage to nearby enemy land units. //============================================================================================ library GoblinBomber initializer InitTrig uses xebasic, xepreload, xedamage globals // - - - - - - - - - - // CHANGABLE THINGS //=========================================================================== // Rawcode global. private constant integer AID_GOBLIN_BOMBER = 'A000' // Spell rawcode. //=========================================================================== // Distance and Speed globals. private constant real ZEPPELIN_VELOCITY = 600.0 // The velocity of the zeppelin. private constant real DISTANCE = 1000.0 // The distance of how far behind the zeppelin is spawned. MUST be positive. //=========================================================================== // Different height globals. private constant real BOMB_HEIGHT = 150.0 // The flying height of the zeppeling when it drops the bombs. private constant real FLY_HEIGHT = 300.0 // Normal flying height of the zeppelin. //=========================================================================== // Unit-right-height duration globals. private constant real BOMBING_TIME = 0.5 // Time it takes to go into bombing-height. MUST be positive. private constant real HEIGHT_RESTORE = 0.7 // Time it takes to revert back to normal height. MUST be positive. //=========================================================================== // Bomb globals. private constant real FALL_TIME = 0.5 // Time it takes for the bombs to fall.MUST be positive. private constant real BOMB_EXPLODE_HEIGHT = 0.010 // The height upon the bombs explodes. Should not be changed. private constant real BOMBING_DISTANCE = 300.0 // All bombs will be dropped over this distance. // The distance between the bombs is: BOMBING_DISTANCE/n, where n is number of bombs. Must be grater than 0! //=========================================================================== // Timer interval global. private constant real INTERVAL = 0.03125// The interval between each iteration. //=========================================================================== // SFX model globals. private constant string ZEPPELIN_MODEL = "Units\\Creeps\\GoblinZeppelin\\GoblinZeppelin.mdl" private constant string BOMB_MODEL = "Abilities\\Weapons\\Mortar\\MortarMissile.mdl" private constant string EXPLOSION_MODEL = "" // "Abilities\\Weapons\\Mortar\\MortarMissile.mdl" // Effects for "name"_MODEL object. //=========================================================================== // Visual globals. private constant real ZEPPELIN_SCALE = 1.50 // Scale of the flying ship. private constant real BOMB_SCALE = 1.30 // Scale of the dropped thing. private constant boolean HIDE_ON_DEATH = false // Hide units when they die? private constant boolean RESET_LOOK = true // Try to reset the facing of the bomb? private constant string DAMAGE_MODEL = "" // Use an effect on damaged units. //=========================================================================== // Attachment globals. private constant string MODEL_ATTACHMENT_POS = "origin" // Attachment point for BOMB/ZEPPELIN effects. private constant string DAMAGE_POS = "chest" // Attachment point for damage model. endglobals //=========================================================================== // How many bombs per level. 3 base + 1/level. private function GetBombs takes integer lvl returns integer return (3 + ((lvl-1) * 1)) endfunction //=========================================================================== // Damage per bomb. 33 base + 11/level. private function GetDamage takes integer lvl returns real return (33.0 + ((lvl-1) * 11.0)) endfunction //=========================================================================== // Radius of each explosion. 200 base + 0/level. private function GetArea takes integer lvl returns real return (200.0 + ((lvl-1) * 0.0)) endfunction //=========================================================================== // Function for exploding stuff. // keywords, do not change. private keyword Bomb private keyword damageOpt private function explode takes Bomb b returns nothing local unit u call DestroyEffect(AddSpecialEffect(EXPLOSION_MODEL, GetUnitX(b.bomb), GetUnitY(b.bomb))) call damageOpt.damageAOE(b.caster, GetUnitX(b.bomb), GetUnitY(b.bomb), b.aoe, b.damage) endfunction //=========================================================================== // Function for managing damage options. private function SetXEDamage takes nothing returns nothing // Target options. set damageOpt.damageAllies = false set damageOpt.damageEnemies = true set damageOpt.damageTrees = true // Damage options. set damageOpt.dtype = DAMAGE_TYPE_UNIVERSAL set damageOpt.atype = ATTACK_TYPE_SIEGE set damageOpt.wtype = WEAPON_TYPE_WHOKNOWS // Use effect on damaged units? call damageOpt.useSpecialEffect(DAMAGE_MODEL, DAMAGE_POS) endfunction // - - - - - - - - - - - - - - - - - - // | NO TOUCHING PAST THIS BLOCK! | // | unless you like errors that is | //==== - - - - - - - - - - - - - - - - - - ================================== //=========================================================================== // Private globals. globals private timer Timer = null private xedamage damageOpt endglobals //=========================================================================== // struct for the bombs. private struct Bomb unit bomb unit caster effect model real lifeTime integer indexPlace real damage real aoe static Bomb array BOMBS static integer COUNTER = 0 //=========================================================================== // creation method. static method create takes unit bomber, unit c, integer lvl returns Bomb local Bomb b = Bomb.allocate() set b.bomb = CreateUnit(GetOwningPlayer(bomber), XE_DUMMY_UNITID, GetUnitX(bomber), GetUnitY(bomber), 0) set b.model = AddSpecialEffectTarget(BOMB_MODEL, b.bomb, MODEL_ATTACHMENT_POS) set b.lifeTime = FALL_TIME set b.damage = GetDamage(lvl) set b.aoe = GetArea(lvl) set b.caster = c // make the unit flyable and set its flying height. Along with facing. call UnitAddAbility(b.bomb, XE_HEIGHT_ENABLER) call UnitRemoveAbility(b.bomb, XE_HEIGHT_ENABLER) call SetUnitFlyHeight(b.bomb, GetUnitFlyHeight(bomber), 0) call SetUnitScale(b.bomb, BOMB_SCALE, BOMB_SCALE, BOMB_SCALE) call SetUnitAnimationByIndex(b.bomb, 0) // calculate the time it takes for the bomb to reach BOMB_EXPLODE_HEIGHT. call SetUnitFlyHeight(b.bomb, BOMB_EXPLODE_HEIGHT, (GetUnitFlyHeight(b.bomb) - BOMB_EXPLODE_HEIGHT) / FALL_TIME) // Correct the position of the bomb. call SetUnitPathing(b.bomb, false) call SetUnitX(b.bomb, GetUnitX(bomber)) call SetUnitY(b.bomb, GetUnitY(bomber)) // "attach" struct to arrays. set b.indexPlace = Bomb.COUNTER set Bomb.BOMBS[Bomb.COUNTER] = b set Bomb.COUNTER = Bomb.COUNTER + 1 return b endmethod //=========================================================================== // update method. method update takes nothing returns nothing set this.lifeTime = this.lifeTime - INTERVAL if (this.lifeTime <= 0.01 ) then call explode(this) call this.destroy() endif endmethod //=========================================================================== // upon destruction method. method onDestroy takes nothing returns nothing if (HIDE_ON_DEATH) then call ShowUnit(this.bomb, false) endif if (RESET_LOOK) then call SetUnitFacing(this.bomb, 0) call SetUnitAnimationByIndex(this.bomb, 90) endif call KillUnit(this.bomb) call DestroyEffect(this.model) // recycle array slots. set Bomb.COUNTER = Bomb.COUNTER - 1 set Bomb.BOMBS[Bomb.COUNTER].indexPlace = this.indexPlace set Bomb.BOMBS[this.indexPlace] = Bomb.BOMBS[Bomb.COUNTER] endmethod endstruct //=========================================================================== // zeppelin struct. private struct Data unit zeppelin unit caster effect model integer level integer nbombs real distToBombing real intervalBetween real nextBomb real distanceLeft real xTick real yTick boolean bombingAct integer indexPlace static Data array DATA static integer COUNTER = 0 //=========================================================================== // creation method. static method create takes nothing returns Data local Data d = Data.allocate() local location loc = GetSpellTargetLoc() local real angle local real x local real y set d.caster = GetTriggerUnit() set d.level = GetUnitAbilityLevel(d.caster, AID_GOBLIN_BOMBER) set d.nbombs = GetBombs(d.level) set angle = Atan2(GetLocationY(loc) - GetUnitY(d.caster), GetLocationX(loc) - GetUnitX(d.caster)) set x = GetUnitX(d.caster) - DISTANCE * Cos(angle) set y = GetUnitY(d.caster) - DISTANCE * Sin(angle) set d.zeppelin = CreateUnit(GetOwningPlayer(d.caster), XE_DUMMY_UNITID, x, y, angle*bj_RADTODEG) set d.model = AddSpecialEffectTarget(ZEPPELIN_MODEL, d.zeppelin, MODEL_ATTACHMENT_POS) call UnitAddAbility(d.zeppelin, XE_HEIGHT_ENABLER) call UnitRemoveAbility(d.zeppelin, XE_HEIGHT_ENABLER) // position correction. call SetUnitPathing(d.zeppelin, false) call SetUnitX(d.zeppelin, x) call SetUnitY(d.zeppelin, y) call SetUnitFlyHeight(d.zeppelin, FLY_HEIGHT, 0) call SetUnitScale(d.zeppelin, ZEPPELIN_SCALE, ZEPPELIN_SCALE, ZEPPELIN_SCALE) // here we calcualte distance left, x/y position per iteration, distance to bombing // and the interval between the bomb drops. set d.distanceLeft = (SquareRoot(Pow(GetLocationX(loc) - GetUnitX(d.caster), 2) + Pow(GetLocationY(loc) - GetUnitY(d.caster), 2)) + DISTANCE) * 2 set d.xTick = (ZEPPELIN_VELOCITY * INTERVAL) * Cos(angle) set d.yTick = (ZEPPELIN_VELOCITY * INTERVAL) * Sin(angle) set d.distToBombing = (d.distanceLeft - BOMBING_DISTANCE) * 0.5 set d.intervalBetween = BOMBING_DISTANCE/d.nbombs set d.nextBomb = 0.0 // set array slots and pointers so we may retrieve data later on. set d.indexPlace = Data.COUNTER set Data.DATA[Data.COUNTER] = d set Data.COUNTER = Data.COUNTER + 1 return d endmethod //=========================================================================== // update method. method update takes nothing returns nothing local real x = GetUnitX(this.zeppelin) + this.xTick // prepare for next position. local real y = GetUnitY(this.zeppelin) + this.yTick if (this.distanceLeft > 0) then if (this.distToBombing > 0) then set this.distToBombing = this.distToBombing - (ZEPPELIN_VELOCITY * INTERVAL) if (this.distToBombing <= 0) then call SetUnitFlyHeight(this.zeppelin, BOMB_HEIGHT, (FLY_HEIGHT - BOMB_HEIGHT)/BOMBING_TIME) set this.bombingAct = true endif elseif (this.bombingAct) then if (this.nbombs > 0) then set this.nextBomb = this.nextBomb - ZEPPELIN_VELOCITY * INTERVAL if (this.nextBomb <= 0) then set this.nbombs = this.nbombs - 1 set this.nextBomb = this.intervalBetween call Bomb.create(this.zeppelin, this.caster, this.level) endif else set this.bombingAct = false call SetUnitFlyHeight(this.zeppelin, FLY_HEIGHT, (FLY_HEIGHT - BOMB_HEIGHT)/HEIGHT_RESTORE) endif endif set this.distanceLeft = this.distanceLeft - (ZEPPELIN_VELOCITY * INTERVAL) call SetUnitX(this.zeppelin, x) call SetUnitY(this.zeppelin, y) else call this.destroy() endif endmethod //=========================================================================== // upon destruction method. method onDestroy takes nothing returns nothing if (HIDE_ON_DEATH) then call ShowUnit(this.zeppelin, false) endif call KillUnit(this.zeppelin) call DestroyEffect(this.model) // here we recycle arrays slots. set Data.COUNTER = Data.COUNTER - 1 set Data.DATA[Data.COUNTER].indexPlace = this.indexPlace set Data.DATA[this.indexPlace] = Data.DATA[Data.COUNTER] endmethod endstruct //=========================================================================== // function for looping through instances. private function handlerFunc takes nothing returns nothing local integer i = 0 // loop through all Zeppelin structs. loop exitwhen i >= Data.COUNTER call Data.DATA[i].update() set i = i + 1 endloop // loop through all bomb structs. set i = 0 loop exitwhen i >= Bomb.COUNTER call Bomb.BOMBS[i].update() set i = i + 1 endloop if (Data.COUNTER == 0 and Bomb.COUNTER == 0) then call PauseTimer(Timer) endif endfunction //=========================================================================== // runs on the spell effect event. private function act takes nothing returns boolean if (GetSpellAbilityId() == AID_GOBLIN_BOMBER) then call Data.create() if (Data.COUNTER == 1) then call TimerStart(Timer, INTERVAL, true, function handlerFunc) endif endif return false endfunction //=========================================================================== // Initialization function. private function InitTrig takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(t, Condition( function act)) // xe functions. set damageOpt = xedamage.create() call SetXEDamage() call XE_PreloadAbility(AID_GOBLIN_BOMBER) // initialize global variables. set Timer = CreateTimer() endfunction endlibrary
Comments and Suggestions are welcome. |
| 09-09-2008, 06:41 PM | #2 |
Seriusly, I don't get it. Why do people use methods for spells? I think it's well, no offense, but, stupid. Well, aside from that, beautifully coded. |
| 09-09-2008, 06:52 PM | #3 | ||
Quote:
Quote:
|
| 09-09-2008, 08:13 PM | #4 |
Methods are useful for spells because they help clean up the code and stuff. At least, Creation methods that is. I dunno about others. |
| 09-10-2008, 05:41 PM | #5 |
Yeah, and other methods makes the code more readable than just chunking everything into one, huge loop function. |
| 09-10-2008, 05:53 PM | #6 | |
Quote:
|
| 09-10-2008, 06:32 PM | #7 | |
Quote:
EDIT: Just some random question; When you are using the SetUnitFlyHeight( someunit, someheight, higher than 0) its fly height (via GetUnitFlyingHeight) automatically returns the specified height. Is there some way around this? |
| 09-11-2008, 03:01 PM | #8 | |
Quote:
Set the height with a timer. |
| 09-11-2008, 05:47 PM | #9 |
Yes, but then I would need to manipulate around with Z heights of terrain and units -- which is too much for me. |
| 09-18-2008, 06:20 PM | #10 |
[bump]B.O.M.B[/bump] |
| 10-01-2008, 05:15 PM | #11 |
I seriously think you stole one of my maps and converted it to vJASS ... I hope I am mistaken, because if I am not (I don't think I am) than we have a problem here... |
| 10-01-2008, 10:48 PM | #12 |
Ok well this is a simple issue. Attach the map you are saying he stole, unprotected, so we can all see. If it is the case then I'm sure a mod will take appropriate actions. |
| 10-02-2008, 10:35 AM | #13 |
I believe this map is way too similar to my map and that he only remade the code and changed some small stuff like the bombs and the goblin.... however, see it by yourselves, but I don't think I am mistaken: http://www.hiveworkshop.com/resources_new/spells/1324/ |
| 10-02-2008, 11:59 AM | #14 | |
FP, don't throw random accusations around. You don't have an exclusive right to bomber-type spells. Let me quote you: Quote:
The code in your map is bad and totally different to this. So, the code is totally different, and yet you think he nicked your spell...? Right...I suggest you drop this. |
| 10-02-2008, 12:41 PM | #15 | |
Quote:
- drops 3 bombs - plane goes down and up - plane appears from behind the caster - plane dies after So, although the code is different, ya I believe he saw something ... |
