oolite/src/Core/Entities/OOQuiriumCascadeEntity.m

181 lines
3.9 KiB
Objective-C

/*
OOQuiriumCascadeEntity.m
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOQuiriumCascadeEntity.h"
#import "PlayerEntity.h"
#import "Universe.h"
#import "OOMacroOpenGL.h"
#define kQuiriumCascadeDuration (20.0) // seconds
#define kQuiriumCollisionDelay (0.05) // seconds before we start colliding with and damaging things.
@implementation OOQuiriumCascadeEntity
- (id) initQuiriumCascadeFromShip:(ShipEntity *)ship
{
if (ship == nil)
{
[self release];
return nil;
}
if ((self = [super init]))
{
[self setPosition:[ship position]];
[self setStatus:STATUS_EFFECT];
scanClass = CLASS_MINE;
[self setOwner:[ship owner]];
// Red and green channels are animated.
_color[2] = 1.0f;
_color[3] = 0.5f;
}
return self;
}
+ (instancetype) quiriumCascadeFromShip:(ShipEntity *)ship
{
return [[[self alloc] initQuiriumCascadeFromShip:ship] autorelease];
}
- (NSString *) descriptionComponents
{
return [NSString stringWithFormat:@"%f seconds passed of %f", _timePassed, kQuiriumCascadeDuration];
}
- (void) update:(OOTimeDelta) delta_t
{
[super update:delta_t];
_timePassed += delta_t;
rotMatrix = OOMatrixForBillboard(position, [PLAYER position]);
GLfloat tf = _timePassed / kQuiriumCascadeDuration;
GLfloat stf = tf * tf;
GLfloat expansionSpeed = 0.0;
if (_timePassed > 0) // Avoid divide by 0
{
expansionSpeed = fmin(240.0f + 10.0f / (tf * tf), 1000.0f);
}
collision_radius += delta_t * expansionSpeed; // expand
energy = delta_t * (100000 - 90000 * tf); // adjusted to take into account delta_t
_color[3] = OOClamp_0_1_f(0.5f * ((0.025f / tf) + 1.0f - stf));
_color[0] = _color[1] = fmin(1.0f - 5.0f * tf, 1.0f);
if (_color[0] < 0.0f)
{
_color[0] = 0.25f * tf * randf();
_color[1] = 0.0f;
}
// manage collisions
Entity *owner = [self owner];
Entity *e = nil;
foreach (e, collidingEntities)
{
// we're going to force the weapon id to be the qbomb key here, because at this point the cascade entity isn't a ship any more
// and there's no link back to the original.
[e takeEnergyDamage:energy from:self becauseOf:owner weaponIdentifier:@"EQ_QC_MINE"];
}
// expire after ttl
if (_timePassed > kQuiriumCascadeDuration)
{
[UNIVERSE removeEntity:self];
}
}
- (void) drawImmediate:(bool)immediate translucent:(bool)translucent
{
if (!translucent || [UNIVERSE breakPatternHide]) return;
OO_ENTER_OPENGL();
OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING);
OOGL(glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT));
OOGL(glDisable(GL_CULL_FACE));
OOGL(glDisable(GL_TEXTURE_2D));
OOGL(glEnable(GL_BLEND));
OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE));
OOGL(glColor4fv(_color));
OOGLBEGIN(GL_TRIANGLE_FAN);
GLDrawBallBillboard(collision_radius, 4, sqrt(cam_zero_distance));
OOGLEND();
OOGL(glPopAttrib());
OOVerifyOpenGLState();
OOCheckOpenGLErrors(@"OOQuiriumCascadeEntity after drawing %@", self);
}
- (BOOL) isEffect
{
return YES;
}
- (BOOL) isCascadeWeapon
{
return YES;
}
- (BOOL) canCollide
{
return _timePassed > kQuiriumCollisionDelay;
}
- (BOOL) checkCloseCollisionWith:(Entity *)other
{
return YES;
}
@end
@implementation Entity (OOQuiriumCascadeExtensions)
- (BOOL) isCascadeWeapon
{
return NO;
}
@end