Advertisement
Matsilagi

RPG init.lua

Jun 10th, 2014
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.62 KB | None | 0 0
  1.  
  2. AddCSLuaFile( "shared.lua" )
  3. include( 'shared.lua' )
  4. include( 'outputs.lua' )
  5.  
  6.  
  7. //-----------------------------------------------------------------------------
  8. // Purpose:
  9. //
  10. //
  11. //-----------------------------------------------------------------------------
  12. function ENT:Precache()
  13.  
  14. util.PrecacheModel( "models/weapons/w_missile.mdl" );
  15. util.PrecacheModel( "models/weapons/w_missile_launch.mdl" );
  16. util.PrecacheModel( "models/weapons/w_missile_closed.mdl" );
  17.  
  18. end
  19.  
  20. /*---------------------------------------------------------
  21. Name: PhysicsCollide
  22. ---------------------------------------------------------*/
  23. function ENT:PhysicsCollide( data, physobj )
  24.  
  25. self:Touch( data.HitEntity )
  26. self.PhysicsCollide = function( ... ) return end
  27.  
  28. end
  29.  
  30.  
  31. //-----------------------------------------------------------------------------
  32. // Purpose:
  33. //
  34. //
  35. //-----------------------------------------------------------------------------
  36. function ENT:Initialize()
  37.  
  38. self:Precache();
  39.  
  40. self.Entity:SetSolid( SOLID_BBOX );
  41. self.Entity:SetModel("models/weapons/w_missile_launch.mdl");
  42. self.Entity:SetCollisionBounds( -Vector(4,4,4), Vector(4,4,4) );
  43.  
  44. self.Entity:SetMoveType( MOVETYPE_FLYGRAVITY );
  45. self.Entity:SetMoveCollide( MOVECOLLIDE_FLY_BOUNCE );
  46. self.Think = self.IgniteThink;
  47.  
  48. self.Entity:NextThink( CurTime() + 0.3 );
  49.  
  50. self.m_takedamage = DAMAGE_YES;
  51. self.m_iHealth = 100;
  52. self.m_iMaxHealth = 100;
  53. self.m_bloodColor = DONT_BLEED;
  54. self.m_flGracePeriodEndsAt = 0;
  55.  
  56. self.Entity:AddFlag( FL_OBJECT );
  57.  
  58. end
  59.  
  60.  
  61. //---------------------------------------------------------
  62. //---------------------------------------------------------
  63. function ENT:Event_Killed( info )
  64.  
  65. self.m_takedamage = DAMAGE_NO;
  66.  
  67. self:ShotDown();
  68.  
  69. end
  70.  
  71. function ENT:PhysicsSolidMaskForEntity()
  72.  
  73. return bit.bor(self.BaseClass:PhysicsSolidMaskForEntity(), CONTENTS_HITBOX)
  74. end
  75.  
  76. //---------------------------------------------------------
  77. //---------------------------------------------------------
  78. function ENT:OnTakeDamage( info )
  79.  
  80. if ( ( info:GetDamageType() != bit.bor(DMG_MISSILEDEFENSE, DMG_AIRBOAT) ) ) then
  81. return 0;
  82. end
  83.  
  84. self.bIsDamaged = nil;
  85. if( self.m_iHealth <= self:AugerHealth() ) then
  86. // This missile is already damaged (i.e., already running AugerThink)
  87. self.bIsDamaged = true;
  88. else
  89. // This missile isn't damaged enough to wobble in flight yet
  90. self.bIsDamaged = false;
  91. end
  92.  
  93. local nRetVal = self.BaseClass:OnTakeDamage( info );
  94.  
  95. if( !self.bIsDamaged ) then
  96. if ( self.m_iHealth <= self:AugerHealth() ) then
  97. self:ShotDown();
  98. end
  99. end
  100.  
  101. return nRetVal;
  102.  
  103. end
  104.  
  105.  
  106. //-----------------------------------------------------------------------------
  107. // Purpose: Stops any kind of tracking and shoots dumb
  108. //-----------------------------------------------------------------------------
  109. function ENT:DumbFire()
  110.  
  111. self.Think = function( ... ) return end;
  112. self.Entity:SetMoveType( MOVETYPE_FLY );
  113.  
  114. self.Entity:SetModel("models/weapons/w_missile.mdl");
  115. self.Entity:SetCollisionBounds( vec3_origin, vec3_origin );
  116.  
  117. self.Entity:EmitSound( "Missile.Ignite" );
  118.  
  119. // Smoke trail.
  120. self:CreateSmokeTrail();
  121.  
  122. end
  123.  
  124. //-----------------------------------------------------------------------------
  125. // Purpose:
  126. //-----------------------------------------------------------------------------
  127. function ENT:SetGracePeriod( flGracePeriod )
  128.  
  129. self.m_flGracePeriodEndsAt = CurTime() + flGracePeriod;
  130.  
  131. // Go non-solid until the grace period ends
  132. self.Entity:AddSolidFlags( FSOLID_NOT_SOLID );
  133.  
  134. end
  135.  
  136. //---------------------------------------------------------
  137. //---------------------------------------------------------
  138. function ENT:AccelerateThink()
  139.  
  140. local vecForward;
  141.  
  142. // !!!UNDONE - make this work exactly the same as HL1 RPG, lest we have looping sound bugs again!
  143. self.Entity:EmitSound( "Missile.Accelerate" );
  144.  
  145. self:AddEffects( EF_LIGHT );
  146.  
  147. vecForward = AngleVectors( self.Entity:GetLocalAngles() );
  148. self.Entity:SetVelocity( vecForward * RPG_SPEED );
  149.  
  150. self.Think = self.SeekThink;
  151. self.Entity:NextThink( CurTime() + 0.1 );
  152.  
  153. end
  154.  
  155. AUGER_YDEVIANCE = 20.0
  156. AUGER_XDEVIANCEUP = 8.0
  157. AUGER_XDEVIANCEDOWN = 1.0
  158.  
  159. //---------------------------------------------------------
  160. //---------------------------------------------------------
  161. function ENT:AugerThink()
  162.  
  163. // If we've augered long enough, then just explode
  164. if ( self.m_flAugerTime < CurTime() ) then
  165. self:Explode();
  166. return;
  167. end
  168.  
  169. if ( self.m_flMarkDeadTime < CurTime() ) then
  170. self.m_lifeState = LIFE_DYING;
  171. end
  172.  
  173. local angles = self.Entity:GetLocalAngles();
  174.  
  175. angles.y = angles.y + math.Rand( -AUGER_YDEVIANCE, AUGER_YDEVIANCE );
  176. angles.x = angles.x + math.Rand( -AUGER_XDEVIANCEDOWN, AUGER_XDEVIANCEUP );
  177.  
  178. self.Entity:SetLocalAngles( angles );
  179.  
  180. local vecForward;
  181.  
  182. vecForward = AngleVectors( self.Entity:GetLocalAngles() );
  183.  
  184. self.Entity:SetVelocity( vecForward * 1000.0 );
  185.  
  186. self.Entity:NextThink( CurTime() + 0.05 );
  187.  
  188. end
  189.  
  190. //-----------------------------------------------------------------------------
  191. // Purpose: Causes the missile to spiral to the ground and explode, due to damage
  192. //-----------------------------------------------------------------------------
  193. function ENT:ShotDown()
  194.  
  195. local data = EffectData();
  196. data:SetOrigin( self.Entity:GetPos() );
  197.  
  198. util.Effect( "RPGShotDown", data );
  199.  
  200. if ( self.m_hRocketTrail != NULL ) then
  201. self.m_hRocketTrail.m_bDamaged = true;
  202. end
  203.  
  204. self.Think = self.AugerThink;
  205. self.Entity:NextThink( CurTime() );
  206. self.m_flAugerTime = CurTime() + 1.5;
  207. self.m_flMarkDeadTime = CurTime() + 0.75;
  208.  
  209. // Let the RPG start reloading immediately
  210. if ( self.m_hOwner != NULL ) then
  211. self.m_hOwner:NotifyRocketDied();
  212. self.m_hOwner = NULL;
  213. end
  214.  
  215. end
  216.  
  217.  
  218. //-----------------------------------------------------------------------------
  219. // The actual explosion
  220. //-----------------------------------------------------------------------------
  221. function ENT:DoExplosion()
  222.  
  223. util.BlastDamage ( self.Entity, self:GetOwner(), self.Entity:GetPos(), 250, 150 );
  224.  
  225. // Explode
  226. ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), GetOwnerEntity(), GetDamage(), GetDamage() * 2, bit.bor(SF_ENVEXPLOSION_NOSPARKS, SF_ENVEXPLOSION_NODLIGHTS, SF_ENVEXPLOSION_NOSMOKE), 0.0, this);
  227.  
  228. end
  229.  
  230.  
  231. //-----------------------------------------------------------------------------
  232. // Purpose:
  233. //-----------------------------------------------------------------------------
  234. function ENT:Explode()
  235.  
  236. // Don't explode against the skybox. Just pretend that
  237. // the missile flies off into the distance.
  238. local forward;
  239.  
  240. forward = self.Entity:GetForward();
  241.  
  242. local tr = {};
  243. tr.start = self.Entity:GetPos();
  244. tr.endpos = self.Entity:GetPos() + forward * 16;
  245. tr.mask = MASK_SHOT;
  246. tr.filter = self;
  247. tr.collision = COLLISION_GROUP_NONE;
  248. tr = util.TraceLine( tr );
  249.  
  250. self.m_takedamage = DAMAGE_NO;
  251. self.Entity:SetSolid( SOLID_NONE );
  252. if( tr.Fraction == 1.0 || !(tr.HitSky) ) then
  253. self:DoExplosion();
  254. end
  255.  
  256. if( self.m_hRocketTrail ) then
  257. self.m_hRocketTrail:SetLifetime(0.1);
  258. self.m_hRocketTrail = NULL;
  259. end
  260.  
  261. if ( self.m_hOwner != NULL ) then
  262. self.m_hOwner:NotifyRocketDied();
  263. self.m_hOwner = NULL;
  264. end
  265.  
  266. util.BlastDamage ( self.Entity, self:GetOwner(), self.Entity:GetPos(), 250, 150 );
  267.  
  268. self.Entity:StopSound( "Missile.Ignite" );
  269. self.Entity:Remove();
  270.  
  271. end
  272.  
  273. //-----------------------------------------------------------------------------
  274. // Purpose:
  275. // Input : *pOther -
  276. //-----------------------------------------------------------------------------
  277. function ENT:Touch( pOther )
  278.  
  279. // Don't touch triggers (but DO hit weapons)
  280. if ( pOther:GetCollisionGroup() != COLLISION_GROUP_WEAPON ) then
  281. return;
  282. end
  283.  
  284. self:Explode();
  285.  
  286. end
  287.  
  288. //-----------------------------------------------------------------------------
  289. // Purpose:
  290. //-----------------------------------------------------------------------------
  291. function ENT:CreateSmokeTrail()
  292.  
  293. if ( self.m_hRocketTrail ) then
  294. return;
  295. end
  296.  
  297. end
  298.  
  299.  
  300. //-----------------------------------------------------------------------------
  301. // Purpose:
  302. //-----------------------------------------------------------------------------
  303. function ENT:IgniteThink()
  304.  
  305. self.Entity:SetMoveType( MOVETYPE_FLY );
  306. self.Entity:SetModel("models/weapons/w_missile.mdl");
  307. self.Entity:SetCollisionBounds( vec3_origin, vec3_origin );
  308. self.Entity:SetSolid( SOLID_NONE );
  309.  
  310. //TODO: Play opening sound
  311.  
  312. local vecForward;
  313.  
  314. self.Entity:EmitSound( "Missile.Ignite" );
  315.  
  316. vecForward = self.Entity:GetLocalAngles();
  317. self.Entity:SetVelocity( vecForward * RPG_SPEED );
  318.  
  319. self.Think = self.SeekThink;
  320. self.Entity:NextThink( CurTime() );
  321.  
  322. if ( self.m_hOwner && self.m_hOwner:GetOwner() ) then
  323. local pPlayer = self.m_hOwner:GetOwner();
  324.  
  325. local white = Color( 255,225,205,64 );
  326. //UTIL_ScreenFade( pPlayer, white, 0.1f, 0.0f, FFADE_IN );
  327. end
  328.  
  329. self:CreateSmokeTrail();
  330.  
  331. end
  332.  
  333.  
  334. //-----------------------------------------------------------------------------
  335. // Gets the shooting position
  336. //-----------------------------------------------------------------------------
  337. function ENT:GetShootPosition( pLaserDot, pShootPosition )
  338.  
  339. if ( pLaserDot:GetOwner() != NULL ) then
  340. //FIXME: Do we care this isn't exactly the muzzle position?
  341. pShootPosition = pLaserDot:GetOwner():LocalToWorld( pLaserDot:GetOwner():OBBCenter() );
  342. else
  343. pShootPosition = pLaserDot:GetChasePosition();
  344. end
  345.  
  346. end
  347.  
  348.  
  349. //-----------------------------------------------------------------------------
  350. // Purpose:
  351. //-----------------------------------------------------------------------------
  352. RPG_HOMING_SPEED = 0.125
  353.  
  354. function ENT:ComputeActualDotPosition( pLaserDot, pActualDotPosition, pHomingSpeed )
  355.  
  356. pHomingSpeed = RPG_HOMING_SPEED;
  357. if ( pLaserDot:GetTargetEntity() ) then
  358. pActualDotPosition = pLaserDot:GetChasePosition();
  359. return;
  360. end
  361.  
  362. local vLaserStart;
  363. vLaserStart = self:GetShootPosition( pLaserDot );
  364.  
  365. //Get the laser's vector
  366. local vLaserDir;
  367. vLaserDir = VectorSubtract( pLaserDot:GetChasePosition(), vLaserStart );
  368.  
  369. //Find the length of the current laser
  370. local flLaserLength = VectorNormalize( vLaserDir );
  371.  
  372. //Find the length from the missile to the laser's owner
  373. local flMissileLength = self.Entity:GetPos():Distance( vLaserStart );
  374.  
  375. //Find the length from the missile to the laser's position
  376. local vecTargetToMissile;
  377. vecTargetToMissile = VectorSubtract( self.Entity:GetPos(), pLaserDot:GetChasePosition() );
  378. local flTargetLength = VectorNormalize( vecTargetToMissile );
  379.  
  380. // See if we should chase the line segment nearest us
  381. if ( ( flMissileLength < flLaserLength ) || ( flTargetLength <= 512.0 ) ) then
  382. pActualDotPosition = UTIL_PointOnLineNearestPoint( vLaserStart, pLaserDot:GetChasePosition(), GetAbsOrigin() );
  383. pActualDotPosition = pActualDotPosition + ( vLaserDir * 256.0 );
  384. else
  385. // Otherwise chase the dot
  386. pActualDotPosition = pLaserDot:GetChasePosition();
  387. end
  388.  
  389. // NDebugOverlay::Line( pLaserDot->GetChasePosition(), vLaserStart, 0, 255, 0, true, 0.05f );
  390. // NDebugOverlay::Line( GetAbsOrigin(), *pActualDotPosition, 255, 0, 0, true, 0.05f );
  391. // NDebugOverlay::Cross3D( *pActualDotPosition, -Vector(4,4,4), Vector(4,4,4), 255, 0, 0, true, 0.05f );
  392.  
  393. end
  394.  
  395.  
  396. //-----------------------------------------------------------------------------
  397. // Purpose:
  398. //-----------------------------------------------------------------------------
  399. function ENT:SeekThink()
  400.  
  401. local pBestDot = NULL;
  402. local flBestDist = MAX_TRACE_LENGTH;
  403. local dotDist;
  404.  
  405. // If we have a grace period, go solid when it ends
  406. if ( self.m_flGracePeriodEndsAt ) then
  407. if ( self.m_flGracePeriodEndsAt < CurTime() ) then
  408. self.Entity:SetSolid( SOLID_NONE );
  409. self.m_flGracePeriodEndsAt = 0;
  410. end
  411. end
  412.  
  413. //Search for all dots relevant to us
  414. for _, pEnt in pairs( self:GetLaserDotList() ) do
  415. if ( !pEnt:IsOn() ) then
  416. break;
  417. end
  418.  
  419. if ( pEnt:GetOwner() != self.Entity:GetOwner() ) then
  420. break;
  421. end
  422.  
  423. dotDist = (self.Entity:GetPos() - pEnt:GetPos()):Length();
  424.  
  425. //Find closest
  426. if ( dotDist < flBestDist ) then
  427. pBestDot = pEnt;
  428. flBestDist = dotDist;
  429. end
  430. end
  431.  
  432. //If we have a dot target
  433. if ( pBestDot == NULL ) then
  434. //Think as soon as possible
  435. self.Entity:NextThink( CurTime() );
  436. return;
  437. end
  438.  
  439. local pLaserDot = pBestDot;
  440. local targetPos;
  441.  
  442. local flHomingSpeed;
  443. local vecLaserDotPosition;
  444. self:ComputeActualDotPosition( pLaserDot, targetPos, flHomingSpeed );
  445.  
  446. if ( self:IsSimulatingOnAlternateTicks() ) then
  447. flHomingSpeed = flHomingSpeed * 2;
  448. end
  449.  
  450. local vTargetDir;
  451. vTargetDir = VectorSubtract( targetPos, self.Entity:GetPos() );
  452. local flDist = VectorNormalize( vTargetDir );
  453.  
  454. local vDir = self.Entity:GetVelocity();
  455. local flSpeed = VectorNormalize( vDir );
  456. local vNewVelocity = vDir;
  457. if ( FrameTime() > 0.0 ) then
  458. if ( flSpeed != 0 ) then
  459. vNewVelocity = ( flHomingSpeed * vTargetDir ) + ( ( 1 - flHomingSpeed ) * vDir );
  460.  
  461. // This computation may happen to cancel itself out exactly. If so, slam to targetdir.
  462. if ( VectorNormalize( vNewVelocity ) < 1e-3 ) then
  463. if (flDist != 0) then
  464. vNewVelocity = vTargetDir;
  465. else
  466. vNewVelocity = vDir;
  467. end
  468. end
  469. else
  470. vNewVelocity = vTargetDir;
  471. end
  472. end
  473.  
  474. local finalAngles;
  475. finalAngles = VectorAngles( vNewVelocity );
  476. self.Entity:SetAngles( finalAngles );
  477.  
  478. vNewVelocity = vNewVelocity * flSpeed;
  479. self.Entity:SetVelocity( vNewVelocity );
  480.  
  481. if( self.Entity:GetVelocity() == vec3_origin ) then
  482. // Strange circumstances have brought this missile to halt. Just blow it up.
  483. self:Explode();
  484. return;
  485. end
  486.  
  487. // Think as soon as possible
  488. self.Entity:NextThink( CurTime() );
  489.  
  490. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement