Line data Source code
1 0 : /* 2 : 3 : OOECMBlastEntity.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 "OOECMBlastEntity.h" 27 : #import "Universe.h" 28 : #import "ShipEntity.h" 29 : #import "OOEntityFilterPredicate.h" 30 : #import "OOJavaScriptEngine.h" 31 : 32 : 33 : // NOTE: these values are documented for scripting, be careful about changing them. 34 0 : #define ECM_EFFECT_DURATION 2.0 35 0 : #define ECM_PULSE_COUNT 4 36 0 : #define ECM_PULSE_INTERVAL (ECM_EFFECT_DURATION / (double)ECM_PULSE_COUNT) 37 : 38 0 : #define ECM_DEBUG_DRAW 0 39 : 40 : 41 : #if ECM_DEBUG_DRAW 42 : #import "OODebugGLDrawing.h" 43 : #endif 44 : 45 : 46 : @implementation OOECMBlastEntity 47 : 48 : - (id) initFromShip:(ShipEntity *)ship 49 : { 50 : if (ship == nil) 51 : { 52 : DESTROY(self); 53 : } 54 : else if ((self = [super init])) 55 : { 56 : _blastsRemaining = ECM_PULSE_COUNT; 57 : _nextBlast = ECM_PULSE_INTERVAL; 58 : _ship = [ship weakRetain]; 59 : 60 : [self setPosition:[ship position]]; 61 : 62 : [self setStatus:STATUS_EFFECT]; 63 : [self setScanClass:CLASS_NO_DRAW]; 64 : } 65 : 66 : return self; 67 : } 68 : 69 : 70 0 : - (void) update:(OOTimeDelta)delta_t 71 : { 72 : _nextBlast -= delta_t; 73 : ShipEntity *ship = [_ship weakRefUnderlyingObject]; 74 : BOOL validShip = (ship != nil) && ([ship status] != STATUS_DEAD); 75 : 76 : if (_nextBlast <= 0.0 && validShip) 77 : { 78 : // Do ECM stuff. 79 : double radius = OOClamp_0_1_d((double)(ECM_PULSE_COUNT - _blastsRemaining + 1) * 1.0 / (double)ECM_PULSE_COUNT); 80 : radius *= SCANNER_MAX_RANGE; 81 : _blastsRemaining--; 82 : 83 : NSArray *targets = [UNIVERSE findEntitiesMatchingPredicate:IsShipPredicate 84 : parameter:NULL 85 : inRange:radius 86 : ofEntity:self]; 87 : NSUInteger i, count = [targets count]; 88 : if (count > 0) 89 : { 90 : JSContext *context = OOJSAcquireContext(); 91 : jsval ecmPulsesRemaining = INT_TO_JSVAL(_blastsRemaining); 92 : jsval whomVal = OOJSValueFromNativeObject(context, ship); 93 : 94 : for (i = 0; i < count; i++) 95 : { 96 : ShipEntity *target = [targets objectAtIndex:i]; 97 : ShipScriptEvent(context, target, "shipHitByECM", ecmPulsesRemaining, whomVal); 98 : [target reactToAIMessage:@"ECM" context:nil]; 99 : [target noticeECM]; 100 : } 101 : 102 : OOJSRelinquishContext(context); 103 : } 104 : _nextBlast += ECM_PULSE_INTERVAL; 105 : } 106 : 107 : if (_blastsRemaining == 0 || !validShip) [UNIVERSE removeEntity:self]; 108 : } 109 : 110 : 111 0 : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent 112 : { 113 : #if ECM_DEBUG_DRAW && OO_DEBUG 114 : OODebugDrawPoint(kZeroVector, [OOColor cyanColor]); 115 : #endif 116 : // Else do nothing, we're invisible! 117 : } 118 : 119 : 120 0 : - (BOOL) isECMBlast 121 : { 122 : return YES; 123 : } 124 : 125 : @end 126 : 127 : 128 : @implementation Entity (OOECMBlastEntity) 129 : 130 : - (BOOL) isECMBlast 131 : { 132 : return NO; 133 : } 134 : 135 : @end