Advertisement
Redxone

[ZScript] GZDoom Simple Laser API!

Dec 28th, 2017
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.29 KB | None | 0 0
  1. /*
  2.             SecuLaserz ClassAPI created by Lewisk3 (Redxone)
  3.        
  4.     SPECIAL THANKS:
  5.         Xaser (One of the main reasons i got into Doom modding)
  6.         phantombeta (ZScript sensei)
  7.         TheZombieKiller (ZScript sensei)
  8.         Tapwave (Some design, ZScript help)
  9.         Gutawer (Helped out in just about every question/problem i had.)
  10.        
  11.     Disclaimer:
  12.         There are multiple ways to do lasers, this one creates them out of sprites
  13.         which if done right can look really good. You could also use a 3D model (If you are a masochist)
  14.         or a couple flat sprites.      
  15.  
  16.     Copyright:
  17.         You may use this in your mod provided you DO NOT remove this
  18.         comment block.
  19.         Please provide credit if you decide to post your mod on the forums
  20.         and you are using this API.
  21.    
  22.     Documentation:
  23.     |
  24.     |1  Creating lasers
  25.     |   --> To create a laser from complete scratch you must follow 3 steps.
  26.     |       : 1 - Include this file in your main ZScript lump. Example below
  27.     |         | Create a ZSCRIPT lump inside put
  28.     |         | #include "<location>/lasers.zsc"
  29.     |       : 2 - Initialize laser sprites. Example below.
  30.     |         | class LaserSpritesYay : Actor
  31.     |         | {
  32.     |         |     States
  33.     |         |     {
  34.     |         |         Sprites: // State can be called whatever you want too!
  35.     |         |             #### # -1;
  36.     |         |             #### # -1;
  37.     |         |             //etc..
  38.     |         |     }
  39.     |         | }
  40.     |       : 3 - Create a laser class extending MWLaser. Example below
  41.     |         |  class MyLaser : MWLaser {};   
  42.     |         This laser will currently fire an invisble beam dealing 5 damage!
  43.     |      
  44.     |2  Customizing lasers
  45.     |   --> There are multiple properties you can use to customize your lasers. See Below
  46.     |        MWLaser.frontOffset    : How far infront of the player the laser is. (Def -100, front to back).
  47.     |        MWLaser.range          : How far the laser can shoot. (Damage dropoff).
  48.     |        MWLaser.laserSprite    : How the laser will look. (Takes a sprite name "####").
  49.     |        MWLaser.laserSize      : How large a laser looks. (Def 0.15, works like Scale).
  50.     |        MWLaser.speedFactor    : How fast the laser moves relative to "lightspeed" (Def 1.0);
  51.     |3  Firing lasers
  52.     |   --> There are 2 ways to fire a laser
  53.     |       : 1 - Use LaserWeapon
  54.     |         | This way is the easiest but requires you are firing it from a weapon.
  55.     |         | To use LaserWeapon extend your weapon by it. (class Pewpew : LaserWeapon)
  56.     |         | In your "Fire" state call shootLaser or shootLaserEx
  57.     |         | shootLaser(Name laserclass, int offsx, int offsy, Name laserpuff);
  58.     |         | shootLaserEx(Name laserclass, int offsx, int offsy, Name laserpuff, int frontOffset);
  59.     |       : 2 - Use A_FireProjectile
  60.     |         | This way is more manual but will work on anything that supports FireProjectile.
  61.     |         | A_FireProjectile(Name class, int angle, bool useammo, int offsx, int offsy);
  62.     |         | It is also very powerful, you can use it to access every laser property! Example below.
  63.     |         | let laserproj = A_FireProjectile(...);
  64.     |         | let laser = MWLaser (laserproj);
  65.     |         | laser.<property> = <value>
  66.     |         | The properties go by their variable names and not by their default definitions. See Below
  67.     |         | frontOffset = DistanceOffs
  68.     |         | range       = MaxRange
  69.     |         | laserSprite = graphic
  70.     |         | laserSize   = graphicScalar
  71.     End Doc.
  72. */
  73.  
  74.  
  75. class LaserWeapon : Weapon
  76. {
  77.     action void shootLaser(Name laserclass, int sx, int sz, Name puff)
  78.     {
  79.         let laser = MWLaser (A_FireProjectile(laserclass,0,0,sx,sz));
  80.         if(laser) A_FireBullets(0,0,1,0.1,puff,0,laser.MaxRange*32);
  81.     }
  82.    
  83.     action void shootPlasma(Name plasmaclass, int sx, int sz, int offs)
  84.     {
  85.         let laser = MWPlasma (A_FireProjectile(plasmaclass,0,0,sx,sz));
  86.         if(laser && offs > 0) laser.distanceoffs = offs;
  87.     }
  88.    
  89.     action Actor shootPlasmaEx(Name plasmaclass, int sx, int sz, int pangle, int ppitch, int offs)
  90.     {
  91.         let laser = MWPlasma (A_FireProjectile(plasmaclass,0,0,sx,sz,0,ppitch));
  92.         if(laser)
  93.         {
  94.             if(offs > 0) laser.distanceoffs = offs;
  95.             if(pangle > 0) laser.customAngle = -pangle;
  96.         }
  97.         return laser;
  98.     }
  99.    
  100.     action Actor shootLaserEx(Name laserclass, int sx, int sz, Name puff, int distance, double scale, int range, double speedFactor)
  101.     {
  102.         let laser = MWLaser (A_FireProjectile(laserclass,0,0,sx,sz));
  103.         if(laser)
  104.         {
  105.             A_FireBullets(0,0,1,0.1,puff,0,range*32);
  106.             laser.DistanceOffs = distance;
  107.             laser.MaxRange = range;
  108.             laser.graphicScalar = scale;
  109.             laser.speedOffs = speedFactor;
  110.         }
  111.         return laser;
  112.     }
  113. }
  114.  
  115. class LaserFollower : FastProjectile
  116. {
  117.     string followSprite;
  118.     int lifetime;
  119.     property lsprite: followSprite;
  120.     property live : lifetime;
  121.  
  122.     Default
  123.     {
  124.         +NOGRAVITY
  125.         +NOINTERACTION
  126.         +NOBLOCKMAP
  127.         Radius 2;
  128.         Height 2;
  129.         Alpha 1.0;
  130.         Speed 0;
  131.         RenderStyle "Add";
  132.         Damage 0;
  133.         Scale 0.15;
  134.         PROJECTILE;
  135.         //LaserFollower.lsprite "TNT1";
  136.         LaserFollower.live 1;
  137.         +RANDOMIZE
  138.     }
  139.    
  140.     States
  141.     {
  142.         Spawn:
  143.             TNT1 A 0; // Interesting little bug here that NoDelay doesn't fix.
  144.             TNT1 A 1 Fast
  145.             {
  146.                 tics = lifetime;
  147.                 sprite = GetSpriteIndex(invoker.followSprite);
  148.             }
  149.         stop;
  150.  
  151.     }
  152. }
  153.  
  154.  
  155. class MWLaser : FastProjectile
  156. {
  157.  
  158.     int DistanceOffs;
  159.     int MaxRange;
  160.     int DistanceTraveled; // In meters.
  161.     string graphic;
  162.     double graphicScalar;
  163.     double speedOffs;
  164.     double laserdensity;
  165.     double laserConverge;
  166.     int followDuration;
  167.     int trailrng;
  168.     int laserRenderAmt;
  169.  
  170.     property frontOffset: DistanceOffs;
  171.     property range : MaxRange;
  172.     property InitalRange: DistanceTraveled;
  173.     property laserSprite : graphic;
  174.     property laserSize  : graphicScalar;
  175.     property speedFactor : speedOffs;
  176.     property laserDensity : laserdensity;
  177.     property trailDuration : followDuration;
  178.     property laserRenderDistance : laserRenderAmt;
  179.     property trailChance : trailrng;
  180.     property convergeScalar : laserConverge;
  181.    
  182.     Default
  183.     {
  184.         // Laser Range:
  185.         // 200upt.
  186.         // 32units = 1m
  187.         // 1 frame = 7m.
  188.        
  189.         +NOGRAVITY
  190.         Radius 1;
  191.         Height 1;
  192.         Alpha 1.0;
  193.         Speed 200; // "Lightspeed"
  194.         RenderStyle "Add";
  195.         Damage 0;
  196.         Decal "DoomImpScorch";
  197.         PROJECTILE;
  198.         MWLaser.frontOffset -98;
  199.         MWLaser.range 500;
  200.         MWLaser.InitalRange 0;
  201.         MWLaser.laserSprite "TNT1";
  202.         MWLaser.laserSize 0.10;
  203.         MWLaser.speedFactor 1.0;
  204.         MWLaser.trailDuration 1;
  205.         MWLaser.trailChance 0;
  206.         MWLaser.laserDensity 50.0;
  207.         MWLaser.laserRenderDistance 200;
  208.         MWLaser.convergeScalar 1.0;
  209.         +RANDOMIZE
  210.     }
  211.    
  212.     Override void postBeginPlay()
  213.     {
  214.         spawnLaser("LaserFollower");
  215.         Super.postBeginPlay();
  216.     }
  217.     Override void tick()
  218.     {
  219.         //A_Warp(AAPTR_TARGET,0,0,-10, 0, WARPF_COPYVELOCITY | WARPF_COPYINTERPOLATION );
  220.         DistanceTraveled += floor(speed/32)+1;
  221.         if(DistanceTraveled >= MaxRange)Destroy();
  222.         //console.printf("%s: %i :> %i","Laser dist: ",DistanceTraveled,MaxRange);
  223.         Super.tick();
  224.     }
  225.    
  226.     void spawnLaser(Name laserclass)
  227.     {
  228.         if(DistanceTraveled < MaxRange)
  229.         {
  230.             int distc = DistanceOffs;
  231.             double fD = distc;
  232.             double sx = 0.06;
  233.             double sy = 0.06;
  234.             double density = laserdensity+CVar.findCVar("sd_lasers_densityoffset").getInt();
  235.             for(double i = 0; i < laserRenderAmt; i++)
  236.             {
  237.                 if(random(0,trailrng) == trailrng)
  238.                 {
  239.                     //console.printf("%i: %s :> %d",i,"Laser",fD);
  240.                     double spawnX = ((fD*velx)/-density);
  241.                     double spawnY = -(fD*vely)/-density;
  242.                     double spawnZ = 2+(fD*velz)/-density;
  243.                     bool success; Actor trail;
  244.                     [success, trail] = A_SpawnItemEx(laserclass, spawnX, spawnY, spawnZ, 0,0,0,0, SXF_ABSOLUTEANGLE | SXF_NOCHECKPOSITION);
  245.                     let las = LaserFollower(trail);
  246.                     las.followSprite = graphic;
  247.                     las.ScaleX        =sx; //graphicScalar- (i / 100)/10;
  248.                     las.ScaleY        =sy; //graphicScalar- (i / 100)/10;
  249.                     las.lifetime      = followDuration;
  250.                     sx += (graphicScalar/(laserRenderAmt*laserConverge));
  251.                     sy += (graphicScalar/(laserRenderAmt*laserConverge));
  252.                     fD = distc+((i+1)/2);
  253.                 }
  254.             }
  255.         }
  256.     }
  257.    
  258.     // Used for max-range.
  259.     States
  260.     {
  261.         Spawn:
  262.         TNT1 A 0 NoDelay
  263.         {
  264.             A_ScaleVelocity(invoker.speedOffs);
  265.             //spawnLaser("LaserFollower");
  266.         }
  267.         LaserDone:
  268.             TNT1 A 1;
  269.         loop;
  270.     }
  271. }
  272.  
  273. class PlasmaSlugFollower : FastProjectile
  274. {
  275.     string followSprite;
  276.     string deathSprite;
  277.     property lsprite: followSprite;
  278.     property dsprite:  deathSprite;
  279.    
  280.     Default
  281.     {
  282.         +NOINTERACTION
  283.         +NOBLOCKMAP
  284.         +NOGRAVITY
  285.         Radius 2;
  286.         Height 4;
  287.         Alpha 1.0;
  288.         Speed 25;
  289.         RenderStyle "Add";
  290.         Damage 0;
  291.         Scale 0.25;
  292.         PlasmaSlugFollower.lsprite "TNT1";
  293.         PROJECTILE;
  294.     }
  295.     States
  296.     {  
  297.         Spawn:
  298.             TNT1 A 0; // Interesting little bug here that NoDelay doesn't fix.
  299.             TNT1 A 25
  300.             {
  301.                 sprite = GetSpriteIndex(invoker.followSprite);
  302.             }
  303.         stop;
  304.         Death:
  305.             TNT1 A 1;
  306.         stop;
  307.     }
  308. }
  309.  
  310. class MWPlasma : FastProjectile
  311. {
  312.     double speedMul;
  313.     double plasmadensity;
  314.     string graphic;
  315.     double plasmascale;
  316.     string deathgraphic;
  317.     int distanceoffs;
  318.     int customangle;
  319.     int plasmaRender;
  320.    
  321.     property speedFactor: speedMul;
  322.     property plasmaDensity : plasmadensity;
  323.     property plasmaSprite : graphic;
  324.     property plasmaDistance : distanceoffs;
  325.     property plasmaSize : plasmascale;
  326.     property specificAngle : customAngle;
  327.     property collideSprite : deathgraphic;
  328.     property plasmaRenderDistance : plasmaRender;
  329.  
  330.     Default
  331.     {
  332.         +NOGRAVITY
  333.         Radius 2;
  334.         Height 4;
  335.         Alpha 1.0;
  336.         Speed 25;
  337.         RenderStyle "Add";
  338.         Damage 5;
  339.         Decal "DoomImpScorch";
  340.         MWPlasma.speedFactor 1.0;
  341.         MWPlasma.plasmaDistance 1;
  342.         MWPlasma.plasmaDensity 35.0;
  343.         MWPlasma.plasmaSprite "TNT1";
  344.         MWPlasma.plasmaSize 1.0;
  345.         MWPlasma.specificAngle 0;
  346.         MWPlasma.collideSprite "TNT1";
  347.         MWPlasma.plasmaRenderDistance 20;
  348.         PROJECTILE;
  349.     }
  350.    
  351.     void spawnPlasma(Name plasmaclass)
  352.     {
  353.         int distc = distanceoffs;
  354.         int fD = distc;
  355.         double density = plasmadensity+CVar.findCVar("sd_lasers_densityoffset").getInt();
  356.         for(double i = 0; i < plasmaRender; i++)
  357.         {
  358.             bool _; Actor aplasma;
  359.             [_, aplasma] = A_SpawnItemEx(plasmaclass, ((fD*velx)/-density), -(fD*vely)/-density, 2+(fD*velz)/-density, velx, -vely,velz,customAngle*random(-1,1), SXF_ABSOLUTEANGLE | SXF_NOCHECKPOSITION);
  360.             let plasma = PlasmaSlugFollower(aplasma);
  361.             plasma.followSprite = graphic;
  362.             plasma.ScaleX = plasmascale;
  363.             plasma.ScaleY = plasmaScale;
  364.             fD = distc+((i+1)/2);
  365.         }
  366.     }
  367.    
  368.     States
  369.     {
  370.         Spawn:
  371.             TNT1 A 0 NoDelay
  372.             {
  373.                 A_ScaleVelocity(invoker.speedMul);
  374.                 spawnPlasma("PlasmaSlugFollower");
  375.             }
  376.         SpawnLoop:
  377.             TNT1 A 1;
  378.         loop;
  379.         Death:
  380.             TNT1 ABCDEF 1 Bright
  381.             {
  382.                 sprite = GetSpriteIndex(invoker.deathgraphic);
  383.             }
  384.         stop;
  385.     }
  386. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement