Line data Source code
1 0 : /* 2 : 3 : OOQuiriumCascadeEntity.m 4 : 5 : 6 : Oolite 7 : Copyright (C) 2004-2013 Giles C Williams and contributors 8 : 9 : This program is free software; you can redistribute it and/or 10 : modify it under the terms of the GNU General Public License 11 : as published by the Free Software Foundation; either version 2 12 : of the License, or (at your option) any later version. 13 : 14 : This program is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU General Public License for more details. 18 : 19 : You should have received a copy of the GNU General Public License 20 : along with this program; if not, write to the Free Software 21 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 22 : MA 02110-1301, USA. 23 : 24 : */ 25 : 26 : #import "OOQuiriumCascadeEntity.h" 27 : #import "PlayerEntity.h" 28 : #import "Universe.h" 29 : #import "OOMacroOpenGL.h" 30 : 31 : 32 0 : #define kQuiriumCascadeDuration (20.0) // seconds 33 0 : #define kQuiriumCollisionDelay (0.05) // seconds before we start colliding with and damaging things. 34 : 35 : 36 : @implementation OOQuiriumCascadeEntity 37 : 38 0 : - (id) initQuiriumCascadeFromShip:(ShipEntity *)ship 39 : { 40 : if (ship == nil) 41 : { 42 : [self release]; 43 : return nil; 44 : } 45 : 46 : if ((self = [super init])) 47 : { 48 : [self setPosition:[ship position]]; 49 : 50 : [self setStatus:STATUS_EFFECT]; 51 : scanClass = CLASS_MINE; 52 : 53 : [self setOwner:[ship owner]]; 54 : 55 : // Red and green channels are animated. 56 : _color[2] = 1.0f; 57 : _color[3] = 0.5f; 58 : } 59 : 60 : return self; 61 : } 62 : 63 : 64 : + (instancetype) quiriumCascadeFromShip:(ShipEntity *)ship 65 : { 66 : return [[[self alloc] initQuiriumCascadeFromShip:ship] autorelease]; 67 : } 68 : 69 : 70 0 : - (NSString *) descriptionComponents 71 : { 72 : return [NSString stringWithFormat:@"%f seconds passed of %f", _timePassed, kQuiriumCascadeDuration]; 73 : } 74 : 75 : 76 0 : - (void) update:(OOTimeDelta) delta_t 77 : { 78 : [super update:delta_t]; 79 : _timePassed += delta_t; 80 : 81 : rotMatrix = OOMatrixForBillboard(position, [PLAYER position]); 82 : 83 : GLfloat tf = _timePassed / kQuiriumCascadeDuration; 84 : GLfloat stf = tf * tf; 85 : GLfloat expansionSpeed = 0.0; 86 : if (_timePassed > 0) // Avoid divide by 0 87 : { 88 : expansionSpeed = fmin(240.0f + 10.0f / (tf * tf), 1000.0f); 89 : } 90 : 91 : collision_radius += delta_t * expansionSpeed; // expand 92 : energy = delta_t * (100000 - 90000 * tf); // adjusted to take into account delta_t 93 : 94 : _color[3] = OOClamp_0_1_f(0.5f * ((0.025f / tf) + 1.0f - stf)); 95 : 96 : _color[0] = _color[1] = fmin(1.0f - 5.0f * tf, 1.0f); 97 : if (_color[0] < 0.0f) 98 : { 99 : _color[0] = 0.25f * tf * randf(); 100 : _color[1] = 0.0f; 101 : } 102 : 103 : // manage collisions 104 : Entity *owner = [self owner]; 105 : Entity *e = nil; 106 : foreach (e, collidingEntities) 107 : { 108 : // 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 109 : // and there's no link back to the original. 110 : [e takeEnergyDamage:energy from:self becauseOf:owner weaponIdentifier:@"EQ_QC_MINE"]; 111 : } 112 : 113 : // expire after ttl 114 : if (_timePassed > kQuiriumCascadeDuration) 115 : { 116 : [UNIVERSE removeEntity:self]; 117 : } 118 : } 119 : 120 : 121 0 : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent 122 : { 123 : if (!translucent || [UNIVERSE breakPatternHide]) return; 124 : 125 : OO_ENTER_OPENGL(); 126 : OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING); 127 : 128 : OOGL(glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT)); 129 : 130 : OOGL(glDisable(GL_CULL_FACE)); 131 : OOGL(glDisable(GL_TEXTURE_2D)); 132 : OOGL(glEnable(GL_BLEND)); 133 : OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE)); 134 : 135 : OOGL(glColor4fv(_color)); 136 : OOGLBEGIN(GL_TRIANGLE_FAN); 137 : GLDrawBallBillboard(collision_radius, 4, sqrt(cam_zero_distance)); 138 : OOGLEND(); 139 : 140 : OOGL(glPopAttrib()); 141 : 142 : OOVerifyOpenGLState(); 143 : OOCheckOpenGLErrors(@"OOQuiriumCascadeEntity after drawing %@", self); 144 : } 145 : 146 : 147 0 : - (BOOL) isEffect 148 : { 149 : return YES; 150 : } 151 : 152 : 153 0 : - (BOOL) isCascadeWeapon 154 : { 155 : return YES; 156 : } 157 : 158 : 159 0 : - (BOOL) canCollide 160 : { 161 : return _timePassed > kQuiriumCollisionDelay; 162 : } 163 : 164 : 165 0 : - (BOOL) checkCloseCollisionWith:(Entity *)other 166 : { 167 : return YES; 168 : } 169 : 170 : @end 171 : 172 : 173 : @implementation Entity (OOQuiriumCascadeExtensions) 174 : 175 : - (BOOL) isCascadeWeapon 176 : { 177 : return NO; 178 : } 179 : 180 : @end