LCOV - code coverage report
Current view: top level - Core/Entities - OOLaserShotEntity.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 21 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOLaserShotEntity.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 "OOLaserShotEntity.h"
      27             : #import "Universe.h"
      28             : #import "ShipEntity.h"
      29             : #import "OOMacroOpenGL.h"
      30             : 
      31             : #import "OOTexture.h"
      32             : #import "OOGraphicsResetManager.h"
      33             : 
      34             : #import "MyOpenGLView.h"
      35             : 
      36             : 
      37           0 : #define kLaserDuration          (0.09)  // seconds
      38             : 
      39             : // Default colour
      40           0 : #define kLaserRed                       (1.0f)
      41           0 : #define kLaserGreen                     (0.0f)
      42           0 : #define kLaserBlue                      (0.0f)
      43             : 
      44             : // Brightness - set to 1.0 for legacy laser appearance
      45           0 : #define kLaserBrightness        (5.0f)
      46             : 
      47             : // Constant alpha
      48           0 : #define kLaserAlpha                     (0.45f / kLaserBrightness)
      49             : 
      50           0 : #define kLaserCoreWidth         (0.4f)
      51           0 : #define kLaserFlareWidth                (1.8f)
      52           0 : #define kLaserHalfWidth         (3.6f)
      53             : 
      54           0 : static OOTexture *sShotTexture = nil;
      55           0 : static OOTexture *sShotTexture2 = nil;
      56             : 
      57             : @implementation OOLaserShotEntity
      58             : 
      59           0 : - (instancetype) initLaserFromShip:(ShipEntity *)srcEntity direction:(OOWeaponFacing)direction offset:(Vector)offset
      60             : {
      61             :         if (!(self = [super init]))  return nil;
      62             :         
      63             :         ShipEntity                      *ship = [srcEntity rootShipEntity];
      64             :         Vector                          middle = OOBoundingBoxCenter([srcEntity boundingBox]);
      65             :         
      66             :         NSCParameterAssert([srcEntity isShip] && [ship isShip]);
      67             :         
      68             :         [self setStatus:STATUS_EFFECT];
      69             :         
      70             :         if (ship == srcEntity) 
      71             :         {
      72             :                 // main laser offset
      73             :                 [self setPosition:HPvector_add([ship position], vectorToHPVector(OOVectorMultiplyMatrix(offset, [ship drawRotationMatrix])))];
      74             :         }
      75             :         else
      76             :         {
      77             :                 // subentity laser
      78             :                 [self setPosition:[srcEntity absolutePositionForSubentityOffset:vectorToHPVector(middle)]];
      79             :         }
      80             :         
      81             :         Quaternion q = kIdentityQuaternion;
      82             :         Vector q_up = vector_up_from_quaternion(q);
      83             :         Quaternion q0 = [ship normalOrientation];
      84             :         velocity = vector_multiply_scalar(vector_forward_from_quaternion(q0), [ship flightSpeed]);
      85             :         
      86             :         switch (direction)
      87             :         {
      88             :                 case WEAPON_FACING_NONE:
      89             :                 case WEAPON_FACING_FORWARD:
      90             :                         break;
      91             :                         
      92             :                 case WEAPON_FACING_AFT:
      93             :                         quaternion_rotate_about_axis(&q, q_up, M_PI);
      94             :                         break;
      95             :                         
      96             :                 case WEAPON_FACING_PORT:
      97             :                         quaternion_rotate_about_axis(&q, q_up, M_PI/2.0);
      98             :                         break;
      99             :                         
     100             :                 case WEAPON_FACING_STARBOARD:
     101             :                         quaternion_rotate_about_axis(&q, q_up, -M_PI/2.0);
     102             :                         break;
     103             :         }
     104             :         
     105             :         [self setOrientation:quaternion_multiply(q,q0)];
     106             :         [self setOwner:ship];
     107             :         [self setRange:[srcEntity weaponRange]];
     108             :         _lifetime = kLaserDuration;
     109             :         
     110             :         _color[0] = kLaserRed/3.0;
     111             :         _color[1] = kLaserGreen/3.0;
     112             :         _color[2] = kLaserBlue/3.0;
     113             :         _color[3] = kLaserAlpha;
     114             : 
     115             :         _offset = (ship == srcEntity) ? offset : middle;
     116             :         _relOrientation = q;
     117             :         
     118             :         return self;
     119             : }
     120             : 
     121             : 
     122             : + (instancetype) laserFromShip:(ShipEntity *)ship direction:(OOWeaponFacing)direction offset:(Vector)offset
     123             : {
     124             :         return [[[self alloc] initLaserFromShip:ship direction:direction offset:offset] autorelease];
     125             : }
     126             : 
     127             : 
     128           0 : - (void) dealloc
     129             : {
     130             :         [self setColor:nil];
     131             :         
     132             :         [super dealloc];
     133             : }
     134             : 
     135             : 
     136           0 : - (NSString *) descriptionComponents
     137             : {
     138             :         return [NSString stringWithFormat:@"ttl: %.3fs - %@ orientation %@", _lifetime, [super descriptionComponents], QuaternionDescription([self orientation])];
     139             : }
     140             : 
     141             : 
     142             : - (void) setColor:(OOColor *)color
     143             : {
     144             :         _color[0] = kLaserBrightness * [color redComponent]/3.0;
     145             :         _color[1] = kLaserBrightness * [color greenComponent]/3.0;
     146             :         _color[2] = kLaserBrightness * [color blueComponent]/3.0;
     147             :         // Ignore alpha; _color[3] is constant.
     148             : }
     149             : 
     150             : 
     151             : - (void) setRange:(GLfloat)range
     152             : {
     153             :         _range = range;
     154             :         [self setCollisionRadius:range];
     155             : }
     156             : 
     157             : 
     158           0 : - (void) update:(OOTimeDelta)delta_t
     159             : {
     160             :         [super update:delta_t];
     161             :         _lifetime -= delta_t;
     162             :         ShipEntity              *ship = [self owner];
     163             :         
     164             :         if ([ship isPlayer]) 
     165             :         {
     166             :                 /*
     167             :                         Reposition this shot accurately. This overrides integration over
     168             :                         velocity in -[Entity update:], which is considered sufficient for
     169             :                         NPC ships.
     170             :                 */
     171             :                 [self setPosition:HPvector_add([ship position], vectorToHPVector(OOVectorMultiplyMatrix(_offset, [ship drawRotationMatrix])))];
     172             :                 [self setOrientation:quaternion_multiply(_relOrientation, [ship normalOrientation])];
     173             :         }
     174             : 
     175             :         if (_lifetime < 0)  
     176             :         {
     177             :                 [UNIVERSE removeEntity:self];
     178             :         }
     179             : }
     180             : 
     181             : 
     182           0 : static const GLfloat kLaserVertices[] = 
     183             : {
     184             :          1.0f, 0.0f, 0.0f,
     185             :          1.0f, 0.0f, 1.0f,
     186             :          -1.0f, 0.0f, 1.0f,
     187             :          -1.0f, 0.0f, 0.0f,
     188             :         
     189             :          0.0f,  1.0f, 0.0f,
     190             :          0.0f,  1.0f, 1.0f,
     191             :          0.0f, -1.0f, 1.0f,
     192             :          0.0f, -1.0f, 0.0f,
     193             : };
     194             : 
     195             : 
     196           0 : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent
     197             : {
     198             :         if (!translucent || [UNIVERSE breakPatternHide])  return;
     199             : 
     200             :         OO_ENTER_OPENGL();
     201             :         OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING);
     202             :         
     203             : 
     204             :         /*      FIXME: spread damage across the lifetime of the shot,
     205             :                 hurting whatever is hit in a given frame.
     206             :                 -- Ahruman 2011-01-31
     207             :         */
     208             :         OOGL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
     209             :         OOGL(glEnable(GL_TEXTURE_2D));
     210             :         OOGLPushModelView();
     211             :         
     212             :         OOGLScaleModelView(make_vector(kLaserHalfWidth, kLaserHalfWidth, _range));
     213             :         [[self texture1] apply];
     214             :         GLfloat s = sinf([UNIVERSE getTime]);
     215             :         GLfloat phase = s*(_range/200.0f);
     216             :         GLfloat phase2 = (1.0f+s)*(_range/200.0f);
     217             :         GLfloat phase3 = -s*(_range/500.0f);
     218             :         GLfloat phase4 = -(1.0f+s)*(_range/500.0f);
     219             : 
     220             :         GLfloat laserTexCoords[] = 
     221             :                 {
     222             :                         0.0f, phase,    0.0f, phase2,   1.0f, phase2,   1.0f, phase,
     223             : 
     224             :                         0.0f, phase,    0.0f, phase2,   1.0f, phase2,   1.0f, phase
     225             :                 };
     226             :         GLfloat laserTexCoords2[] = 
     227             :                 {
     228             :                         0.0f, phase3,   0.0f, phase4,   1.0f, phase4,   1.0f, phase3,
     229             : 
     230             :                         0.0f, phase3,   0.0f, phase4,   1.0f, phase4,   1.0f, phase3
     231             :                 };
     232             :         
     233             :         OOGL(glColor4fv(_color));
     234             :         glVertexPointer(3, GL_FLOAT, 0, kLaserVertices);
     235             :         glTexCoordPointer(2, GL_FLOAT, 0, laserTexCoords2);
     236             :         glDrawArrays(GL_QUADS, 0, 8);
     237             :         
     238             :         OOGLScaleModelView(make_vector(kLaserCoreWidth / kLaserHalfWidth, kLaserCoreWidth / kLaserHalfWidth, 1.0));
     239             :         OOGL(glColor4f(kLaserBrightness,kLaserBrightness,kLaserBrightness,0.9));
     240             :         glDrawArrays(GL_QUADS, 0, 8);
     241             : 
     242             :         [[self texture2] apply];
     243             :         OOGLScaleModelView(make_vector(kLaserFlareWidth / kLaserCoreWidth, kLaserFlareWidth / kLaserCoreWidth, 1.0));
     244             :         OOGL(glColor4f(_color[0],_color[1],_color[2],0.9));
     245             :         glTexCoordPointer(2, GL_FLOAT, 0, laserTexCoords);
     246             :         glDrawArrays(GL_QUADS, 0, 8);
     247             :         
     248             :         OOGLPopModelView();
     249             :         OOGL(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
     250             :         OOGL(glDisable(GL_TEXTURE_2D));
     251             :         
     252             :         OOVerifyOpenGLState();
     253             :         OOCheckOpenGLErrors(@"OOLaserShotEntity after drawing %@", self);
     254             : }
     255             : 
     256             : 
     257           0 : - (BOOL) isEffect
     258             : {
     259             :         return YES;
     260             : }
     261             : 
     262             : 
     263           0 : - (BOOL) canCollide
     264             : {
     265             :         return NO;
     266             : }
     267             : 
     268             : - (OOTexture *) texture1
     269             : {
     270             :         return [OOLaserShotEntity outerTexture];
     271             : }
     272             : 
     273             : 
     274             : - (OOTexture *) texture2
     275             : {
     276             :         return [OOLaserShotEntity innerTexture];
     277             : }
     278             : 
     279             : 
     280             : + (void) setUpTexture
     281             : {
     282             :         if (sShotTexture == nil)
     283             :         {
     284             :                 sShotTexture = [[OOTexture textureWithName:@"oolite-laser-blur.png"
     285             :                                                                                   inFolder:@"Textures"
     286             :                                                                                    options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask | kOOTextureRepeatT
     287             :                                                                                 anisotropy:kOOTextureDefaultAnisotropy / 2.0
     288             :                                                                                    lodBias:0.0] retain];
     289             :                 [[OOGraphicsResetManager sharedManager] registerClient:(id<OOGraphicsResetClient>)[OOLaserShotEntity class]];
     290             : 
     291             :                 sShotTexture2 = [[OOTexture textureWithName:@"oolite-laser-blur2.png"
     292             :                                                                                   inFolder:@"Textures"
     293             :                                                                                    options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask | kOOTextureRepeatT
     294             :                                                                                 anisotropy:kOOTextureDefaultAnisotropy / 2.0
     295             :                                                                                    lodBias:0.0] retain];
     296             :         }
     297             : }
     298             : 
     299             : 
     300             : + (OOTexture *) innerTexture
     301             : {
     302             :         if (sShotTexture2 == nil)  [self setUpTexture];
     303             :         return sShotTexture2;
     304             : }
     305             : 
     306             : 
     307             : + (OOTexture *) outerTexture
     308             : {
     309             :         if (sShotTexture == nil)  [self setUpTexture];
     310             :         return sShotTexture;
     311             : }
     312             : 
     313             : 
     314           0 : + (void) resetGraphicsState
     315             : {
     316             :         [sShotTexture release];
     317             :         sShotTexture = nil;
     318             :         [sShotTexture2 release];
     319             :         sShotTexture2 = nil;
     320             : }
     321             : 
     322             : 
     323             : @end
     324             : 
     325             : 

Generated by: LCOV version 1.14