Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOExplosionCloudEntity.m
Go to the documentation of this file.
1/*
2
3OOExplosionCloudEntity.m
4
5
6Oolite
7Copyright (C) 2004-2013 Giles C Williams and contributors
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22MA 02110-1301, USA.
23
24*/
25
27#import "Universe.h"
28#import "PlayerEntity.h"
29#import "OOColor.h"
30#import "OOTexture.h"
33
34#define kExplosionCloudDuration 0.9
35#define kGrowthRateFactor 1.5f
36#define kExplosionCloudAlpha 0.85f
37#define kExplosionBrightnessMult 1.0f
38#define kExplosionDefaultSize 2.5f
39
40// keys for plist file
41static NSString * const kExplosionAlpha = @"alpha";
42static NSString * const kExplosionBrightness = @"brightness";
43static NSString * const kExplosionColors = @"color_order";
44static NSString * const kExplosionCount = @"count";
45static NSString * const kExplosionDuration = @"duration";
46static NSString * const kExplosionGrowth = @"growth_rate";
47static NSString * const kExplosionSize = @"size";
48static NSString * const kExplosionSpread = @"spread";
49static NSString * const kExplosionTexture = @"texture";
50
51
52@interface OOExplosionCloudEntity (OOPrivate)
53- (id) initExplosionCloudWithEntity:(Entity *)entity size:(float)size andSettings:(NSDictionary *)settings;
54@end
55
56@implementation OOExplosionCloudEntity
57
58- (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- (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- (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- (OOTexture *) texture
289{
290 return _texture;
291}
292
293@end
#define DESTROY(x)
Definition OOCocoa.h:77
static NSString *const kExplosionSpread
static NSString *const kExplosionAlpha
static NSString *const kExplosionColors
static NSString *const kExplosionSize
static NSString *const kExplosionCount
static NSString *const kExplosionGrowth
static NSString *const kExplosionTexture
static NSString *const kExplosionDuration
static NSString *const kExplosionBrightness
float maxSpeed
GLfloat baseColor[4]
unsigned count
return nil
@ DETAIL_LEVEL_SHADERS
Definition OOTypes.h:246
double OOTimeDelta
Definition OOTypes.h:224
GLfloat collisionRadius()
Definition Entity.m:905
HPVector position
Definition Entity.h:112
Vector velocity
Definition Entity.h:140
id textureWithName:inFolder:options:anisotropy:lodBias:(NSString *name,[inFolder] NSString *directory,[options] OOTextureFlags options,[anisotropy] GLfloat anisotropy,[lodBias] GLfloat lodBias)
Definition OOTexture.m:134
voidpf void uLong size
Definition ioapi.h:134
float randf(void)