diff --git a/flixel/addons/weapon/FlxBullet.hx b/flixel/addons/weapon/FlxBullet.hx index 883f2cbe..7cb4d2e6 100644 --- a/flixel/addons/weapon/FlxBullet.hx +++ b/flixel/addons/weapon/FlxBullet.hx @@ -1,9 +1,9 @@ package flixel.addons.weapon; -import flixel.FlxG; import flixel.FlxSprite; import flixel.math.FlxMath; import flixel.math.FlxRect; +import flixel.util.FlxDestroyUtil; /** * @link http://www.photonstorm.com @@ -47,4 +47,11 @@ class FlxBullet extends FlxSprite super.update(elapsed); } + + override public function destroy():Void + { + super.destroy(); + + bounds = FlxDestroyUtil.put(bounds); + } } diff --git a/flixel/addons/weapon/FlxWeapon.hx b/flixel/addons/weapon/FlxWeapon.hx index 289786fe..c57b83d5 100644 --- a/flixel/addons/weapon/FlxWeapon.hx +++ b/flixel/addons/weapon/FlxWeapon.hx @@ -4,22 +4,22 @@ import flixel.FlxBasic; import flixel.FlxG; import flixel.FlxObject; import flixel.FlxSprite; -import flixel.addons.weapon.FlxWeapon.FlxTypedWeapon; import flixel.group.FlxGroup.FlxTypedGroup; -import flixel.input.touch.FlxTouch; import flixel.math.FlxAngle; import flixel.math.FlxPoint; -import flixel.math.FlxRandom; import flixel.math.FlxRect; import flixel.math.FlxVelocity; import flixel.sound.FlxSound; import flixel.tile.FlxTilemap; +import flixel.util.FlxDestroyUtil; import flixel.util.helpers.FlxBounds; -import flixel.util.helpers.FlxRange; +#if FLX_TOUCH +import flixel.input.touch.FlxTouch; +#end /** - * A Weapon can only fire 1 type of bullet. But it can fire many of them at once (in different directions if needed) via createBulletPattern - * A Player could fire multiple Weapons at the same time however, if you need to layer them up + * A Weapon can only fire 1 type of bullet. + * A Player could fire multiple Weapons at the same time, however, if you need to layer them up. * * @version 1.3 - October 9th 2011 * @link http://www.photonstorm.com @@ -28,7 +28,7 @@ import flixel.util.helpers.FlxRange; * @author Touch added by Impaler / Beeblerox * * TODO: Angled bullets - * TODO: multishot + * TODO: Multishot * TODO: Baked Rotation support for angled bullets * TODO: Bullet death styles (particle effects) * TODO: Bullet trails - blur FX style and Missile Command "draw lines" style? (could be another FX plugin) @@ -38,7 +38,7 @@ import flixel.util.helpers.FlxRange; */ typedef FlxWeapon = FlxTypedWeapon; -class FlxTypedWeapon +class FlxTypedWeapon implements IFlxDestroyable { // Quick firing direction angle constants public static inline var BULLET_UP:Int = -90; @@ -51,106 +51,127 @@ class FlxTypedWeapon public static inline var BULLET_SOUTH_WEST:Int = 135; /** - * Internal name for this weapon (i.e. "pulse rifle") + * Internal name for this weapon (e.g., `"pulse rifle"`). */ public var name:String; /** - * The FlxGroup into which all the bullets for this weapon are drawn. This should be added to your display and collision checked against it. + * The `FlxGroup` from which all the bullets for this weapon are drawn. This should be added to your display and collision-checked against it. */ public var group(default, null):FlxTypedGroup; - // Internal variables, use with caution + /** + * The game tick after which the weapon will be able to fire. Only used if `fireRate > 0`. + * Internal variable; use with caution. + */ public var nextFire:Int = 0; /** - * The delay in milliseconds (ms) between which each bullet is fired, set to zero to clear. By default there is no rate, as it can be controlled by FlxControl.setFireButton. - * However if you are firing using the mouse you may wish to set a firing rate. + * The delay in milliseconds (ms) between which each bullet is fired. Default is `0`, which means there is no delay. */ public var fireRate:Int = 0; /** - * When a bullet goes outside of this bounds it will be automatically killed, freeing it up for firing again. + * When a bullet goes outside of these bounds, it will be automatically killed, freeing it up for firing again. * TODO - Needs testing with a scrolling map (when not using single screen display) */ public var bounds:FlxRect; /** - * Only accessible when fireFrom is "PARENT" + * The parent sprite of this weapon. Only accessible when `fireFrom == PARENT`. */ public var parent(default, null):FlxSprite; /** - * If true, when fired the bullet direction is based on parent sprites facing value (up/down/left/right) + * Whether to fire bullets in the direction of the `parent`'s angle. Only accessible when `fireFrom == PARENT`. */ - public var useParentDirection:Bool; + public var useParentDirection(default, set):Bool; /** - * If parent is null, the Weapon will fire from a fixed x/y position on the screen, like in the game Missile Command. + * A fixed position from which to fire the weapon, like in the game Missile Command. Only accessible when `fireFrom == POSITION`. */ public var firePosition(default, null):FlxBounds; /** - * When the bullet is fired if you need to offset it on the x/y axis, for example to line it up with the "nose" of a space ship, set the amount here (positive or negative) + * A value used to offset a bullet's position when it is fired. Can be used to, for example, line a bullet up with the "nose" of a space ship. + * Only accessible when `fireFrom == PARENT`. */ + @:deprecated("Use positionOffsetBounds instead") public var positionOffset(default, null):FlxPoint; + /** + * A value used to offset a bullet's position when it is fired. Can be used to, for example, + * line a bullet up with the "nose" of a space ship. Only accessible when `fireFrom == PARENT`. + * @since 3.2.0 + */ + public var positionOffsetBounds(default, null):FlxBounds; + public var fireFrom(default, set):FlxWeaponFireFrom; public var speedMode:FlxWeaponSpeedMode; /** * The lifespan of the bullet, given in seconds. - * The bullet will be killed once it passes this lifespan, if still alive and in bounds. + * The bullet will be killed once it passes this lifespan, if it is still alive and in bounds. */ public var bulletLifeSpan:FlxBounds; /** * The elasticity of the fired bullet controls how much it rebounds off collision surfaces. - * Between 0 and 1 (0 being no rebound, 1 being 100% force rebound). Set to zero to disable. + * Between `0` and `1` (`0` being no rebound, and `1` being 100% force rebound). Default is `0`. */ public var bulletElasticity:Float = 0; /** - * Auto set the bullet angle when firing, such that it faces towards the target + * Whether to automatically set the bullet's angle when firing, such that it faces towards the target. */ public var rotateBulletTowardsTarget:Bool = false; /** - * A reference to the Bullet that was last fired + * A reference to the bullet that was last fired. */ public var currentBullet:TBullet; - // Callbacks + /** + * A function that is called immediately before a bullet is fired. + */ public var onPreFireCallback:Void->Void; + + /** + * A function that is called immediately after a bullet is fired. + */ public var onPostFireCallback:Void->Void; - // Sounds + /** + * A sound that is played immediately before a bullet is fired. + */ public var onPreFireSound:FlxSound; + + /** + * A sound that is played immediately after a bullet is fired. + */ public var onPostFireSound:FlxSound; /** - * The factory function to create a bullet + * The factory function used to create new bullets. */ var bulletFactory:FlxTypedWeapon->TBullet; - var lastFired:Int = 0; - var skipParentCollision:Bool; /** - * When the bullet is fired if you need to offset it's angle from the parent angle, for example if the bullet sprite is angle offsetted, only used when useParentAngle is true + * A value used to offset a bullet's initial angle when it is fired. */ var angleOffset:Float = 0; /** - * Creates the FlxWeapon class which will fire your bullets. - * You should call one of the makeBullet functions to visually create the bullets. - * Then either use setDirection with fire() or one of the fireAt functions to launch them. + * Creates an `FlxWeapon` instance which can fire bullets. + * Use one of the `fireFrom...()` or `fireAt...()` functions to fire bullets. * - * @param name The name of your weapon (i.e. "laser" or "shotgun"). For your internal reference really, but could be displayed in-game. - * @param bulletFactory FlxWeapon uses this factory function to actually create a bullet - * @param fireFrom enum that describes the weapon firing position, for Example Parent, Position. - * @param speedMode enum that describes the bullets speed mode, for Example Velocity, Acceleration. + * @param name The name of the weapon (e.g., `"laser"`, `"shotgun"`) + * For your internal reference really, but could be displayed in-game too. + * @param bulletFactory The factory function used to create new bullets. + * @param fireFrom The weapon's firing position (i.e., `PARENT`, `POSITION`). + * @param speedMode The speed mode for the bullets (i.e., `SPEED`, `ACCELERATION`). */ public function new(name:String, bulletFactory:FlxTypedWeapon->TBullet, fireFrom:FlxWeaponFireFrom, speedMode:FlxWeaponSpeedMode) { @@ -165,12 +186,13 @@ class FlxTypedWeapon } /** - * Internal function that handles the actual firing of the bullets + * Internal function that handles the actual firing of the bullets. * - * @param Mode Mode to use for firing the bullet - * @return True if a bullet was fired or false if one wasn't available. The bullet last fired is stored in FlxWeapon.prevBullet + * @param mode The mode to use for firing the bullet. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ - function runFire(Mode:FlxWeaponFireMode):Bool + function runFire(mode:FlxWeaponFireMode):Bool { if (fireRate > 0 && FlxG.game.ticks < nextFire) { @@ -189,7 +211,6 @@ class FlxTypedWeapon } #end - lastFired = FlxG.game.ticks; nextFire = FlxG.game.ticks + Std.int(fireRate / FlxG.timeScale); // Get a free bullet from the pool @@ -200,20 +221,19 @@ class FlxTypedWeapon } // Clear any velocity that may have been previously set from the pool - currentBullet.velocity.x = 0; // TODO is this really necessary? - currentBullet.velocity.y = 0; + currentBullet.velocity.zero(); // TODO is this really necessary? switch (fireFrom) { - case PARENT(parent, offset, useParentDirection, angleOffset): + case PARENT(parent, offset, useParentAngle, angleOffset): // store new offset in a new variable - var actualOffset = new FlxPoint(FlxG.random.float(offset.min.x, offset.max.x), FlxG.random.float(offset.min.y, offset.max.y)); - if (useParentDirection) + var actualOffset = FlxPoint.get(FlxG.random.float(offset.min.x, offset.max.x), FlxG.random.float(offset.min.y, offset.max.y)); + if (useParentAngle) { // rotate actual offset around parent origin using the parent angle - actualOffset = rotatePoints(actualOffset, parent.origin, parent.angle); + rotatePoints(actualOffset, parent.origin, parent.angle, actualOffset); - // reposition offset to have it's origin at the new returned point + // reposition offset to have its origin at the new returned point actualOffset.subtract(currentBullet.width / 2, currentBullet.height / 2); actualOffset.subtract(parent.offset.x, parent.offset.y); } @@ -221,6 +241,8 @@ class FlxTypedWeapon currentBullet.last.x = currentBullet.x = parent.x + actualOffset.x; currentBullet.last.y = currentBullet.y = parent.y + actualOffset.y; + actualOffset.put(); + case POSITION(position): currentBullet.last.x = currentBullet.x = FlxG.random.float(position.min.x, position.max.x); currentBullet.last.y = currentBullet.y = FlxG.random.float(position.min.y, position.max.y); @@ -231,7 +253,7 @@ class FlxTypedWeapon currentBullet.elasticity = bulletElasticity; currentBullet.lifespan = FlxG.random.float(bulletLifeSpan.min, bulletLifeSpan.max); - switch (Mode) + switch (mode) { case FIRE_AT_POSITION(x, y): internalFireAtPoint(currentBullet, FlxPoint.weak(x, y)); @@ -281,30 +303,32 @@ class FlxTypedWeapon } /** - * Calculates the new position for a point rotated around another point + * Calculates the new position for a point rotated around another point. * - * @param point The to be rotated point - * @param origin The to be rotated around point. usually the origin of the parent flxsprite - * @param angle the current angle from of the origin. usually the parent angle. - * @return The new rotated Point + * @param point The point to be rotated. + * @param origin The point around which to be rotated. Usually the origin of the `parent`. + * @param degrees The angle by which to rotate `point` around `origin`. Usually the `parent`'s angle. + * @param result An optional point to reuse instead of getting another from the pool. + * @return The new rotated point. */ - public function rotatePoints(point:FlxPoint, origin:FlxPoint, angle:Float):FlxPoint + public function rotatePoints(point:FlxPoint, origin:FlxPoint, degrees:Float, ?result:FlxPoint):FlxPoint { - var returnedPoint:FlxPoint = FlxPoint.weak(); + if (result == null) + result = FlxPoint.get(); - var inBetweenAngle:Float = origin.degreesTo(point); - inBetweenAngle = angle + inBetweenAngle; - var inBetweenDistance:Float = origin.distanceTo(point); + final distanceTo = origin.distanceTo(point); + final degreesTo = degrees + origin.distanceTo(point); - returnedPoint.x = Math.cos(inBetweenAngle * Math.PI / 180) * inBetweenDistance; - returnedPoint.y = Math.sin(inBetweenAngle * Math.PI / 180) * inBetweenDistance; - return returnedPoint.add(origin.x, origin.y); + result.setPolarDegrees(distanceTo, degreesTo); + result.addPoint(origin); + return result; } /** - * Fires a bullet (if one is available) based on the facing (UP/DOWN/LEFT/RIGHT) of the Weapons parent + * Fires a bullet (if one is available) based on the `facing` variable of the weapon's `parent`. * - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ public inline function fireFromParentFacing(angleNoise:FlxBounds):Bool { @@ -313,9 +337,11 @@ class FlxTypedWeapon #if FLX_MOUSE /** - * Fires a bullet (if one is available) at the mouse coordinates, using the speed set in setBulletSpeed and the rate set in setFireRate. + * Fires a bullet (if one is available) at the mouse coordinates, + * using the speed set in `speedMode` and the rate set in `fireRate`. * - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ public inline function fireAtMouse():Bool { @@ -325,14 +351,16 @@ class FlxTypedWeapon #if FLX_TOUCH /** - * Fires a bullet (if one is available) at the FlxTouch coordinates, using the speed set in setBulletSpeed and the rate set in setFireRate. + * Fires a bullet (if one is available) at the `FlxTouch` coordinates, + * using the speed set in `speedMode` and the rate set in `fireRate`. * - * @param Touch The FlxTouch object to fire at, if null use the first available one - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @param touch The `FlxTouch` object to fire at. If `null`, uses the first available one. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ - public function fireAtTouch(?Touch:FlxTouch):Bool + public function fireAtTouch(?touch:FlxTouch):Bool { - var touch = Touch == null ? FlxG.touches.getFirst() : Touch; + var touch = touch == null ? FlxG.touches.getFirst() : touch; if (touch != null) return runFire(FIRE_AT_TOUCH(touch)); else @@ -341,33 +369,39 @@ class FlxTypedWeapon #end /** - * Fires a bullet (if one is available) at the given x/y coordinates, using the speed set in setBulletSpeed and the rate set in setFireRate. + * Fires a bullet (if one is available) at the given x/y coordinates, + * using the speed set in `speedMode` and the rate set in `fireRate`. * - * @param X The x coordinate (in game world pixels) to fire at - * @param Y The y coordinate (in game world pixels) to fire at - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @param x The x coordinate (in game world pixels) to fire at. + * @param y The y coordinate (in game world pixels) to fire at. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ - public inline function fireAtPosition(X:Int, Y:Int):Bool + public inline function fireAtPosition(x:Int, y:Int):Bool { - return runFire(FIRE_AT_POSITION(X, Y)); + return runFire(FIRE_AT_POSITION(x, y)); } /** - * Fires a bullet (if one is available) at the given targets x/y coordinates, using the speed set in setBulletSpeed and the rate set in setFireRate. + * Fires a bullet (if one is available) at the given target's position, + * using the speed set in `speedMode` and the rate set in `fireRate`. * - * @param Target The FlxSprite you wish to fire the bullet at - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @param target The `FlxSprite` to fire the bullet at. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ - public inline function fireAtTarget(Target:FlxSprite):Bool + public inline function fireAtTarget(target:FlxSprite):Bool { - return runFire(FIRE_AT_TARGET(Target)); + return runFire(FIRE_AT_TARGET(target)); } /** - * Fires a bullet (if one is available) based on the given angle + * Fires a bullet (if one is available) based on the given angle. * - * @param angle The angle (in degrees) calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative) - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @param angle The angle (in degrees) calculated in clockwise positive direction + * (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative) + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ public inline function fireFromAngle(angle:FlxBounds):Bool { @@ -375,9 +409,10 @@ class FlxTypedWeapon } /** - * Fires a bullet (if one is available) based on the angle of the Weapons parent + * Fires a bullet (if one is available) based on the angle of the weapon's `parent`. * - * @return True if a bullet was fired or false if one wasn't available. A reference to the bullet fired is stored in FlxWeapon.currentBullet. + * @return `true` if a bullet was fired, or `false` if one wasn't available. + * A reference to the last fired bullet is stored in `currentBullet`. */ public inline function fireFromParentAngle(angle:FlxBounds):Bool { @@ -387,53 +422,53 @@ class FlxTypedWeapon /** * Sets a pre-fire callback function and sound. These are played immediately before the bullet is fired. * - * @param Callback The function to call - * @param Sound A FlxSound to play + * @param callback The function to call before a bullet is fired. + * @param sound An `FlxSound` to play before a bullet is fired. */ - public function setPreFireCallback(?Callback:Void->Void, ?Sound:FlxSound):Void + public function setPreFireCallback(?callback:Void->Void, ?sound:FlxSound):Void { - onPreFireCallback = Callback; - onPreFireSound = Sound; + onPreFireCallback = callback; + onPreFireSound = sound; } /** * Sets a post-fire callback function and sound. These are played immediately after the bullet is fired. * - * @param Callback The function to call - * @param Sound An FlxSound to play + * @param callback The function to call after a bullet is fired. + * @param sound An `FlxSound` to play after a bullet is fired. */ - public function setPostFireCallback(?Callback:Void->Void, ?Sound:FlxSound):Void + public function setPostFireCallback(?callback:Void->Void, ?sound:FlxSound):Void { - onPostFireCallback = Callback; - onPostFireSound = Sound; + onPostFireCallback = callback; + onPostFireSound = sound; } /** - * Checks to see if the bullets are overlapping the specified object or group + * Checks whether the bullets are overlapping the specified object or group. * - * @param ObjectOrGroup The group or object to check if bullets collide - * @param NotifyCallBack A function that will get called if a bullet overlaps an object - * @param SkipParent Don't trigger collision notifies with the parent of this object + * @param objectOrGroup The object or group to check against. + * @param notifyCallBack A function that will get called if a bullet overlaps the object or group. + * @param skipParent Whether to ignore collisions with the parent of this weapon. */ - public inline function bulletsOverlap(ObjectOrGroup:FlxBasic, ?NotifyCallBack:FlxObject->FlxObject->Void, SkipParent:Bool = true):Void + public inline function bulletsOverlap(objectOrGroup:FlxBasic, ?notifyCallBack:FlxObject->FlxObject->Void, skipParent = true):Void { if (group != null && group.length > 0) { - skipParentCollision = SkipParent; - FlxG.overlap(ObjectOrGroup, group, NotifyCallBack != null ? NotifyCallBack : onBulletHit, shouldBulletHit); + skipParentCollision = skipParent; + FlxG.overlap(objectOrGroup, group, notifyCallBack != null ? notifyCallBack : onBulletHit, shouldBulletHit); } } - function shouldBulletHit(Object:FlxObject, Bullet:FlxObject):Bool + function shouldBulletHit(object:FlxObject, bullet:FlxObject):Bool { - if (parent == Object && skipParentCollision) + if (parent == object && skipParentCollision) { return false; } - if ((Object is FlxTilemap)) + if ((object is FlxTilemap)) { - return cast(Object, FlxTilemap).overlapsWithCallback(Bullet); + return cast(object, FlxTilemap).overlapsWithCallback(bullet); } else { @@ -441,9 +476,9 @@ class FlxTypedWeapon } } - function onBulletHit(Object:FlxObject, Bullet:FlxObject):Void + function onBulletHit(object:FlxObject, bullet:FlxObject):Void { - Bullet.kill(); + bullet.kill(); } function internalFireAtPoint(bullet:TBullet, point:FlxPoint):Void @@ -476,6 +511,7 @@ class FlxTypedWeapon var velocity = FlxVelocity.velocityFromAngle(FlxAngle.asDegrees(radians), FlxG.random.float(speed.min, speed.max)); bullet.velocity.x = velocity.x; bullet.velocity.y = velocity.y; + velocity.put(); case ACCELERATION(acceleration, maxSpeed): FlxVelocity.accelerateFromAngle(bullet, radians, FlxG.random.float(acceleration.min, acceleration.max), @@ -488,17 +524,107 @@ class FlxTypedWeapon } } - inline function set_fireFrom(v:FlxWeaponFireFrom):FlxWeaponFireFrom + public function destroy():Void + { + name = null; + group = FlxDestroyUtil.destroy(group); + bounds = FlxDestroyUtil.put(bounds); + parent = null; // Don't destroy the parent + positionOffset = FlxDestroyUtil.put(positionOffset); + if (positionOffsetBounds != null) + { + positionOffsetBounds.min = FlxDestroyUtil.put(positionOffsetBounds.min); + positionOffsetBounds.max = FlxDestroyUtil.put(positionOffsetBounds.max); + positionOffsetBounds = null; + } + if (firePosition != null) + { + firePosition.min = FlxDestroyUtil.put(firePosition.min); + firePosition.max = FlxDestroyUtil.put(firePosition.max); + firePosition = null; + } + if (fireFrom != null) + { + switch (fireFrom) + { + case PARENT(parent, offset, useParentAngle, angleOffset): + parent = null; + if (offset != null) + { + offset.min = FlxDestroyUtil.put(offset.min); + offset.max = FlxDestroyUtil.put(offset.max); + offset = null; + } + angleOffset = null; + case POSITION(position): + if (position != null) + { + position.min = FlxDestroyUtil.put(position.min); + position.max = FlxDestroyUtil.put(position.max); + position = null; + } + } + // fireFrom = null; // Can't do this because sending null to set_fireFrom() causes an NPE + @:bypassAccessor fireFrom = null; + } + if (speedMode != null) + { + switch (speedMode) + { + case SPEED(speed): + speed = null; + case ACCELERATION(acceleration, maxSpeed): + acceleration = null; + maxSpeed = null; + } + speedMode = null; + } + bulletLifeSpan = null; + currentBullet = FlxDestroyUtil.destroy(currentBullet); + onPreFireCallback = null; + onPostFireCallback = null; + onPreFireSound = null; + onPostFireSound = null; + bulletFactory = null; + } + + function set_useParentDirection(v:Bool):Bool + { + switch (fireFrom) + { + case PARENT(parent, offset, useParentAngle, angleOffset): + @:bypassAccessor fireFrom = PARENT(parent, offset, v, angleOffset); + default: + } + return v; + } + + function set_fireFrom(v:FlxWeaponFireFrom):FlxWeaponFireFrom { switch (v) { - case PARENT(parent, _, _, angleOffset): + case PARENT(parent, offset, useParentAngle, angleOffset): this.parent = parent; + // this.positionOffset = offset; + this.positionOffsetBounds = offset; + this.useParentDirection = useParentAngle; if (angleOffset != null) this.angleOffset = angleOffset; + this.firePosition = null; + + case POSITION(position): + this.firePosition = position; + + this.parent = null; + this.positionOffset = null; + this.positionOffsetBounds = null; + default: - parent = null; + this.parent = null; + this.positionOffset = null; + this.positionOffsetBounds = null; + this.firePosition = null; } return fireFrom = v; } @@ -506,7 +632,19 @@ class FlxTypedWeapon enum FlxWeaponFireFrom { + /** + * @param parent The parent sprite of the weapon. + * @param offset A value used to offset a bullet's position when it is fired + * (e.g. to line a bullet up with the "nose" of a space ship). + * @param useParentAngle Whether to fire bullets in the direction of the `parent`'s angle. + * @param angleOffset A value used to offset a bullet's angle from the `parent`'s angle + * when it is fired. + */ PARENT(parent:FlxSprite, offset:FlxBounds, ?useParentAngle:Bool, ?angleOffset:Float); + + /** + * @param position A fixed position from which to fire the weapon, like in the game Missile Command. + */ POSITION(position:FlxBounds); }