54#import "MyOpenGLView.h"
56@interface OOVisualEffectEntity (Private)
58- (void) drawSubEntityImmediate:(
bool)immediate translucent:(
bool)translucent;
60- (void) addSubEntity:(
Entity<OOSubEntity> *) subent;
61- (BOOL) setUpOneSubentity:(NSDictionary *) subentDict;
62- (BOOL) setUpOneFlasher:(NSDictionary *) subentDict;
63- (BOOL) setUpOneStandardSubentity:(NSDictionary *)subentDict;
75- (id)initWithKey:(NSString *)key definition:(NSDictionary *)dict
79 NSParameterAssert(dict !=
nil);
82 if (
self ==
nil)
return nil;
84 _effectKey = [key retain];
86 if (![
self setUpVisualEffectFromDictionary:dict])
92 _haveExecutedSpawnAction = NO;
100- (BOOL) setUpVisualEffectFromDictionary:(NSDictionary *) effectDict
104 effectinfoDictionary = [effectDict copy];
105 if (effectinfoDictionary ==
nil) effectinfoDictionary = [[NSDictionary alloc] init];
110 collision_radius = 0.0;
112 NSString *modelName = [effectDict oo_stringForKey:@"model"];
113 if (modelName !=
nil)
119 smooth:[effectDict oo_boolForKey:@"smooth" defaultValue:NO]
122 if (mesh ==
nil)
return NO;
126 isImmuneToBreakPatternHide = [effectDict oo_boolForKey:@"is_break_pattern"];
131 [
self clearSubEntities];
132 [
self setUpSubEntities];
134 [
self setScannerDisplayColor1:nil];
135 [
self setScannerDisplayColor2:nil];
137 scanClass = CLASS_VISUAL_EFFECT;
139 [
self setStatus:STATUS_EFFECT];
141 _hullHeatLevel = 60.0 / 256.0;
149 [
self setBeaconCode:[effectDict oo_stringForKey:@"beacon"]];
150 [
self setBeaconLabel:[effectDict oo_stringForKey:@"beacon_label" defaultValue:[
self beaconCode]]];
152 scriptInfo = [[effectDict oo_dictionaryForKey:@"script_info" defaultValue:nil] retain];
153 [
self setScript:[effectDict oo_stringForKey:@"script"]];
163 [
self clearSubEntities];
166 DESTROY(scanner_display_color1);
167 DESTROY(scanner_display_color2);
184- (BOOL) isVisualEffect
198 return (
OOMesh *)[
self drawable];
202- (void)setMesh:(
OOMesh *)mesh
204 if (mesh != [
self mesh])
206 [
self setDrawable:mesh];
211- (NSString *)effectKey
217- (GLfloat)frustumRadius
219 return [
self scaleMax] * _profileRadius;
223- (void) clearSubEntities
225 [subEntities makeObjectsPerformSelector:@selector(setOwner:) withObject:nil];
226 [subEntities release];
232 collision_radius = [
self findCollisionRadius];
236 collision_radius = 0.0;
238 _profileRadius = collision_radius;
242- (BOOL)setUpSubEntities
245 _profileRadius = collision_radius;
246 NSArray *subs = [effectinfoDictionary oo_arrayForKey:@"subentities"];
248 for (i = 0; i < [subs count]; i++)
250 [
self setUpOneSubentity:[subs oo_dictionaryAtIndex:i]];
253 [
self setNoDrawDistance];
259- (void) removeSubEntity:(
Entity<OOSubEntity> *)sub
262 [subEntities removeObject:sub];
266- (void) setNoDrawDistance
268 GLfloat r = _profileRadius * [
self scaleMax];
274- (BOOL) setUpOneSubentity:(NSDictionary *) subentDict
276 NSString *type = [subentDict oo_stringForKey:@"type"];
277 if ([type isEqualToString:
@"flasher"])
279 return [
self setUpOneFlasher:subentDict];
283 return [
self setUpOneStandardSubentity:subentDict];
290- (BOOL) setUpOneFlasher:(NSDictionary *) subentDict
293 [flasher
setPosition:[subentDict oo_hpvectorForKey:@"position"]];
294 [
self addSubEntity:flasher];
299- (BOOL) setUpOneStandardSubentity:(NSDictionary *)subentDict
302 NSString *subentKey =
nil;
303 HPVector subPosition;
304 Quaternion subOrientation;
306 subentKey = [subentDict oo_stringForKey:@"subentity_key"];
307 if (subentKey ==
nil) {
308 OOLog(
@"setup.visualeffect.badEntry.subentities",
@"Failed to set up entity - no subentKey in %@",subentDict);
312 subentity = [UNIVERSE newVisualEffectWithName:subentKey];
313 if (subentity ==
nil) {
314 OOLog(
@"setup.visualeffect.badEntry.subentities",
@"Failed to set up entity %@",subentKey);
318 subPosition = [subentDict oo_hpvectorForKey:@"position"];
319 subOrientation = [subentDict oo_quaternionForKey:@"orientation"];
324 [
self addSubEntity:subentity];
332- (void) addSubEntity:(
Entity<OOSubEntity> *)sub
334 if (sub ==
nil)
return;
336 if (subEntities ==
nil) subEntities = [[NSMutableArray alloc] init];
339 [subEntities addObject:sub];
342 double distance = HPmagnitude([sub position]) + [sub findCollisionRadius];
343 if (distance > _profileRadius)
345 _profileRadius = distance;
350- (NSArray *)subEntities
352 return [[subEntities copy] autorelease];
356- (NSUInteger) subEntityCount
358 return [subEntities count];
362- (NSEnumerator *) visualEffectSubEntityEnumerator
364 return [[
self subEntities] objectEnumeratorFilteredWithSelector:@selector(isVisualEffect)];
368- (BOOL) hasSubEntity:(
Entity<OOSubEntity> *)sub
370 return [subEntities containsObject:sub];
374- (NSEnumerator *)subEntityEnumerator
376 return [[
self subEntities] objectEnumerator];
380- (NSEnumerator *)effectSubEntityEnumerator
382 return [[
self subEntities] objectEnumeratorFilteredWithSelector:@selector(isVisualEffect)];
386- (NSEnumerator *)flasherEnumerator
388 return [[
self subEntities] objectEnumeratorFilteredWithSelector:@selector(isFlasher)];
392- (void) drawSubEntityImmediate:(
bool)immediate translucent:(
bool)translucent
394 if (cam_zero_distance > no_draw_distance)
402 [
self drawImmediate:immediate translucent:translucent];
408- (void) rescaleBy:(GLfloat)factor
410 if ([
self mesh] !=
nil) {
411 [
self setMesh:[[
self mesh] meshRescaledBy:factor]];
416 foreach (se, [
self subEntities])
419 [se rescaleBy:factor];
422 collision_radius *= factor;
423 _profileRadius *= factor;
427- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache
448 else if (scaleY > scaleZ)
465- (void) setScaleX:(GLfloat)factor
469 GLfloat flasher_factor = pow(factor/scaleX,1.0/3.0);
470 foreach (se, [
self subEntities])
473 move.x *= factor/scaleX;
475 if ([se isVisualEffect])
481 [se rescaleBy:flasher_factor];
486 [
self setNoDrawDistance];
496- (void) setScaleY:(GLfloat)factor
500 GLfloat flasher_factor = pow(factor/scaleY,1.0/3.0);
501 foreach (se, [
self subEntities])
504 move.y *= factor/scaleY;
506 if ([se isVisualEffect])
512 [se rescaleBy:flasher_factor];
517 [
self setNoDrawDistance];
527- (void) setScaleZ:(GLfloat)factor
531 GLfloat flasher_factor = pow(factor/scaleZ,1.0/3.0);
532 foreach (se, [
self subEntities])
535 move.z *= factor/scaleZ;
537 if ([se isVisualEffect])
543 [se rescaleBy:flasher_factor];
548 [
self setNoDrawDistance];
552- (GLfloat) collisionRadius
554 return [
self scaleMax] * collision_radius;
558- (void) orientationChanged
560 [
super orientationChanged];
569- (Vector) forwardVector
583- (Vector) rightVector
589- (
OOColor *)scannerDisplayColor1
591 return [[scanner_display_color1 retain] autorelease];
595- (
OOColor *)scannerDisplayColor2
597 return [[scanner_display_color2 retain] autorelease];
601- (void)setScannerDisplayColor1:(
OOColor *)color
603 DESTROY(scanner_display_color1);
606 scanner_display_color1 = [color retain];
610- (void)setScannerDisplayColor2:(
OOColor *)color
612 DESTROY(scanner_display_color2);
615 scanner_display_color2 = [color retain];
621- (GLfloat *) scannerDisplayColorForShip:(BOOL)flash :(
OOColor *)scannerDisplayColor1 :(
OOColor *)scannerDisplayColor2
624 if (scannerDisplayColor1 || scannerDisplayColor2)
626 if (scannerDisplayColor1 && !scannerDisplayColor2)
628 [scannerDisplayColor1 getRed:&scripted_color[0] green:&scripted_color[1] blue:&scripted_color[2] alpha:&scripted_color[3]];
631 if (!scannerDisplayColor1 && scannerDisplayColor2)
633 [scannerDisplayColor2
getRed:&scripted_color[0]
green:&scripted_color[1]
blue:&scripted_color[2]
alpha:&scripted_color[3]];
636 if (scannerDisplayColor1 && scannerDisplayColor2)
639 [scannerDisplayColor1 getRed:&scripted_color[0] green:&scripted_color[1] blue:&scripted_color[2] alpha:&scripted_color[3]];
641 [scannerDisplayColor2
getRed:&scripted_color[0]
green:&scripted_color[1]
blue:&scripted_color[2]
alpha:&scripted_color[3]];
650- (void) drawImmediate:(
bool)immediate translucent:(
bool)translucent
652 if (no_draw_distance < cam_zero_distance)
659 if ([
self mesh] !=
nil)
661 [
super drawImmediate:immediate translucent:translucent];
669 foreach (subEntity, [
self subEntities])
679 [
super update:delta_t];
681 if (!_haveExecutedSpawnAction) {
682 [
self doScriptEvent:OOJSID("effectSpawned")];
683 _haveExecutedSpawnAction = YES;
687 foreach (se, [
self subEntities])
694- (BOOL) isBreakPattern
696 return isImmuneToBreakPatternHide;
700- (void) setIsBreakPattern:(BOOL)bp
702 isImmuneToBreakPatternHide = bp;
706- (NSDictionary *)effectInfoDictionary
708 return effectinfoDictionary;
714- (void) setScript:(NSString *)script_name
716 NSMutableDictionary *properties =
nil;
718 properties = [NSMutableDictionary dictionary];
719 [properties setObject:self forKey:@"visualEffect"];
721 [script autorelease];
737- (NSDictionary *)scriptInfo
739 return (scriptInfo !=
nil) ? scriptInfo : (NSDictionary *)[NSDictionary dictionary];
743- (void) doScriptEvent:(jsid)message
746 [script callMethod:message inContext:context withArguments:NULL count:0 result:NULL];
753 [
self doScriptEvent:OOJSID("effectRemoved")];
754 [UNIVERSE removeEntity:(Entity*)self];
760- (NSComparisonResult) compareBeaconCodeWith:(
Entity<OOBeaconEntity> *) other
762 return [[
self beaconCode] compare:[other beaconCode] options: NSCaseInsensitiveSearch];
766- (NSString *) beaconCode
772- (void) setBeaconCode:(NSString *)bcode
774 if ([bcode length] == 0) bcode =
nil;
776 if (_beaconCode != bcode)
778 [_beaconCode release];
779 _beaconCode = [bcode copy];
784 if (bcode !=
nil && (_beaconLabel ==
nil || [_beaconLabel length] == 0))
786 [
self setBeaconLabel:bcode];
792- (NSString *) beaconLabel
798- (void) setBeaconLabel:(NSString *)blabel
800 if ([blabel length] == 0) blabel =
nil;
802 if (_beaconLabel != blabel)
804 [_beaconLabel release];
805 _beaconLabel = [OOExpand(blabel) retain];
812 return [
self beaconCode] !=
nil;
816- (
id <OOHUDBeaconIcon>) beaconDrawable
818 if (_beaconDrawable ==
nil)
820 NSString *beaconCode = [
self beaconCode];
821 NSUInteger length = [beaconCode length];
825 NSArray *iconData = [[UNIVERSE descriptions] oo_arrayForKey:beaconCode];
826 if (iconData !=
nil) _beaconDrawable = [[
OOPolygonSprite alloc] initWithDataArray:iconData outlineWidth:0.5 name:beaconCode];
829 if (_beaconDrawable ==
nil)
831 if (length > 0) _beaconDrawable = [[beaconCode substringToIndex:1] retain];
832 else _beaconDrawable =
@"";
836 return _beaconDrawable;
840- (
Entity <OOBeaconEntity> *) prevBeacon
842 return [_prevBeacon weakRefUnderlyingObject];
846- (
Entity <OOBeaconEntity> *) nextBeacon
848 return [_nextBeacon weakRefUnderlyingObject];
852- (void) setPrevBeacon:(
Entity <OOBeaconEntity> *)beaconShip
854 if (beaconShip != [
self prevBeacon])
856 [_prevBeacon release];
857 _prevBeacon = [beaconShip weakRetain];
862- (void) setNextBeacon:(
Entity <OOBeaconEntity> *)beaconShip
864 if (beaconShip != [
self nextBeacon])
866 [_nextBeacon release];
867 _nextBeacon = [beaconShip weakRetain];
872- (BOOL) isJammingScanning
881- (GLfloat)hullHeatLevel
883 return _hullHeatLevel;
887- (void)setHullHeatLevel:(GLfloat)value
889 _hullHeatLevel = OOClamp_0_1_f(value);
893- (GLfloat) shaderFloat1
895 return _shaderFloat1;
899- (void)setShaderFloat1:(GLfloat)value
901 _shaderFloat1 = value;
905- (GLfloat) shaderFloat2
907 return _shaderFloat2;
911- (void)setShaderFloat2:(GLfloat)value
913 _shaderFloat2 = value;
923- (void)setShaderInt1:(
int)value
935- (void)setShaderInt2:(
int)value
941- (Vector) shaderVector1
943 return _shaderVector1;
947- (void)setShaderVector1:(Vector)value
949 _shaderVector1 = value;
953- (Vector) shaderVector2
955 return _shaderVector2;
959- (void)setShaderVector2:(Vector)value
961 _shaderVector2 = value;
967@implementation OOVisualEffectEntity (SubEntityRelationship)
970- (BOOL) isShipWithSubEntityShip:(
Entity *)other
972 assert ([
self isVisualEffect]);
974 if (![other isVisualEffect])
return NO;
975 if (![other isSubEntity])
return NO;
976 if ([other owner] !=
self)
return NO;
982 OOLogERR(
@"visualeffect.subentity.sanityCheck.failed",
@"%@ thinks it's a subentity of %@, but the supposed parent does not agree. %@", [other shortDescription], [
self shortDescription],
@"This is an internal error, please report it.");
#define NO_DRAW_DISTANCE_FACTOR
#define OOJS_PROFILE_EXIT
#define OOJS_PROFILE_ENTER
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
#define OOLogERR(class, format,...)
#define OOLog(class, format,...)
const OOMatrix kIdentityMatrix
void OOGLScaleModelView(Vector scale)
void OOGLPushModelView(void)
void OOGLTranslateModelView(Vector vector)
void OOGLMultModelView(OOMatrix matrix)
OOMatrix OOGLPopModelView(void)
Vector vector_up_from_quaternion(Quaternion quat)
Vector vector_right_from_quaternion(Quaternion quat)
Vector vector_forward_from_quaternion(Quaternion quat)
const Quaternion kIdentityQuaternion
static GLfloat scripted_color[4]
static GLfloat default_color[4]
void setOrientation:(Quaternion quat)
void update:(OOTimeDelta delta_t)
void setOwner:(Entity *ent)
void drawSubEntityImmediate:translucent:(bool immediate, [translucent] bool translucent)
void setPosition:(HPVector posn)
OOColor * colorWithDescription:(id description)
void getRed:green:blue:alpha:(float *red,[green] float *green,[blue] float *blue,[alpha] float *alpha)
instancetype flasherWithDictionary:(NSDictionary *dictionary)
instancetype meshWithName:cacheKey:materialDictionary:shadersDictionary:smooth:shaderMacros:shaderBindingTarget:(NSString *name,[cacheKey] NSString *cacheKey,[materialDictionary] NSDictionary *materialDict,[shadersDictionary] NSDictionary *shadersDict,[smooth] BOOL smooth,[shaderMacros] NSDictionary *macros,[shaderBindingTarget] id< OOWeakReferenceSupport > object)
id jsScriptFromFileNamed:properties:(NSString *fileName,[properties] NSDictionary *properties)
id initWithKey:definition:(NSString *key,[definition] NSDictionary *dict)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque