Line data Source code
1 0 : /* 2 : 3 : OOExplosionCloudEntity.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 "OOExplosionCloudEntity.h" 27 : #import "Universe.h" 28 : #import "PlayerEntity.h" 29 : #import "OOColor.h" 30 : #import "OOTexture.h" 31 : #import "OOGraphicsResetManager.h" 32 : #import "OOCollectionExtractors.h" 33 : 34 0 : #define kExplosionCloudDuration 0.9 35 0 : #define kGrowthRateFactor 1.5f 36 0 : #define kExplosionCloudAlpha 0.85f 37 0 : #define kExplosionBrightnessMult 1.0f 38 0 : #define kExplosionDefaultSize 2.5f 39 : 40 : // keys for plist file 41 0 : static NSString * const kExplosionAlpha = @"alpha"; 42 0 : static NSString * const kExplosionBrightness = @"brightness"; 43 0 : static NSString * const kExplosionColors = @"color_order"; 44 0 : static NSString * const kExplosionCount = @"count"; 45 0 : static NSString * const kExplosionDuration = @"duration"; 46 0 : static NSString * const kExplosionGrowth = @"growth_rate"; 47 0 : static NSString * const kExplosionSize = @"size"; 48 0 : static NSString * const kExplosionSpread = @"spread"; 49 0 : static NSString * const kExplosionTexture = @"texture"; 50 : 51 : 52 : @interface OOExplosionCloudEntity (OOPrivate) 53 0 : - (id) initExplosionCloudWithEntity:(Entity *)entity size:(float)size andSettings:(NSDictionary *)settings; 54 : @end 55 : 56 : @implementation OOExplosionCloudEntity 57 : 58 0 : - (id) initExplosionCloudWithEntity:(Entity *)entity size:(float)size andSettings:(NSDictionary *)settings 59 : { 60 : unsigned i; 61 : unsigned maxCount = [UNIVERSE detailLevel] <= DETAIL_LEVEL_SHADERS ? 10 : 25; 62 : HPVector pos = [entity position]; 63 : Vector vel = [entity velocity]; 64 : 65 : if (settings == nil) { 66 : _settings = [[NSDictionary dictionary] retain]; 67 : } else { 68 : _settings = [settings retain]; 69 : } 70 : 71 : unsigned count = [_settings oo_unsignedIntForKey:kExplosionCount defaultValue:25]; 72 : if (count > maxCount) { 73 : count = maxCount; 74 : } 75 : 76 : if (size == 0.0) { 77 : size = [entity collisionRadius]*[_settings oo_floatForKey:kExplosionSize defaultValue:kExplosionDefaultSize]; 78 : } 79 : 80 : _growthRate = [_settings oo_floatForKey:kExplosionGrowth defaultValue:kGrowthRateFactor] * size; 81 : _alpha = [_settings oo_floatForKey:kExplosionAlpha defaultValue:kExplosionCloudAlpha]; 82 : _brightnessMult = [_settings oo_floatForKey:kExplosionBrightness defaultValue:kExplosionBrightnessMult]; 83 : if (_brightnessMult < 1.0f) _brightnessMult = 1.0f; 84 : _cloudDuration = [_settings oo_doubleForKey:kExplosionDuration defaultValue:kExplosionCloudDuration]; 85 : 86 : GLfloat spread = [_settings oo_floatForKey:kExplosionSpread defaultValue:1.0]; 87 : 88 : NSString *textureFile = [_settings oo_stringForKey:kExplosionTexture defaultValue:@"oolite-particle-cloud2.png"]; 89 : 90 : _texture = [[OOTexture textureWithName:textureFile 91 : inFolder:@"Textures" 92 : options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask 93 : anisotropy:kOOTextureDefaultAnisotropy 94 : lodBias:0.0] retain]; 95 : if (_texture == nil) 96 : { 97 : [self release]; 98 : return nil; 99 : } 100 : 101 : GLfloat baseColor[4] = {1.0,1.0,1.0,1.0}; 102 : 103 : if (magnitude2(vel) > 1000000) 104 : { 105 : // slow down rapidly translating explosions 106 : vel = vector_multiply_scalar(vector_normal(vel),1000); 107 : } 108 : 109 : if ((self = [super initWithPosition:pos velocity:vel count:count minSpeed:size*0.8f*spread maxSpeed:size*1.2f*spread duration:_cloudDuration baseColor:baseColor])) 110 : { 111 : NSString *color_order = [_settings oo_stringForKey:kExplosionColors defaultValue:@"rgb"]; 112 : 113 : for (i=0;i<count;i++) 114 : { 115 : if ([color_order isEqualToString:@"white"]) { 116 : // grey 117 : _particleColor[i][0] = _particleColor[i][1] = _particleColor[i][2] = randf(); 118 : } else { 119 : float c1 = randf(); 120 : float c2 = randf(); 121 : float c3 = randf(); 122 : if (c2 > c1) { 123 : c2 = c1; 124 : } 125 : if (c3 > c2) { 126 : c3 = c2; 127 : } 128 : if ([color_order isEqualToString:@"rgb"]) 129 : { 130 : _particleColor[i][0] = c1; 131 : _particleColor[i][1] = c2; 132 : _particleColor[i][2] = c3; 133 : } 134 : else if ([color_order isEqualToString:@"rbg"]) 135 : { 136 : _particleColor[i][0] = c1; 137 : _particleColor[i][1] = c3; 138 : _particleColor[i][2] = c2; 139 : } 140 : else if ([color_order isEqualToString:@"grb"]) 141 : { 142 : _particleColor[i][0] = c2; 143 : _particleColor[i][1] = c1; 144 : _particleColor[i][2] = c3; 145 : } 146 : else if ([color_order isEqualToString:@"gbr"]) 147 : { 148 : _particleColor[i][0] = c3; 149 : _particleColor[i][1] = c1; 150 : _particleColor[i][2] = c2; 151 : } 152 : else if ([color_order isEqualToString:@"brg"]) 153 : { 154 : _particleColor[i][0] = c2; 155 : _particleColor[i][1] = c3; 156 : _particleColor[i][2] = c1; 157 : } 158 : else if ([color_order isEqualToString:@"bgr"]) 159 : { 160 : _particleColor[i][0] = c3; 161 : _particleColor[i][1] = c2; 162 : _particleColor[i][2] = c1; 163 : } 164 : 165 : } 166 : 167 : _particleColor[i][0] *= _brightnessMult; 168 : _particleColor[i][1] *= _brightnessMult; 169 : _particleColor[i][2] *= _brightnessMult; 170 : _particleColor[i][3] = _alpha; 171 : } 172 : } 173 : return self; 174 : } 175 : 176 : 177 0 : - (void) dealloc 178 : { 179 : DESTROY(_texture); 180 : DESTROY(_settings); 181 : [super dealloc]; 182 : } 183 : 184 : 185 : + (instancetype) explosionCloudFromEntity:(Entity *)entity withSettings:(NSDictionary *)settings 186 : { 187 : return [[[self alloc] initExplosionCloudWithEntity:entity size:0 andSettings:settings] autorelease]; 188 : } 189 : 190 : 191 : + (instancetype) explosionCloudFromEntity:(Entity *)entity withSize:(float)size andSettings:(NSDictionary *)settings 192 : { 193 : return [[[self alloc] initExplosionCloudWithEntity:entity size:size andSettings:settings] autorelease]; 194 : } 195 : 196 : 197 0 : - (void) update:(OOTimeDelta)delta_t 198 : { 199 : [super update:delta_t]; 200 : 201 : // Fade out. 202 : GLfloat fadeRate = _count * _brightnessMult / 25.0; 203 : unsigned i, count = _count; 204 : GLfloat (*particleColor)[4] = _particleColor; 205 : 206 : float newAlpha = _alpha * (1-(_timePassed / _cloudDuration)); 207 : NSString *color_order = [_settings oo_stringForKey:kExplosionColors defaultValue:@"rgb"]; 208 : NSUInteger primary = 0, secondary = 1, tertiary = 2; 209 : 210 : if ([color_order isEqualToString:@"rgb"]) 211 : { 212 : primary = 0; 213 : secondary = 1; 214 : tertiary = 2; 215 : } 216 : else if ([color_order isEqualToString:@"rbg"]) 217 : { 218 : primary = 0; 219 : secondary = 2; 220 : tertiary = 1; 221 : } 222 : else if ([color_order isEqualToString:@"grb"]) 223 : { 224 : primary = 1; 225 : secondary = 0; 226 : tertiary = 2; 227 : } 228 : else if ([color_order isEqualToString:@"gbr"]) 229 : { 230 : primary = 1; 231 : secondary = 2; 232 : tertiary = 0; 233 : } 234 : else if ([color_order isEqualToString:@"brg"]) 235 : { 236 : primary = 2; 237 : secondary = 0; 238 : tertiary = 1; 239 : } 240 : else if ([color_order isEqualToString:@"bgr"]) 241 : { 242 : primary = 2; 243 : secondary = 1; 244 : tertiary = 0; 245 : } 246 : 247 : 248 : float fdelta_t = delta_t; 249 : for (i=0;i<count;i++) { 250 : 251 : _particleSize[i] += delta_t * _growthRate; 252 : 253 : particleColor[i][3] = newAlpha; 254 : if (![color_order isEqualToString:@"white"]) 255 : { 256 : 257 : if (particleColor[i][tertiary] > 0.0f) // fade blue (white to yellow) 258 : { 259 : particleColor[i][tertiary] -= fdelta_t * 0.5f * fadeRate; 260 : if (particleColor[i][tertiary] < 0.0f) 261 : { 262 : particleColor[i][tertiary] = 0.0f; 263 : } 264 : } 265 : else if (particleColor[i][secondary] > 0.0f) // fade green (yellow to red) 266 : { 267 : particleColor[i][secondary] -= fdelta_t * fadeRate; 268 : if (particleColor[i][secondary] < 0.0f) 269 : { 270 : particleColor[i][secondary] = 0.0f; 271 : } 272 : } 273 : else if (particleColor[i][primary] > 0.0f) // fade red (red to black) 274 : { 275 : particleColor[i][primary] -= fdelta_t * 2.0f * fadeRate; 276 : if (particleColor[i][primary] < 0.0f) 277 : { 278 : particleColor[i][primary] = 0.0f; 279 : } 280 : } 281 : 282 : } 283 : } 284 : 285 : } 286 : 287 : 288 0 : - (OOTexture *) texture 289 : { 290 : return _texture; 291 : } 292 : 293 : @end